summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Hristov <andrey@php.net>2010-03-12 13:03:46 +0000
committerAndrey Hristov <andrey@php.net>2010-03-12 13:03:46 +0000
commit564a1d07f893137870820e882301fabdb3668227 (patch)
tree306e3596a465103bd78ba865c2d0dcc7c642e70c
parentd9dda48f8a7e182ed8c0f56e5fde9e367131a07a (diff)
downloadphp-git-564a1d07f893137870820e882301fabdb3668227.tar.gz
allow persistency of PS
-rw-r--r--ext/mysqli/mysqli_api.c8
-rw-r--r--ext/mysqlnd/mysqlnd.c6
-rw-r--r--ext/mysqlnd/mysqlnd.h24
-rw-r--r--ext/mysqlnd/mysqlnd_ps.c142
-rw-r--r--ext/mysqlnd/mysqlnd_result.c19
-rw-r--r--ext/mysqlnd/mysqlnd_result.h4
-rw-r--r--ext/mysqlnd/mysqlnd_result_meta.c29
-rw-r--r--ext/mysqlnd/mysqlnd_result_meta.h2
-rw-r--r--ext/mysqlnd/mysqlnd_structs.h24
-rw-r--r--ext/mysqlnd/mysqlnd_wireprotocol.c7
-rw-r--r--ext/mysqlnd/mysqlnd_wireprotocol.h1
11 files changed, 137 insertions, 129 deletions
diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c
index e4d61310b3..d2cc043da8 100644
--- a/ext/mysqli/mysqli_api.c
+++ b/ext/mysqli/mysqli_api.c
@@ -166,7 +166,7 @@ int mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, unsigned int argc, unsigned in
if (argc == start) {
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++) {
zend_uchar type;
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 */
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Undefined fieldtype %c (parameter %d)", types[i], i + start + 1);
ret = FAIL;
- efree(params);
+ mysqlnd_stmt_free_param_bind(stmt->stmt, params);
goto end;
}
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)
{
unsigned int i;
- MYSQLND_RESULT_BIND *params;
-
- params = safe_emalloc(argc - start, sizeof(MYSQLND_RESULT_BIND), 0);
+ MYSQLND_RESULT_BIND * params = mysqlnd_stmt_alloc_result_bind(stmt->stmt);
for (i = 0; i < (argc - start); i++) {
params[i].zv = *(args[i + start]);
}
diff --git a/ext/mysqlnd/mysqlnd.c b/ext/mysqlnd/mysqlnd.c
index 7940cead3a..3a31a1d7e6 100644
--- a/ext/mysqlnd/mysqlnd.c
+++ b/ext/mysqlnd/mysqlnd.c
@@ -142,8 +142,8 @@ MYSQLND_METHOD(mysqlnd_conn, free_contents)(MYSQLND *conn TSRMLS_DC)
mysqlnd_local_infile_default(conn);
if (conn->current_result) {
- conn->current_result->m.free_result_contents(conn->current_result TSRMLS_CC);
- mnd_efree(conn->current_result);
+ conn->current_result->m.free_result(conn->current_result, TRUE TSRMLS_CC);
+// mnd_pefree(conn->current_result, conn->current_result->persistent);
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.
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)) {
diff --git a/ext/mysqlnd/mysqlnd.h b/ext/mysqlnd/mysqlnd.h
index 43fd6a9324..c4aad5eae6 100644
--- a/ext/mysqlnd/mysqlnd.h
+++ b/ext/mysqlnd/mysqlnd.h
@@ -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_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);
@@ -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_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_send_long_data(s,p,d,l) (s)->m->send_long_data((s), (p), (d), (l) TSRMLS_CC)
-#define mysqlnd_stmt_bind_param(stmt,bind) (stmt)->m->bind_parameters((stmt), (bind) 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_refresh_bind_param(s) (s)->m->refresh_bind_param((s) 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_result(stmt,bind) (stmt)->m->bind_result((stmt), (bind) TSRMLS_CC)
-#define mysqlnd_stmt_bind_one_result(s,no) (s)->m->bind_one_result((s), (no) TSRMLS_CC)
-#define mysqlnd_stmt_set_result_bind_dtor(s,d) (s)->m->set_result_bind_dtor((s), (d) 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_send_long_data(stmt,p,d,l) (stmt)->m->send_long_data((stmt), (p), (d), (l) TSRMLS_CC)
+#define mysqlnd_stmt_alloc_param_bind(stmt) (stmt)->m->alloc_parameter_bind((stmt) TSRMLS_CC)
+#define mysqlnd_stmt_free_param_bind(stmt,bind) (stmt)->m->free_parameter_bind((stmt), (bind) TSRMLS_CC)
+#define mysqlnd_stmt_bind_param(stmt,bind) (stmt)->m->bind_parameters((stmt), (bind) 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_refresh_bind_param(s) (s)->m->refresh_bind_param((s) TSRMLS_CC)
+#define mysqlnd_stmt_alloc_result_bind(stmt) (stmt)->m->alloc_result_bind((stmt) TSRMLS_CC)
+#define mysqlnd_stmt_free_result_bind(stmt,bind) (stmt)->m->free_result_bind((stmt), (bind) TSRMLS_CC)
+#define mysqlnd_stmt_bind_result(stmt,bind) (stmt)->m->bind_result((stmt), (bind) 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_close(stmt, implicit) (stmt)->m->dtor((stmt), (implicit) TSRMLS_CC)
diff --git a/ext/mysqlnd/mysqlnd_ps.c b/ext/mysqlnd/mysqlnd_ps.c
index a22aaa3dca..4401c3d5d1 100644
--- a/ext/mysqlnd/mysqlnd_ps.c
+++ b/ext/mysqlnd/mysqlnd_ps.c
@@ -154,7 +154,7 @@ MYSQLND_METHOD(mysqlnd_stmt, get_result)(MYSQLND_STMT * const stmt TSRMLS_DC)
SET_EMPTY_ERROR(stmt->conn->error_info);
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);
@@ -335,9 +335,9 @@ MYSQLND_METHOD(mysqlnd_stmt, prepare)(MYSQLND_STMT * const stmt, const char * co
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,
- query_len, PROT_LAST, FALSE, TRUE TSRMLS_CC) ||
- FAIL == mysqlnd_stmt_read_prepare_response(stmt_to_prepare TSRMLS_CC)) {
+ 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) ||
+ FAIL == mysqlnd_stmt_read_prepare_response(stmt_to_prepare TSRMLS_CC))
+ {
goto fail;
}
@@ -355,7 +355,7 @@ MYSQLND_METHOD(mysqlnd_stmt, prepare)(MYSQLND_STMT * const stmt, const char * co
no metadata at prepare.
*/
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 */
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));
/* 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;
DBG_INF("PASS");
@@ -1248,8 +1248,8 @@ MYSQLND_METHOD(mysqlnd_stmt, bind_parameters)(MYSQLND_STMT * const stmt, MYSQLND
if (stmt->state < MYSQLND_STMT_PREPARED) {
SET_STMT_ERROR(stmt, CR_NO_PREPARE_STMT, UNKNOWN_SQLSTATE, mysqlnd_stmt_not_prepared);
DBG_ERR("not prepared");
- if (param_bind && stmt->param_bind_dtor) {
- stmt->param_bind_dtor(param_bind TSRMLS_CC);
+ if (param_bind) {
+ stmt->m->free_parameter_bind(stmt, param_bind TSRMLS_CC);
}
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);
}
}
- if (stmt->param_bind != param_bind && stmt->param_bind_dtor) {
- stmt->param_bind_dtor(stmt->param_bind TSRMLS_CC);
+ if (stmt->param_bind != param_bind) {
+ 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 */
static enum_func_status
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) {
SET_STMT_ERROR(stmt, CR_NO_PREPARE_STMT, UNKNOWN_SQLSTATE, mysqlnd_stmt_not_prepared);
- if (result_bind && stmt->result_bind_dtor) {
- stmt->result_bind_dtor(result_bind TSRMLS_CC);
+ if (result_bind) {
+ stmt->m->free_result_bind(stmt, result_bind TSRMLS_CC);
}
DBG_ERR("not prepared");
DBG_RETURN(FAIL);
@@ -1438,8 +1425,8 @@ MYSQLND_METHOD(mysqlnd_stmt, bind_result)(MYSQLND_STMT * const stmt,
*/
stmt->result_bind[i].bound = TRUE;
}
- } else if (result_bind && stmt->result_bind_dtor) {
- stmt->result_bind_dtor(result_bind TSRMLS_CC);
+ } else if (result_bind) {
+ stmt->m->free_result_bind(stmt, result_bind TSRMLS_CC);
}
DBG_INF("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 */
static uint64_t
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
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->m.fetch_row = result->m.fetch_row_normal_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->result_bind_dtor(stmt->result_bind TSRMLS_CC);
- }
+ stmt->m->free_result_bind(stmt, stmt->result_bind TSRMLS_CC);
stmt->result_bind = NULL;
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);
}
}
- if (stmt->param_bind_dtor) {
- stmt->param_bind_dtor(stmt->param_bind TSRMLS_CC);
- }
+ stmt->m->free_parameter_bind(stmt, stmt->param_bind TSRMLS_CC);
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) {
- mnd_efree(stmt->execute_cmd_buffer.buffer);
+ mnd_pefree(stmt->execute_cmd_buffer.buffer, stmt->persistent);
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);
ret = stmt->m->net_close(stmt, implicit TSRMLS_CC);
- mnd_efree(stmt);
+ mnd_pefree(stmt, stmt->persistent);
DBG_INF(ret == PASS? "PASS":"FAIL");
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_METHOD(mysqlnd_stmt, prepare),
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_one_parameter),
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_one_result),
- MYSQLND_METHOD(mysqlnd_stmt, set_result_bind_dtor),
MYSQLND_METHOD(mysqlnd_stmt, send_long_data),
MYSQLND_METHOD(mysqlnd_stmt, param_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, 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;
@@ -2069,15 +2082,16 @@ MYSQLND_CLASS_METHODS_END;
MYSQLND_STMT * _mysqlnd_stmt_init(MYSQLND * const conn TSRMLS_DC)
{
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_INF_FMT("stmt=%p", stmt);
+ stmt->persistent = conn->persistent;
stmt->m = mysqlnd_stmt_methods;
stmt->state = MYSQLND_STMT_INITTED;
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;
/*
@@ -2086,10 +2100,6 @@ MYSQLND_STMT * _mysqlnd_stmt_init(MYSQLND * const conn TSRMLS_DC)
or normal query result will close it then.
*/
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);
}
/* }}} */
@@ -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 */
void _mysqlnd_init_ps_subsystem()
diff --git a/ext/mysqlnd/mysqlnd_result.c b/ext/mysqlnd/mysqlnd_result.c
index 1c9af8472b..3739c60326 100644
--- a/ext/mysqlnd/mysqlnd_result.c
+++ b/ext/mysqlnd/mysqlnd_result.c
@@ -280,7 +280,7 @@ void mysqlnd_internal_free_result_contents(MYSQLND_RES *result TSRMLS_DC)
result->m.free_result_buffers(result TSRMLS_CC);
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;
}
@@ -301,7 +301,7 @@ void mysqlnd_internal_free_result(MYSQLND_RES *result TSRMLS_DC)
result->conn = NULL;
}
- mnd_efree(result);
+ mnd_pefree(result, result->persistent);
DBG_VOID_RETURN;
}
@@ -321,11 +321,11 @@ MYSQLND_METHOD(mysqlnd_res, read_result_metadata)(MYSQLND_RES *result, MYSQLND *
infrastructure!
*/
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 = 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 */
@@ -440,7 +440,7 @@ mysqlnd_query_read_result_set_header(MYSQLND *conn, MYSQLND_STMT *stmt TSRMLS_DC
/* PS has already allocated it */
conn->field_count = rset_header->field_count;
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 {
if (!stmt->result) {
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
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 {
/*
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 *
-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 *);
- MYSQLND_RES *ret = mnd_ecalloc(1, alloc_size);
+ MYSQLND_RES *ret = mnd_pecalloc(1, alloc_size, persistent);
DBG_ENTER("mysqlnd_result_init");
DBG_INF_FMT("field_count=%u", field_count);
+ ret->persistent = persistent;
ret->field_count = field_count;
ret->m.use_result = MYSQLND_METHOD(mysqlnd_res, use_result);
diff --git a/ext/mysqlnd/mysqlnd_result.h b/ext/mysqlnd/mysqlnd_result.h
index 1e9494419b..088fc69702 100644
--- a/ext/mysqlnd/mysqlnd_result.h
+++ b/ext/mysqlnd/mysqlnd_result.h
@@ -23,9 +23,9 @@
#ifndef 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 */
diff --git a/ext/mysqlnd/mysqlnd_result_meta.c b/ext/mysqlnd/mysqlnd_result_meta.c
index 5186f6d94f..0ceee4bac3 100644
--- a/ext/mysqlnd/mysqlnd_result_meta.c
+++ b/ext/mysqlnd/mysqlnd_result_meta.c
@@ -150,12 +150,13 @@ MYSQLND_METHOD(mysqlnd_res_meta, read_metadata)(MYSQLND_RES_METADATA * const met
DBG_ENTER("mysqlnd_res_meta::read_metadata");
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++) {
long idx;
if (meta->fields[i].root) {
/* 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;
}
@@ -260,21 +261,20 @@ MYSQLND_METHOD(mysqlnd_res_meta, read_metadata)(MYSQLND_RES_METADATA * const met
/* {{{ mysqlnd_res_meta::free */
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;
MYSQLND_FIELD *fields;
-
DBG_ENTER("mysqlnd_res_meta::free");
- DBG_INF_FMT("persistent=%d", persistent);
+ DBG_INF_FMT("persistent=%d", meta->persistent);
if ((fields = meta->fields)) {
DBG_INF("Freeing fields metadata");
i = meta->field_count;
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;
}
@@ -284,16 +284,16 @@ MYSQLND_METHOD(mysqlnd_res_meta, free)(MYSQLND_RES_METADATA *meta, zend_bool per
if (UG(unicode)) {
for (i = 0; i < meta->field_count; i++) {
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
- mnd_pefree(meta->zend_hash_keys, persistent);
+ mnd_pefree(meta->zend_hash_keys, meta->persistent);
meta->zend_hash_keys = NULL;
}
DBG_INF("Freeing metadata structure");
- mnd_pefree(meta, persistent);
+ mnd_pefree(meta, meta->persistent);
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_INF_FMT("persistent=%d", persistent);
+ new_meta->persistent = persistent;
new_meta->zend_hash_keys = mnd_pemalloc(len, persistent);
memcpy(new_meta->zend_hash_keys, meta->zend_hash_keys, len);
new_meta->m = meta->m;
@@ -435,16 +436,18 @@ MYSQLND_CLASS_METHODS_END;
/* {{{ mysqlnd_result_meta_init */
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;
DBG_ENTER("mysqlnd_result_meta_init");
+ DBG_INF_FMT("persistent=%d", persistent);
/* +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->fields = mnd_ecalloc(field_count + 1, sizeof(MYSQLND_FIELD));
- ret->zend_hash_keys = mnd_ecalloc(field_count, sizeof(struct mysqlnd_field_hash_key));
+ ret->fields = mnd_pecalloc(field_count + 1, sizeof(MYSQLND_FIELD), ret->persistent);
+ ret->zend_hash_keys = mnd_pecalloc(field_count, sizeof(struct mysqlnd_field_hash_key), ret->persistent);
ret->m = & mysqlnd_mysqlnd_res_meta_methods;
DBG_INF_FMT("meta=%p", ret);
diff --git a/ext/mysqlnd/mysqlnd_result_meta.h b/ext/mysqlnd/mysqlnd_result_meta.h
index 84e495d4c4..05d868e3a9 100644
--- a/ext/mysqlnd/mysqlnd_result_meta.h
+++ b/ext/mysqlnd/mysqlnd_result_meta.h
@@ -24,7 +24,7 @@
#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);
diff --git a/ext/mysqlnd/mysqlnd_structs.h b/ext/mysqlnd/mysqlnd_structs.h
index e9a7681b6e..e81ad59196 100644
--- a/ext/mysqlnd/mysqlnd_structs.h
+++ b/ext/mysqlnd/mysqlnd_structs.h
@@ -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_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 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 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
{
@@ -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_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 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_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 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);
@@ -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 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 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
@@ -598,10 +600,8 @@ struct st_mysqlnd_stmt_methods
func_mysqlnd_stmt__bind_parameters bind_parameters;
func_mysqlnd_stmt__bind_one_parameter bind_one_parameter;
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_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__get_parameter_metadata get_parameter_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__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 */
unsigned int bit_fields_count;
size_t bit_fields_total_len; /* trailing \0 not counted */
+ zend_bool persistent;
struct st_mysqlnd_res_meta_methods *m;
};
@@ -803,6 +810,7 @@ struct st_mysqlnd_res
struct st_mysqlnd_packet_row * row_packet;
MYSQLND_MEMORY_POOL * result_set_memory_pool;
+ zend_bool persistent;
};
@@ -834,6 +842,7 @@ struct st_mysqlnd_stmt
MYSQLND_PARAM_BIND *param_bind;
MYSQLND_RESULT_BIND *result_bind;
zend_bool result_zvals_separated_once;
+ zend_bool persistent;
MYSQLND_UPSERT_STATUS upsert_status;
@@ -848,9 +857,6 @@ struct st_mysqlnd_stmt
MYSQLND_CMD_BUFFER execute_cmd_buffer;
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;
};
diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.c b/ext/mysqlnd/mysqlnd_wireprotocol.c
index 5710377882..ea41a9a137 100644
--- a/ext/mysqlnd/mysqlnd_wireprotocol.c
+++ b/ext/mysqlnd/mysqlnd_wireprotocol.c
@@ -929,8 +929,8 @@ php_mysqlnd_rset_field_read(void *_packet, MYSQLND *conn TSRMLS_DC)
(len = php_mysqlnd_net_field_length(&p)) &&
len != MYSQLND_NULL_LENGTH)
{
- DBG_INF_FMT("Def found, length %lu", len);
- meta->def = mnd_emalloc(len + 1);
+ DBG_INF_FMT("Def found, length %lu, persistent=%d", len, packet->persistent_alloc);
+ meta->def = mnd_pemalloc(len + 1, packet->persistent_alloc);
memcpy(meta->def, p, len);
meta->def[len] = '\0';
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);
}
- 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;
/* Now do allocs */
if (meta->catalog && meta->catalog != mysqlnd_empty_string) {
diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.h b/ext/mysqlnd/mysqlnd_wireprotocol.h
index beb54845ed..6d5cdff421 100644
--- a/ext/mysqlnd/mysqlnd_wireprotocol.h
+++ b/ext/mysqlnd/mysqlnd_wireprotocol.h
@@ -174,6 +174,7 @@ typedef struct st_mysqlnd_packet_res_field {
/* For table definitions, empty for result sets */
zend_bool skip_parsing;
zend_bool stupid_list_fields_eof;
+ zend_bool persistent_alloc;
MYSQLND_ERROR_INFO error_info;
} MYSQLND_PACKET_RES_FIELD;