summaryrefslogtreecommitdiff
path: root/ext/oci8/oci8_statement.c
diff options
context:
space:
mode:
authorChristopher Jones <sixd@php.net>2010-01-06 18:58:16 +0000
committerChristopher Jones <sixd@php.net>2010-01-06 18:58:16 +0000
commit5e8e34bac84661ddb69d29f2ad760bb5e3819b8f (patch)
tree05bb2c139a9425b8fba9a3ce1a9c6039e084c0a8 /ext/oci8/oci8_statement.c
parentbc1feb90343239d1a2fa2c9035eee712b6c88e32 (diff)
downloadphp-git-5e8e34bac84661ddb69d29f2ad760bb5e3819b8f.tar.gz
Fixed bug #49560 (oci8: using LOBs causes slow PHP shutdown)
- Improved descriptor refcounting to remove unneeded items sooner - Replaced n^2 list traversal during descriptor list destruction
Diffstat (limited to 'ext/oci8/oci8_statement.c')
-rw-r--r--ext/oci8/oci8_statement.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/ext/oci8/oci8_statement.c b/ext/oci8/oci8_statement.c
index 3ca43b60bf..2cbc284773 100644
--- a/ext/oci8/oci8_statement.c
+++ b/ext/oci8/oci8_statement.c
@@ -93,6 +93,7 @@ php_oci_statement *php_oci_statement_create (php_oci_connection *connection, cha
statement->connection = connection;
statement->has_data = 0;
+ statement->has_descr = 0;
statement->parent_stmtid = 0;
zend_list_addref(statement->connection->rsrc_id);
@@ -131,6 +132,40 @@ int php_oci_statement_set_prefetch(php_oci_statement *statement, long size TSRML
}
/* }}} */
+/* {{{ php_oci_cleanup_pre_fetch()
+ Helper function to cleanup ref-cursors and descriptors from the previous row */
+int php_oci_cleanup_pre_fetch(void *data TSRMLS_DC)
+{
+ php_oci_out_column *outcol = data;
+
+ if (!outcol->is_descr && !outcol->is_cursor)
+ return ZEND_HASH_APPLY_KEEP;
+
+ switch(outcol->data_type) {
+ case SQLT_CLOB:
+ case SQLT_BLOB:
+ case SQLT_RDD:
+ case SQLT_BFILE:
+ if (outcol->descid) {
+ zend_list_delete(outcol->descid);
+ outcol->descid = 0;
+ }
+ break;
+ case SQLT_RSET:
+ if (outcol->stmtid) {
+ zend_list_delete(outcol->stmtid);
+ outcol->stmtid = 0;
+ outcol->nested_statement = NULL;
+ }
+ break;
+ default:
+ break;
+ }
+ return ZEND_HASH_APPLY_KEEP;
+
+} /* }}} */
+
+
/* {{{ php_oci_statement_fetch()
Fetch a row from the statement */
int php_oci_statement_fetch(php_oci_statement *statement, ub4 nrows TSRMLS_DC)
@@ -143,6 +178,10 @@ int php_oci_statement_fetch(php_oci_statement *statement, ub4 nrows TSRMLS_DC)
php_oci_out_column *column;
+ if (statement->has_descr && statement->columns) {
+ zend_hash_apply(statement->columns, (apply_func_t) php_oci_cleanup_pre_fetch TSRMLS_CC);
+ }
+
PHP_OCI_CALL_RETURN(statement->errcode, OCIStmtFetch, (statement->stmt, statement->err, nrows, OCI_FETCH_NEXT, OCI_DEFAULT));
if ( statement->errcode == OCI_NO_DATA || nrows == 0 ) {
@@ -570,6 +609,7 @@ int php_oci_statement_execute(php_oci_statement *statement, ub4 mode TSRMLS_DC)
define_type = SQLT_RSET;
outcol->is_cursor = 1;
+ outcol->statement->has_descr = 1;
outcol->storage_size4 = -1;
outcol->retlen = -1;
dynamic = OCI_DYNAMIC_FETCH;
@@ -583,6 +623,7 @@ int php_oci_statement_execute(php_oci_statement *statement, ub4 mode TSRMLS_DC)
define_type = outcol->data_type;
outcol->is_descr = 1;
+ outcol->statement->has_descr = 1;
outcol->storage_size4 = -1;
dynamic = OCI_DYNAMIC_FETCH;
break;