abies Wed Sep 3 11:15:31 2003 EDT Modified files: /php-src/ext/interbase interbase.c Log: Fix binding of 16-bit NUMERIC parameters
Index: php-src/ext/interbase/interbase.c diff -u php-src/ext/interbase/interbase.c:1.169 php-src/ext/interbase/interbase.c:1.170 --- php-src/ext/interbase/interbase.c:1.169 Tue Sep 2 18:37:26 2003 +++ php-src/ext/interbase/interbase.c Wed Sep 3 11:15:30 2003 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: interbase.c,v 1.169 2003/09/02 22:37:26 abies Exp $ */ +/* $Id: interbase.c,v 1.170 2003/09/03 15:15:30 abies Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -706,7 +706,7 @@ php_info_print_table_start(); php_info_print_table_row(2, "Interbase Support", "enabled"); - php_info_print_table_row(2, "Revision", "$Revision: 1.169 $"); + php_info_print_table_row(2, "Revision", "$Revision: 1.170 $"); #ifdef COMPILE_DL_INTERBASE php_info_print_table_row(2, "Dynamic Module", "Yes"); #endif @@ -1311,190 +1311,152 @@ Bind parameter placeholders in a previously prepared query */ static int _php_ibase_bind(XSQLDA *sqlda, zval **b_vars, BIND_BUF *buf, ibase_query *ib_query TSRMLS_DC) { - XSQLVAR *var; - zval *b_var; - int i; + int i , rv = SUCCESS; + XSQLVAR *var = sqlda->sqlvar; - var = sqlda->sqlvar; - for (i = 0; i < sqlda->sqld; var++, i++) { /* bound vars */ + for (i = 0; i < sqlda->sqld; ++var, ++i) { /* bound vars */ - buf[i].sqlind = 0; + zval *b_var = b_vars[i]; + var->sqlind = &buf[i].sqlind; - b_var = b_vars[i]; if (Z_TYPE_P(b_var) == IS_NULL) { - static char nothing[64]; - static short null_flag = -1; - var->sqldata = nothing; - var->sqltype |= 1; - var->sqlind = &null_flag; - if (var->sqllen > 64) { - var->sqllen = 64; + + if ((var->sqltype & 1) != 1) { + _php_ibase_module_error("Parameter %d must have a value" TSRMLS_CC, i+1); + rv = FAILURE; } - } else - - switch (var->sqltype & ~1) { - case SQL_TEXT: /* direct to variable */ - case SQL_VARYING: - convert_to_string(b_var); - var->sqldata = (void *) Z_STRVAL_P(b_var); - var->sqllen = Z_STRLEN_P(b_var); - var->sqltype = SQL_TEXT + (var->sqltype & 1); - break; - case SQL_SHORT: - convert_to_long(b_var); - if (Z_LVAL_P(b_var) > SHRT_MAX || Z_LVAL_P(b_var) < SHRT_MIN) { - _php_ibase_module_error("Field %*s overflow" TSRMLS_CC, var->aliasname_length, var->aliasname); - return FAILURE; - } - buf[i].val.sval = (short) Z_LVAL_P(b_var); - var->sqldata = (void *) (&buf[i].val.sval); - break; - case SQL_LONG: - if (var->sqlscale < 0) { - /* - DECIMAL or NUMERIC field stored internally as scaled integer. - Coerce it to string and let InterBase's internal routines - handle it. - */ - convert_to_string(b_var); - var->sqldata = (void *) Z_STRVAL_P(b_var); - var->sqllen = Z_STRLEN_P(b_var); - var->sqltype = SQL_TEXT; - } else { - convert_to_long(b_var); - var->sqldata = (void *) (&Z_LVAL_P(b_var)); - } - break; - case SQL_FLOAT: - convert_to_double(b_var); - buf[i].val.fval = (float) Z_DVAL_P(b_var); - var->sqldata = (void *) (&buf[i].val.fval); - break; - case SQL_DOUBLE: /* direct to variable */ - convert_to_double(b_var); - var->sqldata = (void *) (&Z_DVAL_P(b_var)); - break; -#ifdef SQL_INT64 - case SQL_INT64: + + buf[i].sqlind = -1; + } else { + buf[i].sqlind = 0; + + if (var->sqlscale < 0) { /* - Just let InterBase's internal routines handle it. - Besides, it might even have originally been a string - to avoid rounding errors... + DECIMAL or NUMERIC field are stored internally as scaled integers. + Coerce it to string and let InterBase's internal routines handle it. */ - convert_to_string(b_var); - var->sqldata = (void *) Z_STRVAL_P(b_var); - var->sqllen = Z_STRLEN_P(b_var); var->sqltype = SQL_TEXT; - break; -#endif -#ifndef SQL_TIMESTAMP - case SQL_DATE: -#else - case SQL_TIMESTAMP: - case SQL_TYPE_DATE: - case SQL_TYPE_TIME: -#endif -#ifndef HAVE_STRPTIME + } + + switch (var->sqltype & ~1) { + case SQL_SHORT: + convert_to_long(b_var); + if (Z_LVAL_P(b_var) > SHRT_MAX || Z_LVAL_P(b_var) < SHRT_MIN) { + _php_ibase_module_error("Parameter %d exceeds field width" TSRMLS_CC, i+1); + rv = FAILURE; + } + buf[i].val.sval = (short) Z_LVAL_P(b_var); + var->sqldata = (void *) &buf[i].val.sval; + break; + case SQL_LONG: + convert_to_long(b_var); + var->sqldata = (void *) &Z_LVAL_P(b_var); + break; + case SQL_FLOAT: + convert_to_double(b_var); + buf[i].val.fval = (float) Z_DVAL_P(b_var); + var->sqldata = (void *) &buf[i].val.fval; + break; + case SQL_DOUBLE: + convert_to_double(b_var); + var->sqldata = (void *) &Z_DVAL_P(b_var); + break; #ifndef SQL_TIMESTAMP - /* Parsing doesn't seem to happen with older versions... */ - { - struct tm t; - int n; - - t.tm_year = t.tm_mon = t.tm_mday = t.tm_hour = t.tm_min = t.tm_sec = 0; - + case SQL_DATE: convert_to_string(b_var); - - n = sscanf(Z_STRVAL_P(b_var), "%d%*[/]%d%*[/]%d %d%*[:]%d%*[:]%d", &t.tm_mon, &t.tm_mday, &t.tm_year, &t.tm_hour, &t.tm_min, &t.tm_sec); - - if (n != 3 && n != 6) { - _php_ibase_module_error("Invalid date/time format: Expected 3 or 6 fields, got %d. Use format m/d/Y H:i:s. You gave '%s'" TSRMLS_CC, n, Z_STRVAL_P(b_var)); - return FAILURE; - } - t.tm_year -= 1900; - t.tm_mon--; - isc_encode_date(&t, &buf[i].val.qval); - var->sqldata = (void *) (&buf[i].val.qval); - } + { + struct tm t; +#ifdef HAVE_STRPTIME + strptime(Z_STRVAL_P(b_var), IBG(timestampformat), &t); #else - /* - Once again, InterBase's internal parsing routines - seems to be a good solution... Might change this on - platforms that have strptime()? Code is there and works, - but the functions existence is not yet tested... - ask Sascha? - */ - convert_to_string(b_var); - var->sqldata = (void *) Z_STRVAL_P(b_var); - var->sqllen = Z_STRLEN_P(b_var); - var->sqltype = SQL_TEXT; + /* Parsing doesn't seem to happen with older versions... */ + int n; + + t.tm_year = t.tm_mon = t.tm_mday = t.tm_hour = t.tm_min = t.tm_sec = 0; + + n = sscanf(Z_STRVAL_P(b_var), "%d%*[/]%d%*[/]%d %d%*[:]%d%*[:]%d", &t.tm_mon, &t.tm_mday, &t.tm_year, &t.tm_hour, &t.tm_min, &t.tm_sec); + + if (n != 3 && n != 6) { + _php_ibase_module_error("Parameter %d: invalid date/time format (expected 3 or 6 fields, got %d. Use format m/d/Y H:i:s. You gave '%s')" TSRMLS_CC, i+1, n, Z_STRVAL_P(b_var)); + rv = FAILURE; + } + t.tm_year -= 1900; + t.tm_mon--; #endif + isc_encode_date(&t, &buf[i].val.qval); + var->sqldata = (void *) (&buf[i].val.qval); + } #else - { - struct tm t; - - convert_to_string(b_var); -#ifndef SQL_TIMESTAMP - strptime(Z_STRVAL_P(b_var), IBG(timestampformat), &t); - isc_encode_date(&t, &buf[i].val.qval); - var->sqldata = (void *) (&buf[i].val.qval); -#else - switch (var->sqltype & ~1) { - case SQL_TIMESTAMP: - strptime(Z_STRVAL_P(b_var), IBG(timestampformat), &t); - isc_encode_timestamp(&t, &buf[i].val.tsval); - var->sqldata = (void *) (&buf[i].val.tsval); - break; - case SQL_TYPE_DATE: - strptime(Z_STRVAL_P(b_var), IBG(dateformat), &t); - isc_encode_sql_date(&t, &buf[i].val.dtval); - var->sqldata = (void *) (&buf[i].val.dtval); - break; - case SQL_TYPE_TIME: - strptime(Z_STRVAL_P(b_var), IBG(timeformat), &t); - isc_encode_sql_time(&t, &buf[i].val.tmval); - var->sqldata = (void *) (&buf[i].val.tmval); - break; +#ifdef HAVE_STRPTIME + case SQL_TIMESTAMP: + case SQL_TYPE_DATE: + case SQL_TYPE_TIME: + { + struct tm t; + + convert_to_string(b_var); + + switch (var->sqltype & ~1) { + case SQL_TIMESTAMP: + strptime(Z_STRVAL_P(b_var), IBG(timestampformat), &t); + isc_encode_timestamp(&t, &buf[i].val.tsval); + var->sqldata = (void *) (&buf[i].val.tsval); + break; + case SQL_TYPE_DATE: + strptime(Z_STRVAL_P(b_var), IBG(dateformat), &t); + isc_encode_sql_date(&t, &buf[i].val.dtval); + var->sqldata = (void *) (&buf[i].val.dtval); + break; + case SQL_TYPE_TIME: + strptime(Z_STRVAL_P(b_var), IBG(timeformat), &t); + isc_encode_sql_time(&t, &buf[i].val.tmval); + var->sqldata = (void *) (&buf[i].val.tmval); + break; + } } #endif - } #endif - break; - case SQL_BLOB: - - convert_to_string(b_var); - - if (Z_STRLEN_P(b_var) != BLOB_ID_LEN || - !_php_ibase_string_to_quad(Z_STRVAL_P(b_var), &buf[i].val.qval)) { - - ibase_blob ib_blob = { NULL, {0, 0}, BLOB_INPUT }; - - if (isc_create_blob(IB_STATUS, &ib_query->link->handle, &ib_query->trans->handle, &ib_blob.bl_handle, &ib_blob.bl_qd)) { - _php_ibase_error(TSRMLS_C); - return FAILURE; - } - - if (_php_ibase_blob_add(&b_var, &ib_blob TSRMLS_CC) != SUCCESS) { - return FAILURE; - } + break; + case SQL_BLOB: - if (isc_close_blob(IB_STATUS, &ib_blob.bl_handle)) { - _php_ibase_error(TSRMLS_C); - return FAILURE; + convert_to_string(b_var); + + if (Z_STRLEN_P(b_var) != BLOB_ID_LEN || + !_php_ibase_string_to_quad(Z_STRVAL_P(b_var), &buf[i].val.qval)) { + + ibase_blob ib_blob = { NULL, {0, 0}, BLOB_INPUT }; + + if (isc_create_blob(IB_STATUS, &ib_query->link->handle, &ib_query->trans->handle, &ib_blob.bl_handle, &ib_blob.bl_qd)) { + _php_ibase_error(TSRMLS_C); + return FAILURE; + } + + if (_php_ibase_blob_add(&b_var, &ib_blob TSRMLS_CC) != SUCCESS) { + return FAILURE; + } + + if (isc_close_blob(IB_STATUS, &ib_blob.bl_handle)) { + _php_ibase_error(TSRMLS_C); + return FAILURE; + } + buf[i].val.qval = ib_blob.bl_qd; } - buf[i].val.qval = ib_blob.bl_qd; - } - var->sqldata = (void *) &buf[i].val.qval; - break; - case SQL_ARRAY: - _php_ibase_module_error("Binding arrays not supported yet" TSRMLS_CC); - return FAILURE; - break; - } /* switch */ + var->sqldata = (void *) &buf[i].val.qval; + break; + case SQL_ARRAY: + _php_ibase_module_error("Parameter %d: arrays not supported" TSRMLS_CC, i+1); + rv = FAILURE; + break; + default: + convert_to_string(b_var); + var->sqldata = Z_STRVAL_P(b_var); + var->sqllen = Z_STRLEN_P(b_var); + var->sqltype = SQL_TEXT; + } /* switch */ + } /* if */ } /* for */ - - return SUCCESS; + return rv; } /* }}} */
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php