[PECL-CVS] [pecl-database-pdo_oci] pdo_oci_param_int_fix: Initial commit

[email protected] (Sharad Chandran R) Wed, 7 Jan 2026 06:31:18 +0000
Newsgroups php.pecl.cvs
Message-ID <[email protected]>
Author: Sharad Chandran R (sharadraju)
Date: 2026-01-07T09:22:26+05:30

Commit: https://github.com/php/pecl-database-pdo_oci/commit/d752646e0372fb3ca99f1424c9efe656e825f0ec
Raw diff: https://github.com/php/pecl-database-pdo_oci/commit/d752646e0372fb3ca99f1424c9efe656e825f0ec.diff

Initial commit

Changed paths:
  A  tests/pdo_oci_bind_int.phpt
  M  oci_statement.c
  M  php_pdo_oci_int.h


Diff:

diff --git a/oci_statement.c b/oci_statement.c
index 440055b..24cf66b 100644
--- a/oci_statement.c
+++ b/oci_statement.c
@@ -225,23 +225,39 @@ static sb4 oci_bind_input_cb(dvoid *ctx, OCIBind *bindp, ub4 iter, ub4 index, dv
 		*bufpp = 0;
 		*alenp = -1;
 	} else if (!P->thing) {
-		if(PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_BOOL) {
-			/* Handle boolean as "1"/ "0" */
-			if(zend_is_true(parameter)) {
-				zval_ptr_dtor(parameter);
-				ZVAL_CHAR(parameter, '1');
-			} else {
-				zval_ptr_dtor(parameter);
-				ZVAL_CHAR(parameter, '0');
+		if (P->oci_type == SQLT_INT)
+		{
+			P->int_val = (sb4) zval_get_long(parameter);
+			*bufpp = &P->int_val;
+			*alenp = sizeof(sb4);
+		}
+		else
+		{
+			if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_BOOL)
+			{
+				/* Handle boolean as "1"/ "0" */
+				if (zend_is_true(parameter))
+				{
+					zval_ptr_dtor(parameter);
+					ZVAL_CHAR(parameter, '1');
+				}
+				else
+				{
+					zval_ptr_dtor(parameter);
+					ZVAL_CHAR(parameter, '0');
+				}
 			}
-		} else {
-			/* regular string bind */
-			if (!try_convert_to_string(parameter)) {
-				return OCI_ERROR;
+			else
+			{
+				/* regular string bind */
+				if (!try_convert_to_string(parameter))
+				{
+					return OCI_ERROR;
+				}
 			}
+			*bufpp = Z_STRVAL_P(parameter);
+			*alenp = (ub4) Z_STRLEN_P(parameter);
 		}
-		*bufpp = Z_STRVAL_P(parameter);
-		*alenp = (ub4) Z_STRLEN_P(parameter);
 	}
 
 	*piecep = OCI_ONE_PIECE;
@@ -272,6 +288,17 @@ static sb4 oci_bind_output_cb(dvoid *ctx, OCIBind *bindp, ub4 iter, ub4 index, d
 		return OCI_CONTINUE;
 	}
 
+	if (P->oci_type == SQLT_INT)
+	{
+		P->actual_len = sizeof(sb4);
+		*bufpp = &P->int_val;
+		*alenpp = &P->actual_len;
+		*piecep = OCI_ONE_PIECE;
+		*rcodepp = &P->retcode;
+		*indpp = &P->indicator;
+		return OCI_CONTINUE;
+	}
+
 	if (Z_TYPE_P(parameter) == IS_OBJECT || Z_TYPE_P(parameter) == IS_RESOURCE) {
 		return OCI_CONTINUE;
 	}
@@ -343,6 +370,11 @@ static int oci_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *pa
 						value_sz = (sb4) sizeof(OCILobLocator*);
 						break;
 
+					case PDO_PARAM_INT:
+						P->oci_type = SQLT_INT;
+						value_sz = (sb4) sizeof(sb4);
+						break;
+
 					case PDO_PARAM_STR:
 					default:
 						P->oci_type = SQLT_CHR;
@@ -392,11 +424,12 @@ static int oci_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *pa
 						/* set up a NULL value */
 						if (Z_TYPE_P(parameter) == IS_STRING) {
 							/* OCI likes to stick non-terminated strings in things */
-							*Z_STRVAL_P(parameter) = '\0';
+							*Z_STRVAL_P(param
+								eter) = '\0';
 						}
 						zval_ptr_dtor_str(parameter);
 						ZVAL_UNDEF(parameter);
-					} else if (Z_TYPE_P(parameter) == IS_STRING) {
+					}	else if (Z_TYPE_P(parameter) == IS_STRING) {
 						Z_STR_P(parameter) = zend_string_init(Z_STRVAL_P(parameter), P->actual_len, 1);
 					}
 				} else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB && P->thing) {
diff --git a/php_pdo_oci_int.h b/php_pdo_oci_int.h
index dd513ff..0afd172 100644
--- a/php_pdo_oci_int.h
+++ b/php_pdo_oci_int.h
@@ -84,6 +84,8 @@ typedef struct {
 
 	dvoid		*thing;	/* for LOBS, REFCURSORS etc. */
 
+	sb4			int_val;
+
 	unsigned used_for_output;
 } pdo_oci_bound_param;
 
diff --git a/tests/pdo_oci_bind_int.phpt b/tests/pdo_oci_bind_int.phpt
new file mode 100644
index 0000000..d27ae5d
--- /dev/null
+++ b/tests/pdo_oci_bind_int.phpt
@@ -0,0 +1,49 @@
+--TEST--
+PDO_OCI: Integer binding test
+--EXTENSIONS--
+pdo
+pdo_oci
+--SKIPIF--
+<?php
+require(getenv('PDO_TEST_DIR').'/pdo_test.inc');
+PDOTest::skip();
+?>
+--FILE--
+<?php
+
+require_once(getenv('PDO_TEST_DIR').'/pdo_test.inc');
+
+$conn = PDOTest::factory();
+
+$sql = 'SELECT :a a, dump(:a) a_type, :b b, dump(:b) b_type, '
+  . '4 num, dump(4) num_type, \'4\' str, dump(\'4\') str_type, '
+  . '(select 1 from dual where \'04\' = :a) a_where, '
+  . '(select 1 from dual where \'04\' = 4) num_where '
+  . 'FROM dual';
+$num = 4;
+$str = '4';
+
+$statement = $conn->prepare($sql);
+$statement->bindValue(':a', $num, PDO::PARAM_INT);
+$statement->bindValue(':b', $str);
+$statement->execute();
+$row = $statement->fetch(PDO::FETCH_ASSOC);
+print_r($row);
+var_dump($row['a_where']);
+
+?>
+--EXPECT--
+Array
+(
+    [a] => 4
+    [a_type] => Typ=2 Len=2: 193,5
+    [b] => 4
+    [b_type] => Typ=1 Len=1: 52
+    [num] => 4
+    [num_type] => Typ=2 Len=2: 193,5
+    [str] => 4
+    [str_type] => Typ=96 Len=1: 52
+    [a_where] => 1
+    [num_where] => 1
+)
+string(1) "1"