]> granicus.if.org Git - php/commitdiff
Bug #46994 (CLOB size does not update when using CLOB IN OUT param in stored procedure)
authorChristopher Jones <sixd@php.net>
Wed, 11 Mar 2009 16:46:38 +0000 (16:46 +0000)
committerChristopher Jones <sixd@php.net>
Wed, 11 Mar 2009 16:46:38 +0000 (16:46 +0000)
ext/oci8/oci8_statement.c
ext/oci8/tests/bug46994.phpt [new file with mode: 0644]

index 4c21d2a035862331a668ced3da3665c7a8b0e8f3..eb195c8f862a1ac75c7bc2f2f3c6b62ddbef8265 100644 (file)
@@ -1211,9 +1211,24 @@ sb4 php_oci_bind_out_callback(
                }
                retval = OCI_CONTINUE;
        } else if (Z_TYPE_P(val) == IS_OBJECT) {
+               zval **tmp;
+               php_oci_descriptor *desc;
+
                if (!phpbind->descriptor) {
                        return OCI_ERROR;
                }
+
+               /* Do not use the cached lob size if the descriptor is an
+                * out-bind as the contents would have been changed for in/out
+                * binds (Bug #46994).
+                */
+               if (zend_hash_find(Z_OBJPROP_P(val), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find object outbind descriptor property");
+                       return OCI_ERROR;
+               }
+               PHP_OCI_ZVAL_TO_DESCRIPTOR_EX(*tmp, desc);
+               desc->lob_size = -1;    /* force OCI8 to update cached size */
+
                *alenpp = &phpbind->dummy_len;
                *bufpp = phpbind->descriptor;
                *piecep = OCI_ONE_PIECE;
diff --git a/ext/oci8/tests/bug46994.phpt b/ext/oci8/tests/bug46994.phpt
new file mode 100644 (file)
index 0000000..6a83e73
--- /dev/null
@@ -0,0 +1,86 @@
+--TEST--
+Bug #46994 (CLOB size does not update when using CLOB IN OUT param in stored procedure)
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die ("skip no oci8 extension"); ?>
+--FILE--
+<?php
+
+require(dirname(__FILE__).'/connect.inc');
+
+// Initialization
+
+$stmtarray = array(
+       "create or replace procedure bug46994_proc1(p1 in out nocopy clob) is
+                begin
+                        dbms_lob.trim(p1, 0);
+                        dbms_lob.writeappend(p1, 26, 'This should be the output.');
+         end bug46994_proc1;",
+       "create or replace procedure bug46994_proc2(p1 in out nocopy clob) is
+                begin
+                        dbms_lob.trim(p1, 0);
+                        dbms_lob.writeappend(p1, 37, 'The output should be even longer now.');
+         end bug46994_proc2;"
+);
+
+foreach ($stmtarray as $stmt) {
+       $s = oci_parse($c, $stmt);
+       @oci_execute($s);
+}
+
+// Run Test
+
+$myclob = oci_new_descriptor($c, OCI_D_LOB);
+$myclob->writeTemporary("some data", OCI_TEMP_CLOB);
+
+echo "Test 1\n";
+
+$s = oci_parse($c, "begin bug46994_proc1(:myclob); end;");
+oci_bind_by_name($s, ":myclob", $myclob, -1, SQLT_CLOB);
+oci_execute($s, OCI_DEFAULT);
+var_dump($myclob->load());
+
+echo "Test 2\n";
+
+$s = oci_parse($c, "begin bug46994_proc2(:myclob); end;");
+oci_bind_by_name($s, ":myclob", $myclob, -1, SQLT_CLOB);
+oci_execute($s, OCI_DEFAULT);
+var_dump($myclob->load());
+
+echo "Test 3\n";
+
+$s = oci_parse($c, "begin bug46994_proc1(:myclob); end;");
+oci_bind_by_name($s, ":myclob", $myclob, -1, SQLT_CLOB);
+oci_execute($s, OCI_DEFAULT);
+var_dump($myclob->load());
+
+echo "Test 4\n";
+
+var_dump($myclob->load());  // Use cached size code path
+
+// Cleanup
+
+$stmtarray = array(
+       "drop procedure bug46994_proc1",
+       "drop procedure bug46994_proc2"
+);
+
+foreach ($stmtarray as $stmt) {
+       $s = oci_parse($c, $stmt);
+       oci_execute($s);
+}
+
+oci_close($c);
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECTF--
+Test 1
+unicode(26) "This should be the output."
+Test 2
+unicode(37) "The output should be even longer now."
+Test 3
+unicode(26) "This should be the output."
+Test 4
+unicode(26) "This should be the output."
+===DONE===