abies Thu Sep 4 07:09:47 2003 EDT
Modified files:
/php-src/ext/interbase interbase.c php_interbase.h
Log:
Fixed fetching of arrays
# Untested for multidimensional arrays
Index: php-src/ext/interbase/interbase.c
diff -u php-src/ext/interbase/interbase.c:1.171 php-src/ext/interbase/interbase.c:1.172
--- php-src/ext/interbase/interbase.c:1.171 Wed Sep 3 21:26:36 2003
+++ php-src/ext/interbase/interbase.c Thu Sep 4 07:09:46 2003
@@ -18,7 +18,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: interbase.c,v 1.171 2003/09/04 01:26:36 abies Exp $ */
+/* $Id: interbase.c,v 1.172 2003/09/04 11:09:46 abies Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -708,7 +708,7 @@
php_info_print_table_start();
php_info_print_table_row(2, "Interbase Support", "enabled");
- php_info_print_table_row(2, "Revision", "$Revision: 1.171 $");
+ php_info_print_table_row(2, "Revision", "$Revision: 1.172 $");
#ifdef COMPILE_DL_INTERBASE
php_info_print_table_row(2, "Dynamic Module", "Yes");
#endif
@@ -1086,117 +1086,101 @@
/* }}} */
/* {{{ _php_ibase_alloc_array() */
-static int _php_ibase_alloc_array(ibase_array **ib_arrayp, int *array_cntp, XSQLDA
*sqlda, isc_db_handle link, isc_tr_handle trans TSRMLS_DC)
+static int _php_ibase_alloc_array(ibase_array **ib_arrayp, XSQLDA *sqlda,
isc_db_handle link, isc_tr_handle trans TSRMLS_DC)
{
#define IB_ARRAY (*ib_arrayp)
- int i, dim, ar_cnt, ar_length;
- XSQLVAR *var;
+ unsigned short i;
+ XSQLVAR *var = sqlda->sqlvar;
- IB_ARRAY = NULL;
+ IB_ARRAY = safe_emalloc(sizeof(ibase_array), sqlda->sqld, 0);
- ar_cnt = 0; /* find arrays */
- var = sqlda->sqlvar;
for (i = 0; i < sqlda->sqld; i++, var++) {
+ unsigned short dim;
+ unsigned long ar_length;
+
if ((var->sqltype & ~1) == SQL_ARRAY) {
- ar_cnt++;
- }
- }
-
- if (ar_cnt) { /* have arrays ? */
- *array_cntp = ar_cnt;
- IB_ARRAY = safe_emalloc(sizeof(ibase_array), ar_cnt, 0);
- ar_cnt = 0;
- var = sqlda->sqlvar;
- for (i = 0; i < sqlda->sqld; i++, var++) {
- if ((var->sqltype & ~1) == SQL_ARRAY) {
+ ISC_ARRAY_DESC *ar_desc = &IB_ARRAY[i].ar_desc;
- ISC_ARRAY_DESC *ar_desc = &IB_ARRAY[ar_cnt].ar_desc;
-
- if (isc_array_lookup_bounds(IB_STATUS, &link, &trans,
var->relname, var->sqlname, ar_desc)) {
- _php_ibase_error(TSRMLS_C);
- efree(IB_ARRAY);
- IB_ARRAY = NULL;
- return FAILURE;
- }
+ if (isc_array_lookup_bounds(IB_STATUS, &link, &trans,
var->relname, var->sqlname, ar_desc)) {
+ _php_ibase_error(TSRMLS_C);
+ efree(IB_ARRAY);
+ IB_ARRAY = NULL;
+ return FAILURE;
+ }
- switch (ar_desc->array_desc_dtype) {
- case blr_text:
- case blr_text2:
- IB_ARRAY[ar_cnt].el_type = SQL_TEXT;
- IB_ARRAY[ar_cnt].el_size =
ar_desc->array_desc_length + 1;
- break;
- case blr_short:
- IB_ARRAY[ar_cnt].el_type = SQL_SHORT;
- IB_ARRAY[ar_cnt].el_size =
sizeof(short);
- break;
- case blr_long:
- IB_ARRAY[ar_cnt].el_type = SQL_LONG;
- IB_ARRAY[ar_cnt].el_size =
sizeof(ISC_LONG);
- break;
- case blr_float:
- IB_ARRAY[ar_cnt].el_type = SQL_FLOAT;
- IB_ARRAY[ar_cnt].el_size =
sizeof(float);
- break;
- case blr_double:
- IB_ARRAY[ar_cnt].el_type = SQL_DOUBLE;
- IB_ARRAY[ar_cnt].el_size =
sizeof(double);
- break;
+ switch (ar_desc->array_desc_dtype) {
+ case blr_text:
+ case blr_text2:
+ IB_ARRAY[i].el_type = SQL_TEXT;
+ IB_ARRAY[i].el_size =
ar_desc->array_desc_length + 1;
+ break;
+ case blr_short:
+ IB_ARRAY[i].el_type = SQL_SHORT;
+ IB_ARRAY[i].el_size = sizeof(short);
+ break;
+ case blr_long:
+ IB_ARRAY[i].el_type = SQL_LONG;
+ IB_ARRAY[i].el_size = sizeof(ISC_LONG);
+ break;
+ case blr_float:
+ IB_ARRAY[i].el_type = SQL_FLOAT;
+ IB_ARRAY[i].el_size = sizeof(float);
+ break;
+ case blr_double:
+ IB_ARRAY[i].el_type = SQL_DOUBLE;
+ IB_ARRAY[i].el_size = sizeof(double);
+ break;
#ifdef blr_int64
- case blr_int64:
- IB_ARRAY[ar_cnt].el_type = SQL_INT64;
- IB_ARRAY[ar_cnt].el_size =
sizeof(ISC_INT64);
- break;
+ case blr_int64:
+ IB_ARRAY[i].el_type = SQL_INT64;
+ IB_ARRAY[i].el_size = sizeof(ISC_INT64);
+ break;
#endif
#ifndef blr_timestamp
- case blr_date:
- IB_ARRAY[ar_cnt].el_type = SQL_DATE;
- IB_ARRAY[ar_cnt].el_size =
sizeof(ISC_QUAD);
- break;
+ case blr_date:
+ IB_ARRAY[i].el_type = SQL_DATE;
+ IB_ARRAY[i].el_size = sizeof(ISC_QUAD);
+ break;
#else
- case blr_timestamp:
- IB_ARRAY[ar_cnt].el_type =
SQL_TIMESTAMP;
- IB_ARRAY[ar_cnt].el_size =
sizeof(ISC_TIMESTAMP);
- break;
- case blr_sql_date:
- IB_ARRAY[ar_cnt].el_type =
SQL_TYPE_DATE;
- IB_ARRAY[ar_cnt].el_size =
sizeof(ISC_DATE);
- break;
- case blr_sql_time:
- IB_ARRAY[ar_cnt].el_type =
SQL_TYPE_TIME;
- IB_ARRAY[ar_cnt].el_size =
sizeof(ISC_TIME);
- break;
+ case blr_timestamp:
+ IB_ARRAY[i].el_type = SQL_TIMESTAMP;
+ IB_ARRAY[i].el_size = sizeof(ISC_TIMESTAMP);
+ break;
+ case blr_sql_date:
+ IB_ARRAY[i].el_type = SQL_TYPE_DATE;
+ IB_ARRAY[i].el_size = sizeof(ISC_DATE);
+ break;
+ case blr_sql_time:
+ IB_ARRAY[i].el_type = SQL_TYPE_TIME;
+ IB_ARRAY[i].el_size = sizeof(ISC_TIME);
+ break;
#endif
- case blr_varying:
- case blr_varying2: /* changed to SQL_TEXT
? */
- /* sql_type = SQL_VARYING; Why? FIXME:
??? */
- IB_ARRAY[ar_cnt].el_type = SQL_TEXT;
- IB_ARRAY[ar_cnt].el_size =
ar_desc->array_desc_length + sizeof(short);
- break;
- case blr_quad:
- case blr_blob_id:
- case blr_cstring:
- case blr_cstring2:
- /* FIXME */
- default:
- _php_ibase_module_error("Unsupported
array type %d in relation '%s' column '%s'" TSRMLS_CC, ar_desc->array_desc_dtype,
var->relname, var->sqlname);
- efree(IB_ARRAY);
- IB_ARRAY = NULL;
- return FAILURE;
- } /* switch array_desc_type */
-
- ar_length = 0; /* calculate elements count */
- for (dim = 0; dim < ar_desc->array_desc_dimensions;
dim++) {
- ar_length += 1 +
ar_desc->array_desc_bounds[dim].array_bound_upper -
ar_desc->array_desc_bounds[dim].array_bound_lower;
- }
- IB_ARRAY[ar_cnt].ar_size = IB_ARRAY[ar_cnt].el_size *
ar_length;
-
- ar_cnt++;
-
- } /* if SQL_ARRAY */
- } /* for column */
- } /* if array_cnt */
-
+ case blr_varying:
+ case blr_varying2: /* changed to SQL_TEXT ? */
+ /* sql_type = SQL_VARYING; Why? FIXME: ??? */
+ IB_ARRAY[i].el_type = SQL_TEXT;
+ IB_ARRAY[i].el_size =
ar_desc->array_desc_length + sizeof(short);
+ break;
+ case blr_quad:
+ case blr_blob_id:
+ case blr_cstring:
+ case blr_cstring2:
+ /* FIXME */
+ default:
+ _php_ibase_module_error("Unsupported array
type %d in relation '%s' column '%s'" TSRMLS_CC, ar_desc->array_desc_dtype,
var->relname, var->sqlname);
+ efree(IB_ARRAY);
+ IB_ARRAY = NULL;
+ return FAILURE;
+ } /* switch array_desc_type */
+
+ ar_length = 0; /* calculate elements count */
+ for (dim = 0; dim < ar_desc->array_desc_dimensions; dim++) {
+ ar_length += 1 +
ar_desc->array_desc_bounds[dim].array_bound_upper -
ar_desc->array_desc_bounds[dim].array_bound_lower;
+ }
+ IB_ARRAY[i].ar_size = IB_ARRAY[i].el_size * ar_length;
+ } /* if SQL_ARRAY */
+ } /* for column */
return SUCCESS;
#undef IB_ARRAY
}
@@ -1214,9 +1198,7 @@
ib_query->result_res_id = 0;
ib_query->stmt = NULL;
ib_query->in_array = NULL;
- ib_query->in_array_cnt = 0;
ib_query->out_array = NULL;
- ib_query->out_array_cnt = 0;
ib_query->dialect = dialect;
ib_query->query = estrdup(query);
ib_query->trans_res_id = trans_res_id;
@@ -1273,24 +1255,19 @@
}
}
- /* allocate arrays... */
- if (_php_ibase_alloc_array(&ib_query->in_array, &ib_query->in_array_cnt,
ib_query->in_sqlda, link->handle, trans->handle TSRMLS_CC) == FAILURE) {
- goto _php_ibase_alloc_query_error; /* error report already done */
- }
-
- if (_php_ibase_alloc_array(&ib_query->out_array, &ib_query->out_array_cnt,
ib_query->out_sqlda, link->handle, trans->handle TSRMLS_CC) == FAILURE) {
- goto _php_ibase_alloc_query_error;
- }
-
/* no, haven't placeholders at all */
if (ib_query->in_sqlda->sqld == 0) {
efree(ib_query->in_sqlda);
ib_query->in_sqlda = NULL;
+ } else if (_php_ibase_alloc_array(&ib_query->in_array, ib_query->in_sqlda,
link->handle, trans->handle TSRMLS_CC) == FAILURE) {
+ goto _php_ibase_alloc_query_error;
}
if (ib_query->out_sqlda->sqld == 0) {
efree(ib_query->out_sqlda);
ib_query->out_sqlda = NULL;
+ } else if (_php_ibase_alloc_array(&ib_query->out_array, ib_query->out_sqlda,
link->handle, trans->handle TSRMLS_CC) == FAILURE) {
+ goto _php_ibase_alloc_query_error;
}
return SUCCESS;
@@ -1638,8 +1615,8 @@
_php_ibase_alloc_xsqlda(out_sqlda);
if (ib_query->out_array) {
- IB_RESULT->out_array = safe_emalloc(sizeof(ibase_array),
ib_query->out_array_cnt, 0);
- memcpy(IB_RESULT->out_array, ib_query->out_array,
sizeof(ibase_array) * ib_query->out_array_cnt);
+ IB_RESULT->out_array = safe_emalloc(sizeof(ibase_array),
out_sqlda->sqld, 0);
+ memcpy(IB_RESULT->out_array, ib_query->out_array,
sizeof(ibase_array) * out_sqlda->sqld);
} else {
IB_RESULT->out_array = NULL;
}
@@ -2324,7 +2301,7 @@
if (scale == 0) {
ZVAL_LONG(val,n);
} else {
- long f = scales[-scale];
+ long f = (long) scales[-scale];
if (n >= 0) {
l = sprintf(string_data, "%ld.%0*ld", n / f,
-scale, n % f);
@@ -2425,42 +2402,48 @@
/* create multidimension array - recursion function
* (*datap) argument changed
*/
-static int _php_ibase_arr_zval(zval *ar_zval, char **datap, ibase_array *ib_array,
int dim, int flag TSRMLS_DC)
+static int _php_ibase_arr_zval(zval *ar_zval, char *data, unsigned long data_size,
ibase_array *ib_array, int dim, int flag TSRMLS_DC)
{
- zval tmp;
- int i, dim_len, l_bound, u_bound;
-
- if (dim > 16) { /* InterBase limit */
- _php_ibase_module_error("Too many dimensions" TSRMLS_CC);
- return FAILURE;
- }
-
- u_bound = ib_array->ar_desc.array_desc_bounds[dim].array_bound_upper;
- l_bound = ib_array->ar_desc.array_desc_bounds[dim].array_bound_lower;
- dim_len = 1 + u_bound - l_bound;
+ int
+ u_bound = ib_array->ar_desc.array_desc_bounds[dim].array_bound_upper,
+ l_bound = ib_array->ar_desc.array_desc_bounds[dim].array_bound_lower,
+ dim_len = 1 + u_bound - l_bound;
+ unsigned short i;
+ array_init(ar_zval);
+
if (dim < ib_array->ar_desc.array_desc_dimensions - 1) { /* array again */
- for (i = 0; i < dim_len; i++) {
+ unsigned long slice_size = data_size / dim_len;
+
+ for (i = 0; i < dim_len; ++i) {
+ zval *slice_zval;
+ ALLOC_INIT_ZVAL(slice_zval);
+
/* recursion here */
- if (_php_ibase_arr_zval(ar_zval, datap, ib_array, dim + 1,
flag TSRMLS_CC) == FAILURE) {
+ if (_php_ibase_arr_zval(slice_zval, data, slice_size,
ib_array, dim + 1, flag TSRMLS_CC) == FAILURE) {
return FAILURE;
}
+ data += slice_size;
+
+ add_index_zval(ar_zval,l_bound+i,slice_zval);
}
} else { /* data at last */
- array_init(ar_zval);
-
- for (i = 0; i < dim_len; i++) {
- if (_php_ibase_var_zval(&tmp, *datap,
+ for (i = 0; i < dim_len; ++i) {
+ zval *var_zval;
+ ALLOC_INIT_ZVAL(var_zval);
+
+ if (_php_ibase_var_zval(var_zval, data,
ib_array->el_type,
ib_array->ar_desc.array_desc_length,
ib_array->ar_desc.array_desc_scale,
flag
TSRMLS_CC) == FAILURE) {
return FAILURE;
}
- /* FIXME ??? */
- zend_hash_index_update(Z_ARRVAL_P(ar_zval), l_bound + i, (void
*) &tmp, sizeof(zval), NULL);
- *datap += ib_array->el_size;
+
+ add_index_zval(ar_zval,l_bound+i,var_zval);
+
+ data += ib_array->el_size;
}
}
return SUCCESS;
@@ -2506,8 +2489,7 @@
static void _php_ibase_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, int fetch_type)
{
zval **result_arg, **flag_arg;
- long flag = 0;
- int i, arr_cnt;
+ long i, flag = 0;
ibase_result *ib_result;
XSQLVAR *var;
@@ -2553,16 +2535,16 @@
array_init(return_value);
- arr_cnt = 0;
var = ib_result->out_sqlda->sqlvar;
for (i = 0; i < ib_result->out_sqlda->sqld; i++, var++) {
if (((var->sqltype & 1) == 0) || *var->sqlind != -1) {
- zval tmp;
+ zval *result;
+ ALLOC_INIT_ZVAL(result);
switch (var->sqltype & ~1) {
default:
- _php_ibase_var_zval(&tmp, var->sqldata,
var->sqltype, var->sqllen, var->sqlscale, flag TSRMLS_CC);
+ _php_ibase_var_zval(result, var->sqldata,
var->sqltype, var->sqllen, var->sqlscale, flag TSRMLS_CC);
break;
case SQL_BLOB:
if (flag & PHP_IBASE_FETCH_BLOBS) { /* fetch
blob contents into hash */
@@ -2578,12 +2560,12 @@
if (isc_open_blob(IB_STATUS,
&ib_result->link->handle, &ib_result->trans->handle, &blob_handle.bl_handle,
&blob_handle.bl_qd)) {
_php_ibase_error(TSRMLS_C);
- RETURN_FALSE;
+ goto _php_ibase_fetch_error;
}
if (isc_blob_info(IB_STATUS,
&blob_handle.bl_handle, sizeof(bl_items), bl_items, sizeof(bl_info), bl_info)) {
_php_ibase_error(TSRMLS_C);
- RETURN_FALSE;
+ goto _php_ibase_fetch_error;
}
/* find total length of blob's data */
@@ -2595,7 +2577,7 @@
item == isc_info_error
|| i >= sizeof(bl_info)) {
_php_ibase_module_error("Could not determine BLOB size (internal error)" TSRMLS_CC);
- RETURN_FALSE;
+ goto
_php_ibase_fetch_error;
}
item_len = (unsigned short)
isc_vax_integer(&bl_info[i], 2);
@@ -2608,76 +2590,54 @@
}
if (max_len == 0) {
- ZVAL_STRING(&tmp, "", 1);
- } else if (_php_ibase_blob_get(&tmp,
&blob_handle, max_len TSRMLS_CC) != SUCCESS) {
- RETURN_FALSE;
+ ZVAL_STRING(result, "", 1);
+ } else if (_php_ibase_blob_get(result,
&blob_handle, max_len TSRMLS_CC) != SUCCESS) {
+ goto _php_ibase_fetch_error;
}
if (isc_close_blob(IB_STATUS,
&blob_handle.bl_handle)) {
- zval_dtor(&tmp);
_php_ibase_error(TSRMLS_C);
- RETURN_FALSE;
+ goto _php_ibase_fetch_error;
}
} else { /* blob id only */
ISC_QUAD bl_qd = *(ISC_QUAD *)
var->sqldata;
-
ZVAL_STRINGL(&tmp,_php_ibase_quad_to_string(bl_qd), BLOB_ID_LEN, 0);
+
ZVAL_STRINGL(result,_php_ibase_quad_to_string(bl_qd), BLOB_ID_LEN, 0);
}
break;
- case SQL_ARRAY: {
+ case SQL_ARRAY:
if (flag & PHP_IBASE_FETCH_ARRAYS) { /* array
can be *huge* so only fetch if asked */
ISC_QUAD ar_qd = *(ISC_QUAD *)
var->sqldata;
- ibase_array *ib_array =
&ib_result->out_array[arr_cnt];
- void *ar_data;
- char *tmp_ptr;
-
- ar_data = emalloc(ib_array->ar_size);
+ ibase_array *ib_array =
&ib_result->out_array[i];
+ void *ar_data =
emalloc(ib_array->ar_size);
if (isc_array_get_slice(IB_STATUS,
&ib_result->link->handle, &ib_result->trans->handle, &ar_qd, &ib_array->ar_desc,
ar_data, &ib_array->ar_size)) {
_php_ibase_error(TSRMLS_C);
efree(ar_data);
- RETURN_FALSE;
+ goto _php_ibase_fetch_error;
}
-
- tmp_ptr = ar_data; /* avoid changes in
_arr_zval */
- if (_php_ibase_arr_zval(&tmp,
&tmp_ptr, ib_array, 0, flag TSRMLS_CC) == FAILURE) {
+
+ if (_php_ibase_arr_zval(result,
ar_data, ib_array->ar_size, ib_array, 0, flag TSRMLS_CC) == FAILURE) {
efree(ar_data);
- RETURN_FALSE;
+ goto _php_ibase_fetch_error;
}
efree(ar_data);
} else { /* blob id only */
ISC_QUAD ar_qd = *(ISC_QUAD *)
var->sqldata;
-
ZVAL_STRINGL(&tmp,_php_ibase_quad_to_string(ar_qd), BLOB_ID_LEN, 0);
+
ZVAL_STRINGL(result,_php_ibase_quad_to_string(ar_qd), BLOB_ID_LEN, 0);
}
- }
- break;
+ break;
+ _php_ibase_fetch_error:
+ zval_dtor(result);
+ FREE_ZVAL(result);
+ RETURN_FALSE;
} /* switch */
if (fetch_type & FETCH_ROW) {
- switch (Z_TYPE(tmp)) {
- case IS_STRING:
- add_index_stringl(return_value, i,
Z_STRVAL(tmp), Z_STRLEN(tmp), 0);
- break;
- case IS_LONG:
- add_index_long(return_value, i,
Z_LVAL(tmp));
- break;
- case IS_DOUBLE:
- add_index_double(return_value, i,
Z_DVAL(tmp));
- break;
- }
+ add_index_zval(return_value, i, result);
} else {
- switch (Z_TYPE(tmp)) {
- case IS_STRING:
- add_assoc_stringl(return_value,
var->aliasname, Z_STRVAL(tmp), Z_STRLEN(tmp), 0);
- break;
- case IS_LONG:
- add_assoc_long(return_value,
var->aliasname, Z_LVAL(tmp));
- break;
- case IS_DOUBLE:
- add_assoc_double(return_value,
var->aliasname, Z_DVAL(tmp));
- break;
- }
+ add_assoc_zval(return_value, var->aliasname, result);
}
} else {
if (fetch_type & FETCH_ROW) {
@@ -2685,9 +2645,6 @@
} else {
add_assoc_null(return_value, var->aliasname);
}
- }
- if ((var->sqltype & ~1) == SQL_ARRAY) {
- arr_cnt++;
}
} /* for field */
}
Index: php-src/ext/interbase/php_interbase.h
diff -u php-src/ext/interbase/php_interbase.h:1.58
php-src/ext/interbase/php_interbase.h:1.59
--- php-src/ext/interbase/php_interbase.h:1.58 Tue Sep 2 18:37:26 2003
+++ php-src/ext/interbase/php_interbase.h Thu Sep 4 07:09:46 2003
@@ -18,7 +18,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: php_interbase.h,v 1.58 2003/09/02 22:37:26 abies Exp $ */
+/* $Id: php_interbase.h,v 1.59 2003/09/04 11:09:46 abies Exp $ */
#ifndef PHP_INTERBASE_H
#define PHP_INTERBASE_H
@@ -130,9 +130,8 @@
typedef struct {
ISC_ARRAY_DESC ar_desc;
- int el_type, /* sqltype kinda SQL_TEXT, ...*/
- el_size; /* element size in bytes */
- ISC_LONG ar_size; /* all array size in bytes */
+ ISC_LONG ar_size; /* size of entire array in bytes */
+ unsigned short el_type, el_size;
} ibase_array;
typedef struct {
@@ -158,7 +157,6 @@
isc_stmt_handle stmt;
XSQLDA *in_sqlda, *out_sqlda;
ibase_array *in_array, *out_array;
- int in_array_cnt, out_array_cnt;
unsigned short dialect;
char statement_type;
char *query;
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php