ID: 43497 User updated by: ghosh at q-one dot com Reported By: ghosh at q-one dot com Status: Open Bug Type: OCI8 related Operating System: Linux 2.6.22-14-server PHP Version: 5.2.5 New Comment:
Really great! Thanks a lot!! This patch works. What I don't understand: I thought OCI_RETURN_LOBS is just a short-cut for those who don't want to write: $s=$result[0]->load(); $result[0]->free(); $result[0]=$s; If you use OCI_RETURN_LOBS you dont want to care about lobs but get the result as a string and forget about lobs altogether. So IMHO this should work as well. My specific problem is solved though. Previous Comments: ------------------------------------------------------------------------ [2007-12-27 21:44:07] [EMAIL PROTECTED] This is really an issue with temporary LOBS since getClobVal() returns a temporary LOB. There are two parts to the fix: changing the script and patching the OCI8 extension. Also don't forget to apply the patch for http://bugs.php.net/bug.php?id=42496 Please test this suggestion and report any issues. Thanks to Krishna & Shankar for the solution. 1. Change the test to get the results as LOBs, not as strings. This allows the script to free temporary LOBs. In the supplied testcase change: $query = "select extract(xml, '/').getclobval() from ugatest"; $stmt = oci_parse($conn, $query); if (oci_execute($stmt)) while ($result = oci_fetch_array($stmt, OCI_NUM+OCI_RETURN_LOBS)) ; to: $query = "select extract(xml, '/').getclobval() from ugatest"; $stmt = oci_parse($conn, $query); if (oci_execute($stmt)) while ($result = oci_fetch_array($stmt, OCI_NUM)) { // echo $result[0]->load(), "\n"; // do something with the XML $result[0]->free(); // free the temporary LOB } The connection must be open when LOB->free() is called, as the underlying OCILobFreeTemporary() call does a roundtrip to the database. 2. Patch oci8_lob.c. The change copies some LOB freeing code from php_oci_lob_close() into php_oci_lob_free(): --- oci8_lob.c.orig 2007-07-31 12:21:08.000000000 -0700 +++ oci8_lob.c 2007-12-27 12:33:19.000000000 -0800 @@ -647,6 +647,9 @@ Close LOB descriptor and free associated resources */ void php_oci_lob_free (php_oci_descriptor *descriptor TSRMLS_DC) { +#ifdef HAVE_OCI8_TEMP_LOB + int is_temporary; +#endif if (!descriptor || !descriptor->connection) { return; @@ -662,6 +665,40 @@ php_oci_lob_flush(descriptor, OCI_LOB_BUFFER_FREE TSRMLS_CC); } +#ifdef HAVE_OCI8_TEMP_LOB + if (descriptor->type == OCI_DTYPE_LOB) { + PHP_OCI_CALL_RETURN(descriptor->connection->errcode, + OCILobIsTemporary, + ( + descriptor->connection->env, + descriptor->connection->err, + descriptor->descriptor, + &is_temporary + ) + ); + if (descriptor->connection->errcode != OCI_SUCCESS) { + php_oci_error(descriptor->connection->err, descriptor->connection->errcode TSRMLS_CC); + PHP_OCI_HANDLE_ERROR(descriptor->connection, descriptor->connection->errcode); + return 1; + } + if (is_temporary) { + PHP_OCI_CALL_RETURN(descriptor->connection->errcode, + OCILobFreeTemporary, + ( + descriptor->connection->svc, + descriptor->connection->err, + descriptor->descriptor + ) + ); + if (descriptor->connection->errcode != OCI_SUCCESS) { + php_oci_error(descriptor->connection->err, descriptor->connection->errcode TSRMLS_CC); + PHP_OCI_HANDLE_ERROR(descriptor->connection, descriptor->connection->errcode); + return 1; + } + } + } +#endif + PHP_OCI_CALL(OCIDescriptorFree, (descriptor->descriptor, descriptor->type)); zend_list_delete(descriptor->connection->rsrc_id); ------------------------------------------------------------------------ [2007-12-20 18:04:32] ghosh at q-one dot com Would pay someone who resolves this bug. Feel free to contact me if you are interested. ------------------------------------------------------------------------ [2007-12-05 23:18:05] [EMAIL PROTECTED] Confirmed. ------------------------------------------------------------------------ [2007-12-04 13:09:49] ghosh at q-one dot com Description: ------------ There is a memory leaking when using the OCI8 interface and querying XML columns. Demo code available via the url below. This creates a table with an XML column and queries this column. UGA memory is leaking. This does not happen when doing the same directly via SQLPlus. Reproduce code: --------------- http://oberon.q-one-hosting.com/6648051.txt Expected result: ---------------- No UGA memory leaking Actual result: -------------- UGA memory going up. Table with temporary lobs filling up. ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/?id=43497&edit=1