allow persistency of PS

This commit is contained in:
Andrey Hristov 2010-03-12 13:03:46 +00:00
parent af49e58f51
commit ccfd9cd744
11 changed files with 137 additions and 129 deletions

View file

@ -166,7 +166,7 @@ int mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, unsigned int argc, unsigned in
if (argc == start) { if (argc == start) {
return PASS; return PASS;
} }
params = safe_emalloc(argc - start, sizeof(MYSQLND_PARAM_BIND), 0); params = mysqlnd_stmt_alloc_param_bind(stmt->stmt);
for (i = 0; i < (argc - start); i++) { for (i = 0; i < (argc - start); i++) {
zend_uchar type; zend_uchar type;
switch (types[i]) { switch (types[i]) {
@ -190,7 +190,7 @@ int mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, unsigned int argc, unsigned in
/* We count parameters from 1 */ /* We count parameters from 1 */
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Undefined fieldtype %c (parameter %d)", types[i], i + start + 1); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Undefined fieldtype %c (parameter %d)", types[i], i + start + 1);
ret = FAIL; ret = FAIL;
efree(params); mysqlnd_stmt_free_param_bind(stmt->stmt, params);
goto end; goto end;
} }
params[i].zv = *(args[i + start]); params[i].zv = *(args[i + start]);
@ -452,9 +452,7 @@ static int
mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval ***args, unsigned int argc, unsigned int start TSRMLS_DC) mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval ***args, unsigned int argc, unsigned int start TSRMLS_DC)
{ {
unsigned int i; unsigned int i;
MYSQLND_RESULT_BIND *params; MYSQLND_RESULT_BIND * params = mysqlnd_stmt_alloc_result_bind(stmt->stmt);
params = safe_emalloc(argc - start, sizeof(MYSQLND_RESULT_BIND), 0);
for (i = 0; i < (argc - start); i++) { for (i = 0; i < (argc - start); i++) {
params[i].zv = *(args[i + start]); params[i].zv = *(args[i + start]);
} }

View file

@ -142,8 +142,8 @@ MYSQLND_METHOD(mysqlnd_conn, free_contents)(MYSQLND *conn TSRMLS_DC)
mysqlnd_local_infile_default(conn); mysqlnd_local_infile_default(conn);
if (conn->current_result) { if (conn->current_result) {
conn->current_result->m.free_result_contents(conn->current_result TSRMLS_CC); conn->current_result->m.free_result(conn->current_result, TRUE TSRMLS_CC);
mnd_efree(conn->current_result); // mnd_pefree(conn->current_result, conn->current_result->persistent);
conn->current_result = NULL; conn->current_result = NULL;
} }
@ -1089,7 +1089,7 @@ MYSQLND_METHOD(mysqlnd_conn, list_fields)(MYSQLND *conn, const char *table, cons
Prepare for the worst case. Prepare for the worst case.
MyISAM goes to 2500 BIT columns, double it for safety. MyISAM goes to 2500 BIT columns, double it for safety.
*/ */
result = mysqlnd_result_init(5000 TSRMLS_CC); result = mysqlnd_result_init(5000, conn->persistent TSRMLS_CC);
if (FAIL == result->m.read_result_metadata(result, conn TSRMLS_CC)) { if (FAIL == result->m.read_result_metadata(result, conn TSRMLS_CC)) {

View file

@ -242,6 +242,8 @@ PHPAPI unsigned int mysqlnd_get_client_version();
PHPAPI void mysqlnd_efree_param_bind_dtor(MYSQLND_PARAM_BIND * param_bind TSRMLS_DC); PHPAPI void mysqlnd_efree_param_bind_dtor(MYSQLND_PARAM_BIND * param_bind TSRMLS_DC);
PHPAPI void mysqlnd_efree_result_bind_dtor(MYSQLND_RESULT_BIND * result_bind TSRMLS_DC); PHPAPI void mysqlnd_efree_result_bind_dtor(MYSQLND_RESULT_BIND * result_bind TSRMLS_DC);
PHPAPI void mysqlnd_free_param_bind_dtor(MYSQLND_PARAM_BIND * param_bind TSRMLS_DC);
PHPAPI void mysqlnd_free_result_bind_dtor(MYSQLND_RESULT_BIND * result_bind TSRMLS_DC);
PHPAPI const char * mysqlnd_field_type_name(enum mysqlnd_field_types field_type); PHPAPI const char * mysqlnd_field_type_name(enum mysqlnd_field_types field_type);
@ -288,16 +290,18 @@ PHPAPI ulong mysqlnd_old_escape_string(char *newstr, const char *escapestr, size
#define mysqlnd_stmt_data_seek(stmt, row) (stmt)->m->seek_data((stmt), (row) TSRMLS_CC) #define mysqlnd_stmt_data_seek(stmt, row) (stmt)->m->seek_data((stmt), (row) TSRMLS_CC)
#define mysqlnd_stmt_prepare(stmt, q, qlen) (stmt)->m->prepare((stmt), (q), (qlen) TSRMLS_CC) #define mysqlnd_stmt_prepare(stmt, q, qlen) (stmt)->m->prepare((stmt), (q), (qlen) TSRMLS_CC)
#define mysqlnd_stmt_execute(stmt) (stmt)->m->execute((stmt) TSRMLS_CC) #define mysqlnd_stmt_execute(stmt) (stmt)->m->execute((stmt) TSRMLS_CC)
#define mysqlnd_stmt_send_long_data(s,p,d,l) (s)->m->send_long_data((s), (p), (d), (l) TSRMLS_CC) #define mysqlnd_stmt_send_long_data(stmt,p,d,l) (stmt)->m->send_long_data((stmt), (p), (d), (l) TSRMLS_CC)
#define mysqlnd_stmt_bind_param(stmt,bind) (stmt)->m->bind_parameters((stmt), (bind) TSRMLS_CC) #define mysqlnd_stmt_alloc_param_bind(stmt) (stmt)->m->alloc_parameter_bind((stmt) TSRMLS_CC)
#define mysqlnd_stmt_bind_one_param(s,n,z,t) (s)->m->bind_one_parameter((s), (n), (z), (t) TSRMLS_CC) #define mysqlnd_stmt_free_param_bind(stmt,bind) (stmt)->m->free_parameter_bind((stmt), (bind) TSRMLS_CC)
#define mysqlnd_stmt_refresh_bind_param(s) (s)->m->refresh_bind_param((s) TSRMLS_CC) #define mysqlnd_stmt_bind_param(stmt,bind) (stmt)->m->bind_parameters((stmt), (bind) TSRMLS_CC)
#define mysqlnd_stmt_set_param_bind_dtor(s,d) (s)->m->set_param_bind_dtor((s), (d) TSRMLS_CC) #define mysqlnd_stmt_bind_one_param(stmt,n,z,t) (stmt)->m->bind_one_parameter((stmt), (n), (z), (t) TSRMLS_CC)
#define mysqlnd_stmt_bind_result(stmt,bind) (stmt)->m->bind_result((stmt), (bind) TSRMLS_CC) #define mysqlnd_stmt_refresh_bind_param(s) (s)->m->refresh_bind_param((s) TSRMLS_CC)
#define mysqlnd_stmt_bind_one_result(s,no) (s)->m->bind_one_result((s), (no) TSRMLS_CC) #define mysqlnd_stmt_alloc_result_bind(stmt) (stmt)->m->alloc_result_bind((stmt) TSRMLS_CC)
#define mysqlnd_stmt_set_result_bind_dtor(s,d) (s)->m->set_result_bind_dtor((s), (d) TSRMLS_CC) #define mysqlnd_stmt_free_result_bind(stmt,bind) (stmt)->m->free_result_bind((stmt), (bind) TSRMLS_CC)
#define mysqlnd_stmt_param_metadata(stmt) (stmt)->m->get_parameter_metadata((stmt)) #define mysqlnd_stmt_bind_result(stmt,bind) (stmt)->m->bind_result((stmt), (bind) TSRMLS_CC)
#define mysqlnd_stmt_result_metadata(stmt) (stmt)->m->get_result_metadata((stmt) TSRMLS_CC) #define mysqlnd_stmt_bind_one_result(s,no) (s)->m->bind_one_result((s), (no) TSRMLS_CC)
#define mysqlnd_stmt_param_metadata(stmt) (stmt)->m->get_parameter_metadata((stmt))
#define mysqlnd_stmt_result_metadata(stmt) (stmt)->m->get_result_metadata((stmt) TSRMLS_CC)
#define mysqlnd_stmt_free_result(stmt) (stmt)->m->free_result((stmt) TSRMLS_CC) #define mysqlnd_stmt_free_result(stmt) (stmt)->m->free_result((stmt) TSRMLS_CC)
#define mysqlnd_stmt_close(stmt, implicit) (stmt)->m->dtor((stmt), (implicit) TSRMLS_CC) #define mysqlnd_stmt_close(stmt, implicit) (stmt)->m->dtor((stmt), (implicit) TSRMLS_CC)

View file

@ -154,7 +154,7 @@ MYSQLND_METHOD(mysqlnd_stmt, get_result)(MYSQLND_STMT * const stmt TSRMLS_DC)
SET_EMPTY_ERROR(stmt->conn->error_info); SET_EMPTY_ERROR(stmt->conn->error_info);
MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_BUFFERED_SETS); MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_BUFFERED_SETS);
result = mysqlnd_result_init(stmt->result->field_count TSRMLS_CC); result = mysqlnd_result_init(stmt->result->field_count, stmt->persistent TSRMLS_CC);
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 TSRMLS_CC);
@ -335,9 +335,9 @@ MYSQLND_METHOD(mysqlnd_stmt, prepare)(MYSQLND_STMT * const stmt, const char * co
stmt_to_prepare = mysqlnd_stmt_init(stmt->conn); stmt_to_prepare = mysqlnd_stmt_init(stmt->conn);
} }
if (FAIL == stmt_to_prepare->conn->m->simple_command(stmt_to_prepare->conn, COM_STMT_PREPARE, query, if (FAIL == stmt_to_prepare->conn->m->simple_command(stmt_to_prepare->conn, COM_STMT_PREPARE, query, query_len, PROT_LAST, FALSE, TRUE TSRMLS_CC) ||
query_len, PROT_LAST, FALSE, TRUE TSRMLS_CC) || FAIL == mysqlnd_stmt_read_prepare_response(stmt_to_prepare TSRMLS_CC))
FAIL == mysqlnd_stmt_read_prepare_response(stmt_to_prepare TSRMLS_CC)) { {
goto fail; goto fail;
} }
@ -355,7 +355,7 @@ MYSQLND_METHOD(mysqlnd_stmt, prepare)(MYSQLND_STMT * const stmt, const char * co
no metadata at prepare. no metadata at prepare.
*/ */
if (stmt_to_prepare->field_count) { if (stmt_to_prepare->field_count) {
MYSQLND_RES *result = mysqlnd_result_init(stmt_to_prepare->field_count TSRMLS_CC); MYSQLND_RES * result = mysqlnd_result_init(stmt_to_prepare->field_count, stmt_to_prepare->persistent TSRMLS_CC);
/* Allocate the result now as it is needed for the reading of metadata */ /* Allocate the result now as it is needed for the reading of metadata */
stmt_to_prepare->result = result; stmt_to_prepare->result = result;
@ -376,7 +376,7 @@ MYSQLND_METHOD(mysqlnd_stmt, prepare)(MYSQLND_STMT * const stmt, const char * co
memcpy(stmt, stmt_to_prepare, sizeof(MYSQLND_STMT)); memcpy(stmt, stmt_to_prepare, sizeof(MYSQLND_STMT));
/* Now we will have a clean new statement object */ /* Now we will have a clean new statement object */
mnd_efree(stmt_to_prepare); mnd_pefree(stmt_to_prepare, stmt_to_prepare->persistent);
} }
stmt->state = MYSQLND_STMT_PREPARED; stmt->state = MYSQLND_STMT_PREPARED;
DBG_INF("PASS"); DBG_INF("PASS");
@ -1248,8 +1248,8 @@ MYSQLND_METHOD(mysqlnd_stmt, bind_parameters)(MYSQLND_STMT * const stmt, MYSQLND
if (stmt->state < MYSQLND_STMT_PREPARED) { if (stmt->state < MYSQLND_STMT_PREPARED) {
SET_STMT_ERROR(stmt, CR_NO_PREPARE_STMT, UNKNOWN_SQLSTATE, mysqlnd_stmt_not_prepared); SET_STMT_ERROR(stmt, CR_NO_PREPARE_STMT, UNKNOWN_SQLSTATE, mysqlnd_stmt_not_prepared);
DBG_ERR("not prepared"); DBG_ERR("not prepared");
if (param_bind && stmt->param_bind_dtor) { if (param_bind) {
stmt->param_bind_dtor(param_bind TSRMLS_CC); stmt->m->free_parameter_bind(stmt, param_bind TSRMLS_CC);
} }
DBG_RETURN(FAIL); DBG_RETURN(FAIL);
} }
@ -1281,8 +1281,8 @@ MYSQLND_METHOD(mysqlnd_stmt, bind_parameters)(MYSQLND_STMT * const stmt, MYSQLND
zval_ptr_dtor(&stmt->param_bind[i].zv); zval_ptr_dtor(&stmt->param_bind[i].zv);
} }
} }
if (stmt->param_bind != param_bind && stmt->param_bind_dtor) { if (stmt->param_bind != param_bind) {
stmt->param_bind_dtor(stmt->param_bind TSRMLS_CC); stmt->m->free_parameter_bind(stmt, stmt->param_bind TSRMLS_CC);
} }
} }
@ -1382,19 +1382,6 @@ MYSQLND_METHOD(mysqlnd_stmt, refresh_bind_param)(MYSQLND_STMT * const stmt TSRML
/* }}} */ /* }}} */
/* {{{ mysqlnd_stmt::set_bind_param_dtor */
static void
MYSQLND_METHOD(mysqlnd_stmt, set_param_bind_dtor)(MYSQLND_STMT * const stmt,
void (*param_bind_dtor)(MYSQLND_PARAM_BIND * dtor TSRMLS_DC) TSRMLS_DC)
{
DBG_ENTER("mysqlnd_stmt::set_bind_param_dtor");
DBG_INF_FMT("stmt=%p", param_bind_dtor);
stmt->param_bind_dtor = param_bind_dtor;
DBG_VOID_RETURN;
}
/* }}} */
/* {{{ mysqlnd_stmt::bind_result */ /* {{{ mysqlnd_stmt::bind_result */
static enum_func_status static enum_func_status
MYSQLND_METHOD(mysqlnd_stmt, bind_result)(MYSQLND_STMT * const stmt, MYSQLND_METHOD(mysqlnd_stmt, bind_result)(MYSQLND_STMT * const stmt,
@ -1406,8 +1393,8 @@ MYSQLND_METHOD(mysqlnd_stmt, bind_result)(MYSQLND_STMT * const stmt,
if (stmt->state < MYSQLND_STMT_PREPARED) { if (stmt->state < MYSQLND_STMT_PREPARED) {
SET_STMT_ERROR(stmt, CR_NO_PREPARE_STMT, UNKNOWN_SQLSTATE, mysqlnd_stmt_not_prepared); SET_STMT_ERROR(stmt, CR_NO_PREPARE_STMT, UNKNOWN_SQLSTATE, mysqlnd_stmt_not_prepared);
if (result_bind && stmt->result_bind_dtor) { if (result_bind) {
stmt->result_bind_dtor(result_bind TSRMLS_CC); stmt->m->free_result_bind(stmt, result_bind TSRMLS_CC);
} }
DBG_ERR("not prepared"); DBG_ERR("not prepared");
DBG_RETURN(FAIL); DBG_RETURN(FAIL);
@ -1438,8 +1425,8 @@ MYSQLND_METHOD(mysqlnd_stmt, bind_result)(MYSQLND_STMT * const stmt,
*/ */
stmt->result_bind[i].bound = TRUE; stmt->result_bind[i].bound = TRUE;
} }
} else if (result_bind && stmt->result_bind_dtor) { } else if (result_bind) {
stmt->result_bind_dtor(result_bind TSRMLS_CC); stmt->m->free_result_bind(stmt, result_bind TSRMLS_CC);
} }
DBG_INF("PASS"); DBG_INF("PASS");
DBG_RETURN(PASS); DBG_RETURN(PASS);
@ -1491,19 +1478,6 @@ MYSQLND_METHOD(mysqlnd_stmt, bind_one_result)(MYSQLND_STMT * const stmt, unsigne
/* }}} */ /* }}} */
/* {{{ mysqlnd_stmt::set_bind_result_dtor */
static void
MYSQLND_METHOD(mysqlnd_stmt, set_result_bind_dtor)(MYSQLND_STMT * const stmt,
void (*result_bind_dtor)(MYSQLND_RESULT_BIND * dtor TSRMLS_DC) TSRMLS_DC)
{
DBG_ENTER("mysqlnd_stmt::set_bind_param_dtor");
DBG_INF_FMT("stmt=%p", result_bind_dtor);
stmt->result_bind_dtor = result_bind_dtor;
DBG_VOID_RETURN;
}
/* }}} */
/* {{{ mysqlnd_stmt::insert_id */ /* {{{ mysqlnd_stmt::insert_id */
static uint64_t static uint64_t
MYSQLND_METHOD(mysqlnd_stmt, insert_id)(const MYSQLND_STMT * const stmt TSRMLS_DC) MYSQLND_METHOD(mysqlnd_stmt, insert_id)(const MYSQLND_STMT * const stmt TSRMLS_DC)
@ -1634,7 +1608,7 @@ MYSQLND_METHOD(mysqlnd_stmt, result_metadata)(MYSQLND_STMT * const stmt TSRMLS_D
In the meantime we don't need a zval cache reference for this fake In the meantime we don't need a zval cache reference for this fake
result set, so we don't get one. result set, so we don't get one.
*/ */
result = mysqlnd_result_init(stmt->field_count TSRMLS_CC); result = mysqlnd_result_init(stmt->field_count, stmt->persistent TSRMLS_CC);
result->type = MYSQLND_RES_NORMAL; result->type = MYSQLND_RES_NORMAL;
result->m.fetch_row = result->m.fetch_row_normal_unbuffered; result->m.fetch_row = result->m.fetch_row_normal_unbuffered;
result->unbuf = mnd_ecalloc(1, sizeof(MYSQLND_RES_UNBUFFERED)); result->unbuf = mnd_ecalloc(1, sizeof(MYSQLND_RES_UNBUFFERED));
@ -1817,9 +1791,7 @@ void mysqlnd_stmt_separate_result_bind(MYSQLND_STMT * const stmt TSRMLS_DC)
} }
} }
} }
if (stmt->result_bind_dtor) { stmt->m->free_result_bind(stmt, stmt->result_bind TSRMLS_CC);
stmt->result_bind_dtor(stmt->result_bind TSRMLS_CC);
}
stmt->result_bind = NULL; stmt->result_bind = NULL;
DBG_VOID_RETURN; DBG_VOID_RETURN;
@ -1898,9 +1870,7 @@ void mysqlnd_internal_free_stmt_content(MYSQLND_STMT * const stmt TSRMLS_DC)
zval_ptr_dtor(&stmt->param_bind[i].zv); zval_ptr_dtor(&stmt->param_bind[i].zv);
} }
} }
if (stmt->param_bind_dtor) { stmt->m->free_parameter_bind(stmt, stmt->param_bind TSRMLS_CC);
stmt->param_bind_dtor(stmt->param_bind TSRMLS_CC);
}
stmt->param_bind = NULL; stmt->param_bind = NULL;
} }
@ -1985,7 +1955,7 @@ MYSQLND_METHOD_PRIVATE(mysqlnd_stmt, net_close)(MYSQLND_STMT * const stmt, zend_
} }
if (stmt->execute_cmd_buffer.buffer) { if (stmt->execute_cmd_buffer.buffer) {
mnd_efree(stmt->execute_cmd_buffer.buffer); mnd_pefree(stmt->execute_cmd_buffer.buffer, stmt->persistent);
stmt->execute_cmd_buffer.buffer = NULL; stmt->execute_cmd_buffer.buffer = NULL;
} }
@ -2013,7 +1983,7 @@ MYSQLND_METHOD(mysqlnd_stmt, dtor)(MYSQLND_STMT * const stmt, zend_bool implicit
STAT_STMT_CLOSE_EXPLICIT); STAT_STMT_CLOSE_EXPLICIT);
ret = stmt->m->net_close(stmt, implicit TSRMLS_CC); ret = stmt->m->net_close(stmt, implicit TSRMLS_CC);
mnd_efree(stmt); mnd_pefree(stmt, stmt->persistent);
DBG_INF(ret == PASS? "PASS":"FAIL"); DBG_INF(ret == PASS? "PASS":"FAIL");
DBG_RETURN(ret); DBG_RETURN(ret);
@ -2021,6 +1991,45 @@ MYSQLND_METHOD(mysqlnd_stmt, dtor)(MYSQLND_STMT * const stmt, zend_bool implicit
/* }}} */ /* }}} */
/* {{{ mysqlnd_stmt::alloc_param_bind */
static MYSQLND_PARAM_BIND *
MYSQLND_METHOD(mysqlnd_stmt, alloc_param_bind)(MYSQLND_STMT * const stmt TSRMLS_DC)
{
DBG_ENTER("mysqlnd_stmt::alloc_param_bind");
DBG_RETURN(safe_pemalloc(stmt->param_count, sizeof(MYSQLND_PARAM_BIND), 0, stmt->persistent));
}
/* }}} */
/* {{{ mysqlnd_stmt::alloc_result_bind */
static MYSQLND_RESULT_BIND *
MYSQLND_METHOD(mysqlnd_stmt, alloc_result_bind)(MYSQLND_STMT * const stmt TSRMLS_DC)
{
DBG_ENTER("mysqlnd_stmt::alloc_result_bind");
DBG_RETURN(safe_pemalloc(stmt->field_count, sizeof(MYSQLND_RESULT_BIND), 0, stmt->persistent));
}
/* }}} */
/* {{{ param_bind::free_parameter_bind */
PHPAPI void
MYSQLND_METHOD(mysqlnd_stmt, free_parameter_bind)(MYSQLND_STMT * const stmt, MYSQLND_PARAM_BIND * param_bind TSRMLS_DC)
{
mnd_pefree(param_bind, stmt->persistent);
}
/* }}} */
/* {{{ mysqlnd_stmt::free_result_bind */
PHPAPI void
MYSQLND_METHOD(mysqlnd_stmt, free_result_bind)(MYSQLND_STMT * const stmt, MYSQLND_RESULT_BIND * result_bind TSRMLS_DC)
{
mnd_pefree(result_bind, stmt->persistent);
}
/* }}} */
MYSQLND_CLASS_METHODS_START(mysqlnd_stmt) MYSQLND_CLASS_METHODS_START(mysqlnd_stmt)
MYSQLND_METHOD(mysqlnd_stmt, prepare), MYSQLND_METHOD(mysqlnd_stmt, prepare),
MYSQLND_METHOD(mysqlnd_stmt, execute), MYSQLND_METHOD(mysqlnd_stmt, execute),
@ -2040,10 +2049,8 @@ MYSQLND_CLASS_METHODS_START(mysqlnd_stmt)
MYSQLND_METHOD(mysqlnd_stmt, bind_parameters), MYSQLND_METHOD(mysqlnd_stmt, bind_parameters),
MYSQLND_METHOD(mysqlnd_stmt, bind_one_parameter), MYSQLND_METHOD(mysqlnd_stmt, bind_one_parameter),
MYSQLND_METHOD(mysqlnd_stmt, refresh_bind_param), MYSQLND_METHOD(mysqlnd_stmt, refresh_bind_param),
MYSQLND_METHOD(mysqlnd_stmt, set_param_bind_dtor),
MYSQLND_METHOD(mysqlnd_stmt, bind_result), MYSQLND_METHOD(mysqlnd_stmt, bind_result),
MYSQLND_METHOD(mysqlnd_stmt, bind_one_result), MYSQLND_METHOD(mysqlnd_stmt, bind_one_result),
MYSQLND_METHOD(mysqlnd_stmt, set_result_bind_dtor),
MYSQLND_METHOD(mysqlnd_stmt, send_long_data), MYSQLND_METHOD(mysqlnd_stmt, send_long_data),
MYSQLND_METHOD(mysqlnd_stmt, param_metadata), MYSQLND_METHOD(mysqlnd_stmt, param_metadata),
MYSQLND_METHOD(mysqlnd_stmt, result_metadata), MYSQLND_METHOD(mysqlnd_stmt, result_metadata),
@ -2061,7 +2068,13 @@ MYSQLND_CLASS_METHODS_START(mysqlnd_stmt)
MYSQLND_METHOD(mysqlnd_stmt, sqlstate), MYSQLND_METHOD(mysqlnd_stmt, sqlstate),
MYSQLND_METHOD(mysqlnd_stmt, attr_get), MYSQLND_METHOD(mysqlnd_stmt, attr_get),
MYSQLND_METHOD(mysqlnd_stmt, attr_set), MYSQLND_METHOD(mysqlnd_stmt, attr_set),
MYSQLND_METHOD(mysqlnd_stmt, alloc_param_bind),
MYSQLND_METHOD(mysqlnd_stmt, alloc_result_bind),
MYSQLND_METHOD(mysqlnd_stmt, free_parameter_bind),
MYSQLND_METHOD(mysqlnd_stmt, free_result_bind)
MYSQLND_CLASS_METHODS_END; MYSQLND_CLASS_METHODS_END;
@ -2069,15 +2082,16 @@ MYSQLND_CLASS_METHODS_END;
MYSQLND_STMT * _mysqlnd_stmt_init(MYSQLND * const conn TSRMLS_DC) MYSQLND_STMT * _mysqlnd_stmt_init(MYSQLND * const conn TSRMLS_DC)
{ {
size_t alloc_size = sizeof(MYSQLND_STMT) + mysqlnd_plugin_count() * sizeof(void *); size_t alloc_size = sizeof(MYSQLND_STMT) + mysqlnd_plugin_count() * sizeof(void *);
MYSQLND_STMT *stmt = mnd_ecalloc(1, alloc_size); MYSQLND_STMT * stmt = mnd_pecalloc(1, alloc_size, conn->persistent);
DBG_ENTER("_mysqlnd_stmt_init"); DBG_ENTER("_mysqlnd_stmt_init");
DBG_INF_FMT("stmt=%p", stmt); DBG_INF_FMT("stmt=%p", stmt);
stmt->persistent = conn->persistent;
stmt->m = mysqlnd_stmt_methods; stmt->m = mysqlnd_stmt_methods;
stmt->state = MYSQLND_STMT_INITTED; stmt->state = MYSQLND_STMT_INITTED;
stmt->execute_cmd_buffer.length = 4096; stmt->execute_cmd_buffer.length = 4096;
stmt->execute_cmd_buffer.buffer = mnd_emalloc(stmt->execute_cmd_buffer.length); stmt->execute_cmd_buffer.buffer = mnd_pemalloc(stmt->execute_cmd_buffer.length, stmt->persistent);
stmt->prefetch_rows = MYSQLND_DEFAULT_PREFETCH_ROWS; stmt->prefetch_rows = MYSQLND_DEFAULT_PREFETCH_ROWS;
/* /*
@ -2086,10 +2100,6 @@ MYSQLND_STMT * _mysqlnd_stmt_init(MYSQLND * const conn TSRMLS_DC)
or normal query result will close it then. or normal query result will close it then.
*/ */
stmt->conn = conn->m->get_reference(conn TSRMLS_CC); stmt->conn = conn->m->get_reference(conn TSRMLS_CC);
stmt->m->set_param_bind_dtor(stmt, mysqlnd_efree_param_bind_dtor TSRMLS_CC);
stmt->m->set_result_bind_dtor(stmt, mysqlnd_efree_result_bind_dtor TSRMLS_CC);
DBG_RETURN(stmt); DBG_RETURN(stmt);
} }
/* }}} */ /* }}} */
@ -2108,22 +2118,6 @@ PHPAPI void ** _mysqlnd_plugin_get_plugin_stmt_data(const MYSQLND_STMT * stmt, u
/* }}} */ /* }}} */
/* {{{ mysqlnd_efree_param_bind_dtor */
PHPAPI void
mysqlnd_efree_param_bind_dtor(MYSQLND_PARAM_BIND * param_bind TSRMLS_DC)
{
mnd_efree(param_bind);
}
/* }}} */
/* {{{ mysqlnd_efree_result_bind_dtor */
PHPAPI void
mysqlnd_efree_result_bind_dtor(MYSQLND_RESULT_BIND * result_bind TSRMLS_DC)
{
mnd_efree(result_bind);
}
/* }}} */
/* {{{ _mysqlnd_init_ps_subsystem */ /* {{{ _mysqlnd_init_ps_subsystem */
void _mysqlnd_init_ps_subsystem() void _mysqlnd_init_ps_subsystem()

View file

@ -280,7 +280,7 @@ void mysqlnd_internal_free_result_contents(MYSQLND_RES *result TSRMLS_DC)
result->m.free_result_buffers(result TSRMLS_CC); result->m.free_result_buffers(result TSRMLS_CC);
if (result->meta) { if (result->meta) {
result->meta->m->free_metadata(result->meta, FALSE TSRMLS_CC); result->meta->m->free_metadata(result->meta TSRMLS_CC);
result->meta = NULL; result->meta = NULL;
} }
@ -301,7 +301,7 @@ void mysqlnd_internal_free_result(MYSQLND_RES *result TSRMLS_DC)
result->conn = NULL; result->conn = NULL;
} }
mnd_efree(result); mnd_pefree(result, result->persistent);
DBG_VOID_RETURN; DBG_VOID_RETURN;
} }
@ -321,11 +321,11 @@ MYSQLND_METHOD(mysqlnd_res, read_result_metadata)(MYSQLND_RES *result, MYSQLND *
infrastructure! infrastructure!
*/ */
if (result->meta) { if (result->meta) {
result->meta->m->free_metadata(result->meta, FALSE TSRMLS_CC); result->meta->m->free_metadata(result->meta TSRMLS_CC);
result->meta = NULL; result->meta = NULL;
} }
result->meta = mysqlnd_result_meta_init(result->field_count TSRMLS_CC); result->meta = mysqlnd_result_meta_init(result->field_count, result->persistent TSRMLS_CC);
/* 1. Read all fields metadata */ /* 1. Read all fields metadata */
@ -440,7 +440,7 @@ mysqlnd_query_read_result_set_header(MYSQLND *conn, MYSQLND_STMT *stmt TSRMLS_DC
/* PS has already allocated it */ /* PS has already allocated it */
conn->field_count = rset_header->field_count; conn->field_count = rset_header->field_count;
if (!stmt) { if (!stmt) {
result = conn->current_result = mysqlnd_result_init(rset_header->field_count TSRMLS_CC); result = conn->current_result = mysqlnd_result_init(rset_header->field_count, conn->persistent TSRMLS_CC);
} else { } else {
if (!stmt->result) { if (!stmt->result) {
DBG_INF("This is 'SHOW'/'EXPLAIN'-like query."); DBG_INF("This is 'SHOW'/'EXPLAIN'-like query.");
@ -449,7 +449,7 @@ mysqlnd_query_read_result_set_header(MYSQLND *conn, MYSQLND_STMT *stmt TSRMLS_DC
prepared statements can't send result set metadata for these queries prepared statements can't send result set metadata for these queries
on prepare stage. Read it now. on prepare stage. Read it now.
*/ */
result = stmt->result = mysqlnd_result_init(rset_header->field_count TSRMLS_CC); result = stmt->result = mysqlnd_result_init(rset_header->field_count, stmt->persistent TSRMLS_CC);
} else { } else {
/* /*
Update result set metadata if it for some reason changed between Update result set metadata if it for some reason changed between
@ -1524,16 +1524,17 @@ MYSQLND_METHOD(mysqlnd_res, fetch_field_data)(MYSQLND_RES *result, unsigned int
/* }}} */ /* }}} */
/* {{{ mysqlnd_result_init */ /* {{{ mysqlnd_result_init_ex */
PHPAPI MYSQLND_RES * PHPAPI MYSQLND_RES *
mysqlnd_result_init(unsigned int field_count TSRMLS_DC) mysqlnd_result_init(unsigned int field_count, zend_bool persistent TSRMLS_DC)
{ {
size_t alloc_size = sizeof(MYSQLND_RES) + mysqlnd_plugin_count() * sizeof(void *); size_t alloc_size = sizeof(MYSQLND_RES) + mysqlnd_plugin_count() * sizeof(void *);
MYSQLND_RES *ret = mnd_ecalloc(1, alloc_size); MYSQLND_RES *ret = mnd_pecalloc(1, alloc_size, persistent);
DBG_ENTER("mysqlnd_result_init"); DBG_ENTER("mysqlnd_result_init");
DBG_INF_FMT("field_count=%u", field_count); DBG_INF_FMT("field_count=%u", field_count);
ret->persistent = persistent;
ret->field_count = field_count; ret->field_count = field_count;
ret->m.use_result = MYSQLND_METHOD(mysqlnd_res, use_result); ret->m.use_result = MYSQLND_METHOD(mysqlnd_res, use_result);

View file

@ -23,9 +23,9 @@
#ifndef MYSQLND_RESULT_H #ifndef MYSQLND_RESULT_H
#define MYSQLND_RESULT_H #define MYSQLND_RESULT_H
PHPAPI MYSQLND_RES * mysqlnd_result_init(unsigned int field_count TSRMLS_DC); PHPAPI MYSQLND_RES * mysqlnd_result_init(unsigned int field_count, zend_bool persistent TSRMLS_DC);
enum_func_status mysqlnd_query_read_result_set_header(MYSQLND *conn, MYSQLND_STMT *stmt TSRMLS_DC); enum_func_status mysqlnd_query_read_result_set_header(MYSQLND * conn, MYSQLND_STMT * stmt TSRMLS_DC);
#endif /* MYSQLND_RESULT_H */ #endif /* MYSQLND_RESULT_H */

View file

@ -150,12 +150,13 @@ MYSQLND_METHOD(mysqlnd_res_meta, read_metadata)(MYSQLND_RES_METADATA * const met
DBG_ENTER("mysqlnd_res_meta::read_metadata"); DBG_ENTER("mysqlnd_res_meta::read_metadata");
field_packet = conn->protocol->m.get_result_field_packet(conn->protocol, FALSE TSRMLS_CC); field_packet = conn->protocol->m.get_result_field_packet(conn->protocol, FALSE TSRMLS_CC);
field_packet->persistent_alloc = meta->persistent;
for (;i < meta->field_count; i++) { for (;i < meta->field_count; i++) {
long idx; long idx;
if (meta->fields[i].root) { if (meta->fields[i].root) {
/* We re-read metadata for PS */ /* We re-read metadata for PS */
mnd_efree(meta->fields[i].root); mnd_pefree(meta->fields[i].root, meta->persistent);
meta->fields[i].root = NULL; meta->fields[i].root = NULL;
} }
@ -260,21 +261,20 @@ MYSQLND_METHOD(mysqlnd_res_meta, read_metadata)(MYSQLND_RES_METADATA * const met
/* {{{ mysqlnd_res_meta::free */ /* {{{ mysqlnd_res_meta::free */
static void static void
MYSQLND_METHOD(mysqlnd_res_meta, free)(MYSQLND_RES_METADATA *meta, zend_bool persistent TSRMLS_DC) MYSQLND_METHOD(mysqlnd_res_meta, free)(MYSQLND_RES_METADATA * meta TSRMLS_DC)
{ {
int i; int i;
MYSQLND_FIELD *fields; MYSQLND_FIELD *fields;
DBG_ENTER("mysqlnd_res_meta::free"); DBG_ENTER("mysqlnd_res_meta::free");
DBG_INF_FMT("persistent=%d", persistent); DBG_INF_FMT("persistent=%d", meta->persistent);
if ((fields = meta->fields)) { if ((fields = meta->fields)) {
DBG_INF("Freeing fields metadata"); DBG_INF("Freeing fields metadata");
i = meta->field_count; i = meta->field_count;
while (i--) { while (i--) {
php_mysqlnd_free_field_metadata(fields++, persistent TSRMLS_CC); php_mysqlnd_free_field_metadata(fields++, meta->persistent TSRMLS_CC);
} }
mnd_pefree(meta->fields, persistent); mnd_pefree(meta->fields, meta->persistent);
meta->fields = NULL; meta->fields = NULL;
} }
@ -284,16 +284,16 @@ MYSQLND_METHOD(mysqlnd_res_meta, free)(MYSQLND_RES_METADATA *meta, zend_bool per
if (UG(unicode)) { if (UG(unicode)) {
for (i = 0; i < meta->field_count; i++) { for (i = 0; i < meta->field_count; i++) {
if (meta->zend_hash_keys[i].ustr.v) { if (meta->zend_hash_keys[i].ustr.v) {
mnd_pefree(meta->zend_hash_keys[i].ustr.v, persistent); mnd_pefree(meta->zend_hash_keys[i].ustr.v, meta->persistent);
} }
} }
} }
#endif #endif
mnd_pefree(meta->zend_hash_keys, persistent); mnd_pefree(meta->zend_hash_keys, meta->persistent);
meta->zend_hash_keys = NULL; meta->zend_hash_keys = NULL;
} }
DBG_INF("Freeing metadata structure"); DBG_INF("Freeing metadata structure");
mnd_pefree(meta, persistent); mnd_pefree(meta, meta->persistent);
DBG_VOID_RETURN; DBG_VOID_RETURN;
} }
@ -314,6 +314,7 @@ MYSQLND_METHOD(mysqlnd_res_meta, clone_metadata)(const MYSQLND_RES_METADATA * co
DBG_ENTER("mysqlnd_res_meta::clone_metadata"); DBG_ENTER("mysqlnd_res_meta::clone_metadata");
DBG_INF_FMT("persistent=%d", persistent); DBG_INF_FMT("persistent=%d", persistent);
new_meta->persistent = persistent;
new_meta->zend_hash_keys = mnd_pemalloc(len, persistent); new_meta->zend_hash_keys = mnd_pemalloc(len, persistent);
memcpy(new_meta->zend_hash_keys, meta->zend_hash_keys, len); memcpy(new_meta->zend_hash_keys, meta->zend_hash_keys, len);
new_meta->m = meta->m; new_meta->m = meta->m;
@ -435,16 +436,18 @@ MYSQLND_CLASS_METHODS_END;
/* {{{ mysqlnd_result_meta_init */ /* {{{ mysqlnd_result_meta_init */
PHPAPI MYSQLND_RES_METADATA * PHPAPI MYSQLND_RES_METADATA *
mysqlnd_result_meta_init(unsigned int field_count TSRMLS_DC) mysqlnd_result_meta_init(unsigned int field_count, zend_bool persistent TSRMLS_DC)
{ {
MYSQLND_RES_METADATA *ret; MYSQLND_RES_METADATA *ret;
DBG_ENTER("mysqlnd_result_meta_init"); DBG_ENTER("mysqlnd_result_meta_init");
DBG_INF_FMT("persistent=%d", persistent);
/* +1 is to have empty marker at the end */ /* +1 is to have empty marker at the end */
ret = mnd_ecalloc(1, sizeof(MYSQLND_RES_METADATA)); ret = mnd_pecalloc(1, sizeof(MYSQLND_RES_METADATA), persistent);
ret->persistent = persistent;
ret->field_count = field_count; ret->field_count = field_count;
ret->fields = mnd_ecalloc(field_count + 1, sizeof(MYSQLND_FIELD)); ret->fields = mnd_pecalloc(field_count + 1, sizeof(MYSQLND_FIELD), ret->persistent);
ret->zend_hash_keys = mnd_ecalloc(field_count, sizeof(struct mysqlnd_field_hash_key)); ret->zend_hash_keys = mnd_pecalloc(field_count, sizeof(struct mysqlnd_field_hash_key), ret->persistent);
ret->m = & mysqlnd_mysqlnd_res_meta_methods; ret->m = & mysqlnd_mysqlnd_res_meta_methods;
DBG_INF_FMT("meta=%p", ret); DBG_INF_FMT("meta=%p", ret);

View file

@ -24,7 +24,7 @@
#define MYSQLND_RESULT_META_H #define MYSQLND_RESULT_META_H
PHPAPI MYSQLND_RES_METADATA * mysqlnd_result_meta_init(unsigned int field_count TSRMLS_DC); PHPAPI MYSQLND_RES_METADATA * mysqlnd_result_meta_init(unsigned int field_count, zend_bool persistent TSRMLS_DC);

View file

@ -527,9 +527,9 @@ typedef const MYSQLND_FIELD * (*func_mysqlnd_res_meta__fetch_field)(MYSQLND_RES_
typedef const MYSQLND_FIELD * (*func_mysqlnd_res_meta__fetch_field_direct)(const MYSQLND_RES_METADATA * const meta, MYSQLND_FIELD_OFFSET fieldnr TSRMLS_DC); typedef const MYSQLND_FIELD * (*func_mysqlnd_res_meta__fetch_field_direct)(const MYSQLND_RES_METADATA * const meta, MYSQLND_FIELD_OFFSET fieldnr TSRMLS_DC);
typedef const MYSQLND_FIELD * (*func_mysqlnd_res_meta__fetch_fields)(MYSQLND_RES_METADATA * const meta TSRMLS_DC); typedef const MYSQLND_FIELD * (*func_mysqlnd_res_meta__fetch_fields)(MYSQLND_RES_METADATA * const meta TSRMLS_DC);
typedef MYSQLND_FIELD_OFFSET (*func_mysqlnd_res_meta__field_tell)(const MYSQLND_RES_METADATA * const meta TSRMLS_DC); typedef MYSQLND_FIELD_OFFSET (*func_mysqlnd_res_meta__field_tell)(const MYSQLND_RES_METADATA * const meta TSRMLS_DC);
typedef enum_func_status (*func_mysqlnd_res_meta__read_metadata)(MYSQLND_RES_METADATA * const meta, MYSQLND *conn TSRMLS_DC); typedef enum_func_status (*func_mysqlnd_res_meta__read_metadata)(MYSQLND_RES_METADATA * const meta, MYSQLND * conn TSRMLS_DC);
typedef MYSQLND_RES_METADATA * (*func_mysqlnd_res_meta__clone_metadata)(const MYSQLND_RES_METADATA * const meta, zend_bool persistent TSRMLS_DC); typedef MYSQLND_RES_METADATA * (*func_mysqlnd_res_meta__clone_metadata)(const MYSQLND_RES_METADATA * const meta, zend_bool persistent TSRMLS_DC);
typedef void (*func_mysqlnd_res_meta__free_metadata)(MYSQLND_RES_METADATA *meta, zend_bool persistent TSRMLS_DC); typedef void (*func_mysqlnd_res_meta__free_metadata)(MYSQLND_RES_METADATA * meta TSRMLS_DC);
struct st_mysqlnd_res_meta_methods struct st_mysqlnd_res_meta_methods
{ {
@ -559,10 +559,8 @@ typedef enum_func_status (*func_mysqlnd_stmt__fetch)(MYSQLND_STMT * const stmt,
typedef enum_func_status (*func_mysqlnd_stmt__bind_parameters)(MYSQLND_STMT * const stmt, MYSQLND_PARAM_BIND * const param_bind TSRMLS_DC); typedef enum_func_status (*func_mysqlnd_stmt__bind_parameters)(MYSQLND_STMT * const stmt, MYSQLND_PARAM_BIND * const param_bind TSRMLS_DC);
typedef enum_func_status (*func_mysqlnd_stmt__bind_one_parameter)(MYSQLND_STMT * const stmt, unsigned int param_no, zval * const zv, zend_uchar type TSRMLS_DC); typedef enum_func_status (*func_mysqlnd_stmt__bind_one_parameter)(MYSQLND_STMT * const stmt, unsigned int param_no, zval * const zv, zend_uchar type TSRMLS_DC);
typedef enum_func_status (*func_mysqlnd_stmt__refresh_bind_param)(MYSQLND_STMT * const stmt TSRMLS_DC); typedef enum_func_status (*func_mysqlnd_stmt__refresh_bind_param)(MYSQLND_STMT * const stmt TSRMLS_DC);
typedef void (*func_mysqlnd_stmt__set_param_bind_dtor)(MYSQLND_STMT * const stmt, void (*param_bind_dtor)(MYSQLND_PARAM_BIND * TSRMLS_DC) TSRMLS_DC);
typedef enum_func_status (*func_mysqlnd_stmt__bind_result)(MYSQLND_STMT * const stmt, MYSQLND_RESULT_BIND * const result_bind TSRMLS_DC); typedef enum_func_status (*func_mysqlnd_stmt__bind_result)(MYSQLND_STMT * const stmt, MYSQLND_RESULT_BIND * const result_bind TSRMLS_DC);
typedef enum_func_status (*func_mysqlnd_stmt__bind_one_result)(MYSQLND_STMT * const stmt, unsigned int param_no TSRMLS_DC); typedef enum_func_status (*func_mysqlnd_stmt__bind_one_result)(MYSQLND_STMT * const stmt, unsigned int param_no TSRMLS_DC);
typedef void (*func_mysqlnd_stmt__set_result_bind_dtor)(MYSQLND_STMT * const stmt, void (*result_bind_dtor)(MYSQLND_RESULT_BIND * TSRMLS_DC) TSRMLS_DC);
typedef enum_func_status (*func_mysqlnd_stmt__send_long_data)(MYSQLND_STMT * const stmt, unsigned int param_num, const char * const data, unsigned long length TSRMLS_DC); typedef enum_func_status (*func_mysqlnd_stmt__send_long_data)(MYSQLND_STMT * const stmt, unsigned int param_num, const char * const data, unsigned long length TSRMLS_DC);
typedef MYSQLND_RES * (*func_mysqlnd_stmt__get_parameter_metadata)(MYSQLND_STMT * const stmt TSRMLS_DC); typedef MYSQLND_RES * (*func_mysqlnd_stmt__get_parameter_metadata)(MYSQLND_STMT * const stmt TSRMLS_DC);
typedef MYSQLND_RES * (*func_mysqlnd_stmt__get_result_metadata)(MYSQLND_STMT * const stmt TSRMLS_DC); typedef MYSQLND_RES * (*func_mysqlnd_stmt__get_result_metadata)(MYSQLND_STMT * const stmt TSRMLS_DC);
@ -577,6 +575,10 @@ typedef const char * (*func_mysqlnd_stmt__get_error_str)(const MYSQLND_STMT * c
typedef const char * (*func_mysqlnd_stmt__get_sqlstate)(const MYSQLND_STMT * const stmt TSRMLS_DC); typedef const char * (*func_mysqlnd_stmt__get_sqlstate)(const MYSQLND_STMT * const stmt TSRMLS_DC);
typedef enum_func_status (*func_mysqlnd_stmt__get_attribute)(const MYSQLND_STMT * const stmt, enum mysqlnd_stmt_attr attr_type, void * const value TSRMLS_DC); typedef enum_func_status (*func_mysqlnd_stmt__get_attribute)(const MYSQLND_STMT * const stmt, enum mysqlnd_stmt_attr attr_type, void * const value TSRMLS_DC);
typedef enum_func_status (*func_mysqlnd_stmt__set_attribute)(MYSQLND_STMT * const stmt, enum mysqlnd_stmt_attr attr_type, const void * const value TSRMLS_DC); typedef enum_func_status (*func_mysqlnd_stmt__set_attribute)(MYSQLND_STMT * const stmt, enum mysqlnd_stmt_attr attr_type, const void * const value TSRMLS_DC);
typedef MYSQLND_PARAM_BIND *(*func_mysqlnd_stmt__alloc_param_bind)(MYSQLND_STMT * const stmt TSRMLS_DC);
typedef MYSQLND_RESULT_BIND*(*func_mysqlnd_stmt__alloc_result_bind)(MYSQLND_STMT * const stmt TSRMLS_DC);
typedef void (*func_mysqlnd_stmt__free_parameter_bind)(MYSQLND_STMT * const stmt, MYSQLND_PARAM_BIND * TSRMLS_DC);
typedef void (*func_mysqlnd_stmt__free_result_bind)(MYSQLND_STMT * const stmt, MYSQLND_RESULT_BIND * TSRMLS_DC);
struct st_mysqlnd_stmt_methods struct st_mysqlnd_stmt_methods
@ -598,10 +600,8 @@ struct st_mysqlnd_stmt_methods
func_mysqlnd_stmt__bind_parameters bind_parameters; func_mysqlnd_stmt__bind_parameters bind_parameters;
func_mysqlnd_stmt__bind_one_parameter bind_one_parameter; func_mysqlnd_stmt__bind_one_parameter bind_one_parameter;
func_mysqlnd_stmt__refresh_bind_param refresh_bind_param; func_mysqlnd_stmt__refresh_bind_param refresh_bind_param;
func_mysqlnd_stmt__set_param_bind_dtor set_param_bind_dtor;
func_mysqlnd_stmt__bind_result bind_result; func_mysqlnd_stmt__bind_result bind_result;
func_mysqlnd_stmt__bind_one_result bind_one_result; func_mysqlnd_stmt__bind_one_result bind_one_result;
func_mysqlnd_stmt__set_result_bind_dtor set_result_bind_dtor;
func_mysqlnd_stmt__send_long_data send_long_data; func_mysqlnd_stmt__send_long_data send_long_data;
func_mysqlnd_stmt__get_parameter_metadata get_parameter_metadata; func_mysqlnd_stmt__get_parameter_metadata get_parameter_metadata;
func_mysqlnd_stmt__get_result_metadata get_result_metadata; func_mysqlnd_stmt__get_result_metadata get_result_metadata;
@ -620,6 +620,12 @@ struct st_mysqlnd_stmt_methods
func_mysqlnd_stmt__get_attribute get_attribute; func_mysqlnd_stmt__get_attribute get_attribute;
func_mysqlnd_stmt__set_attribute set_attribute; func_mysqlnd_stmt__set_attribute set_attribute;
func_mysqlnd_stmt__alloc_param_bind alloc_parameter_bind;
func_mysqlnd_stmt__alloc_result_bind alloc_result_bind;
func_mysqlnd_stmt__free_parameter_bind free_parameter_bind;
func_mysqlnd_stmt__free_result_bind free_result_bind;
}; };
@ -748,6 +754,7 @@ struct st_mysqlnd_result_metadata
/* We need this to make fast allocs in rowp_read */ /* We need this to make fast allocs in rowp_read */
unsigned int bit_fields_count; unsigned int bit_fields_count;
size_t bit_fields_total_len; /* trailing \0 not counted */ size_t bit_fields_total_len; /* trailing \0 not counted */
zend_bool persistent;
struct st_mysqlnd_res_meta_methods *m; struct st_mysqlnd_res_meta_methods *m;
}; };
@ -803,6 +810,7 @@ struct st_mysqlnd_res
struct st_mysqlnd_packet_row * row_packet; struct st_mysqlnd_packet_row * row_packet;
MYSQLND_MEMORY_POOL * result_set_memory_pool; MYSQLND_MEMORY_POOL * result_set_memory_pool;
zend_bool persistent;
}; };
@ -834,6 +842,7 @@ struct st_mysqlnd_stmt
MYSQLND_PARAM_BIND *param_bind; MYSQLND_PARAM_BIND *param_bind;
MYSQLND_RESULT_BIND *result_bind; MYSQLND_RESULT_BIND *result_bind;
zend_bool result_zvals_separated_once; zend_bool result_zvals_separated_once;
zend_bool persistent;
MYSQLND_UPSERT_STATUS upsert_status; MYSQLND_UPSERT_STATUS upsert_status;
@ -848,9 +857,6 @@ struct st_mysqlnd_stmt
MYSQLND_CMD_BUFFER execute_cmd_buffer; MYSQLND_CMD_BUFFER execute_cmd_buffer;
unsigned int execute_count;/* count how many times the stmt was executed */ unsigned int execute_count;/* count how many times the stmt was executed */
void (*param_bind_dtor)(MYSQLND_PARAM_BIND * TSRMLS_DC);
void (*result_bind_dtor)(MYSQLND_RESULT_BIND * TSRMLS_DC);
struct st_mysqlnd_stmt_methods *m; struct st_mysqlnd_stmt_methods *m;
}; };

View file

@ -929,8 +929,8 @@ php_mysqlnd_rset_field_read(void *_packet, MYSQLND *conn TSRMLS_DC)
(len = php_mysqlnd_net_field_length(&p)) && (len = php_mysqlnd_net_field_length(&p)) &&
len != MYSQLND_NULL_LENGTH) len != MYSQLND_NULL_LENGTH)
{ {
DBG_INF_FMT("Def found, length %lu", len); DBG_INF_FMT("Def found, length %lu, persistent=%d", len, packet->persistent_alloc);
meta->def = mnd_emalloc(len + 1); meta->def = mnd_pemalloc(len + 1, packet->persistent_alloc);
memcpy(meta->def, p, len); memcpy(meta->def, p, len);
meta->def[len] = '\0'; meta->def[len] = '\0';
meta->def_length = len; meta->def_length = len;
@ -943,7 +943,8 @@ php_mysqlnd_rset_field_read(void *_packet, MYSQLND *conn TSRMLS_DC)
"shorter than expected", p - begin - packet->header.size); "shorter than expected", p - begin - packet->header.size);
} }
root_ptr = meta->root = mnd_emalloc(total_len); DBG_INF_FMT("allocing root. persistent=%d", packet->persistent_alloc);
root_ptr = meta->root = mnd_pemalloc(total_len, packet->persistent_alloc);
meta->root_len = total_len; meta->root_len = total_len;
/* Now do allocs */ /* Now do allocs */
if (meta->catalog && meta->catalog != mysqlnd_empty_string) { if (meta->catalog && meta->catalog != mysqlnd_empty_string) {

View file

@ -174,6 +174,7 @@ typedef struct st_mysqlnd_packet_res_field {
/* For table definitions, empty for result sets */ /* For table definitions, empty for result sets */
zend_bool skip_parsing; zend_bool skip_parsing;
zend_bool stupid_list_fields_eof; zend_bool stupid_list_fields_eof;
zend_bool persistent_alloc;
MYSQLND_ERROR_INFO error_info; MYSQLND_ERROR_INFO error_info;
} MYSQLND_PACKET_RES_FIELD; } MYSQLND_PACKET_RES_FIELD;