]> granicus.if.org Git - php/commitdiff
Fix #42496. Cursor leak fetching LOBs
authorChristopher Jones <sixd@php.net>
Tue, 11 Dec 2007 06:07:13 +0000 (06:07 +0000)
committerChristopher Jones <sixd@php.net>
Tue, 11 Dec 2007 06:07:13 +0000 (06:07 +0000)
ext/oci8/oci8_statement.c
ext/oci8/tests/bug42496_1.phpt [new file with mode: 0644]
ext/oci8/tests/bug42496_2.phpt [new file with mode: 0644]
ext/oci8/tests/lob_041.phpt [new file with mode: 0644]

index 6b03536772c822f083e6169a2fc2f1e3d6bd654a..c4bf10652bf5e1e7d5399b9d467441b5dcb4c72b 100644 (file)
@@ -368,7 +368,6 @@ sb4 php_oci_define_callback(dvoid *ctx, OCIDefine *define, ub4 iter, dvoid **buf
                                if (!descr) {
                                        return OCI_ERROR;
                                }
-                               zend_list_addref(outcol->statement->id);
                                outcol->descid = descr->id;
                                descr->charset_form = outcol->charset_form;
                                
diff --git a/ext/oci8/tests/bug42496_1.phpt b/ext/oci8/tests/bug42496_1.phpt
new file mode 100644 (file)
index 0000000..4d7e2c5
--- /dev/null
@@ -0,0 +1,61 @@
+--TEST--
+Bug #42496 (LOB fetch leaks cursors, eventually failing with ORA-1000 maximum open cursors reached)
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die ("skip no oci8 extension"); ?>
+--FILE--
+<?php
+
+require dirname(__FILE__).'/connect.inc';
+
+// Initialization
+
+$stmtarray = array(
+       "DROP table bug42496_tab",
+       "CREATE table bug42496_tab(c1 CLOB, c2 CLOB)",
+       "INSERT INTO bug42496_tab VALUES('test1', 'test1')",
+       "INSERT INTO bug42496_tab VALUES('test2', 'test2')",
+       "INSERT INTO bug42496_tab VALUES('test3', 'test3')"
+);
+
+foreach ($stmtarray as $stmt) {
+       $s = oci_parse($c, $stmt);
+       @oci_execute($s);
+}
+
+// Run Test
+
+echo "Test 1\n";
+
+for ($i = 0; $i < 15000; $i++) {
+       $s = oci_parse($c, "SELECT * from bug42496_tab");
+       oci_define_by_name($s, "C1", $col1);
+       oci_define_by_name($s, "C2", $col2);
+       if (oci_execute($s)) {
+               $arr = array();
+               while ($arr = oci_fetch_assoc($s)) {
+                       $arr['C1']->free();
+                       $arr['C2']->free();
+               }
+       }
+       oci_free_statement($s);
+}
+
+echo "Done\n";
+
+// Cleanup
+
+$stmtarray = array(
+       "DROP table bug42496_tab"
+);
+
+foreach ($stmtarray as $stmt) {
+       $s = oci_parse($c, $stmt);
+       @oci_execute($s);
+}
+
+oci_close($c);
+
+?>
+--EXPECTF--
+Test 1
+Done
diff --git a/ext/oci8/tests/bug42496_2.phpt b/ext/oci8/tests/bug42496_2.phpt
new file mode 100644 (file)
index 0000000..e2800bb
--- /dev/null
@@ -0,0 +1,59 @@
+--TEST--
+Bug #42496 (LOB fetch leaks cursors, eventually failing with ORA-1000 maximum open cursors reached)
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die ("skip no oci8 extension"); ?>
+--FILE--
+<?php
+
+require dirname(__FILE__).'/connect.inc';
+
+// Initialization
+
+$stmtarray = array(
+       "DROP table bug42496_tab",
+       "CREATE table bug42496_tab(c1 CLOB, c2 CLOB)",
+       "INSERT INTO bug42496_tab VALUES('test1', 'test1')",
+       "INSERT INTO bug42496_tab VALUES('test2', 'test2')",
+       "INSERT INTO bug42496_tab VALUES('test3', 'test3')"
+);
+
+foreach ($stmtarray as $stmt) {
+       $s = oci_parse($c, $stmt);
+       @oci_execute($s);
+}
+
+// Run Test
+
+echo "Test 2\n";
+
+for ($i = 0; $i < 15000; $i++) {
+       $s = oci_parse($c, "SELECT * from bug42496_tab");
+       if (oci_execute($s)) {
+               $arr = array();
+               while ($arr = oci_fetch_assoc($s)) {
+                       $arr['C1']->free();
+                       $arr['C2']->free();
+               }
+       }
+       oci_free_statement($s);
+}
+
+echo "Done\n";
+
+// Cleanup
+
+$stmtarray = array(
+       "DROP table bug42496_tab"
+);
+
+foreach ($stmtarray as $stmt) {
+       $s = oci_parse($c, $stmt);
+       @oci_execute($s);
+}
+
+oci_close($c);
+
+?>
+--EXPECTF--
+Test 2
+Done
diff --git a/ext/oci8/tests/lob_041.phpt b/ext/oci8/tests/lob_041.phpt
new file mode 100644 (file)
index 0000000..d04b436
--- /dev/null
@@ -0,0 +1,92 @@
+--TEST--
+Check LOBS are valid after statement free
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die ("skip no oci8 extension"); ?>
+--FILE--
+<?php
+
+require dirname(__FILE__).'/connect.inc';
+
+// Initialization
+
+$stmtarray = array(
+       "DROP table lob_041_tab",
+       "CREATE table lob_041_tab(c1 CLOB)",
+       "INSERT INTO lob_041_tab VALUES('test data')"
+);
+
+foreach ($stmtarray as $stmt) {
+       $s = oci_parse($c, $stmt);
+       @oci_execute($s);
+}
+
+echo "Test 1 - explicit statement close\n";
+
+$s = oci_parse($c, "SELECT C1 FROM lob_041_tab");
+$desc = oci_new_descriptor($c, OCI_DTYPE_LOB);
+oci_define_by_name($s, "C1", $desc);
+oci_execute($s);
+$data = oci_fetch_assoc($s);
+oci_free_statement($s);
+echo $data['C1']->load(), "\n";
+oci_free_descriptor($desc);
+
+echo "\nTest 2 - implicit statement close\n";
+
+$s = oci_parse($c, "SELECT C1 FROM lob_041_tab");
+$desc = oci_new_descriptor($c, OCI_DTYPE_LOB);
+oci_define_by_name($s, "C1", $desc);
+oci_execute($s);
+$data = oci_fetch_assoc($s);
+$s = null;
+echo $data['C1']->load(), "\n";
+oci_free_descriptor($desc);
+var_dump($desc);
+
+echo "\nTest 3 - no preallocated descriptor\n";
+
+$s = oci_parse($c, "SELECT C1 FROM lob_041_tab");
+oci_execute($s);
+$data = oci_fetch_assoc($s);
+$s = null;
+echo $data['C1']->load(), "\n";
+var_dump($data);
+
+// Cleanup
+
+echo "Done\n";
+
+$stmtarray = array(
+       "DROP table lob_041_tab"
+);
+
+foreach ($stmtarray as $stmt) {
+       $s = oci_parse($c, $stmt);
+       @oci_execute($s);
+}
+
+oci_close($c);
+
+?>
+
+--EXPECTF--
+Test 1 - explicit statement close
+test data
+
+Test 2 - implicit statement close
+test data
+object(OCI-Lob)#%d (1) {
+  ["descriptor"]=>
+  resource(%d) of type (oci8 descriptor)
+}
+
+Test 3 - no preallocated descriptor
+test data
+array(1) {
+  ["C1"]=>
+  object(OCI-Lob)#%d (1) {
+    ["descriptor"]=>
+    resource(%d) of type (oci8 descriptor)
+  }
+}
+Done