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

Reply via email to