thekid          Mon Jul 12 17:07:21 2004 EDT

  Modified files:              (Branch: PHP_4_3)
    /php-src/ext/sybase_ct      php_sybase_ct.c 
  Log:
  - Fixed bug #29064 (Exact numeric/decimal/money datatypes lose precision)
  - Fixed bug #27843 (sybase_query() triggers (spurious?) notices when 
    query is a stored procedure)
  - Fixed multiple memory leaks with sybase_unbuffered_query()
  - Changed sybase_query() to ignore store_results = false in  buffering 
    mode, it would yield unpredictable results
  - Fixed sybase_unbuffered_query() when used with store_results = false
  - Changed sybase_fetch_object() to ignore second argument when passed 
    as NULL
  - Made sybase_data_seek() error message more verbose
  - Fixed memory leak in shutdown when not all rows where selected in an 
    unbuffered query
  CVS ----------------------------------------------------------------------
  
  
http://cvs.php.net/diff.php/php-src/ext/sybase_ct/php_sybase_ct.c?r1=1.73.2.16&r2=1.73.2.17&ty=u
Index: php-src/ext/sybase_ct/php_sybase_ct.c
diff -u php-src/ext/sybase_ct/php_sybase_ct.c:1.73.2.16 
php-src/ext/sybase_ct/php_sybase_ct.c:1.73.2.17
--- php-src/ext/sybase_ct/php_sybase_ct.c:1.73.2.16     Fri May 21 17:00:19 2004
+++ php-src/ext/sybase_ct/php_sybase_ct.c       Mon Jul 12 17:07:21 2004
@@ -18,7 +18,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: php_sybase_ct.c,v 1.73.2.16 2004/05/21 21:00:19 edink Exp $ */
+/* $Id: php_sybase_ct.c,v 1.73.2.17 2004/07/12 21:07:21 thekid Exp $ */
 
 
 #ifdef HAVE_CONFIG_H
@@ -118,13 +118,12 @@
        return 0;
 }
 
-
 static void _free_sybase_result(sybase_result *result)
 {
        int i, j;
 
        if (result->data) {
-               for (i=0; i<(result->store ? result->num_rows : 0); i++) {
+               for (i = 0; i < (result->store ? result->num_rows : MIN(1, 
result->num_rows)); i++) {
                        for (j=0; j<result->num_fields; j++) {
                                zval_dtor(&result->data[i][j]);
                        }
@@ -144,10 +143,21 @@
        efree(result);
 }
 
+/* Forward declaration */
+static int php_sybase_finish_results (sybase_result *result);
+
 static void php_free_sybase_result(zend_rsrc_list_entry *rsrc TSRMLS_DC)
 {
        sybase_result *result = (sybase_result *)rsrc->ptr;
 
+       /* Check to see if we've read all rows */
+       if (result->sybase_ptr && result->sybase_ptr->active_result_index) {
+               if (result->sybase_ptr->cmd) {
+                       ct_cancel(NULL, result->sybase_ptr->cmd, CS_CANCEL_ALL);
+               }
+               php_sybase_finish_results(result);
+       }
+
        _free_sybase_result(result);
 }
 
@@ -1040,11 +1050,15 @@
                        case CS_PARAM_RESULT:
                        case CS_ROW_RESULT:
                                /* Unexpected results, cancel them. */
-                       case CS_STATUS_RESULT:
                                php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Sybase:  
Unexpected results, cancelling current");
                                ct_cancel(NULL, result->sybase_ptr->cmd, 
CS_CANCEL_CURRENT);
                                break;
 
+                       case CS_STATUS_RESULT:
+                               /* Status result from a stored procedure, cancel it 
but do not tell user */
+                               ct_cancel(NULL, result->sybase_ptr->cmd, 
CS_CANCEL_CURRENT);
+                               break;
+
                        default:
                                php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Sybase:  
Unexpected results, cancelling all");
                                ct_cancel(NULL, result->sybase_ptr->cmd, 
CS_CANCEL_ALL);
@@ -1085,6 +1099,19 @@
        return retcode;
 }
 
+#define RETURN_DOUBLE_VAL(result, buf, length)          \
+       if ((length - 1) <= EG(precision)) {                \
+               errno = 0;                                      \
+               Z_DVAL(result) = strtod(buf, NULL);             \
+               if (errno != ERANGE) {                          \
+                       Z_TYPE(result) = IS_DOUBLE;                 \
+               } else {                                        \
+                       ZVAL_STRINGL(&result, buf, length- 1, 1);   \
+               }                                               \
+       } else {                                            \
+               ZVAL_STRINGL(&result, buf, length- 1, 1);       \
+       }
+
 static int php_sybase_fetch_result_row (sybase_result *result, int numrows) 
 {
        int i, j;
@@ -1105,7 +1132,6 @@
                }
                */
                
-               /* i= result->num_rows++; */
                result->num_rows++;
                i= result->store ? result->num_rows- 1 : 0;
                if (i >= result->blocks_initialized*SYBASE_ROWS_BLOCK) {
@@ -1115,27 +1141,48 @@
                        result->data[i] = (zval *) safe_emalloc(sizeof(zval), 
result->num_fields, 0);
                }
 
-               for (j=0; j<result->num_fields; j++) {
+               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]));
+                       }
+
                        if (result->indicators[j] == -1) { /* null value */
                                ZVAL_NULL(&result->data[i][j]);
                        } else {
-                               Z_STRLEN(result->data[i][j]) = result->lengths[j]-1;  
/* we don't need the NULL in the length */
-                               Z_STRVAL(result->data[i][j]) = 
estrndup(result->tmp_buffer[j], result->lengths[j]);
-                               Z_TYPE(result->data[i][j]) = IS_STRING;
-                               
                                switch (result->numerics[j]) {
-                                       case 1:
-                                               convert_to_long(&result->data[i][j]);
+                                       case 1: {
+                                               /* This indicates a long */
+                                               ZVAL_LONG(&result->data[i][j], 
strtol(result->tmp_buffer[j], NULL, 10));
                                                break;
-                                       case 2:
-                                               convert_to_double(&result->data[i][j]);
+                                       }
+                                       
+                                       case 2: {
+                                               /* This indicates a float */
+                                               RETURN_DOUBLE_VAL(result->data[i][j], 
result->tmp_buffer[j], result->lengths[j]); 
                                                break;
-                                       case 3:
-                                               /* This signals we have an integer 
datatype, but we need to convert to double if we 
-                                                * overflow. 
-                                                */
-                                               
convert_scalar_to_number(&result->data[i][j] TSRMLS_CC);
+                                       }
+
+                                       case 3: {
+                                               /* This indicates either a long or a 
float, which ever fits */
+                                               errno = 0;
+                                               Z_LVAL(result->data[i][j]) = 
strtol(result->tmp_buffer[j], NULL, 10);
+                                               if (errno == ERANGE) {
+                                               
+                                                       /* An overflow occurred, so 
try to fit it into a double */
+                                                       
RETURN_DOUBLE_VAL(result->data[i][j], result->tmp_buffer[j], result->lengths[j]); 
+                                                       break;
+                                               }
+                                               Z_TYPE(result->data[i][j]) = IS_LONG;
                                                break;
+                                       }
+                                       
+                                       default: {
+                                               /* This indicates anything else, 
return it as string */
+                                               ZVAL_STRINGL(&result->data[i][j], 
result->tmp_buffer[j], result->lengths[j]- 1, 1);
+                                               break;
+                                       }          
                                }
                        }
                }
@@ -1278,9 +1325,12 @@
                Z_TYPE(result->fields[i]) = result->types[i];
        }
        
-       retcode= php_sybase_fetch_result_row(result, buffered ? 1 : -1);
-       if (retcode == CS_FAIL) {
-               return NULL;
+       if (buffered) {
+               retcode = CS_SUCCEED;
+       } else {
+               if ((retcode = php_sybase_fetch_result_row(result, -1)) == CS_FAIL) {
+                       return NULL;
+               }
        }
 
        result->last_retcode = retcode;
@@ -1320,9 +1370,14 @@
                        if (zend_get_parameters_ex(3, &query, &sybase_link_index, 
&store_mode)==FAILURE) {
                                RETURN_FALSE;
                        }
+                       if (!buffered) {
+                               php_error_docref(NULL TSRMLS_CC, E_NOTICE, "cannot use 
non-storing mode with buffered queries");
+                               store = 1;
+                       } else {
+                               convert_to_long_ex(store_mode);
+                               store= (Z_LVAL_PP(store_mode) != 0);
+                       }
                        id = -1;
-                       convert_to_long_ex(store_mode);
-                       store= (Z_LVAL_PP(store_mode) != 0);
                        break;
                default:
                        WRONG_PARAM_COUNT;
@@ -1760,19 +1815,20 @@
                
                switch (Z_TYPE_PP(object)) {
                        case IS_OBJECT:
-                               ce= Z_OBJCE_PP(object);
+                               ce = Z_OBJCE_PP(object);
                                break;
-                       default:
+                       case IS_NULL:
+                               break;
+                       default: {
                                convert_to_string_ex(object);
                                zend_str_tolower(Z_STRVAL_PP(object), 
Z_STRLEN_PP(object));
-                               zend_hash_find(EG(class_table), Z_STRVAL_PP(object), 
Z_STRLEN_PP(object)+1, (void **)&ce);
-
-                               if (!ce) {
+                               if (zend_hash_find(EG(class_table), 
Z_STRVAL_PP(object), Z_STRLEN_PP(object)+1, (void **)&ce) == FAILURE) {
                                        php_error_docref(NULL TSRMLS_CC, E_NOTICE, 
"Sybase:  Class %s has not been declared", Z_STRVAL_PP(object));
-                                       ce= ZEND_STANDARD_CLASS_DEF_PTR;
                                }
+                       }
                }
-               
+
+               /* Reset no. of arguments to 1 so that we can use 
INTERNAL_FUNCTION_PARAM_PASSTHRU */
                ht= 1;
        }
        
@@ -1780,7 +1836,7 @@
        if (Z_TYPE_P(return_value)==IS_ARRAY) {
                object_and_properties_init(
                        return_value, 
-                       object ? ce : ZEND_STANDARD_CLASS_DEF_PTR, 
+                       ce ? ce : ZEND_STANDARD_CLASS_DEF_PTR, 
                        Z_ARRVAL_P(return_value)
                );
        }
@@ -1821,11 +1877,11 @@
 
        /* Unbuffered ? */
        if (result->last_retcode != CS_END_DATA && result->last_retcode != 
CS_END_RESULTS && Z_LVAL_PP(offset)>=result->num_rows) {
-               php_sybase_fetch_result_row(result, Z_LVAL_PP(offset));
+               php_sybase_fetch_result_row(result, Z_LVAL_PP(offset)+ 1);
        }
        
        if (Z_LVAL_PP(offset)<0 || Z_LVAL_PP(offset)>=result->num_rows) {
-               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase:  Bad row offset");
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase:  Bad row offset 
%ld, must be betweem 0 and %d", Z_LVAL_PP(offset), result->num_rows - 1);
                RETURN_FALSE;
        }
 

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to