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

Reply via email to