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