diff options
author | Christopher Jones <sixd@php.net> | 2010-01-06 18:58:16 +0000 |
---|---|---|
committer | Christopher Jones <sixd@php.net> | 2010-01-06 18:58:16 +0000 |
commit | 5e8e34bac84661ddb69d29f2ad760bb5e3819b8f (patch) | |
tree | 05bb2c139a9425b8fba9a3ce1a9c6039e084c0a8 /ext/oci8/oci8_statement.c | |
parent | bc1feb90343239d1a2fa2c9035eee712b6c88e32 (diff) | |
download | php-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.c | 41 |
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; |