#48675 [Com]: sybase_ct does not support multiple result sets returned by stored procedures

From: Date: Wed, 24 Jun 2009 13:40:17 +0000
Subject: #48675 [Com]: sybase_ct does not support multiple result sets returned by stored procedures
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-138766@lists.php.net to get a copy of this message
ID: 48675 Comment by: lo at readyon dot com Reported By: lo at readyon dot com Status: Open Bug Type: Sybase-ct (ctlib) related Operating System: Mac OS X 10.5.7 (9J61) PHP Version: 5.2.10 New Comment: Here is a patch to add support for sybase_next_result() for 5.2.9: diff -rupN ../orig/php-5.2.9/ext/sybase_ct/php_sybase_ct.c ext/sybase_ct/php_sybase_ct.c --- ../orig/php-5.2.9/ext/sybase_ct/php_sybase_ct.c 2008-12-31 05:17:46.000000000 -0600 +++ ext/sybase_ct/php_sybase_ct.c 2009-06-24 08:28:52.000000000 -0500 @@ -47,8 +47,9 @@ zend_function_entry sybase_functions[] = PHP_FE(sybase_close, NULL) PHP_FE(sybase_select_db, NULL) PHP_FE(sybase_query, NULL) - PHP_FE(sybase_unbuffered_query, NULL) PHP_FE(sybase_free_result, NULL) + PHP_FE(sybase_unbuffered_query, NULL) + PHP_FE(sybase_next_result, NULL) PHP_FE(sybase_get_last_message, NULL) PHP_FE(sybase_num_rows, NULL) PHP_FE(sybase_num_fields, NULL) @@ -73,6 +74,7 @@ zend_function_entry sybase_functions[] = PHP_FALIAS(mssql_select_db, sybase_select_db, NULL) PHP_FALIAS(mssql_query, sybase_query, NULL) PHP_FALIAS(mssql_unbuffered_query, sybase_unbuffered_query, NULL) + PHP_FALIAS(mssql_next_result, sybase_next_result, NULL) PHP_FALIAS(mssql_free_result, sybase_free_result, NULL) PHP_FALIAS(mssql_get_last_message, sybase_get_last_message, NULL) PHP_FALIAS(mssql_num_rows, sybase_num_rows, NULL) @@ -1052,7 +1054,8 @@ static int php_sybase_finish_results(syb efree_n(result->numerics); efree_n(result->types); for (i=0; i<result->num_fields; i++) { - efree(result->tmp_buffer[i]); + if (result->tmp_buffer != NULL) + efree(result->tmp_buffer[i]); } efree_n(result->tmp_buffer); @@ -1085,7 +1088,14 @@ static int php_sybase_finish_results(syb case CS_ROW_RESULT: /* Unexpected results, cancel them. */ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Sybase: Unexpected results, cancelling current"); - ct_cancel(NULL, result->sybase_ptr- >cmd, CS_CANCEL_CURRENT); + // !!!:KLS:20090624 Do not cancel when there are additional + // rows. THe command will be cancelled upon next query if + // sybase_next_result() is not invoked. + // { + fail = 1; + retcode = CS_END_RESULTS; + // ct_cancel(NULL, result->sybase_ptr->cmd, CS_CANCEL_CURRENT); + // } break; case CS_STATUS_RESULT: @@ -1167,7 +1177,6 @@ static int php_sybase_fetch_result_row ( } for (j = 0; j < result->num_fields; j++) { - /* If we are in non-storing mode, free the previous result */ if (!result->store && result->num_rows > 1 && Z_TYPE(result->data[i][j]) == IS_STRING) { efree(Z_STRVAL(result->data[i][j])); @@ -1645,6 +1654,98 @@ PHP_FUNCTION(sybase_unbuffered_query) { php_sybase_query(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); } +/* }}} */ + +// MARK: sybase_next_result +/* {{{ proto int sybase_next_result(int result) + Send Sybase query */ +PHP_FUNCTION(sybase_next_result) +{ + zval **db, **sybase_link_index; + int id; + char *cmdbuf; + sybase_link *sybase_ptr; + sybase_result *result; + int retcode; + int restype; + + switch(ZEND_NUM_ARGS()) { + case 1: + if (zend_get_parameters_ex(1, &db) == FAILURE) { + RETURN_FALSE; + } + id = php_sybase_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU); + CHECK_LINK(id); + break; + case 2: + if (zend_get_parameters_ex(2, &db, &sybase_link_index) == FAILURE) { + RETURN_FALSE; + } + id = -1; + break; + default: + WRONG_PARAM_COUNT; + break; + } + + ZEND_FETCH_RESOURCE2(sybase_ptr, sybase_link *, sybase_link_index, id, "Sybase-Link", le_link, le_plink); + + /* Check to see if a previous sybase_unbuffered_query has read all rows */ + if (sybase_ptr->active_result_index) { + zval *tmp = NULL; + + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "called without first fetching all rows from a previous unbuffered query"); + if (sybase_ptr->cmd) { + ct_cancel(NULL, sybase_ptr->cmd, CS_CANCEL_ALL); + } + + /* Get the resultset and free it */ + ALLOC_ZVAL(tmp); + Z_LVAL_P(tmp)= sybase_ptr->active_result_index; + Z_TYPE_P(tmp)= IS_RESOURCE; + INIT_PZVAL(tmp); + ZEND_FETCH_RESOURCE(result, sybase_result *, &tmp, -1, "Sybase result", le_result); + + if (result) { + php_sybase_finish_results(result TSRMLS_CC); + } + + zval_ptr_dtor(&tmp); + zend_list_delete(sybase_ptr->active_result_index); + sybase_ptr->active_result_index= 0; + } + + retcode = ct_results(sybase_ptr->cmd, &restype); + //printf(" ct_results(): retcode=%d, restype=%d\n", retcode, restype); + switch (retcode) { + case CS_SUCCEED: + result = php_sybase_fetch_result_set(sybase_ptr, 0, 1); + if (result == NULL) { + ct_cancel(NULL, sybase_ptr->cmd, CS_CANCEL_ALL); + sybase_ptr->dead = 1; + RETURN_FALSE; + } + + /* Indicate we have data in case of buffered queries */ + id= ZEND_REGISTER_RESOURCE(return_value, result, le_result); + sybase_ptr->active_result_index= 0 ? id : 0; + break; + + case CS_END_RESULTS: + /* No more result sets */ + RETURN_FALSE; + + case CS_FAIL: + ct_cancel(NULL, sybase_ptr->cmd, CS_CANCEL_ALL); + sybase_ptr->dead = 1; + /* Fall through */ + + case CS_CANCELED: + default: + RETURN_FALSE; + } +} +/* }}} */ /* {{{ proto bool sybase_free_result(int result) Free result memory */ diff -rupN ../orig/php-5.2.9/ext/sybase_ct/php_sybase_ct.h ext/sybase_ct/php_sybase_ct.h --- ../orig/php-5.2.9/ext/sybase_ct/php_sybase_ct.h 2008-12-31 05:17:46.000000000 -0600 +++ ext/sybase_ct/php_sybase_ct.h 2009-06-23 11:44:01.000000000 -0500 @@ -42,6 +42,7 @@ PHP_FUNCTION(sybase_select_db); PHP_FUNCTION(sybase_query); PHP_FUNCTION(sybase_unbuffered_query); PHP_FUNCTION(sybase_free_result); +PHP_FUNCTION(sybase_next_result); PHP_FUNCTION(sybase_get_last_message); PHP_FUNCTION(sybase_num_rows); PHP_FUNCTION(sybase_num_fields); Previous Comments: ------------------------------------------------------------------------ [2009-06-24 13:38:09] lo at readyon dot com Description: ------------ Sybase CTLib does not support fetching more than one result set from a stored procedure. This seems to be a long standing issue detailed in the closed (status: bogus) issue #26636 and others, detailed in the user comments on the page http://us3.php.net/manual/en/function.sybase- query.php. Reproduce code: --------------- $conn = sybase_connect($server, $user, $pass); sybase_select_db($db, $conn); $result = sybase_query("sp_help $table", $conn); do { echo "Next result set...\n"; while ($row = sybase_fetch_assoc($result)) { echo " - fetched row...\n"; } } while ($result = sybase_next_result($conn)); // <- No such function Expected result: ---------------- Many result sets, for example: Next result set... - fetched row Next result set... - fetched row - fetched row - fetched row - fetched row - fetched row - fetched row Next result set... - fetched row - fetched row Next result set... - fetched row - fetched row Next result set... - fetched row Next result set... - fetched row Next result set... - fetched row Next result set... - fetched row Next result set... - fetched row Next result set... - fetched row Actual result: -------------- Next result set... - fetched row Then no supported function sybase_next_result(). ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/?id=48675&edit=1

« previous php.bugs (#138766) next »