]> granicus.if.org Git - php/commitdiff
Do not reuse data structure for ibase_execute() results.
authorArd Biesheuvel <abies@php.net>
Wed, 27 Aug 2003 22:55:06 +0000 (22:55 +0000)
committerArd Biesheuvel <abies@php.net>
Wed, 27 Aug 2003 22:55:06 +0000 (22:55 +0000)
Invalidate the results whose statement handle has been invalidated.
# EXEC PROCEDURE results don't need a statement handle, so
# the result doesn't have to be invalidated.
Fixed some add_{index|assoc}_*() bogosity

ext/interbase/interbase.c
ext/interbase/php_interbase.h

index c4292c6dadcb0c4bfa14aaa2cf3234ccb5f39ea4..bb90154f965fbf6c4d2a3ec63fa0fd8ba20b8f52 100644 (file)
 #define SQL_DIALECT_CURRENT SQL_DIALECT_V5
 #endif
 
-#ifdef ZEND_DEBUG
-/* #define IBDEBUG(a) php_printf("::: %s (%d)\n", a, __LINE__); */
-#define IBDEBUG(a)
-#else
+#ifdef ZEND_DEBUG_
+#define IBDEBUG(a) php_printf("::: %s (%d)\n", a, __LINE__);
+#endif
+
+#ifndef IBDEBUG
 #define IBDEBUG(a)
 #endif
 
 #define LL_MASK "ll"
 #endif
 
-#define BLOB_ID_LEN 18
-#define BLOB_ID_MASK "0x%" LL_MASK "x"
+#define QUERY_RESULT   1
+#define EXECUTE_RESULT 2
+
+#define ROLLBACK               0
+#define COMMIT                 1
+#define RETAIN                 2
 
-#define BLOB_INPUT 1
-#define BLOB_OUTPUT 2
+#define FETCH_ROW              1
+#define FETCH_ARRAY            2
+
+#define BLOB_ID_LEN            18
+#define BLOB_ID_MASK   "0x%" LL_MASK "x"
+
+#define BLOB_INPUT             1
+#define BLOB_OUTPUT            2
+
+#define BLOB_CLOSE             1
+#define BLOB_CANCEL            2
 
 /* {{{ extension definition structures */
 function_entry ibase_functions[] = {
@@ -230,6 +244,11 @@ typedef struct {
     char *tpb_ptr;
 } ISC_TEB;
 
+typedef struct {
+       ISC_USHORT vary_length;
+       char vary_string[1];
+} IBVARY;
+
 /* Fill ib_link and trans with the correct database link and transaction.
  */
 static void _php_ibase_get_link_trans(INTERNAL_FUNCTION_PARAMETERS, zval **link_id, ibase_db_link **ib_link, ibase_trans **trans)
@@ -298,7 +317,7 @@ static inline char *_php_ibase_quad_to_string(ISC_QUAD const qd)
 
        /* shortcut for most common case */
        if (sizeof(ISC_QUAD) == sizeof(ISC_UINT64)) {
-               sprintf(result, BLOB_ID_MASK, *(ISC_UINT64*) &qd);
+               sprintf(result, BLOB_ID_MASK, *(ISC_UINT64*)(void *) &qd); 
        } else {
                ISC_UINT64 res = ((ISC_UINT64) qd.gds_quad_high << 0x20) | qd.gds_quad_low;
                sprintf(result, BLOB_ID_MASK, res);
@@ -346,7 +365,7 @@ static void _php_ibase_free_xsqlda(XSQLDA *sqlda)
  */
 static void _php_ibase_commit_link(ibase_db_link *link TSRMLS_DC)
 {
-       int i = 0, j;
+       unsigned short i = 0, j;
        ibase_tr_list *l;
        IBDEBUG("Checking transactions to close...");
 
@@ -433,9 +452,9 @@ static void _php_ibase_free_result(zend_rsrc_list_entry *rsrc TSRMLS_DC)
        ibase_result *ib_result = (ibase_result *) rsrc->ptr;
 
        IBDEBUG("Freeing result by dtor...");
-       if (ib_result && ib_result->query == NULL) { /* doesn't belong to a query */
+       if (ib_result) {
                _php_ibase_free_xsqlda(ib_result->out_sqlda);
-               if (ib_result->stmt) {
+               if (ib_result->stmt && ib_result->type != EXECUTE_RESULT) {
                        IBDEBUG("Dropping statement handle (free_result dtor)...");
                        isc_dsql_free_statement(IB_STATUS, &ib_result->stmt, DSQL_drop);
                }
@@ -460,14 +479,6 @@ static void _php_ibase_free_query(ibase_query *ib_query TSRMLS_DC)
        }
        if (ib_query->stmt) {
                IBDEBUG("Dropping statement handle (free_query)...");
-               if (ib_query->result) {
-                       _php_ibase_free_xsqlda(ib_query->result->out_sqlda);
-       
-                       if (ib_query->result->out_array) {
-                               efree(ib_query->result->out_array);
-                       }
-                       efree(ib_query->result);
-               }
                if (isc_dsql_free_statement(IB_STATUS, &ib_query->stmt, DSQL_drop)) {
                        _php_ibase_error(TSRMLS_C);
                }
@@ -487,10 +498,16 @@ static void _php_ibase_free_query(ibase_query *ib_query TSRMLS_DC)
 /* {{{ php_ibase_free_query_rsrc() */
 static void php_ibase_free_query_rsrc(zend_rsrc_list_entry *rsrc TSRMLS_DC)
 {
-       if (rsrc->ptr != NULL) {
+       ibase_query *ib_query = (ibase_query *)rsrc->ptr;
+
+       if (ib_query != NULL) {
                IBDEBUG("Preparing to free query by dtor...");
-               _php_ibase_free_query((ibase_query *)rsrc->ptr TSRMLS_CC);
-               efree(rsrc->ptr);
+
+               _php_ibase_free_query(ib_query TSRMLS_CC);
+               if (ib_query->statement_type != isc_info_sql_stmt_exec_procedure) {
+                       zend_list_delete(ib_query->result_res_id);
+               }
+               efree(ib_query);
        }
 }
 /* }}} */
@@ -514,7 +531,7 @@ static void _php_ibase_free_blob(zend_rsrc_list_entry *rsrc TSRMLS_DC)
 static void _php_ibase_free_trans(zend_rsrc_list_entry *rsrc TSRMLS_DC)
 {
        ibase_trans *trans = (ibase_trans *)rsrc->ptr;
-       int i;
+       unsigned short i;
        
        IBDEBUG("Cleaning up transaction resource...");
        if (trans->handle != NULL) {
@@ -847,7 +864,7 @@ static void _php_ibase_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
                list_entry *le;
                int open_new_connection = 1;
                
-               if (zend_hash_find(&EG(persistent_list), hashed_details, hashed_details_length + 1, (void **) &le) != FAILURE) {
+               if ( (zend_hash_find(&EG(persistent_list), hashed_details, hashed_details_length + 1, (void *) &le)) ) {
                        static char info[] = {isc_info_base_level, isc_info_end};
                        char result[8]; /* Enough? Hope so... */ 
 
@@ -912,7 +929,7 @@ static void _php_ibase_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
                 * if it doesn't, open a new ib_link, add it to the resource list,
                 * and add a pointer to it with hashed_details as the key.
                 */
-               if (zend_hash_find(&EG(regular_list), hashed_details, hashed_details_length + 1, (void **) &index_ptr) == SUCCESS) {
+               if ( (zend_hash_find(&EG(regular_list), hashed_details, hashed_details_length + 1, (void *) &index_ptr)) ) {
                        int type, xlink;
                        void *ptr;
                        if (Z_TYPE_P(index_ptr) != le_index_ptr) {
@@ -1160,7 +1177,6 @@ static int _php_ibase_alloc_query(ibase_query *ib_query, ibase_db_link *link, ib
        
        ib_query->link = link;
        ib_query->trans = trans;
-       ib_query->result = NULL;
        ib_query->result_res_id = 0;
        ib_query->stmt = NULL;
        ib_query->in_array = NULL;
@@ -1613,26 +1629,24 @@ static int _php_ibase_exec(INTERNAL_FUNCTION_PARAMETERS, ibase_result **ib_resul
        /* allocate sqlda and output buffers */
        if (ib_query->out_sqlda) { /* output variables in select, select for update */
                IBDEBUG("Query wants XSQLDA for output");
-               if (IB_RESULT == NULL) { 
-                       IB_RESULT = emalloc(sizeof(ibase_result));
-                       IB_RESULT->link = ib_query->link;
-                       IB_RESULT->trans = ib_query->trans;
-                       IB_RESULT->stmt = ib_query->stmt; 
-                       IB_RESULT->statement_type = ib_query->statement_type;
-                       IB_RESULT->out_sqlda = NULL;
-
-                       out_sqlda = IB_RESULT->out_sqlda = emalloc(XSQLDA_LENGTH(ib_query->out_sqlda->sqld));
-                       memcpy(out_sqlda, ib_query->out_sqlda, XSQLDA_LENGTH(ib_query->out_sqlda->sqld));
-                       _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);
-                       } else {
-                               IB_RESULT->out_array = NULL;
-                       }
-               }
+               IB_RESULT = emalloc(sizeof(ibase_result));
+               IB_RESULT->link = ib_query->link;
+               IB_RESULT->trans = ib_query->trans;
+               IB_RESULT->stmt = ib_query->stmt; 
+               IB_RESULT->statement_type = ib_query->statement_type;
+               IB_RESULT->out_sqlda = NULL;
                IB_RESULT->has_more_rows = 1;
+
+               out_sqlda = IB_RESULT->out_sqlda = emalloc(XSQLDA_LENGTH(ib_query->out_sqlda->sqld));
+               memcpy(out_sqlda, ib_query->out_sqlda, XSQLDA_LENGTH(ib_query->out_sqlda->sqld));
+               _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);
+               } else {
+                       IB_RESULT->out_array = NULL;
+               }
        }
 
        if (ib_query->in_sqlda) { /* has placeholders */
@@ -1904,10 +1918,6 @@ static int _php_ibase_def_trans(ibase_db_link *ib_link, ibase_trans **trans TSRM
 /* }}} */
 
 /* {{{ _php_ibase_trans_end() */
-#define RETAIN 2
-#define COMMIT 1
-#define ROLLBACK 0
-
 static void _php_ibase_trans_end(INTERNAL_FUNCTION_PARAMETERS, int commit)
 {
        ibase_trans *trans = NULL;
@@ -2027,7 +2037,8 @@ PHP_FUNCTION(ibase_query)
        int i, bind_n = 0, trans_res_id = 0;
        ibase_db_link *ib_link = NULL;
        ibase_trans *trans = NULL;
-       ibase_query ib_query= { NULL, NULL, NULL, 0 };
+       ibase_query ib_query = { NULL, NULL, 0, 0 };
+       ibase_result *result = NULL;
        char *query;
 
        RESET_ERRMSG;
@@ -2152,7 +2163,7 @@ PHP_FUNCTION(ibase_query)
                RETURN_FALSE;
        }
 
-       if (_php_ibase_exec(INTERNAL_FUNCTION_PARAM_PASSTHRU, &ib_query.result, &ib_query, bind_n, bind_args) == FAILURE) {
+       if (_php_ibase_exec(INTERNAL_FUNCTION_PARAM_PASSTHRU, &result, &ib_query, bind_n, bind_args) == FAILURE) {
                _php_ibase_free_query(&ib_query TSRMLS_CC);
                free_alloca(args);
                RETURN_FALSE;
@@ -2160,11 +2171,14 @@ PHP_FUNCTION(ibase_query)
 
        free_alloca(args);
        
-       if (ib_query.result != NULL) { /* select statement */
-               ib_query.result->query = NULL; /* drop stmt when free result */
-               ZEND_REGISTER_RESOURCE(return_value, ib_query.result, le_result);
+       if (result != NULL) { /* statement returns a result */
+               result->type = QUERY_RESULT;    
 
-               ib_query.stmt = NULL; /* keep stmt when free query */
+               /* EXECUTE PROCEDURE returns only one row => statement can be released immediately */
+               if (ib_query.statement_type != isc_info_sql_stmt_exec_procedure) {
+                       ib_query.stmt = NULL; /* keep stmt when free query */
+               }
+               ZEND_REGISTER_RESOURCE(return_value, result, le_result);
        }
        _php_ibase_free_query(&ib_query TSRMLS_CC);
 }
@@ -2286,8 +2300,8 @@ static int _php_ibase_var_zval(zval *val, void *data, int type, int len, int sca
                unsigned short j;
 
                case SQL_VARYING:
-                       len = ((PARAMVARY *) data)->vary_length;
-                       data = ((PARAMVARY *) data)->vary_string;
+                       len = ((IBVARY *) data)->vary_length;
+                       data = ((IBVARY *) data)->vary_string;
                        /* fallout */
                case SQL_TEXT:
                        if (PG(magic_quotes_runtime)) {
@@ -2500,10 +2514,6 @@ static int _php_ibase_blob_get(zval *return_value, ibase_blob *ib_blob, unsigned
 /* }}} */
 
 /* {{{ _php_ibase_fetch_hash() */
-
-#define FETCH_ROW      1
-#define FETCH_ARRAY 2
-
 static void _php_ibase_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, int fetch_type)
 {
        zval **result_arg, **flag_arg;
@@ -2839,6 +2849,7 @@ PHP_FUNCTION(ibase_execute)
 {
        zval ***args, **bind_args = NULL;
        ibase_query *ib_query;
+       ibase_result *result = NULL;
 
        RESET_ERRMSG;
 
@@ -2859,15 +2870,17 @@ PHP_FUNCTION(ibase_execute)
                bind_args = args[1];
        }
        
-       /* Have we used this cursor before and it's still open? */
-       if (ib_query->result != NULL) {
+       /* Have we used this cursor before and it's still open (exec proc has no cursor) ? */
+       if (ib_query->result_res_id != 0 && ib_query->statement_type != isc_info_sql_stmt_exec_procedure) {
                IBDEBUG("Implicitly closing a cursor");
                if (isc_dsql_free_statement(IB_STATUS, &ib_query->stmt, DSQL_close)) {
                        _php_ibase_error(TSRMLS_C);
                }
+               /* invalidate previous results returned by this query (not necessary for exec proc) */
+               zend_list_delete(ib_query->result_res_id);      
        }
                
-       if (_php_ibase_exec(INTERNAL_FUNCTION_PARAM_PASSTHRU, &ib_query->result, ib_query, ZEND_NUM_ARGS() - 1, bind_args) == FAILURE) {
+       if (_php_ibase_exec(INTERNAL_FUNCTION_PARAM_PASSTHRU, &result, ib_query, ZEND_NUM_ARGS() - 1, bind_args) == FAILURE) {
                free_alloca(args);
                RETURN_FALSE;
        }
@@ -2879,18 +2892,12 @@ PHP_FUNCTION(ibase_execute)
 
        free_alloca(args);
        
-       if (ib_query->result != NULL) {
-               int type;
-
-               ib_query->result->query = ib_query;
-               
-               /* return the same resource at every execution if it hasn't been freed */
-               if (ib_query->result_res_id == 0 ||
-                       !zend_list_find(ib_query->result_res_id, &type) || 
-                       type != le_result) {
-
-                       ib_query->result_res_id = zend_list_insert(ib_query->result, le_result);
+       if (result != NULL) {
+               result->type = EXECUTE_RESULT;
+               if (ib_query->statement_type == isc_info_sql_stmt_exec_procedure) {
+                       result->stmt = NULL;
                }
+               ib_query->result_res_id = zend_list_insert(result, le_result);
                RETURN_RESOURCE(ib_query->result_res_id);
        }
 }
@@ -3012,7 +3019,6 @@ PHP_FUNCTION(ibase_num_fields)
    Get information about a field */
 PHP_FUNCTION(ibase_field_info)
 {
-       zval *ret_val;
        zval **result_arg, **field_arg;
        ibase_result *ib_result;
        char buf[30], *s;
@@ -3042,17 +3048,17 @@ PHP_FUNCTION(ibase_field_info)
 
        var = ib_result->out_sqlda->sqlvar + Z_LVAL_PP(field_arg);
 
-       add_get_index_stringl(return_value, 0, var->sqlname, var->sqlname_length, (void **) &ret_val, 1);
+       add_index_stringl(return_value, 0, var->sqlname, var->sqlname_length, 1);
        add_assoc_stringl(return_value, "name", var->sqlname, var->sqlname_length, 1);
 
-       add_get_index_stringl(return_value, 1, var->aliasname, var->aliasname_length, (void **) &ret_val, 1);
+       add_index_stringl(return_value, 1, var->aliasname, var->aliasname_length, 1);
        add_assoc_stringl(return_value, "alias", var->aliasname, var->aliasname_length, 1);
 
-       add_get_index_stringl(return_value, 2, var->relname, var->relname_length, (void **) &ret_val, 1);
+       add_index_stringl(return_value, 2, var->relname, var->relname_length, 1);
        add_assoc_stringl(return_value, "relation", var->relname, var->relname_length, 1);
 
        len = sprintf(buf, "%d", var->sqllen);
-       add_get_index_stringl(return_value, 3, buf, len, (void **) &ret_val, 1);
+       add_index_stringl(return_value, 3, buf, len, 1);
        add_assoc_stringl(return_value, "length", buf, len, 1);
 
        switch (var->sqltype & ~1) {
@@ -3089,7 +3095,7 @@ PHP_FUNCTION(ibase_field_info)
                s = buf;
                break;
        }
-       add_get_index_stringl(return_value, 4, s, strlen(s), (void **) &ret_val, 1);
+       add_index_stringl(return_value, 4, s, strlen(s), 1);
        add_assoc_stringl(return_value, "type", s, strlen(s), 1);
 }
 /* }}} */
@@ -3121,7 +3127,6 @@ PHP_FUNCTION(ibase_num_params)
    Get information about a parameter */
 PHP_FUNCTION(ibase_param_info)
 {
-       zval *ret_val;
        zval **result_arg, **field_arg;
        ibase_query *ib_query;
        char buf[30], *s;
@@ -3151,7 +3156,7 @@ PHP_FUNCTION(ibase_param_info)
        var = ib_query->in_sqlda->sqlvar + Z_LVAL_PP(field_arg);
 
        len = sprintf(buf, "%d", var->sqllen);
-       add_get_index_stringl(return_value, 0, buf, len, (void **) &ret_val, 1);
+       add_index_stringl(return_value, 0, buf, len, 1);
        add_assoc_stringl(return_value, "length", buf, len, 1);
 
        switch (var->sqltype & ~1) {
@@ -3184,7 +3189,7 @@ PHP_FUNCTION(ibase_param_info)
                s = buf;
                break;
        }
-       add_get_index_stringl(return_value, 1, s, strlen(s), (void **) &ret_val, 1);
+       add_index_stringl(return_value, 1, s, strlen(s), 1);
        add_assoc_stringl(return_value, "type", s, strlen(s), 1);
 }
 /* }}} */
@@ -3401,9 +3406,6 @@ PHP_FUNCTION(ibase_blob_get)
 }
 /* }}} */
 
-#define BLOB_CLOSE 1
-#define BLOB_CANCEL 2
-
 /* {{{ _php_ibase_blob_end() */
 /* Close or Cancel created or Close open blob */
 static void _php_ibase_blob_end(INTERNAL_FUNCTION_PARAMETERS, int bl_end)
@@ -3462,7 +3464,7 @@ PHP_FUNCTION(ibase_blob_cancel)
    Return blob length and other useful info */
 PHP_FUNCTION(ibase_blob_info)
 {
-       zval **blob_arg, **link_arg, **result_var;
+       zval **blob_arg, **link_arg;
        ibase_db_link *link;
        ibase_trans *trans = NULL;
        ibase_blob ib_blob = { NULL, { 0, 0 }, BLOB_INPUT };
@@ -3522,31 +3524,20 @@ PHP_FUNCTION(ibase_blob_info)
 
        array_init(return_value);
        
-       /* FIXME */
-       add_get_index_long(return_value, 0, bl_info.total_length, (void **) &result_var);
-       /*
-       zend_hash_pointer_update(Z_ARRVAL_P(return_value), "length", sizeof("length"), result_var);
-       */
-
-       add_get_index_long(return_value, 1, bl_info.num_segments, (void **) &result_var);
-       /*
-       zend_hash_pointer_update(Z_ARRVAL_P(return_value), "numseg", sizeof("numseg"), result_var);
-       */
-
-       add_get_index_long(return_value, 2, bl_info.max_segment, (void **) &result_var);
-       /*
-       zend_hash_pointer_update(Z_ARRVAL_P(return_value), "maxseg", sizeof("maxseg"), result_var);
-       */
-
-       add_get_index_long(return_value, 3, bl_info.bl_stream, (void **) &result_var);
-       /*
-       zend_hash_pointer_update(Z_ARRVAL_P(return_value), "stream", sizeof("stream"), result_var);
-       */
-       
-       add_get_index_long(return_value, 4, (!ib_blob.bl_qd.gds_quad_high && !ib_blob.bl_qd.gds_quad_low), (void **) &result_var);
-       /*
-       zend_hash_pointer_update(Z_ARRVAL_P(return_value), "isnull", sizeof("isnull"), result_var);
-       */
+       add_index_long(return_value, 0, bl_info.total_length);
+       add_assoc_long(return_value, "length", bl_info.total_length);
+
+       add_index_long(return_value, 1, bl_info.num_segments);
+       add_assoc_long(return_value, "numseg", bl_info.num_segments);
+
+       add_index_long(return_value, 2, bl_info.max_segment);
+       add_assoc_long(return_value, "maxseg", bl_info.max_segment);
+
+       add_index_bool(return_value, 3, bl_info.bl_stream);
+       add_assoc_bool(return_value, "stream", bl_info.bl_stream);
+
+       add_index_bool(return_value, 4, (!ib_blob.bl_qd.gds_quad_high && !ib_blob.bl_qd.gds_quad_low));
+       add_assoc_bool(return_value, "isnull", (!ib_blob.bl_qd.gds_quad_high && !ib_blob.bl_qd.gds_quad_low));
 }
 /* }}} */
 
index 6cc80a307ca5c924f553ac8bacc06ffb0d755a2b..e36648101c8f220a29da727cc73d4615b8d40407 100644 (file)
@@ -144,18 +144,17 @@ typedef struct {
 typedef struct {
        ibase_db_link *link;
        ibase_trans *trans;
-       struct _ibase_query *query;
        isc_stmt_handle stmt;
+       unsigned short type;
        XSQLDA *out_sqlda;
        ibase_array *out_array;
        unsigned char has_more_rows;
        char statement_type;
 } ibase_result;
 
-typedef struct _ibase_query {
+typedef struct {
        ibase_db_link *link;
        ibase_trans *trans;
-       ibase_result *result;
        int result_res_id;
        isc_stmt_handle stmt;
        XSQLDA *in_sqlda, *out_sqlda;