Edit report at http://bugs.php.net/bug.php?id=48675&edit=1

 ID:                 48675
 Comment by:         hexes at mail dot ru
 Reported by:        lo at readyon dot com
 Summary:            sybase_ct does not support multiple result sets
                     returned by stored procedures
 Status:             Open
 Type:               Bug
 Package:            Sybase-ct (ctlib) related
 Operating System:   Mac OS X 10.5.8 (9L31a)
 PHP Version:        5.2.10
 Block user comment: N
 Private report:     N

 New Comment:

Gentlemen developers!

When??? There is a patch, i'm not so cleaver as you, and cant use it. Can you 

apply it to main branch?


Previous Comments:
------------------------------------------------------------------------
[2009-09-25 17:48:18] lo at readyon dot com

I haven't looked at 5.3.0. However, the changes to php_sybase_ct.c are 

relatively straightforward:



1. Disable cancelling/closing after successful result

   php_sybase_finish_results()



        case CS_COMPUTE_RESULT:

        case CS_CURSOR_RESULT:

        case CS_PARAM_RESULT:

        case CS_ROW_RESULT:

                /* Unexpected results, cancel them. */

                php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Sybase:  

Unexpected results, cancelling 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;





2. Add a sybase_next_result() function and register these functions.



    /* {{{ proto int sybase_next_result(int conn)

       Fetch the next result set */

    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);

        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;

        }

    }

    /* }}} */

------------------------------------------------------------------------
[2009-09-25 03:26:25] murali_dharan_2000 at yahoo dot com

The proposed solution did not work for me on PHP 5.3.0 on Linux x86-64. This 
functionality is really useful to have in PHP as the power of stored procedures 
in Sybase is the ability to return multiple result sets and PHP needs to be 
enhanced to handle the same.

------------------------------------------------------------------------
[2009-06-24 13:40:16] lo at readyon dot com

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);

------------------------------------------------------------------------


The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at

    http://bugs.php.net/bug.php?id=48675


-- 
Edit this bug report at http://bugs.php.net/bug.php?id=48675&edit=1

Reply via email to