diff options
Diffstat (limited to 'ext/mysqlnd/mysqlnd_ps.c')
| -rw-r--r-- | ext/mysqlnd/mysqlnd_ps.c | 493 |
1 files changed, 244 insertions, 249 deletions
diff --git a/ext/mysqlnd/mysqlnd_ps.c b/ext/mysqlnd/mysqlnd_ps.c index e3bfc7b7fb..7053ebe8e7 100644 --- a/ext/mysqlnd/mysqlnd_ps.c +++ b/ext/mysqlnd/mysqlnd_ps.c @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 2006-2016 The PHP Group | +----------------------------------------------------------------------+ @@ -12,13 +12,12 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Andrey Hristov <andrey@mysql.com> | - | Ulf Wendel <uwendel@mysql.com> | - | Georg Richter <georg@mysql.com> | + | Authors: Andrey Hristov <andrey@php.net> | + | Ulf Wendel <uw@php.net> | + | Georg Richter <georg@php.net> | +----------------------------------------------------------------------+ */ -/* $Id$ */ #include "php.h" #include "mysqlnd.h" #include "mysqlnd_wireprotocol.h" @@ -37,14 +36,15 @@ const char * const mysqlnd_not_bound_as_blob = "Can't send long data for non-str const char * const mysqlnd_stmt_not_prepared = "Statement not prepared"; /* Exported by mysqlnd_ps_codec.c */ -enum_func_status mysqlnd_stmt_execute_generate_request(MYSQLND_STMT * const s, zend_uchar ** request, size_t *request_len, zend_bool * free_buffer TSRMLS_DC); +enum_func_status mysqlnd_stmt_execute_generate_request(MYSQLND_STMT * const s, zend_uchar ** request, size_t *request_len, zend_bool * free_buffer); +enum_func_status mysqlnd_stmt_execute_batch_generate_request(MYSQLND_STMT * const s, zend_uchar ** request, size_t *request_len, zend_bool * free_buffer); -static void mysqlnd_stmt_separate_result_bind(MYSQLND_STMT * const stmt TSRMLS_DC); -static void mysqlnd_stmt_separate_one_result_bind(MYSQLND_STMT * const stmt, unsigned int param_no TSRMLS_DC); +static void mysqlnd_stmt_separate_result_bind(MYSQLND_STMT * const stmt); +static void mysqlnd_stmt_separate_one_result_bind(MYSQLND_STMT * const stmt, unsigned int param_no); /* {{{ mysqlnd_stmt::store_result */ static MYSQLND_RES * -MYSQLND_METHOD(mysqlnd_stmt, store_result)(MYSQLND_STMT * const s TSRMLS_DC) +MYSQLND_METHOD(mysqlnd_stmt, store_result)(MYSQLND_STMT * const s) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; enum_func_status ret; @@ -66,7 +66,7 @@ MYSQLND_METHOD(mysqlnd_stmt, store_result)(MYSQLND_STMT * const s TSRMLS_DC) if (stmt->cursor_exists) { /* Silently convert buffered to unbuffered, for now */ - DBG_RETURN(s->m->use_result(s TSRMLS_CC)); + DBG_RETURN(s->m->use_result(s)); } /* Nothing to store for UPSERT/LOAD DATA*/ @@ -88,13 +88,13 @@ MYSQLND_METHOD(mysqlnd_stmt, store_result)(MYSQLND_STMT * const s TSRMLS_DC) result->type = MYSQLND_RES_PS_BUF; /* result->m.row_decoder = php_mysqlnd_rowp_read_binary_protocol; */ - result->stored_data = (MYSQLND_RES_BUFFERED *) mysqlnd_result_buffered_zval_init(result->field_count, TRUE, result->persistent TSRMLS_CC); + result->stored_data = (MYSQLND_RES_BUFFERED *) mysqlnd_result_buffered_zval_init(result->field_count, TRUE, result->persistent); if (!result->stored_data) { SET_OOM_ERROR(*conn->error_info); DBG_RETURN(NULL); } - ret = result->m.store_result_fetch_data(conn, result, result->meta, &result->stored_data->row_buffers, TRUE TSRMLS_CC); + ret = result->m.store_result_fetch_data(conn, result, result->meta, &result->stored_data->row_buffers, TRUE); result->stored_data->m.fetch_row = mysqlnd_stmt_fetch_row_buffered; @@ -109,12 +109,12 @@ MYSQLND_METHOD(mysqlnd_stmt, store_result)(MYSQLND_STMT * const s TSRMLS_DC) DBG_RETURN(NULL); } /* if pecalloc is used valgrind barks gcc version 4.3.1 20080507 (prerelease) [gcc-4_3-branch revision 135036] (SUSE Linux) */ - set->data = mnd_emalloc((size_t)(result->stored_data->row_count * result->meta->field_count * sizeof(zval *))); + set->data = mnd_emalloc((size_t)(result->stored_data->row_count * result->meta->field_count * sizeof(zval))); if (!set->data) { SET_OOM_ERROR(*conn->error_info); DBG_RETURN(NULL); } - memset(set->data, 0, (size_t)(result->stored_data->row_count * result->meta->field_count * sizeof(zval *))); + memset(set->data, 0, (size_t)(result->stored_data->row_count * result->meta->field_count * sizeof(zval))); } /* Position at the first row */ set->data_cursor = set->data; @@ -128,7 +128,7 @@ MYSQLND_METHOD(mysqlnd_stmt, store_result)(MYSQLND_STMT * const s TSRMLS_DC) stmt->state = MYSQLND_STMT_USE_OR_STORE_CALLED; } else { COPY_CLIENT_ERROR(*conn->error_info, result->stored_data->error_info); - stmt->result->m.free_result_contents(stmt->result TSRMLS_CC); + stmt->result->m.free_result_contents(stmt->result); mnd_efree(stmt->result); stmt->result = NULL; stmt->state = MYSQLND_STMT_PREPARED; @@ -141,7 +141,7 @@ MYSQLND_METHOD(mysqlnd_stmt, store_result)(MYSQLND_STMT * const s TSRMLS_DC) /* {{{ mysqlnd_stmt::get_result */ static MYSQLND_RES * -MYSQLND_METHOD(mysqlnd_stmt, get_result)(MYSQLND_STMT * const s TSRMLS_DC) +MYSQLND_METHOD(mysqlnd_stmt, get_result)(MYSQLND_STMT * const s) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; MYSQLND_CONN_DATA * conn; @@ -162,7 +162,7 @@ MYSQLND_METHOD(mysqlnd_stmt, get_result)(MYSQLND_STMT * const s TSRMLS_DC) if (stmt->cursor_exists) { /* Silently convert buffered to unbuffered, for now */ - DBG_RETURN(s->m->use_result(s TSRMLS_CC)); + DBG_RETURN(s->m->use_result(s)); } /* Nothing to store for UPSERT/LOAD DATA*/ @@ -177,19 +177,19 @@ MYSQLND_METHOD(mysqlnd_stmt, get_result)(MYSQLND_STMT * const s TSRMLS_DC) MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_BUFFERED_SETS); do { - result = conn->m->result_init(stmt->result->field_count, stmt->persistent TSRMLS_CC); + result = conn->m->result_init(stmt->result->field_count, stmt->persistent); if (!result) { SET_OOM_ERROR(*conn->error_info); break; } - result->meta = stmt->result->meta->m->clone_metadata(stmt->result->meta, FALSE TSRMLS_CC); + result->meta = stmt->result->meta->m->clone_metadata(stmt->result->meta, FALSE); if (!result->meta) { SET_OOM_ERROR(*conn->error_info); break; } - if ((result = result->m.store_result(result, conn, MYSQLND_STORE_PS | MYSQLND_STORE_NO_COPY TSRMLS_CC))) { + if ((result = result->m.store_result(result, conn, MYSQLND_STORE_PS | MYSQLND_STORE_NO_COPY))) { stmt->upsert_status->affected_rows = result->stored_data->row_count; stmt->state = MYSQLND_STMT_PREPARED; result->type = MYSQLND_RES_PS_BUF; @@ -202,7 +202,7 @@ MYSQLND_METHOD(mysqlnd_stmt, get_result)(MYSQLND_STMT * const s TSRMLS_DC) } while (0); if (result) { - result->m.free_result(result, TRUE TSRMLS_CC); + result->m.free_result(result, TRUE); } DBG_RETURN(NULL); } @@ -211,12 +211,12 @@ MYSQLND_METHOD(mysqlnd_stmt, get_result)(MYSQLND_STMT * const s TSRMLS_DC) /* {{{ mysqlnd_stmt::more_results */ static zend_bool -MYSQLND_METHOD(mysqlnd_stmt, more_results)(const MYSQLND_STMT * s TSRMLS_DC) +MYSQLND_METHOD(mysqlnd_stmt, more_results)(const MYSQLND_STMT * s) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; DBG_ENTER("mysqlnd_stmt::more_results"); /* (conn->state == CONN_NEXT_RESULT_PENDING) too */ - DBG_RETURN((stmt && stmt->conn && (stmt->conn->m->get_server_status(stmt->conn TSRMLS_CC) & SERVER_MORE_RESULTS_EXISTS))? + DBG_RETURN((stmt && stmt->conn && (stmt->conn->m->get_server_status(stmt->conn) & SERVER_MORE_RESULTS_EXISTS))? TRUE: FALSE); } @@ -225,7 +225,7 @@ MYSQLND_METHOD(mysqlnd_stmt, more_results)(const MYSQLND_STMT * s TSRMLS_DC) /* {{{ mysqlnd_stmt::next_result */ static enum_func_status -MYSQLND_METHOD(mysqlnd_stmt, next_result)(MYSQLND_STMT * s TSRMLS_DC) +MYSQLND_METHOD(mysqlnd_stmt, next_result)(MYSQLND_STMT * s) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; MYSQLND_CONN_DATA * conn; @@ -244,9 +244,9 @@ MYSQLND_METHOD(mysqlnd_stmt, next_result)(MYSQLND_STMT * s TSRMLS_DC) DBG_INF_FMT("server_status=%u cursor=%u", stmt->upsert_status->server_status, stmt->upsert_status->server_status & SERVER_STATUS_CURSOR_EXISTS); /* Free space for next result */ - s->m->free_stmt_result(s TSRMLS_CC); + s->m->free_stmt_result(s); { - enum_func_status ret = s->m->parse_execute_response(s TSRMLS_CC); + enum_func_status ret = s->m->parse_execute_response(s, MYSQLND_PARSE_EXEC_RESPONSE_IMPLICIT_NEXT_RESULT); DBG_RETURN(ret); } } @@ -255,7 +255,7 @@ MYSQLND_METHOD(mysqlnd_stmt, next_result)(MYSQLND_STMT * s TSRMLS_DC) /* {{{ mysqlnd_stmt_skip_metadata */ static enum_func_status -mysqlnd_stmt_skip_metadata(MYSQLND_STMT * s TSRMLS_DC) +mysqlnd_stmt_skip_metadata(MYSQLND_STMT * s) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; /* Follows parameter metadata, we have just to skip it, as libmysql does */ @@ -269,7 +269,7 @@ mysqlnd_stmt_skip_metadata(MYSQLND_STMT * s TSRMLS_DC) } DBG_INF_FMT("stmt=%lu", stmt->stmt_id); - field_packet = stmt->conn->protocol->m.get_result_field_packet(stmt->conn->protocol, FALSE TSRMLS_CC); + field_packet = stmt->conn->protocol->m.get_result_field_packet(stmt->conn->protocol, FALSE); if (!field_packet) { SET_OOM_ERROR(*stmt->error_info); SET_OOM_ERROR(*stmt->conn->error_info); @@ -292,7 +292,7 @@ mysqlnd_stmt_skip_metadata(MYSQLND_STMT * s TSRMLS_DC) /* {{{ mysqlnd_stmt_read_prepare_response */ static enum_func_status -mysqlnd_stmt_read_prepare_response(MYSQLND_STMT * s TSRMLS_DC) +mysqlnd_stmt_read_prepare_response(MYSQLND_STMT * s) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; MYSQLND_PACKET_PREPARE_RESPONSE * prepare_resp; @@ -304,7 +304,7 @@ mysqlnd_stmt_read_prepare_response(MYSQLND_STMT * s TSRMLS_DC) } DBG_INF_FMT("stmt=%lu", stmt->stmt_id); - prepare_resp = stmt->conn->protocol->m.get_prepare_response_packet(stmt->conn->protocol, FALSE TSRMLS_CC); + prepare_resp = stmt->conn->protocol->m.get_prepare_response_packet(stmt->conn->protocol, FALSE); if (!prepare_resp) { SET_OOM_ERROR(*stmt->error_info); SET_OOM_ERROR(*stmt->conn->error_info); @@ -336,7 +336,7 @@ done: /* {{{ mysqlnd_stmt_prepare_read_eof */ static enum_func_status -mysqlnd_stmt_prepare_read_eof(MYSQLND_STMT * s TSRMLS_DC) +mysqlnd_stmt_prepare_read_eof(MYSQLND_STMT * s) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; MYSQLND_PACKET_EOF * fields_eof; @@ -348,14 +348,14 @@ mysqlnd_stmt_prepare_read_eof(MYSQLND_STMT * s TSRMLS_DC) } DBG_INF_FMT("stmt=%lu", stmt->stmt_id); - fields_eof = stmt->conn->protocol->m.get_eof_packet(stmt->conn->protocol, FALSE TSRMLS_CC); + fields_eof = stmt->conn->protocol->m.get_eof_packet(stmt->conn->protocol, FALSE); if (!fields_eof) { SET_OOM_ERROR(*stmt->error_info); SET_OOM_ERROR(*stmt->conn->error_info); } else { if (FAIL == (ret = PACKET_READ(fields_eof, stmt->conn))) { if (stmt->result) { - stmt->result->m.free_result_contents(stmt->result TSRMLS_CC); + stmt->result->m.free_result_contents(stmt->result); mnd_efree(stmt->result); memset(stmt, 0, sizeof(MYSQLND_STMT_DATA)); stmt->state = MYSQLND_STMT_INITTED; @@ -375,7 +375,7 @@ mysqlnd_stmt_prepare_read_eof(MYSQLND_STMT * s TSRMLS_DC) /* {{{ mysqlnd_stmt::prepare */ static enum_func_status -MYSQLND_METHOD(mysqlnd_stmt, prepare)(MYSQLND_STMT * const s, const char * const query, unsigned int query_len TSRMLS_DC) +MYSQLND_METHOD(mysqlnd_stmt, prepare)(MYSQLND_STMT * const s, const char * const query, unsigned int query_len) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; MYSQLND_STMT * s_to_prepare = s; @@ -399,32 +399,32 @@ MYSQLND_METHOD(mysqlnd_stmt, prepare)(MYSQLND_STMT * const s, const char * const if (stmt->state == MYSQLND_STMT_WAITING_USE_OR_STORE) { /* Do implicit use_result and then flush the result */ stmt->default_rset_handler = s->m->use_result; - stmt->default_rset_handler(s TSRMLS_CC); + stmt->default_rset_handler(s); } /* No 'else' here please :) */ if (stmt->state > MYSQLND_STMT_WAITING_USE_OR_STORE && stmt->result) { - stmt->result->m.skip_result(stmt->result TSRMLS_CC); + stmt->result->m.skip_result(stmt->result); } /* Create a new test statement, which we will prepare, but if anything fails, we will scrap it. */ - s_to_prepare = stmt->conn->m->stmt_init(stmt->conn TSRMLS_CC); + s_to_prepare = stmt->conn->m->stmt_init(stmt->conn); if (!s_to_prepare) { goto fail; } stmt_to_prepare = s_to_prepare->data; } - if (FAIL == stmt_to_prepare->conn->m->simple_command(stmt_to_prepare->conn, COM_STMT_PREPARE, (const zend_uchar *) query, query_len, PROT_LAST, FALSE, TRUE TSRMLS_CC) || - FAIL == mysqlnd_stmt_read_prepare_response(s_to_prepare TSRMLS_CC)) + if (FAIL == stmt_to_prepare->conn->m->simple_command(stmt_to_prepare->conn, COM_STMT_PREPARE, (const zend_uchar *) query, query_len, PROT_LAST, FALSE, TRUE) || + FAIL == mysqlnd_stmt_read_prepare_response(s_to_prepare)) { goto fail; } if (stmt_to_prepare->param_count) { - if (FAIL == mysqlnd_stmt_skip_metadata(s_to_prepare TSRMLS_CC) || - FAIL == mysqlnd_stmt_prepare_read_eof(s_to_prepare TSRMLS_CC)) + if (FAIL == mysqlnd_stmt_skip_metadata(s_to_prepare) || + FAIL == mysqlnd_stmt_prepare_read_eof(s_to_prepare)) { goto fail; } @@ -436,20 +436,20 @@ MYSQLND_METHOD(mysqlnd_stmt, prepare)(MYSQLND_STMT * const s, const char * const no metadata at prepare. */ if (stmt_to_prepare->field_count) { - MYSQLND_RES * result = stmt->conn->m->result_init(stmt_to_prepare->field_count, stmt_to_prepare->persistent TSRMLS_CC); + MYSQLND_RES * result = stmt->conn->m->result_init(stmt_to_prepare->field_count, stmt_to_prepare->persistent); if (!result) { SET_OOM_ERROR(*stmt->conn->error_info); goto fail; } /* Allocate the result now as it is needed for the reading of metadata */ - stmt_to_prepare->result = result; + stmt_to_prepare->result = result; - result->conn = stmt_to_prepare->conn->m->get_reference(stmt_to_prepare->conn TSRMLS_CC); + result->conn = stmt_to_prepare->conn->m->get_reference(stmt_to_prepare->conn); result->type = MYSQLND_RES_PS_BUF; - if (FAIL == result->m.read_result_metadata(result, stmt_to_prepare->conn TSRMLS_CC) || - FAIL == mysqlnd_stmt_prepare_read_eof(s_to_prepare TSRMLS_CC)) + if (FAIL == result->m.read_result_metadata(result, stmt_to_prepare->conn) || + FAIL == mysqlnd_stmt_prepare_read_eof(s_to_prepare)) { goto fail; } @@ -468,7 +468,7 @@ MYSQLND_METHOD(mysqlnd_stmt, prepare)(MYSQLND_STMT * const s, const char * const stmt_to_prepare = stmt; stmt = tmp_swap_data; } - s_to_prepare->m->dtor(s_to_prepare, TRUE TSRMLS_CC); + s_to_prepare->m->dtor(s_to_prepare, TRUE); } stmt->state = MYSQLND_STMT_PREPARED; DBG_INF("PASS"); @@ -476,7 +476,7 @@ MYSQLND_METHOD(mysqlnd_stmt, prepare)(MYSQLND_STMT * const s, const char * const fail: if (stmt_to_prepare != stmt && s_to_prepare) { - s_to_prepare->m->dtor(s_to_prepare, TRUE TSRMLS_CC); + s_to_prepare->m->dtor(s_to_prepare, TRUE); } stmt->state = MYSQLND_STMT_INITTED; @@ -488,7 +488,7 @@ fail: /* {{{ mysqlnd_stmt_execute_parse_response */ static enum_func_status -mysqlnd_stmt_execute_parse_response(MYSQLND_STMT * const s TSRMLS_DC) +mysqlnd_stmt_execute_parse_response(MYSQLND_STMT * const s, enum_mysqlnd_parse_exec_response_type type) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; enum_func_status ret; @@ -501,7 +501,7 @@ mysqlnd_stmt_execute_parse_response(MYSQLND_STMT * const s TSRMLS_DC) conn = stmt->conn; CONN_SET_STATE(conn, CONN_QUERY_SENT); - ret = mysqlnd_query_read_result_set_header(stmt->conn, s TSRMLS_CC); + ret = mysqlnd_query_read_result_set_header(stmt->conn, s); if (ret == FAIL) { COPY_CLIENT_ERROR(*stmt->error_info, *conn->error_info); memset(stmt->upsert_status, 0, sizeof(*stmt->upsert_status)); @@ -534,7 +534,7 @@ mysqlnd_stmt_execute_parse_response(MYSQLND_STMT * const s TSRMLS_DC) For SHOW we don't create (bypasses PS in server) a result set at prepare and thus a connection was missing */ - stmt->result->conn = stmt->conn->m->get_reference(stmt->conn TSRMLS_CC); + stmt->result->conn = stmt->conn->m->get_reference(stmt->conn); } /* Update stmt->field_count as SHOW sets it to 0 at prepare */ @@ -586,13 +586,19 @@ mysqlnd_stmt_execute_parse_response(MYSQLND_STMT * const s TSRMLS_DC) } #ifndef MYSQLND_DONT_SKIP_OUT_PARAMS_RESULTSET if (stmt->upsert_status->server_status & SERVER_PS_OUT_PARAMS) { - s->m->free_stmt_content(s TSRMLS_CC); + s->m->free_stmt_content(s); DBG_INF("PS OUT Variable RSet, skipping"); /* OUT params result set. Skip for now to retain compatibility */ - ret = mysqlnd_stmt_execute_parse_response(s TSRMLS_CC); + ret = mysqlnd_stmt_execute_parse_response(s, MYSQLND_PARSE_EXEC_RESPONSE_IMPLICIT_OUT_VARIABLES); } #endif + DBG_INF_FMT("server_status=%u cursor=%u", stmt->upsert_status->server_status, stmt->upsert_status->server_status & SERVER_STATUS_CURSOR_EXISTS); + + if (ret == PASS && conn->last_query_type == QUERY_UPSERT && stmt->upsert_status->affected_rows) { + MYSQLND_INC_CONN_STATISTIC_W_VALUE(conn->stats, STAT_ROWS_AFFECTED_PS, stmt->upsert_status->affected_rows); + } + DBG_INF(ret == PASS? "PASS":"FAIL"); DBG_RETURN(ret); } @@ -601,7 +607,22 @@ mysqlnd_stmt_execute_parse_response(MYSQLND_STMT * const s TSRMLS_DC) /* {{{ mysqlnd_stmt::execute */ static enum_func_status -MYSQLND_METHOD(mysqlnd_stmt, execute)(MYSQLND_STMT * const s TSRMLS_DC) +MYSQLND_METHOD(mysqlnd_stmt, execute)(MYSQLND_STMT * const s) +{ + DBG_ENTER("mysqlnd_stmt::execute"); + if (FAIL == s->m->send_execute(s, MYSQLND_SEND_EXECUTE_IMPLICIT, NULL, NULL) || + FAIL == s->m->parse_execute_response(s, MYSQLND_PARSE_EXEC_RESPONSE_IMPLICIT)) + { + DBG_RETURN(FAIL); + } + DBG_RETURN(PASS); +} +/* }}} */ + + +/* {{{ mysqlnd_stmt::send_execute */ +static enum_func_status +MYSQLND_METHOD(mysqlnd_stmt, send_execute)(MYSQLND_STMT * const s, enum_mysqlnd_send_execute_type type, zval * read_cb, zval * err_cb) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; enum_func_status ret; @@ -610,7 +631,7 @@ MYSQLND_METHOD(mysqlnd_stmt, execute)(MYSQLND_STMT * const s TSRMLS_DC) size_t request_len; zend_bool free_request; - DBG_ENTER("mysqlnd_stmt::execute"); + DBG_ENTER("mysqlnd_stmt::send_execute"); if (!stmt || !stmt->conn) { DBG_RETURN(FAIL); } @@ -628,7 +649,7 @@ MYSQLND_METHOD(mysqlnd_stmt, execute)(MYSQLND_STMT * const s TSRMLS_DC) */ #ifdef WE_DONT_COPY_IN_BUFFERED_AND_UNBUFFERED_BECAUSEOF_IS_REF if (stmt->result_bind && - stmt->result_zvals_separated_once == TRUE && + stmt->result_zvals_separated_once == TRUE && stmt->state >= MYSQLND_STMT_USER_FETCHING) { /* @@ -642,24 +663,26 @@ MYSQLND_METHOD(mysqlnd_stmt, execute)(MYSQLND_STMT * const s TSRMLS_DC) fetch(); <-- no binding, but that's not a problem bind_result(); execute(); <-- here we will leak because we separate without need - */ + */ unsigned int i; for (i = 0; i < stmt->field_count; i++) { if (stmt->result_bind[i].bound == TRUE) { - zval_copy_ctor(stmt->result_bind[i].zv); + zval *result = &stmt->result_bind[i].zv; + ZVAL_DEREF(result); + Z_TRY_ADDREF_P(result); } } } #endif - s->m->flush(s TSRMLS_CC); + s->m->flush(s); /* Executed, but the user hasn't started to fetch This will clean also the metadata, but after the EXECUTE call we will have it again. */ - stmt->result->m.free_result_buffers(stmt->result TSRMLS_CC); + stmt->result->m.free_result_buffers(stmt->result); stmt->state = MYSQLND_STMT_PREPARED; } else if (stmt->state < MYSQLND_STMT_PREPARED) { @@ -680,7 +703,7 @@ MYSQLND_METHOD(mysqlnd_stmt, execute)(MYSQLND_STMT * const s TSRMLS_DC) DBG_RETURN(FAIL); } for (i = 0; i < stmt->param_count; i++) { - if (stmt->param_bind[i].zv == NULL) { + if (Z_ISUNDEF(stmt->param_bind[i].zv)) { not_bound++; } } @@ -696,12 +719,12 @@ MYSQLND_METHOD(mysqlnd_stmt, execute)(MYSQLND_STMT * const s TSRMLS_DC) DBG_RETURN(FAIL); } } - ret = s->m->generate_execute_request(s, &request, &request_len, &free_request TSRMLS_CC); + ret = s->m->generate_execute_request(s, &request, &request_len, &free_request); if (ret == PASS) { /* support for buffer types should be added here ! */ ret = stmt->conn->m->simple_command(stmt->conn, COM_STMT_EXECUTE, request, request_len, PROT_LAST /* we will handle the response packet*/, - FALSE, FALSE TSRMLS_CC); + FALSE, FALSE); } else { SET_STMT_ERROR(stmt, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, "Couldn't generate the request. Possibly OOM."); } @@ -717,21 +740,14 @@ MYSQLND_METHOD(mysqlnd_stmt, execute)(MYSQLND_STMT * const s TSRMLS_DC) } stmt->execute_count++; - ret = s->m->parse_execute_response(s TSRMLS_CC); - - DBG_INF_FMT("server_status=%u cursor=%u", stmt->upsert_status->server_status, stmt->upsert_status->server_status & SERVER_STATUS_CURSOR_EXISTS); - - if (ret == PASS && conn->last_query_type == QUERY_UPSERT && stmt->upsert_status->affected_rows) { - MYSQLND_INC_CONN_STATISTIC_W_VALUE(conn->stats, STAT_ROWS_AFFECTED_PS, stmt->upsert_status->affected_rows); - } - DBG_RETURN(ret); + DBG_RETURN(PASS); } /* }}} */ /* {{{ mysqlnd_stmt_fetch_row_buffered */ enum_func_status -mysqlnd_stmt_fetch_row_buffered(MYSQLND_RES * result, void * param, unsigned int flags, zend_bool * fetched_anything TSRMLS_DC) +mysqlnd_stmt_fetch_row_buffered(MYSQLND_RES * result, void * param, unsigned int flags, zend_bool * fetched_anything) { MYSQLND_STMT * s = (MYSQLND_STMT *) param; MYSQLND_STMT_DATA * stmt = s? s->data:NULL; @@ -751,16 +767,16 @@ mysqlnd_stmt_fetch_row_buffered(MYSQLND_RES * result, void * param, unsigned int /* The user could have skipped binding - don't crash*/ if (stmt->result_bind) { unsigned int i; - zval **current_row = set->data_cursor; + zval *current_row = set->data_cursor; - if (NULL == current_row[0]) { + if (Z_ISUNDEF(current_row[0])) { uint64_t row_num = (set->data_cursor - set->data) / field_count; enum_func_status rc = result->stored_data->m.row_decoder(result->stored_data->row_buffers[row_num], current_row, meta->field_count, meta->fields, result->conn->options->int_and_float_native, - result->conn->stats TSRMLS_CC); + result->conn->stats); if (PASS != rc) { DBG_RETURN(FAIL); } @@ -772,8 +788,8 @@ mysqlnd_stmt_fetch_row_buffered(MYSQLND_RES * result, void * param, unsigned int String of zero size, definitely can't be the next max_length. Thus for NULL and zero-length we are quite efficient. */ - if (Z_TYPE_P(current_row[i]) >= IS_STRING) { - unsigned long len = Z_STRLEN_P(current_row[i]); + if (Z_TYPE(current_row[i]) == IS_STRING) { + zend_ulong len = Z_STRLEN(current_row[i]); if (meta->fields[i].max_length < len) { meta->fields[i].max_length = len; } @@ -783,16 +799,17 @@ mysqlnd_stmt_fetch_row_buffered(MYSQLND_RES * result, void * param, unsigned int } for (i = 0; i < result->field_count; i++) { + zval *result = &stmt->result_bind[i].zv; + + ZVAL_DEREF(result); /* Clean what we copied last time */ #ifndef WE_DONT_COPY_IN_BUFFERED_AND_UNBUFFERED_BECAUSEOF_IS_REF - if (stmt->result_bind[i].zv) { - zval_dtor(stmt->result_bind[i].zv); - } + zval_dtor(result); #endif /* copy the type */ if (stmt->result_bind[i].bound == TRUE) { - DBG_INF_FMT("i=%u type=%u", i, Z_TYPE_P(current_row[i])); - if (Z_TYPE_P(current_row[i]) != IS_NULL) { + DBG_INF_FMT("i=%u type=%u", i, Z_TYPE(current_row[i])); + if (Z_TYPE(current_row[i]) != IS_NULL) { /* Copy the value. Pre-condition is that the zvals in the result_bind buffer @@ -801,13 +818,12 @@ mysqlnd_stmt_fetch_row_buffered(MYSQLND_RES * result, void * param, unsigned int counting the user can't delete the strings the variables point to. */ - Z_TYPE_P(stmt->result_bind[i].zv) = Z_TYPE_P(current_row[i]); - stmt->result_bind[i].zv->value = current_row[i]->value; + ZVAL_COPY_VALUE(result, ¤t_row[i]); #ifndef WE_DONT_COPY_IN_BUFFERED_AND_UNBUFFERED_BECAUSEOF_IS_REF - zval_copy_ctor(stmt->result_bind[i].zv); + Z_TRY_ADDREF_P(result); #endif } else { - ZVAL_NULL(stmt->result_bind[i].zv); + ZVAL_NULL(result); } } } @@ -832,7 +848,7 @@ mysqlnd_stmt_fetch_row_buffered(MYSQLND_RES * result, void * param, unsigned int /* {{{ mysqlnd_stmt_fetch_row_unbuffered */ enum_func_status -mysqlnd_stmt_fetch_row_unbuffered(MYSQLND_RES * result, void * param, unsigned int flags, zend_bool * fetched_anything TSRMLS_DC) +mysqlnd_stmt_fetch_row_unbuffered(MYSQLND_RES * result, void * param, unsigned int flags, zend_bool * fetched_anything) { enum_func_status ret; MYSQLND_STMT * s = (MYSQLND_STMT *) param; @@ -870,7 +886,7 @@ mysqlnd_stmt_fetch_row_unbuffered(MYSQLND_RES * result, void * param, unsigned i unsigned int i, field_count = result->field_count; if (!row_packet->skip_extraction) { - result->unbuf->m.free_last_data(result->unbuf, result->conn? result->conn->stats : NULL TSRMLS_CC); + result->unbuf->m.free_last_data(result->unbuf, result->conn? result->conn->stats : NULL); result->unbuf->last_row_data = row_packet->fields; result->unbuf->last_row_buffer = row_packet->row_buffer; @@ -882,28 +898,34 @@ mysqlnd_stmt_fetch_row_unbuffered(MYSQLND_RES * result, void * param, unsigned i row_packet->field_count, row_packet->fields_metadata, result->conn->options->int_and_float_native, - result->conn->stats TSRMLS_CC)) + result->conn->stats)) { DBG_RETURN(FAIL); } for (i = 0; i < field_count; i++) { if (stmt->result_bind[i].bound == TRUE) { - zval *data = result->unbuf->last_row_data[i]; + zval *data = &result->unbuf->last_row_data[i]; + zval *result = &stmt->result_bind[i].zv; + + ZVAL_DEREF(result); /* stmt->result_bind[i].zv has been already destructed in result->unbuf->m.free_last_data() */ #ifndef WE_DONT_COPY_IN_BUFFERED_AND_UNBUFFERED_BECAUSEOF_IS_REF - zval_dtor(stmt->result_bind[i].zv); + zval_dtor(result); #endif - if (IS_NULL != (Z_TYPE_P(stmt->result_bind[i].zv) = Z_TYPE_P(data)) ) { - if ((Z_TYPE_P(data) == IS_STRING) && (meta->fields[i].max_length < (unsigned long) Z_STRLEN_P(data))) { + if (!Z_ISNULL_P(data)) { + if ((Z_TYPE_P(data) == IS_STRING) && + (meta->fields[i].max_length < (zend_ulong) Z_STRLEN_P(data))) { meta->fields[i].max_length = Z_STRLEN_P(data); } - stmt->result_bind[i].zv->value = data->value; + ZVAL_COPY_VALUE(result, data); /* copied data, thus also the ownership. Thus null data */ ZVAL_NULL(data); + } else { + ZVAL_NULL(result); } } } @@ -916,7 +938,7 @@ mysqlnd_stmt_fetch_row_unbuffered(MYSQLND_RES * result, void * param, unsigned i the bound variables. Thus we need to do part of what it does or Zend will report leaks. */ - row_packet->row_buffer->free_chunk(row_packet->row_buffer TSRMLS_CC); + row_packet->row_buffer->free_chunk(row_packet->row_buffer); row_packet->row_buffer = NULL; } @@ -955,7 +977,7 @@ mysqlnd_stmt_fetch_row_unbuffered(MYSQLND_RES * result, void * param, unsigned i /* {{{ mysqlnd_stmt::use_result */ static MYSQLND_RES * -MYSQLND_METHOD(mysqlnd_stmt, use_result)(MYSQLND_STMT * s TSRMLS_DC) +MYSQLND_METHOD(mysqlnd_stmt, use_result)(MYSQLND_STMT * s) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; MYSQLND_RES * result; @@ -985,7 +1007,7 @@ MYSQLND_METHOD(mysqlnd_stmt, use_result)(MYSQLND_STMT * s TSRMLS_DC) MYSQLND_INC_CONN_STATISTIC(stmt->conn->stats, STAT_PS_UNBUFFERED_SETS); result = stmt->result; - result->m.use_result(stmt->result, TRUE TSRMLS_CC); + result->m.use_result(stmt->result, TRUE); result->unbuf->m.fetch_row = stmt->cursor_exists? mysqlnd_fetch_stmt_row_cursor: mysqlnd_stmt_fetch_row_unbuffered; stmt->state = MYSQLND_STMT_USE_OR_STORE_CALLED; @@ -1000,7 +1022,7 @@ MYSQLND_METHOD(mysqlnd_stmt, use_result)(MYSQLND_STMT * s TSRMLS_DC) /* {{{ mysqlnd_fetch_row_cursor */ enum_func_status -mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES * result, void * param, unsigned int flags, zend_bool * fetched_anything TSRMLS_DC) +mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES * result, void * param, unsigned int flags, zend_bool * fetched_anything) { enum_func_status ret; MYSQLND_STMT * s = (MYSQLND_STMT *) param; @@ -1036,7 +1058,7 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES * result, void * param, unsigned int f if (FAIL == stmt->conn->m->simple_command(stmt->conn, COM_STMT_FETCH, buf, sizeof(buf), PROT_LAST /* we will handle the response packet*/, - FALSE, TRUE TSRMLS_CC)) { + FALSE, TRUE)) { COPY_CLIENT_ERROR(*stmt->error_info, *stmt->conn->error_info); DBG_RETURN(FAIL); } @@ -1049,7 +1071,7 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES * result, void * param, unsigned int f unsigned int i, field_count = result->field_count; if (!row_packet->skip_extraction) { - result->unbuf->m.free_last_data(result->unbuf, result->conn? result->conn->stats : NULL TSRMLS_CC); + result->unbuf->m.free_last_data(result->unbuf, result->conn? result->conn->stats : NULL); result->unbuf->last_row_data = row_packet->fields; result->unbuf->last_row_buffer = row_packet->row_buffer; @@ -1061,31 +1083,39 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES * result, void * param, unsigned int f row_packet->field_count, row_packet->fields_metadata, result->conn->options->int_and_float_native, - result->conn->stats TSRMLS_CC)) + result->conn->stats)) { - DBG_RETURN(FAIL); + DBG_RETURN(FAIL); } /* If no result bind, do nothing. We consumed the data */ for (i = 0; i < field_count; i++) { if (stmt->result_bind[i].bound == TRUE) { - zval *data = result->unbuf->last_row_data[i]; + zval *data = &result->unbuf->last_row_data[i]; + zval *result = &stmt->result_bind[i].zv; + + ZVAL_DEREF(result); /* stmt->result_bind[i].zv has been already destructed in result->unbuf->m.free_last_data() */ #ifndef WE_DONT_COPY_IN_BUFFERED_AND_UNBUFFERED_BECAUSEOF_IS_REF - zval_dtor(stmt->result_bind[i].zv); + zval_dtor(result); #endif - DBG_INF_FMT("i=%u bound_var=%p type=%u refc=%u", i, stmt->result_bind[i].zv, - Z_TYPE_P(data), Z_REFCOUNT_P(stmt->result_bind[i].zv)); - if (IS_NULL != (Z_TYPE_P(stmt->result_bind[i].zv) = Z_TYPE_P(data))) { - if ((Z_TYPE_P(data) == IS_STRING) && (meta->fields[i].max_length < (unsigned long) Z_STRLEN_P(data))) { + DBG_INF_FMT("i=%u bound_var=%p type=%u refc=%u", i, &stmt->result_bind[i].zv, + Z_TYPE_P(data), Z_REFCOUNTED(stmt->result_bind[i].zv)? + Z_REFCOUNT(stmt->result_bind[i].zv) : 0); + + if (!Z_ISNULL_P(data)) { + if ((Z_TYPE_P(data) == IS_STRING) && + (meta->fields[i].max_length < (zend_ulong) Z_STRLEN_P(data))) { meta->fields[i].max_length = Z_STRLEN_P(data); } - stmt->result_bind[i].zv->value = data->value; + ZVAL_COPY_VALUE(result, data); /* copied data, thus also the ownership. Thus null data */ ZVAL_NULL(data); + } else { + ZVAL_NULL(result); } } } @@ -1097,13 +1127,13 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES * result, void * param, unsigned int f the bound variables. Thus we need to do part of what it does or Zend will report leaks. */ - row_packet->row_buffer->free_chunk(row_packet->row_buffer TSRMLS_CC); + row_packet->row_buffer->free_chunk(row_packet->row_buffer); row_packet->row_buffer = NULL; } /* We asked for one row, the next one should be EOF, eat it */ ret = PACKET_READ(row_packet, result->conn); if (row_packet->row_buffer) { - row_packet->row_buffer->free_chunk(row_packet->row_buffer TSRMLS_CC); + row_packet->row_buffer->free_chunk(row_packet->row_buffer); row_packet->row_buffer = NULL; } MYSQLND_INC_CONN_STATISTIC(stmt->conn->stats, STAT_ROWS_FETCHED_FROM_CLIENT_PS_CURSOR); @@ -1117,7 +1147,7 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES * result, void * param, unsigned int f stmt->conn->upsert_status->warning_count = row_packet->warning_count; - stmt->upsert_status->server_status = + stmt->upsert_status->server_status = stmt->conn->upsert_status->server_status = row_packet->server_status; @@ -1126,7 +1156,7 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES * result, void * param, unsigned int f stmt->upsert_status->warning_count = stmt->conn->upsert_status->warning_count = row_packet->warning_count; - stmt->upsert_status->server_status = + stmt->upsert_status->server_status = stmt->conn->upsert_status->server_status = row_packet->server_status; @@ -1141,7 +1171,7 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES * result, void * param, unsigned int f /* {{{ mysqlnd_stmt::fetch */ static enum_func_status -MYSQLND_METHOD(mysqlnd_stmt, fetch)(MYSQLND_STMT * const s, zend_bool * const fetched_anything TSRMLS_DC) +MYSQLND_METHOD(mysqlnd_stmt, fetch)(MYSQLND_STMT * const s, zend_bool * const fetched_anything) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; enum_func_status ret; @@ -1160,14 +1190,14 @@ MYSQLND_METHOD(mysqlnd_stmt, fetch)(MYSQLND_STMT * const s, zend_bool * const fe } else if (stmt->state == MYSQLND_STMT_WAITING_USE_OR_STORE) { /* Execute only once. We have to free the previous contents of user's bound vars */ - stmt->default_rset_handler(s TSRMLS_CC); + stmt->default_rset_handler(s); } stmt->state = MYSQLND_STMT_USER_FETCHING; SET_EMPTY_ERROR(*stmt->error_info); SET_EMPTY_ERROR(*stmt->conn->error_info); - DBG_INF_FMT("result_bind=%p separated_once=%u", stmt->result_bind, stmt->result_zvals_separated_once); + DBG_INF_FMT("result_bind=%p separated_once=%u", &stmt->result_bind, stmt->result_zvals_separated_once); /* The user might have not bound any variables for result. Do the binding once she does it. @@ -1180,14 +1210,16 @@ MYSQLND_METHOD(mysqlnd_stmt, fetch)(MYSQLND_STMT * const s, zend_bool * const fe */ for (i = 0; i < stmt->result->field_count; i++) { if (stmt->result_bind[i].bound == TRUE) { - zval_dtor(stmt->result_bind[i].zv); - ZVAL_NULL(stmt->result_bind[i].zv); + zval *result = &stmt->result_bind[i].zv; + ZVAL_DEREF(result); + zval_dtor(result); + ZVAL_NULL(result); } } stmt->result_zvals_separated_once = TRUE; } - ret = stmt->result->m.fetch_row(stmt->result, (void*)s, 0, fetched_anything TSRMLS_CC); + ret = stmt->result->m.fetch_row(stmt->result, (void*)s, 0, fetched_anything); DBG_RETURN(ret); } /* }}} */ @@ -1195,7 +1227,7 @@ MYSQLND_METHOD(mysqlnd_stmt, fetch)(MYSQLND_STMT * const s, zend_bool * const fe /* {{{ mysqlnd_stmt::reset */ static enum_func_status -MYSQLND_METHOD(mysqlnd_stmt, reset)(MYSQLND_STMT * const s TSRMLS_DC) +MYSQLND_METHOD(mysqlnd_stmt, reset)(MYSQLND_STMT * const s) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; enum_func_status ret = PASS; @@ -1223,7 +1255,7 @@ MYSQLND_METHOD(mysqlnd_stmt, reset)(MYSQLND_STMT * const s TSRMLS_DC) } } - s->m->flush(s TSRMLS_CC); + s->m->flush(s); /* Don't free now, let the result be usable. When the stmt will again be @@ -1235,7 +1267,7 @@ MYSQLND_METHOD(mysqlnd_stmt, reset)(MYSQLND_STMT * const s TSRMLS_DC) if (CONN_GET_STATE(conn) == CONN_READY && FAIL == (ret = conn->m->simple_command(conn, COM_STMT_RESET, cmd_buf, sizeof(cmd_buf), PROT_OK_PACKET, - FALSE, TRUE TSRMLS_CC))) { + FALSE, TRUE))) { COPY_CLIENT_ERROR(*stmt->error_info, *conn->error_info); } *stmt->upsert_status = *conn->upsert_status; @@ -1248,7 +1280,7 @@ MYSQLND_METHOD(mysqlnd_stmt, reset)(MYSQLND_STMT * const s TSRMLS_DC) /* {{{ mysqlnd_stmt::flush */ static enum_func_status -MYSQLND_METHOD(mysqlnd_stmt, flush)(MYSQLND_STMT * const s TSRMLS_DC) +MYSQLND_METHOD(mysqlnd_stmt, flush)(MYSQLND_STMT * const s) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; enum_func_status ret = PASS; @@ -1268,13 +1300,13 @@ MYSQLND_METHOD(mysqlnd_stmt, flush)(MYSQLND_STMT * const s TSRMLS_DC) do { if (stmt->state == MYSQLND_STMT_WAITING_USE_OR_STORE) { DBG_INF("fetching result set header"); - stmt->default_rset_handler(s TSRMLS_CC); + stmt->default_rset_handler(s); stmt->state = MYSQLND_STMT_USER_FETCHING; } if (stmt->result) { DBG_INF("skipping result"); - stmt->result->m.skip_result(stmt->result TSRMLS_CC); + stmt->result->m.skip_result(stmt->result); } } while (mysqlnd_stmt_more_results(s) && mysqlnd_stmt_next_result(s) == PASS); } @@ -1287,7 +1319,7 @@ MYSQLND_METHOD(mysqlnd_stmt, flush)(MYSQLND_STMT * const s TSRMLS_DC) /* {{{ mysqlnd_stmt::send_long_data */ static enum_func_status MYSQLND_METHOD(mysqlnd_stmt, send_long_data)(MYSQLND_STMT * const s, unsigned int param_no, - const char * const data, unsigned long length TSRMLS_DC) + const char * const data, zend_ulong length) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; enum_func_status ret = FAIL; @@ -1348,7 +1380,7 @@ MYSQLND_METHOD(mysqlnd_stmt, send_long_data)(MYSQLND_STMT * const s, unsigned in memcpy(cmd_buf + STMT_ID_LENGTH + 2, data, length); /* COM_STMT_SEND_LONG_DATA doesn't send an OK packet*/ - ret = conn->m->simple_command(conn, cmd, cmd_buf, packet_len, PROT_LAST , FALSE, TRUE TSRMLS_CC); + ret = conn->m->simple_command(conn, cmd, cmd_buf, packet_len, PROT_LAST , FALSE, TRUE); mnd_efree(cmd_buf); if (FAIL == ret) { COPY_CLIENT_ERROR(*stmt->error_info, *conn->error_info); @@ -1378,8 +1410,8 @@ MYSQLND_METHOD(mysqlnd_stmt, send_long_data)(MYSQLND_STMT * const s, unsigned in #if HAVE_USLEEP && !defined(PHP_WIN32) usleep(120000); #endif - if ((packet_len = conn->net->m.consume_uneaten_data(conn->net, cmd TSRMLS_CC))) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "There was an error " + if ((packet_len = conn->net->m.consume_uneaten_data(conn->net, cmd))) { + php_error_docref(NULL, E_WARNING, "There was an error " "while sending long data. Probably max_allowed_packet_size " "is smaller than the data. You have to increase it or send " "smaller chunks of data. Answer was "MYSQLND_SZ_T_SPEC" bytes long.", packet_len); @@ -1398,7 +1430,7 @@ MYSQLND_METHOD(mysqlnd_stmt, send_long_data)(MYSQLND_STMT * const s, unsigned in /* {{{ mysqlnd_stmt::bind_parameters */ static enum_func_status -MYSQLND_METHOD(mysqlnd_stmt, bind_parameters)(MYSQLND_STMT * const s, MYSQLND_PARAM_BIND * const param_bind TSRMLS_DC) +MYSQLND_METHOD(mysqlnd_stmt, bind_parameters)(MYSQLND_STMT * const s, MYSQLND_PARAM_BIND * const param_bind) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; DBG_ENTER("mysqlnd_stmt::bind_param"); @@ -1411,7 +1443,7 @@ MYSQLND_METHOD(mysqlnd_stmt, bind_parameters)(MYSQLND_STMT * const s, MYSQLND_PA SET_STMT_ERROR(stmt, CR_NO_PREPARE_STMT, UNKNOWN_SQLSTATE, mysqlnd_stmt_not_prepared); DBG_ERR("not prepared"); if (param_bind) { - s->m->free_parameter_bind(s, param_bind TSRMLS_CC); + s->m->free_parameter_bind(s, param_bind); } DBG_RETURN(FAIL); } @@ -1437,12 +1469,10 @@ MYSQLND_METHOD(mysqlnd_stmt, bind_parameters)(MYSQLND_STMT * const s, MYSQLND_PA We may have the last reference, then call zval_ptr_dtor() or we may leak memory. Switching from bind_one_parameter to bind_parameters may result in zv being NULL */ - if (stmt->param_bind[i].zv) { - zval_ptr_dtor(&stmt->param_bind[i].zv); - } + zval_ptr_dtor(&stmt->param_bind[i].zv); } if (stmt->param_bind != param_bind) { - s->m->free_parameter_bind(s, stmt->param_bind TSRMLS_CC); + s->m->free_parameter_bind(s, stmt->param_bind); } } @@ -1452,7 +1482,7 @@ MYSQLND_METHOD(mysqlnd_stmt, bind_parameters)(MYSQLND_STMT * const s, MYSQLND_PA DBG_INF_FMT("%u is of type %u", i, stmt->param_bind[i].type); /* Prevent from freeing */ /* Don't update is_ref, or we will leak during conversion */ - Z_ADDREF_P(stmt->param_bind[i].zv); + Z_TRY_ADDREF(stmt->param_bind[i].zv); stmt->param_bind[i].flags = 0; if (stmt->param_bind[i].type == MYSQL_TYPE_LONG_BLOB) { stmt->param_bind[i].flags &= ~MYSQLND_PARAM_BIND_BLOB_USED; @@ -1469,7 +1499,7 @@ MYSQLND_METHOD(mysqlnd_stmt, bind_parameters)(MYSQLND_STMT * const s, MYSQLND_PA /* {{{ mysqlnd_stmt::bind_one_parameter */ static enum_func_status MYSQLND_METHOD(mysqlnd_stmt, bind_one_parameter)(MYSQLND_STMT * const s, unsigned int param_no, - zval * const zv, zend_uchar type TSRMLS_DC) + zval * const zv, zend_uchar type) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; DBG_ENTER("mysqlnd_stmt::bind_one_parameter"); @@ -1502,17 +1532,15 @@ MYSQLND_METHOD(mysqlnd_stmt, bind_one_parameter)(MYSQLND_STMT * const s, unsigne /* Prevent from freeing */ /* Don't update is_ref, or we will leak during conversion */ - Z_ADDREF_P(zv); + Z_TRY_ADDREF_P(zv); DBG_INF("Binding"); /* Release what we had, if we had */ - if (stmt->param_bind[param_no].zv) { - zval_ptr_dtor(&stmt->param_bind[param_no].zv); - } + zval_ptr_dtor(&stmt->param_bind[param_no].zv); if (type == MYSQL_TYPE_LONG_BLOB) { /* The client will use stmt_send_long_data */ stmt->param_bind[param_no].flags &= ~MYSQLND_PARAM_BIND_BLOB_USED; } - stmt->param_bind[param_no].zv = zv; + ZVAL_COPY_VALUE(&stmt->param_bind[param_no].zv, zv); stmt->param_bind[param_no].type = type; stmt->send_types_to_server = 1; @@ -1525,7 +1553,7 @@ MYSQLND_METHOD(mysqlnd_stmt, bind_one_parameter)(MYSQLND_STMT * const s, unsigne /* {{{ mysqlnd_stmt::refresh_bind_param */ static enum_func_status -MYSQLND_METHOD(mysqlnd_stmt, refresh_bind_param)(MYSQLND_STMT * const s TSRMLS_DC) +MYSQLND_METHOD(mysqlnd_stmt, refresh_bind_param)(MYSQLND_STMT * const s) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; DBG_ENTER("mysqlnd_stmt::refresh_bind_param"); @@ -1554,7 +1582,7 @@ MYSQLND_METHOD(mysqlnd_stmt, refresh_bind_param)(MYSQLND_STMT * const s TSRMLS_D /* {{{ mysqlnd_stmt::bind_result */ static enum_func_status MYSQLND_METHOD(mysqlnd_stmt, bind_result)(MYSQLND_STMT * const s, - MYSQLND_RESULT_BIND * const result_bind TSRMLS_DC) + MYSQLND_RESULT_BIND * const result_bind) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; DBG_ENTER("mysqlnd_stmt::bind_result"); @@ -1566,7 +1594,7 @@ MYSQLND_METHOD(mysqlnd_stmt, bind_result)(MYSQLND_STMT * const s, if (stmt->state < MYSQLND_STMT_PREPARED) { SET_STMT_ERROR(stmt, CR_NO_PREPARE_STMT, UNKNOWN_SQLSTATE, mysqlnd_stmt_not_prepared); if (result_bind) { - s->m->free_result_bind(s, result_bind TSRMLS_CC); + s->m->free_result_bind(s, result_bind); } DBG_ERR("not prepared"); DBG_RETURN(FAIL); @@ -1583,13 +1611,15 @@ MYSQLND_METHOD(mysqlnd_stmt, bind_result)(MYSQLND_STMT * const s, DBG_RETURN(FAIL); } - mysqlnd_stmt_separate_result_bind(s TSRMLS_CC); + mysqlnd_stmt_separate_result_bind(s); stmt->result_zvals_separated_once = FALSE; stmt->result_bind = result_bind; for (i = 0; i < stmt->field_count; i++) { /* Prevent from freeing */ - Z_ADDREF_P(stmt->result_bind[i].zv); - DBG_INF_FMT("ref of %p = %u", stmt->result_bind[i].zv, Z_REFCOUNT_P(stmt->result_bind[i].zv)); + Z_TRY_ADDREF(stmt->result_bind[i].zv); + + DBG_INF_FMT("ref of %p = %u", &stmt->result_bind[i].zv, + Z_REFCOUNTED(stmt->result_bind[i].zv)? Z_REFCOUNT(stmt->result_bind[i].zv) : 0); /* Don't update is_ref !!! it's not our job Otherwise either 009.phpt or mysqli_stmt_bind_result.phpt @@ -1598,7 +1628,7 @@ MYSQLND_METHOD(mysqlnd_stmt, bind_result)(MYSQLND_STMT * const s, stmt->result_bind[i].bound = TRUE; } } else if (result_bind) { - s->m->free_result_bind(s, result_bind TSRMLS_CC); + s->m->free_result_bind(s, result_bind); } DBG_INF("PASS"); DBG_RETURN(PASS); @@ -1608,7 +1638,7 @@ MYSQLND_METHOD(mysqlnd_stmt, bind_result)(MYSQLND_STMT * const s, /* {{{ mysqlnd_stmt::bind_result */ static enum_func_status -MYSQLND_METHOD(mysqlnd_stmt, bind_one_result)(MYSQLND_STMT * const s, unsigned int param_no TSRMLS_DC) +MYSQLND_METHOD(mysqlnd_stmt, bind_one_result)(MYSQLND_STMT * const s, unsigned int param_no) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; DBG_ENTER("mysqlnd_stmt::bind_result"); @@ -1633,7 +1663,7 @@ MYSQLND_METHOD(mysqlnd_stmt, bind_one_result)(MYSQLND_STMT * const s, unsigned i SET_EMPTY_ERROR(*stmt->conn->error_info); if (stmt->field_count) { - mysqlnd_stmt_separate_one_result_bind(s, param_no TSRMLS_CC); + mysqlnd_stmt_separate_one_result_bind(s, param_no); /* Guaranteed is that stmt->result_bind is NULL */ if (!stmt->result_bind) { stmt->result_bind = mnd_pecalloc(stmt->field_count, sizeof(MYSQLND_RESULT_BIND), stmt->persistent); @@ -1643,7 +1673,7 @@ MYSQLND_METHOD(mysqlnd_stmt, bind_one_result)(MYSQLND_STMT * const s, unsigned i if (!stmt->result_bind) { DBG_RETURN(FAIL); } - ALLOC_INIT_ZVAL(stmt->result_bind[param_no].zv); + ZVAL_NULL(&stmt->result_bind[param_no].zv); /* Don't update is_ref !!! it's not our job Otherwise either 009.phpt or mysqli_stmt_bind_result.phpt @@ -1659,7 +1689,7 @@ MYSQLND_METHOD(mysqlnd_stmt, bind_one_result)(MYSQLND_STMT * const s, unsigned i /* {{{ mysqlnd_stmt::insert_id */ static uint64_t -MYSQLND_METHOD(mysqlnd_stmt, insert_id)(const MYSQLND_STMT * const s TSRMLS_DC) +MYSQLND_METHOD(mysqlnd_stmt, insert_id)(const MYSQLND_STMT * const s) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; return stmt? stmt->upsert_status->last_insert_id : 0; @@ -1669,7 +1699,7 @@ MYSQLND_METHOD(mysqlnd_stmt, insert_id)(const MYSQLND_STMT * const s TSRMLS_DC) /* {{{ mysqlnd_stmt::affected_rows */ static uint64_t -MYSQLND_METHOD(mysqlnd_stmt, affected_rows)(const MYSQLND_STMT * const s TSRMLS_DC) +MYSQLND_METHOD(mysqlnd_stmt, affected_rows)(const MYSQLND_STMT * const s) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; return stmt? stmt->upsert_status->affected_rows : 0; @@ -1679,7 +1709,7 @@ MYSQLND_METHOD(mysqlnd_stmt, affected_rows)(const MYSQLND_STMT * const s TSRMLS_ /* {{{ mysqlnd_stmt::num_rows */ static uint64_t -MYSQLND_METHOD(mysqlnd_stmt, num_rows)(const MYSQLND_STMT * const s TSRMLS_DC) +MYSQLND_METHOD(mysqlnd_stmt, num_rows)(const MYSQLND_STMT * const s) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; return stmt && stmt->result? mysqlnd_num_rows(stmt->result):0; @@ -1689,7 +1719,7 @@ MYSQLND_METHOD(mysqlnd_stmt, num_rows)(const MYSQLND_STMT * const s TSRMLS_DC) /* {{{ mysqlnd_stmt::warning_count */ static unsigned int -MYSQLND_METHOD(mysqlnd_stmt, warning_count)(const MYSQLND_STMT * const s TSRMLS_DC) +MYSQLND_METHOD(mysqlnd_stmt, warning_count)(const MYSQLND_STMT * const s) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; return stmt? stmt->upsert_status->warning_count : 0; @@ -1699,7 +1729,7 @@ MYSQLND_METHOD(mysqlnd_stmt, warning_count)(const MYSQLND_STMT * const s TSRMLS_ /* {{{ mysqlnd_stmt::server_status */ static unsigned int -MYSQLND_METHOD(mysqlnd_stmt, server_status)(const MYSQLND_STMT * const s TSRMLS_DC) +MYSQLND_METHOD(mysqlnd_stmt, server_status)(const MYSQLND_STMT * const s) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; return stmt? stmt->upsert_status->server_status : 0; @@ -1709,7 +1739,7 @@ MYSQLND_METHOD(mysqlnd_stmt, server_status)(const MYSQLND_STMT * const s TSRMLS_ /* {{{ mysqlnd_stmt::field_count */ static unsigned int -MYSQLND_METHOD(mysqlnd_stmt, field_count)(const MYSQLND_STMT * const s TSRMLS_DC) +MYSQLND_METHOD(mysqlnd_stmt, field_count)(const MYSQLND_STMT * const s) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; return stmt? stmt->field_count : 0; @@ -1719,7 +1749,7 @@ MYSQLND_METHOD(mysqlnd_stmt, field_count)(const MYSQLND_STMT * const s TSRMLS_DC /* {{{ mysqlnd_stmt::param_count */ static unsigned int -MYSQLND_METHOD(mysqlnd_stmt, param_count)(const MYSQLND_STMT * const s TSRMLS_DC) +MYSQLND_METHOD(mysqlnd_stmt, param_count)(const MYSQLND_STMT * const s) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; return stmt? stmt->param_count : 0; @@ -1729,7 +1759,7 @@ MYSQLND_METHOD(mysqlnd_stmt, param_count)(const MYSQLND_STMT * const s TSRMLS_DC /* {{{ mysqlnd_stmt::errno */ static unsigned int -MYSQLND_METHOD(mysqlnd_stmt, errno)(const MYSQLND_STMT * const s TSRMLS_DC) +MYSQLND_METHOD(mysqlnd_stmt, errno)(const MYSQLND_STMT * const s) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; return stmt? stmt->error_info->error_no : 0; @@ -1739,7 +1769,7 @@ MYSQLND_METHOD(mysqlnd_stmt, errno)(const MYSQLND_STMT * const s TSRMLS_DC) /* {{{ mysqlnd_stmt::error */ static const char * -MYSQLND_METHOD(mysqlnd_stmt, error)(const MYSQLND_STMT * const s TSRMLS_DC) +MYSQLND_METHOD(mysqlnd_stmt, error)(const MYSQLND_STMT * const s) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; return stmt? stmt->error_info->error : 0; @@ -1749,7 +1779,7 @@ MYSQLND_METHOD(mysqlnd_stmt, error)(const MYSQLND_STMT * const s TSRMLS_DC) /* {{{ mysqlnd_stmt::sqlstate */ static const char * -MYSQLND_METHOD(mysqlnd_stmt, sqlstate)(const MYSQLND_STMT * const s TSRMLS_DC) +MYSQLND_METHOD(mysqlnd_stmt, sqlstate)(const MYSQLND_STMT * const s) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; return stmt && stmt->error_info->sqlstate[0] ? stmt->error_info->sqlstate:MYSQLND_SQLSTATE_NULL; @@ -1759,17 +1789,17 @@ MYSQLND_METHOD(mysqlnd_stmt, sqlstate)(const MYSQLND_STMT * const s TSRMLS_DC) /* {{{ mysqlnd_stmt::data_seek */ static enum_func_status -MYSQLND_METHOD(mysqlnd_stmt, data_seek)(const MYSQLND_STMT * const s, uint64_t row TSRMLS_DC) +MYSQLND_METHOD(mysqlnd_stmt, data_seek)(const MYSQLND_STMT * const s, uint64_t row) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; - return stmt && stmt->result? stmt->result->m.seek_data(stmt->result, row TSRMLS_CC) : FAIL; + return stmt && stmt->result? stmt->result->m.seek_data(stmt->result, row) : FAIL; } /* }}} */ /* {{{ mysqlnd_stmt::param_metadata */ static MYSQLND_RES * -MYSQLND_METHOD(mysqlnd_stmt, param_metadata)(MYSQLND_STMT * const s TSRMLS_DC) +MYSQLND_METHOD(mysqlnd_stmt, param_metadata)(MYSQLND_STMT * const s) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; if (!stmt || !stmt->param_count) { @@ -1782,7 +1812,7 @@ MYSQLND_METHOD(mysqlnd_stmt, param_metadata)(MYSQLND_STMT * const s TSRMLS_DC) /* {{{ mysqlnd_stmt::result_metadata */ static MYSQLND_RES * -MYSQLND_METHOD(mysqlnd_stmt, result_metadata)(MYSQLND_STMT * const s TSRMLS_DC) +MYSQLND_METHOD(mysqlnd_stmt, result_metadata)(MYSQLND_STMT * const s) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; MYSQLND_RES *result; @@ -1801,7 +1831,7 @@ MYSQLND_METHOD(mysqlnd_stmt, result_metadata)(MYSQLND_STMT * const s TSRMLS_DC) if (stmt->update_max_length && stmt->result->stored_data) { /* stored result, we have to update the max_length before we clone the meta data :( */ stmt->result->stored_data->m.initialize_result_set_rest(stmt->result->stored_data, stmt->result->meta, stmt->conn->stats, - stmt->conn->options->int_and_float_native TSRMLS_CC); + stmt->conn->options->int_and_float_native); } /* TODO: This implementation is kind of a hack, @@ -1813,17 +1843,17 @@ MYSQLND_METHOD(mysqlnd_stmt, result_metadata)(MYSQLND_STMT * const s TSRMLS_DC) result set, so we don't get one. */ do { - result = stmt->conn->m->result_init(stmt->field_count, stmt->persistent TSRMLS_CC); + result = stmt->conn->m->result_init(stmt->field_count, stmt->persistent); if (!result) { break; } result->type = MYSQLND_RES_NORMAL; - result->unbuf = mysqlnd_result_unbuffered_init(stmt->field_count, TRUE, result->persistent TSRMLS_CC); + result->unbuf = mysqlnd_result_unbuffered_init(stmt->field_count, TRUE, result->persistent); if (!result->unbuf) { break; } result->unbuf->eof_reached = TRUE; - result->meta = stmt->result->meta->m->clone_metadata(stmt->result->meta, FALSE TSRMLS_CC); + result->meta = stmt->result->meta->m->clone_metadata(stmt->result->meta, FALSE); if (!result->meta) { break; } @@ -1834,7 +1864,7 @@ MYSQLND_METHOD(mysqlnd_stmt, result_metadata)(MYSQLND_STMT * const s TSRMLS_DC) SET_OOM_ERROR(*stmt->conn->error_info); if (result) { - result->m.free_result(result, TRUE TSRMLS_CC); + result->m.free_result(result, TRUE); } DBG_RETURN(NULL); } @@ -1845,7 +1875,7 @@ MYSQLND_METHOD(mysqlnd_stmt, result_metadata)(MYSQLND_STMT * const s TSRMLS_DC) static enum_func_status MYSQLND_METHOD(mysqlnd_stmt, attr_set)(MYSQLND_STMT * const s, enum mysqlnd_stmt_attr attr_type, - const void * const value TSRMLS_DC) + const void * const value) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; DBG_ENTER("mysqlnd_stmt::attr_set"); @@ -1866,7 +1896,7 @@ MYSQLND_METHOD(mysqlnd_stmt, attr_set)(MYSQLND_STMT * const s, } case STMT_ATTR_CURSOR_TYPE: { unsigned int ival = *(unsigned int *) value; - if (ival > (unsigned long) CURSOR_TYPE_READ_ONLY) { + if (ival > (zend_ulong) CURSOR_TYPE_READ_ONLY) { SET_STMT_ERROR(stmt, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE, "Not implemented"); DBG_INF("FAIL"); DBG_RETURN(FAIL); @@ -1900,7 +1930,7 @@ MYSQLND_METHOD(mysqlnd_stmt, attr_set)(MYSQLND_STMT * const s, static enum_func_status MYSQLND_METHOD(mysqlnd_stmt, attr_get)(const MYSQLND_STMT * const s, enum mysqlnd_stmt_attr attr_type, - void * const value TSRMLS_DC) + void * const value) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; DBG_ENTER("mysqlnd_stmt::attr_set"); @@ -1914,10 +1944,10 @@ MYSQLND_METHOD(mysqlnd_stmt, attr_get)(const MYSQLND_STMT * const s, *(zend_bool *) value= stmt->update_max_length; break; case STMT_ATTR_CURSOR_TYPE: - *(unsigned long *) value= stmt->flags; + *(zend_ulong *) value= stmt->flags; break; case STMT_ATTR_PREFETCH_ROWS: - *(unsigned long *) value= stmt->prefetch_rows; + *(zend_ulong *) value= stmt->prefetch_rows; break; default: DBG_RETURN(FAIL); @@ -1931,7 +1961,7 @@ MYSQLND_METHOD(mysqlnd_stmt, attr_get)(const MYSQLND_STMT * const s, /* free_result() doesn't actually free stmt->result but only the buffers */ /* {{{ mysqlnd_stmt::free_result */ static enum_func_status -MYSQLND_METHOD(mysqlnd_stmt, free_result)(MYSQLND_STMT * const s TSRMLS_DC) +MYSQLND_METHOD(mysqlnd_stmt, free_result)(MYSQLND_STMT * const s) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; DBG_ENTER("mysqlnd_stmt::free_result"); @@ -1953,21 +1983,21 @@ MYSQLND_METHOD(mysqlnd_stmt, free_result)(MYSQLND_STMT * const s TSRMLS_DC) DBG_INF("fetching result set header"); /* Do implicit use_result and then flush the result */ stmt->default_rset_handler = s->m->use_result; - stmt->default_rset_handler(s TSRMLS_CC); + stmt->default_rset_handler(s); } if (stmt->state > MYSQLND_STMT_WAITING_USE_OR_STORE) { DBG_INF("skipping result"); /* Flush if anything is left and unbuffered set */ - stmt->result->m.skip_result(stmt->result TSRMLS_CC); + stmt->result->m.skip_result(stmt->result); /* Separate the bound variables, which point to the result set, then destroy the set. */ - mysqlnd_stmt_separate_result_bind(s TSRMLS_CC); + mysqlnd_stmt_separate_result_bind(s); /* Now we can destroy the result set */ - stmt->result->m.free_result_buffers(stmt->result TSRMLS_CC); + stmt->result->m.free_result_buffers(stmt->result); } if (stmt->state > MYSQLND_STMT_PREPARED) { @@ -1985,7 +2015,7 @@ MYSQLND_METHOD(mysqlnd_stmt, free_result)(MYSQLND_STMT * const s TSRMLS_DC) /* {{{ mysqlnd_stmt_separate_result_bind */ static void -mysqlnd_stmt_separate_result_bind(MYSQLND_STMT * const s TSRMLS_DC) +mysqlnd_stmt_separate_result_bind(MYSQLND_STMT * const s) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; unsigned int i; @@ -2008,30 +2038,13 @@ mysqlnd_stmt_separate_result_bind(MYSQLND_STMT * const s TSRMLS_DC) for (i = 0; i < stmt->field_count; i++) { /* Let's try with no cache */ if (stmt->result_bind[i].bound == TRUE) { - DBG_INF_FMT("%u has refcount=%u", i, Z_REFCOUNT_P(stmt->result_bind[i].zv)); - /* - We have to separate the actual zval value of the bound - variable from our allocated zvals or we will face double-free - */ - if (Z_REFCOUNT_P(stmt->result_bind[i].zv) > 1) { -#ifdef WE_DONT_COPY_IN_BUFFERED_AND_UNBUFFERED_BECAUSEOF_IS_REF - zval_copy_ctor(stmt->result_bind[i].zv); -#endif - zval_ptr_dtor(&stmt->result_bind[i].zv); - } else { - /* - If it is a string, what is pointed will be freed - later in free_result(). We need to remove the variable to - which the user has lost reference. - */ -#ifdef WE_DONT_COPY_IN_BUFFERED_AND_UNBUFFERED_BECAUSEOF_IS_REF - ZVAL_NULL(stmt->result_bind[i].zv); -#endif - zval_ptr_dtor(&stmt->result_bind[i].zv); - } + DBG_INF_FMT("%u has refcount=%u", i, + Z_REFCOUNTED(stmt->result_bind[i].zv)? Z_REFCOUNT(stmt->result_bind[i].zv) : 0); + zval_ptr_dtor(&stmt->result_bind[i].zv); } } - s->m->free_result_bind(s, stmt->result_bind TSRMLS_CC); + + s->m->free_result_bind(s, stmt->result_bind); stmt->result_bind = NULL; DBG_VOID_RETURN; @@ -2041,7 +2054,7 @@ mysqlnd_stmt_separate_result_bind(MYSQLND_STMT * const s TSRMLS_DC) /* {{{ mysqlnd_stmt_separate_one_result_bind */ static void -mysqlnd_stmt_separate_one_result_bind(MYSQLND_STMT * const s, unsigned int param_no TSRMLS_DC) +mysqlnd_stmt_separate_one_result_bind(MYSQLND_STMT * const s, unsigned int param_no) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; DBG_ENTER("mysqlnd_stmt_separate_one_result_bind"); @@ -2061,27 +2074,10 @@ mysqlnd_stmt_separate_one_result_bind(MYSQLND_STMT * const s, unsigned int param */ /* Let's try with no cache */ if (stmt->result_bind[param_no].bound == TRUE) { - DBG_INF_FMT("%u has refcount=%u", param_no, Z_REFCOUNT_P(stmt->result_bind[param_no].zv)); - /* - We have to separate the actual zval value of the bound - variable from our allocated zvals or we will face double-free - */ - if (Z_REFCOUNT_P(stmt->result_bind[param_no].zv) > 1) { -#ifdef WE_DONT_COPY_IN_BUFFERED_AND_UNBUFFERED_BECAUSEOF_IS_REF - zval_copy_ctor(stmt->result_bind[param_no].zv); -#endif - zval_ptr_dtor(&stmt->result_bind[param_no].zv); - } else { - /* - If it is a string, what is pointed will be freed - later in free_result(). We need to remove the variable to - which the user has lost reference. - */ -#ifdef WE_DONT_COPY_IN_BUFFERED_AND_UNBUFFERED_BECAUSEOF_IS_REF - ZVAL_NULL(stmt->result_bind[param_no].zv); -#endif - zval_ptr_dtor(&stmt->result_bind[param_no].zv); - } + DBG_INF_FMT("%u has refcount=%u", param_no, + Z_REFCOUNTED(stmt->result_bind[param_no].zv)? + Z_REFCOUNT(stmt->result_bind[param_no].zv) : 0); + zval_ptr_dtor(&stmt->result_bind[param_no].zv); } DBG_VOID_RETURN; @@ -2091,7 +2087,7 @@ mysqlnd_stmt_separate_one_result_bind(MYSQLND_STMT * const s, unsigned int param /* {{{ mysqlnd_stmt::free_stmt_result */ static void -MYSQLND_METHOD(mysqlnd_stmt, free_stmt_result)(MYSQLND_STMT * const s TSRMLS_DC) +MYSQLND_METHOD(mysqlnd_stmt, free_stmt_result)(MYSQLND_STMT * const s) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; DBG_ENTER("mysqlnd_stmt::free_stmt_result"); @@ -2103,10 +2099,10 @@ MYSQLND_METHOD(mysqlnd_stmt, free_stmt_result)(MYSQLND_STMT * const s TSRMLS_DC) First separate the bound variables, which point to the result set, then destroy the set. */ - mysqlnd_stmt_separate_result_bind(s TSRMLS_CC); + mysqlnd_stmt_separate_result_bind(s); /* Not every statement has a result set attached */ if (stmt->result) { - stmt->result->m.free_result_internal(stmt->result TSRMLS_CC); + stmt->result->m.free_result_internal(stmt->result); stmt->result = NULL; } if (stmt->error_info->error_list) { @@ -2122,7 +2118,7 @@ MYSQLND_METHOD(mysqlnd_stmt, free_stmt_result)(MYSQLND_STMT * const s TSRMLS_DC) /* {{{ mysqlnd_stmt::free_stmt_content */ static void -MYSQLND_METHOD(mysqlnd_stmt, free_stmt_content)(MYSQLND_STMT * const s TSRMLS_DC) +MYSQLND_METHOD(mysqlnd_stmt, free_stmt_content)(MYSQLND_STMT * const s) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; DBG_ENTER("mysqlnd_stmt::free_stmt_content"); @@ -2144,15 +2140,13 @@ MYSQLND_METHOD(mysqlnd_stmt, free_stmt_content)(MYSQLND_STMT * const s TSRMLS_DC If bind_one_parameter was used, but not everything was bound and nothing was fetched, then some `zv` could be NULL */ - if (stmt->param_bind[i].zv) { - zval_ptr_dtor(&stmt->param_bind[i].zv); - } + zval_ptr_dtor(&stmt->param_bind[i].zv); } - s->m->free_parameter_bind(s, stmt->param_bind TSRMLS_CC); + s->m->free_parameter_bind(s, stmt->param_bind); stmt->param_bind = NULL; } - s->m->free_stmt_result(s TSRMLS_CC); + s->m->free_stmt_result(s); DBG_VOID_RETURN; } /* }}} */ @@ -2160,7 +2154,7 @@ MYSQLND_METHOD(mysqlnd_stmt, free_stmt_content)(MYSQLND_STMT * const s TSRMLS_DC /* {{{ mysqlnd_stmt::net_close */ static enum_func_status -MYSQLND_METHOD_PRIVATE(mysqlnd_stmt, net_close)(MYSQLND_STMT * const s, zend_bool implicit TSRMLS_DC) +MYSQLND_METHOD_PRIVATE(mysqlnd_stmt, net_close)(MYSQLND_STMT * const s, zend_bool implicit) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; MYSQLND_CONN_DATA * conn; @@ -2186,14 +2180,14 @@ MYSQLND_METHOD_PRIVATE(mysqlnd_stmt, net_close)(MYSQLND_STMT * const s, zend_boo do { if (stmt->state == MYSQLND_STMT_WAITING_USE_OR_STORE) { DBG_INF("fetching result set header"); - stmt->default_rset_handler(s TSRMLS_CC); + stmt->default_rset_handler(s); stmt->state = MYSQLND_STMT_USER_FETCHING; } /* unbuffered set not fetched to the end ? Clean the line */ if (stmt->result) { DBG_INF("skipping result"); - stmt->result->m.skip_result(stmt->result TSRMLS_CC); + stmt->result->m.skip_result(stmt->result); } } while (mysqlnd_stmt_more_results(s) && mysqlnd_stmt_next_result(s) == PASS); /* @@ -2208,7 +2202,7 @@ MYSQLND_METHOD_PRIVATE(mysqlnd_stmt, net_close)(MYSQLND_STMT * const s, zend_boo if (CONN_GET_STATE(conn) == CONN_READY && FAIL == conn->m->simple_command(conn, COM_STMT_CLOSE, cmd_buf, sizeof(cmd_buf), PROT_LAST /* COM_STMT_CLOSE doesn't send an OK packet*/, - FALSE, TRUE TSRMLS_CC)) { + FALSE, TRUE)) { COPY_CLIENT_ERROR(*stmt->error_info, *conn->error_info); DBG_RETURN(FAIL); } @@ -2232,10 +2226,10 @@ MYSQLND_METHOD_PRIVATE(mysqlnd_stmt, net_close)(MYSQLND_STMT * const s, zend_boo stmt->execute_cmd_buffer.buffer = NULL; } - s->m->free_stmt_content(s TSRMLS_CC); + s->m->free_stmt_content(s); if (stmt->conn) { - stmt->conn->m->free_reference(stmt->conn TSRMLS_CC); + stmt->conn->m->free_reference(stmt->conn); stmt->conn = NULL; } @@ -2245,7 +2239,7 @@ MYSQLND_METHOD_PRIVATE(mysqlnd_stmt, net_close)(MYSQLND_STMT * const s, zend_boo /* {{{ mysqlnd_stmt::dtor */ static enum_func_status -MYSQLND_METHOD(mysqlnd_stmt, dtor)(MYSQLND_STMT * const s, zend_bool implicit TSRMLS_DC) +MYSQLND_METHOD(mysqlnd_stmt, dtor)(MYSQLND_STMT * const s, zend_bool implicit) { MYSQLND_STMT_DATA * stmt = (s != NULL) ? s->data:NULL; enum_func_status ret = FAIL; @@ -2258,7 +2252,7 @@ MYSQLND_METHOD(mysqlnd_stmt, dtor)(MYSQLND_STMT * const s, zend_bool implicit TS MYSQLND_INC_GLOBAL_STATISTIC(implicit == TRUE? STAT_STMT_CLOSE_IMPLICIT: STAT_STMT_CLOSE_EXPLICIT); - ret = s->m->net_close(s, implicit TSRMLS_CC); + ret = s->m->net_close(s, implicit); mnd_pefree(stmt, persistent); } mnd_pefree(s, persistent); @@ -2271,7 +2265,7 @@ MYSQLND_METHOD(mysqlnd_stmt, dtor)(MYSQLND_STMT * const s, zend_bool implicit TS /* {{{ mysqlnd_stmt::alloc_param_bind */ static MYSQLND_PARAM_BIND * -MYSQLND_METHOD(mysqlnd_stmt, alloc_param_bind)(MYSQLND_STMT * const s TSRMLS_DC) +MYSQLND_METHOD(mysqlnd_stmt, alloc_param_bind)(MYSQLND_STMT * const s) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; DBG_ENTER("mysqlnd_stmt::alloc_param_bind"); @@ -2285,7 +2279,7 @@ MYSQLND_METHOD(mysqlnd_stmt, alloc_param_bind)(MYSQLND_STMT * const s TSRMLS_DC) /* {{{ mysqlnd_stmt::alloc_result_bind */ static MYSQLND_RESULT_BIND * -MYSQLND_METHOD(mysqlnd_stmt, alloc_result_bind)(MYSQLND_STMT * const s TSRMLS_DC) +MYSQLND_METHOD(mysqlnd_stmt, alloc_result_bind)(MYSQLND_STMT * const s) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; DBG_ENTER("mysqlnd_stmt::alloc_result_bind"); @@ -2299,7 +2293,7 @@ MYSQLND_METHOD(mysqlnd_stmt, alloc_result_bind)(MYSQLND_STMT * const s TSRMLS_DC /* {{{ param_bind::free_parameter_bind */ PHPAPI void -MYSQLND_METHOD(mysqlnd_stmt, free_parameter_bind)(MYSQLND_STMT * const s, MYSQLND_PARAM_BIND * param_bind TSRMLS_DC) +MYSQLND_METHOD(mysqlnd_stmt, free_parameter_bind)(MYSQLND_STMT * const s, MYSQLND_PARAM_BIND * param_bind) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; if (stmt) { @@ -2311,7 +2305,7 @@ MYSQLND_METHOD(mysqlnd_stmt, free_parameter_bind)(MYSQLND_STMT * const s, MYSQLN /* {{{ mysqlnd_stmt::free_result_bind */ PHPAPI void -MYSQLND_METHOD(mysqlnd_stmt, free_result_bind)(MYSQLND_STMT * const s, MYSQLND_RESULT_BIND * result_bind TSRMLS_DC) +MYSQLND_METHOD(mysqlnd_stmt, free_result_bind)(MYSQLND_STMT * const s, MYSQLND_RESULT_BIND * result_bind) { MYSQLND_STMT_DATA * stmt = s? s->data:NULL; if (stmt) { @@ -2324,6 +2318,7 @@ MYSQLND_METHOD(mysqlnd_stmt, free_result_bind)(MYSQLND_STMT * const s, MYSQLND_R MYSQLND_CLASS_METHODS_START(mysqlnd_stmt) MYSQLND_METHOD(mysqlnd_stmt, prepare), + MYSQLND_METHOD(mysqlnd_stmt, send_execute), MYSQLND_METHOD(mysqlnd_stmt, execute), MYSQLND_METHOD(mysqlnd_stmt, use_result), MYSQLND_METHOD(mysqlnd_stmt, store_result), @@ -2378,11 +2373,11 @@ MYSQLND_CLASS_METHODS_END; /* {{{ _mysqlnd_stmt_init */ MYSQLND_STMT * -_mysqlnd_stmt_init(MYSQLND_CONN_DATA * const conn TSRMLS_DC) +_mysqlnd_stmt_init(MYSQLND_CONN_DATA * const conn) { MYSQLND_STMT * ret; DBG_ENTER("_mysqlnd_stmt_init"); - ret = MYSQLND_CLASS_METHOD_TABLE_NAME(mysqlnd_object_factory).get_prepared_statement(conn TSRMLS_CC); + ret = MYSQLND_CLASS_METHOD_TABLE_NAME(mysqlnd_object_factory).get_prepared_statement(conn); DBG_RETURN(ret); } /* }}} */ |
