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