mirror of
https://github.com/php/php-src.git
synced 2024-09-21 18:07:23 +00:00
Refactoring mysqlnd (incompleted, only mysqlnd ext compilable)
This commit is contained in:
parent
accaaf9d6e
commit
6288bb8ffe
15
Zend/zend.h
15
Zend/zend.h
@ -317,6 +317,21 @@ void zend_error_noreturn(int type, const char *format, ...) __attribute__ ((nore
|
||||
#define Z_ADDREF(z) Z_ADDREF_P(&(z))
|
||||
#define Z_DELREF(z) Z_DELREF_P(&(z))
|
||||
|
||||
#define Z_TRY_ADDREF_P(pz) do { \
|
||||
if (Z_REFCOUNT_P((pz))) { \
|
||||
Z_ADDREF_P((pz)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define Z_TRY_DELREF_P(pz) do { \
|
||||
if (Z_REFCOUNT_P((pz))) { \
|
||||
Z_DELREF_P((pz)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define Z_TRY_ADDREF(z) Z_TRY_ADDREF_P(&(z))
|
||||
#define Z_TRY_DELREF(z) Z_TRY_DELREF_P(&(z))
|
||||
|
||||
#if ZEND_DEBUG
|
||||
#define zend_always_inline inline
|
||||
#define zend_never_inline
|
||||
|
@ -269,11 +269,11 @@ MYSQLND_METHOD(mysqlnd_debug, func_enter)(MYSQLND_DEBUG * self,
|
||||
const char ** p = self->skip_functions;
|
||||
while (*p) {
|
||||
if (*p == func_name) {
|
||||
zend_stack_push(&self->call_stack, "", sizeof(""));
|
||||
zend_stack_push(&self->call_stack, "");
|
||||
#ifndef MYSQLND_PROFILING_DISABLED
|
||||
if (self->flags & MYSQLND_DEBUG_PROFILE_CALLS) {
|
||||
uint64_t some_time = 0;
|
||||
zend_stack_push(&self->call_time_stack, &some_time, sizeof(some_time));
|
||||
zend_stack_push(&self->call_time_stack, &some_time);
|
||||
}
|
||||
#endif
|
||||
return FALSE;
|
||||
@ -282,16 +282,16 @@ MYSQLND_METHOD(mysqlnd_debug, func_enter)(MYSQLND_DEBUG * self,
|
||||
}
|
||||
}
|
||||
|
||||
zend_stack_push(&self->call_stack, func_name, func_name_len + 1);
|
||||
zend_stack_push(&self->call_stack, func_name);
|
||||
#ifndef MYSQLND_PROFILING_DISABLED
|
||||
if (self->flags & MYSQLND_DEBUG_PROFILE_CALLS) {
|
||||
uint64_t some_time = 0;
|
||||
zend_stack_push(&self->call_time_stack, &some_time, sizeof(some_time));
|
||||
zend_stack_push(&self->call_time_stack, &some_time);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (zend_hash_num_elements(&self->not_filtered_functions) &&
|
||||
0 == zend_hash_exists(&self->not_filtered_functions, func_name, strlen(func_name) + 1))
|
||||
0 == zend_hash_str_exists(&self->not_filtered_functions, func_name, strlen(func_name)))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@ -336,11 +336,11 @@ MYSQLND_METHOD(mysqlnd_debug, func_leave)(MYSQLND_DEBUG * self, unsigned int lin
|
||||
return PASS;
|
||||
}
|
||||
|
||||
zend_stack_top(&self->call_stack, (void **)&func_name);
|
||||
func_name = zend_stack_top(&self->call_stack);
|
||||
|
||||
#ifndef MYSQLND_PROFILING_DISABLED
|
||||
if (profile_calls) {
|
||||
zend_stack_top(&self->call_time_stack, (void **)&mine_non_own_time_ptr);
|
||||
mine_non_own_time_ptr = zend_stack_top(&self->call_time_stack);
|
||||
mine_non_own_time = *mine_non_own_time_ptr;
|
||||
zend_stack_del_top(&self->call_time_stack); /* callee - removing ourselves */
|
||||
}
|
||||
@ -349,7 +349,7 @@ MYSQLND_METHOD(mysqlnd_debug, func_leave)(MYSQLND_DEBUG * self, unsigned int lin
|
||||
if (func_name[0] == '\0') {
|
||||
; /* don't log that function */
|
||||
} else if (!zend_hash_num_elements(&self->not_filtered_functions) ||
|
||||
1 == zend_hash_exists(&self->not_filtered_functions, func_name, strlen(func_name) + 1))
|
||||
1 == zend_hash_str_exists(&self->not_filtered_functions, func_name, strlen(func_name)))
|
||||
{
|
||||
#ifndef MYSQLND_PROFILING_DISABLED
|
||||
if (FALSE == profile_calls) {
|
||||
@ -367,7 +367,7 @@ MYSQLND_METHOD(mysqlnd_debug, func_leave)(MYSQLND_DEBUG * self, unsigned int lin
|
||||
func_name, (unsigned int) call_time, (unsigned int) own_time, (unsigned int) mine_non_own_time
|
||||
);
|
||||
|
||||
if (SUCCESS == zend_hash_find(&self->function_profiles, func_name, func_name_len + 1, (void **) &f_profile)) {
|
||||
if ((f_profile = zend_hash_str_find_ptr(&self->function_profiles, func_name, func_name_len)) != NULL) {
|
||||
/* found */
|
||||
if (f_profile) {
|
||||
if (mine_non_own_time < f_profile->min_in_calls) {
|
||||
@ -411,16 +411,16 @@ MYSQLND_METHOD(mysqlnd_debug, func_leave)(MYSQLND_DEBUG * self, unsigned int lin
|
||||
f_profile->min_total = f_profile->max_total = f_profile->avg_total = call_time;
|
||||
f_profile->min_own = f_profile->max_own = f_profile->avg_own = own_time;
|
||||
f_profile->calls = 1;
|
||||
zend_hash_add(&self->function_profiles, func_name, func_name_len+1, f_profile, sizeof(struct st_mysqlnd_dbg_function_profile), NULL);
|
||||
zend_hash_str_add_mem(&self->function_profiles, func_name, func_name_len, f_profile, sizeof(struct st_mysqlnd_dbg_function_profile));
|
||||
}
|
||||
if ((uint) zend_stack_count(&self->call_time_stack)) {
|
||||
uint64_t parent_non_own_time = 0;
|
||||
|
||||
zend_stack_top(&self->call_time_stack, (void **)&parent_non_own_time_ptr);
|
||||
parent_non_own_time_ptr = zend_stack_top(&self->call_time_stack);
|
||||
parent_non_own_time = *parent_non_own_time_ptr;
|
||||
parent_non_own_time += call_time;
|
||||
zend_stack_del_top(&self->call_time_stack); /* the caller */
|
||||
zend_stack_push(&self->call_time_stack, &parent_non_own_time, sizeof(parent_non_own_time)); /* add back the caller */
|
||||
zend_stack_push(&self->call_time_stack, &parent_non_own_time); /* add back the caller */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -440,29 +440,22 @@ MYSQLND_METHOD(mysqlnd_debug, close)(MYSQLND_DEBUG * self)
|
||||
#ifndef MYSQLND_PROFILING_DISABLED
|
||||
if (!(self->flags & MYSQLND_DEBUG_FLUSH) && (self->flags & MYSQLND_DEBUG_PROFILE_CALLS)) {
|
||||
struct st_mysqlnd_dbg_function_profile * f_profile;
|
||||
HashPosition pos_values;
|
||||
zend_string *string_key = NULL;
|
||||
|
||||
self->m->log_va(self, __LINE__, __FILE__, 0, "info : ",
|
||||
"number of functions: %d", zend_hash_num_elements(&self->function_profiles));
|
||||
zend_hash_internal_pointer_reset_ex(&self->function_profiles, &pos_values);
|
||||
while (zend_hash_get_current_data_ex(&self->function_profiles, (void **) &f_profile, &pos_values) == SUCCESS) {
|
||||
char *string_key = NULL;
|
||||
uint string_key_len;
|
||||
ulong num_key;
|
||||
|
||||
zend_hash_get_current_key_ex(&self->function_profiles, &string_key, &string_key_len, &num_key, 0, &pos_values);
|
||||
|
||||
ZEND_HASH_FOREACH_STR_KEY_PTR(&self->function_profiles, string_key, f_profile) {
|
||||
self->m->log_va(self, __LINE__, __FILE__, -1, "info : ",
|
||||
"%-40s\tcalls=%5llu own_slow=%5llu in_calls_slow=%5llu total_slow=%5llu"
|
||||
" min_own=%5llu max_own=%7llu avg_own=%7llu "
|
||||
" min_in_calls=%5llu max_in_calls=%7llu avg_in_calls=%7llu"
|
||||
" min_total=%5llu max_total=%7llu avg_total=%7llu"
|
||||
,string_key
|
||||
,string_key->val
|
||||
,(uint64_t) f_profile->calls
|
||||
,(uint64_t) f_profile->own_underporm_calls
|
||||
,(uint64_t) f_profile->in_calls_underporm_calls
|
||||
,(uint64_t) f_profile->total_underporm_calls
|
||||
|
||||
|
||||
,(uint64_t) f_profile->min_own
|
||||
,(uint64_t) f_profile->max_own
|
||||
,(uint64_t) f_profile->avg_own
|
||||
@ -473,8 +466,7 @@ MYSQLND_METHOD(mysqlnd_debug, close)(MYSQLND_DEBUG * self)
|
||||
,(uint64_t) f_profile->max_total
|
||||
,(uint64_t) f_profile->avg_total
|
||||
);
|
||||
zend_hash_move_forward_ex(&self->function_profiles, &pos_values);
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -592,8 +584,8 @@ MYSQLND_METHOD(mysqlnd_debug, set_mode)(MYSQLND_DEBUG * self, const char * const
|
||||
memcpy(func_name, mode + i + 1, func_name_len);
|
||||
func_name[func_name_len] = '\0';
|
||||
|
||||
zend_hash_add_empty_element(&self->not_filtered_functions,
|
||||
func_name, func_name_len + 1);
|
||||
zend_hash_str_add_empty_element(&self->not_filtered_functions,
|
||||
func_name, func_name_len);
|
||||
i = j;
|
||||
}
|
||||
if (mode[j] == ':') {
|
||||
@ -730,8 +722,8 @@ mysqlnd_debug_init(const char * skip_functions[] TSRMLS_DC)
|
||||
#endif
|
||||
ret->nest_level_limit = 0;
|
||||
ret->pid = getpid();
|
||||
zend_stack_init(&ret->call_stack);
|
||||
zend_stack_init(&ret->call_time_stack);
|
||||
zend_stack_init(&ret->call_stack, sizeof(char *));
|
||||
zend_stack_init(&ret->call_time_stack, sizeof(uint64_t));
|
||||
zend_hash_init(&ret->not_filtered_functions, 0, NULL, NULL, 0);
|
||||
zend_hash_init(&ret->function_profiles, 0, NULL, NULL, 0);
|
||||
|
||||
|
@ -106,9 +106,9 @@ mysqlnd_plugin_subsystem_init(TSRMLS_D)
|
||||
|
||||
/* {{{ mysqlnd_plugin_end_apply_func */
|
||||
int
|
||||
mysqlnd_plugin_end_apply_func(void *pDest TSRMLS_DC)
|
||||
mysqlnd_plugin_end_apply_func(zval *el TSRMLS_DC)
|
||||
{
|
||||
struct st_mysqlnd_plugin_header * plugin_header = *(struct st_mysqlnd_plugin_header **) pDest;
|
||||
struct st_mysqlnd_plugin_header * plugin_header = (struct st_mysqlnd_plugin_header *)Z_PTR_P(el);
|
||||
if (plugin_header->m.plugin_shutdown) {
|
||||
plugin_header->m.plugin_shutdown(plugin_header TSRMLS_CC);
|
||||
}
|
||||
@ -141,7 +141,7 @@ PHPAPI unsigned int mysqlnd_plugin_register_ex(struct st_mysqlnd_plugin_header *
|
||||
{
|
||||
if (plugin) {
|
||||
if (plugin->plugin_api_version == MYSQLND_PLUGIN_API_VERSION) {
|
||||
zend_hash_update(&mysqlnd_registered_plugins, plugin->plugin_name, strlen(plugin->plugin_name) + 1, &plugin, sizeof(void *), NULL);
|
||||
zend_hash_str_update_ptr(&mysqlnd_registered_plugins, plugin->plugin_name, strlen(plugin->plugin_name), plugin);
|
||||
} else {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Plugin API version mismatch while loading plugin %s. Expected %d, got %d",
|
||||
plugin->plugin_name, MYSQLND_PLUGIN_API_VERSION, plugin->plugin_api_version);
|
||||
@ -157,7 +157,7 @@ PHPAPI unsigned int mysqlnd_plugin_register_ex(struct st_mysqlnd_plugin_header *
|
||||
PHPAPI void * _mysqlnd_plugin_find(const char * const name TSRMLS_DC)
|
||||
{
|
||||
void * plugin;
|
||||
if (SUCCESS == zend_hash_find(&mysqlnd_registered_plugins, name, strlen(name) + 1, (void **) &plugin)) {
|
||||
if ((plugin = zend_hash_str_find_ptr(&mysqlnd_registered_plugins, name, strlen(name))) != NULL) {
|
||||
return (void *)*(char **) plugin;
|
||||
}
|
||||
return NULL;
|
||||
@ -173,22 +173,18 @@ PHPAPI void _mysqlnd_plugin_apply_with_argument(apply_func_arg_t apply_func, voi
|
||||
* zend_hash_apply_with_argument nor zend_hash_internal_pointer_reset and
|
||||
* friends
|
||||
*/
|
||||
uint idx;
|
||||
Bucket *p;
|
||||
zval *val;
|
||||
int result;
|
||||
|
||||
for (idx = 0; idx < mysqlnd_registered_plugins.nNumUsed; idx++) {
|
||||
p = mysqlnd_registered_plugins.arData + idx;
|
||||
if (!p->xData) continue;
|
||||
result = apply_func(HASH_DATA(&mysqlnd_registered_plugins, p), argument TSRMLS_CC);
|
||||
|
||||
ZEND_HASH_FOREACH_VAL(&mysqlnd_registered_plugins, val) {
|
||||
result = apply_func(val, argument TSRMLS_CC);
|
||||
if (result & ZEND_HASH_APPLY_REMOVE) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "mysqlnd_plugin_apply_with_argument must not remove table entries");
|
||||
}
|
||||
if (result & ZEND_HASH_APPLY_STOP) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
@ -648,7 +648,7 @@ MYSQLND_METHOD(mysqlnd_stmt, execute)(MYSQLND_STMT * const s TSRMLS_DC)
|
||||
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_copy_ctor(&stmt->result_bind[i].zv);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -682,7 +682,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++;
|
||||
}
|
||||
}
|
||||
@ -753,9 +753,9 @@ 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,
|
||||
@ -774,8 +774,9 @@ 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) {
|
||||
if (Z_TYPE(current_row[i]) == IS_STRING) {
|
||||
unsigned long len = Z_STRLEN(current_row[i]);
|
||||
if (meta->fields[i].max_length < len) {
|
||||
meta->fields[i].max_length = len;
|
||||
}
|
||||
@ -787,14 +788,12 @@ mysqlnd_stmt_fetch_row_buffered(MYSQLND_RES * result, void * param, unsigned int
|
||||
for (i = 0; i < result->field_count; i++) {
|
||||
/* 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(&stmt->result_bind[i].zv);
|
||||
#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
|
||||
@ -803,13 +802,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(&stmt->result_bind[i].zv, ¤t_row[i]);
|
||||
#ifndef WE_DONT_COPY_IN_BUFFERED_AND_UNBUFFERED_BECAUSEOF_IS_REF
|
||||
zval_copy_ctor(stmt->result_bind[i].zv);
|
||||
zval_copy_ctor(&stmt->result_bind[i].zv);
|
||||
#endif
|
||||
} else {
|
||||
ZVAL_NULL(stmt->result_bind[i].zv);
|
||||
ZVAL_NULL(&stmt->result_bind[i].zv);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -891,19 +889,20 @@ mysqlnd_stmt_fetch_row_unbuffered(MYSQLND_RES * result, void * param, unsigned i
|
||||
|
||||
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];
|
||||
/*
|
||||
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(&stmt->result_bind[i].zv);
|
||||
#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 < (unsigned long) Z_STRLEN_P(data))) {
|
||||
meta->fields[i].max_length = Z_STRLEN_P(data);
|
||||
}
|
||||
stmt->result_bind[i].zv->value = data->value;
|
||||
ZVAL_COPY_VALUE(&stmt->result_bind[i].zv, data);
|
||||
/* copied data, thus also the ownership. Thus null data */
|
||||
ZVAL_NULL(data);
|
||||
}
|
||||
@ -1071,21 +1070,23 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES * result, void * param, unsigned int f
|
||||
/* 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];
|
||||
/*
|
||||
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(&stmt->result_bind[i].zv);
|
||||
#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 < (unsigned long) Z_STRLEN_P(data))) {
|
||||
meta->fields[i].max_length = Z_STRLEN_P(data);
|
||||
}
|
||||
stmt->result_bind[i].zv->value = data->value;
|
||||
ZVAL_COPY_VALUE(&stmt->result_bind[i].zv, data);
|
||||
/* copied data, thus also the ownership. Thus null data */
|
||||
ZVAL_NULL(data);
|
||||
}
|
||||
@ -1169,7 +1170,7 @@ MYSQLND_METHOD(mysqlnd_stmt, fetch)(MYSQLND_STMT * const s, zend_bool * const fe
|
||||
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.
|
||||
@ -1182,8 +1183,8 @@ 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_dtor(&stmt->result_bind[i].zv);
|
||||
ZVAL_NULL(&stmt->result_bind[i].zv);
|
||||
}
|
||||
}
|
||||
stmt->result_zvals_separated_once = TRUE;
|
||||
@ -1439,9 +1440,7 @@ 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);
|
||||
@ -1454,7 +1453,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;
|
||||
@ -1507,14 +1506,12 @@ MYSQLND_METHOD(mysqlnd_stmt, bind_one_parameter)(MYSQLND_STMT * const s, unsigne
|
||||
Z_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;
|
||||
@ -1590,8 +1587,9 @@ MYSQLND_METHOD(mysqlnd_stmt, bind_result)(MYSQLND_STMT * const s,
|
||||
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
|
||||
@ -1645,7 +1643,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
|
||||
@ -2010,14 +2008,15 @@ 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));
|
||||
DBG_INF_FMT("%u has refcount=%u", i,
|
||||
Z_REFCOUNTED(stmt->result_bind[i].zv)? Z_REFCOUNT(stmt->result_bind[i].zv) : 0);
|
||||
/*
|
||||
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) {
|
||||
if (Z_REFCOUNTED(stmt->result_bind[i].zv) && Z_REFCOUNT(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);
|
||||
zval_copy_ctor(&stmt->result_bind[i].zv);
|
||||
#endif
|
||||
zval_ptr_dtor(&stmt->result_bind[i].zv);
|
||||
} else {
|
||||
@ -2063,14 +2062,16 @@ 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));
|
||||
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);
|
||||
/*
|
||||
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) {
|
||||
if (Z_REFCOUNTED(stmt->result_bind[param_no].zv) && Z_REFCOUNT(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);
|
||||
zval_copy_ctor(&stmt->result_bind[param_no].zv);
|
||||
#endif
|
||||
zval_ptr_dtor(&stmt->result_bind[param_no].zv);
|
||||
} else {
|
||||
@ -2080,7 +2081,7 @@ mysqlnd_stmt_separate_one_result_bind(MYSQLND_STMT * const s, unsigned int param
|
||||
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);
|
||||
ZVAL_NULL(&stmt->result_bind[param_no].zv);
|
||||
#endif
|
||||
zval_ptr_dtor(&stmt->result_bind[param_no].zv);
|
||||
}
|
||||
@ -2115,9 +2116,7 @@ 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);
|
||||
stmt->param_bind = NULL;
|
||||
|
@ -117,7 +117,7 @@ ps_fetch_from_1_to_8_bytes(zval * zv, const MYSQLND_FIELD * const field, unsigne
|
||||
}
|
||||
|
||||
if (tmp_len) {
|
||||
ZVAL_STRINGL(zv, tmp, tmp_len, 1);
|
||||
ZVAL_STRINGL(zv, tmp, tmp_len);
|
||||
}
|
||||
(*row)+= byte_count;
|
||||
DBG_VOID_RETURN;
|
||||
@ -236,7 +236,7 @@ ps_fetch_time(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_le
|
||||
length = mnd_sprintf(&value, 0, "%s%02u:%02u:%02u", (t.neg ? "-" : ""), t.hour, t.minute, t.second);
|
||||
|
||||
DBG_INF_FMT("%s", value);
|
||||
ZVAL_STRINGL(zv, value, length, 1);
|
||||
ZVAL_STRINGL(zv, value, length);
|
||||
mnd_sprintf_free(value);
|
||||
DBG_VOID_RETURN;
|
||||
}
|
||||
@ -273,7 +273,7 @@ ps_fetch_date(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_le
|
||||
length = mnd_sprintf(&value, 0, "%04u-%02u-%02u", t.year, t.month, t.day);
|
||||
|
||||
DBG_INF_FMT("%s", value);
|
||||
ZVAL_STRINGL(zv, value, length, 1);
|
||||
ZVAL_STRINGL(zv, value, length);
|
||||
mnd_sprintf_free(value);
|
||||
DBG_VOID_RETURN;
|
||||
}
|
||||
@ -317,7 +317,7 @@ ps_fetch_datetime(zval * zv, const MYSQLND_FIELD * const field, unsigned int pac
|
||||
length = mnd_sprintf(&value, 0, "%04u-%02u-%02u %02u:%02u:%02u", t.year, t.month, t.day, t.hour, t.minute, t.second);
|
||||
|
||||
DBG_INF_FMT("%s", value);
|
||||
ZVAL_STRINGL(zv, value, length, 1);
|
||||
ZVAL_STRINGL(zv, value, length);
|
||||
mnd_sprintf_free(value);
|
||||
DBG_VOID_RETURN;
|
||||
}
|
||||
@ -336,7 +336,7 @@ ps_fetch_string(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_
|
||||
DBG_ENTER("ps_fetch_string");
|
||||
DBG_INF_FMT("len = %lu", length);
|
||||
DBG_INF("copying from the row buffer");
|
||||
ZVAL_STRINGL(zv, (char *)*row, length, 1);
|
||||
ZVAL_STRINGL(zv, (char *)*row, length);
|
||||
|
||||
(*row) += length;
|
||||
DBG_VOID_RETURN;
|
||||
@ -499,16 +499,15 @@ void _mysqlnd_init_ps_fetch_subsystem()
|
||||
|
||||
/* {{{ mysqlnd_stmt_copy_it */
|
||||
static enum_func_status
|
||||
mysqlnd_stmt_copy_it(zval *** copies, zval * original, unsigned int param_count, unsigned int current TSRMLS_DC)
|
||||
mysqlnd_stmt_copy_it(zval ** copies, zval * original, unsigned int param_count, unsigned int current TSRMLS_DC)
|
||||
{
|
||||
if (!*copies) {
|
||||
*copies = mnd_ecalloc(param_count, sizeof(zval *));
|
||||
*copies = mnd_ecalloc(param_count, sizeof(zval));
|
||||
}
|
||||
if (*copies) {
|
||||
MAKE_STD_ZVAL((*copies)[current]);
|
||||
*(*copies)[current] = *original;
|
||||
Z_SET_REFCOUNT_P((*copies)[current], 1);
|
||||
zval_copy_ctor((*copies)[current]);
|
||||
ZVAL_COPY(&(*copies)[current], original);
|
||||
//????Z_SET_REFCOUNT_P((*copies)[current], 1);
|
||||
//zval_copy_ctor((*copies)[current]);
|
||||
return PASS;
|
||||
}
|
||||
return FAIL;
|
||||
@ -518,14 +517,12 @@ mysqlnd_stmt_copy_it(zval *** copies, zval * original, unsigned int param_count,
|
||||
|
||||
/* {{{ mysqlnd_stmt_free_copies */
|
||||
static void
|
||||
mysqlnd_stmt_free_copies(MYSQLND_STMT_DATA * stmt, zval ** copies TSRMLS_DC)
|
||||
mysqlnd_stmt_free_copies(MYSQLND_STMT_DATA * stmt, zval *copies TSRMLS_DC)
|
||||
{
|
||||
if (copies) {
|
||||
unsigned int i;
|
||||
for (i = 0; i < stmt->param_count; i++) {
|
||||
if (copies[i]) {
|
||||
zval_ptr_dtor(&copies[i]);
|
||||
}
|
||||
zval_ptr_dtor(&copies[i]);
|
||||
}
|
||||
mnd_efree(copies);
|
||||
}
|
||||
@ -563,39 +560,34 @@ mysqlnd_stmt_execute_check_n_enlarge_buffer(zend_uchar **buf, zend_uchar **p, si
|
||||
|
||||
/* {{{ mysqlnd_stmt_execute_prepare_param_types */
|
||||
static enum_func_status
|
||||
mysqlnd_stmt_execute_prepare_param_types(MYSQLND_STMT_DATA * stmt, zval *** copies_param, int * resend_types_next_time TSRMLS_DC)
|
||||
mysqlnd_stmt_execute_prepare_param_types(MYSQLND_STMT_DATA * stmt, zval ** copies_param, int * resend_types_next_time TSRMLS_DC)
|
||||
{
|
||||
unsigned int i;
|
||||
DBG_ENTER("mysqlnd_stmt_execute_prepare_param_types");
|
||||
for (i = 0; i < stmt->param_count; i++) {
|
||||
short current_type = stmt->param_bind[i].type;
|
||||
|
||||
if (Z_TYPE_P(stmt->param_bind[i].zv) != IS_NULL && (current_type == MYSQL_TYPE_LONG || current_type == MYSQL_TYPE_LONGLONG)) {
|
||||
zval ** copies;
|
||||
if (Z_TYPE(stmt->param_bind[i].zv) != IS_NULL && (current_type == MYSQL_TYPE_LONG || current_type == MYSQL_TYPE_LONGLONG)) {
|
||||
/* always copy the var, because we do many conversions */
|
||||
if (Z_TYPE_P(stmt->param_bind[i].zv) != IS_LONG &&
|
||||
PASS != mysqlnd_stmt_copy_it(copies_param, stmt->param_bind[i].zv, stmt->param_count, i TSRMLS_CC))
|
||||
if (Z_TYPE(stmt->param_bind[i].zv) != IS_LONG &&
|
||||
PASS != mysqlnd_stmt_copy_it(copies_param, &stmt->param_bind[i].zv, stmt->param_count, i TSRMLS_CC))
|
||||
{
|
||||
SET_OOM_ERROR(*stmt->error_info);
|
||||
goto end;
|
||||
}
|
||||
copies = *copies_param;
|
||||
/*
|
||||
if it doesn't fit in a long send it as a string.
|
||||
Check bug #52891 : Wrong data inserted with mysqli/mysqlnd when using bind_param, value > LONG_MAX
|
||||
*/
|
||||
if (Z_TYPE_P(stmt->param_bind[i].zv) != IS_LONG) {
|
||||
zval *tmp_data = (copies && copies[i])? copies[i]: stmt->param_bind[i].zv;
|
||||
if (Z_TYPE(stmt->param_bind[i].zv) != IS_LONG) {
|
||||
zval *tmp_data = (*copies_param && !Z_ISUNDEF((*copies_param)[i]))? &(*copies_param)[i]: &stmt->param_bind[i].zv;
|
||||
/*
|
||||
Because converting to double and back to long can lead
|
||||
to losing precision we need second variable. Conversion to double is to see if
|
||||
value is too big for a long. As said, precision could be lost.
|
||||
*/
|
||||
zval *tmp_data_copy;
|
||||
MAKE_STD_ZVAL(tmp_data_copy);
|
||||
*tmp_data_copy = *tmp_data;
|
||||
Z_SET_REFCOUNT_P(tmp_data_copy, 1);
|
||||
zval_copy_ctor(tmp_data_copy);
|
||||
zval tmp_data_copy;
|
||||
ZVAL_COPY(&tmp_data_copy, tmp_data);
|
||||
convert_to_double_ex(&tmp_data_copy);
|
||||
|
||||
/*
|
||||
@ -603,11 +595,11 @@ mysqlnd_stmt_execute_prepare_param_types(MYSQLND_STMT_DATA * stmt, zval *** copi
|
||||
Check bug #52891 : Wrong data inserted with mysqli/mysqlnd when using bind_param, value > LONG_MAX
|
||||
We do transformation here, which will be used later when sending types. The code later relies on this.
|
||||
*/
|
||||
if (Z_DVAL_P(tmp_data_copy) > LONG_MAX || Z_DVAL_P(tmp_data_copy) < LONG_MIN) {
|
||||
if (Z_DVAL(tmp_data_copy) > LONG_MAX || Z_DVAL(tmp_data_copy) < LONG_MIN) {
|
||||
stmt->send_types_to_server = *resend_types_next_time = 1;
|
||||
convert_to_string_ex(&tmp_data);
|
||||
convert_to_string_ex(tmp_data);
|
||||
} else {
|
||||
convert_to_long_ex(&tmp_data);
|
||||
convert_to_long_ex(tmp_data);
|
||||
}
|
||||
|
||||
zval_ptr_dtor(&tmp_data_copy);
|
||||
@ -623,7 +615,7 @@ end:
|
||||
|
||||
/* {{{ mysqlnd_stmt_execute_store_types */
|
||||
static void
|
||||
mysqlnd_stmt_execute_store_types(MYSQLND_STMT_DATA * stmt, zval ** copies, zend_uchar ** p)
|
||||
mysqlnd_stmt_execute_store_types(MYSQLND_STMT_DATA * stmt, zval * copies, zend_uchar ** p)
|
||||
{
|
||||
unsigned int i;
|
||||
for (i = 0; i < stmt->param_count; i++) {
|
||||
@ -634,13 +626,13 @@ mysqlnd_stmt_execute_store_types(MYSQLND_STMT_DATA * stmt, zval ** copies, zend_
|
||||
current_type = MYSQL_TYPE_LONGLONG;
|
||||
}
|
||||
#endif
|
||||
if (Z_TYPE_P(stmt->param_bind[i].zv) != IS_NULL && (current_type == MYSQL_TYPE_LONG || current_type == MYSQL_TYPE_LONGLONG)) {
|
||||
if (!Z_ISNULL(stmt->param_bind[i].zv) && (current_type == MYSQL_TYPE_LONG || current_type == MYSQL_TYPE_LONGLONG)) {
|
||||
/*
|
||||
if it doesn't fit in a long send it as a string.
|
||||
Check bug #52891 : Wrong data inserted with mysqli/mysqlnd when using bind_param, value > LONG_MAX
|
||||
*/
|
||||
if (Z_TYPE_P(stmt->param_bind[i].zv) != IS_LONG) {
|
||||
const zval *tmp_data = (copies && copies[i])? copies[i]: stmt->param_bind[i].zv;
|
||||
if (Z_TYPE(stmt->param_bind[i].zv) != IS_LONG) {
|
||||
const zval *tmp_data = (copies && !Z_ISUNDEF(copies[i]))? &copies[i]: &stmt->param_bind[i].zv;
|
||||
/*
|
||||
In case of IS_LONG we do nothing, it is ok, in case of string, we just need to set current_type.
|
||||
The actual transformation has been performed several dozens line above.
|
||||
@ -665,22 +657,22 @@ mysqlnd_stmt_execute_store_types(MYSQLND_STMT_DATA * stmt, zval ** copies, zend_
|
||||
|
||||
/* {{{ mysqlnd_stmt_execute_calculate_param_values_size */
|
||||
static enum_func_status
|
||||
mysqlnd_stmt_execute_calculate_param_values_size(MYSQLND_STMT_DATA * stmt, zval *** copies_param, size_t * data_size TSRMLS_DC)
|
||||
mysqlnd_stmt_execute_calculate_param_values_size(MYSQLND_STMT_DATA * stmt, zval ** copies_param, size_t * data_size TSRMLS_DC)
|
||||
{
|
||||
unsigned int i;
|
||||
DBG_ENTER("mysqlnd_stmt_execute_calculate_param_values_size");
|
||||
for (i = 0; i < stmt->param_count; i++) {
|
||||
unsigned short is_longlong = 0;
|
||||
unsigned int j;
|
||||
zval *the_var = stmt->param_bind[i].zv;
|
||||
zval *the_var = &stmt->param_bind[i].zv;
|
||||
|
||||
if (!the_var || (stmt->param_bind[i].type != MYSQL_TYPE_LONG_BLOB && Z_TYPE_P(the_var) == IS_NULL)) {
|
||||
continue;
|
||||
}
|
||||
for (j = i + 1; j < stmt->param_count; j++) {
|
||||
if (stmt->param_bind[j].zv == the_var) {
|
||||
if (&stmt->param_bind[j].zv == the_var) {
|
||||
/* Double binding of the same zval, make a copy */
|
||||
if (!*copies_param || !(*copies_param)[i]) {
|
||||
if (!*copies_param || Z_ISUNDEF((*copies_param)[i])) {
|
||||
if (PASS != mysqlnd_stmt_copy_it(copies_param, the_var, stmt->param_count, i TSRMLS_CC)) {
|
||||
SET_OOM_ERROR(*stmt->error_info);
|
||||
goto end;
|
||||
@ -694,7 +686,7 @@ mysqlnd_stmt_execute_calculate_param_values_size(MYSQLND_STMT_DATA * stmt, zval
|
||||
case MYSQL_TYPE_DOUBLE:
|
||||
*data_size += 8;
|
||||
if (Z_TYPE_P(the_var) != IS_DOUBLE) {
|
||||
if (!*copies_param || !(*copies_param)[i]) {
|
||||
if (!*copies_param || Z_ISUNDEF((*copies_param)[i])) {
|
||||
if (PASS != mysqlnd_stmt_copy_it(copies_param, the_var, stmt->param_count, i TSRMLS_CC)) {
|
||||
SET_OOM_ERROR(*stmt->error_info);
|
||||
goto end;
|
||||
@ -707,11 +699,11 @@ mysqlnd_stmt_execute_calculate_param_values_size(MYSQLND_STMT_DATA * stmt, zval
|
||||
/* fall-through */
|
||||
case MYSQL_TYPE_LONG:
|
||||
{
|
||||
zval *tmp_data = (*copies_param && (*copies_param)[i])? (*copies_param)[i]: stmt->param_bind[i].zv;
|
||||
zval *tmp_data = (*copies_param && !Z_ISUNDEF((*copies_param)[i]))? &(*copies_param)[i]: &stmt->param_bind[i].zv;
|
||||
if (Z_TYPE_P(tmp_data) == IS_STRING) {
|
||||
goto use_string;
|
||||
}
|
||||
convert_to_long_ex(&tmp_data);
|
||||
convert_to_long_ex(tmp_data);
|
||||
}
|
||||
*data_size += 4 + is_longlong;
|
||||
break;
|
||||
@ -729,15 +721,15 @@ mysqlnd_stmt_execute_calculate_param_values_size(MYSQLND_STMT_DATA * stmt, zval
|
||||
use_string:
|
||||
*data_size += 8; /* max 8 bytes for size */
|
||||
if (Z_TYPE_P(the_var) != IS_STRING) {
|
||||
if (!*copies_param || !(*copies_param)[i]) {
|
||||
if (!*copies_param || Z_ISUNDEF((*copies_param)[i])) {
|
||||
if (PASS != mysqlnd_stmt_copy_it(copies_param, the_var, stmt->param_count, i TSRMLS_CC)) {
|
||||
SET_OOM_ERROR(*stmt->error_info);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
the_var = (*copies_param)[i];
|
||||
the_var = &((*copies_param)[i]);
|
||||
}
|
||||
convert_to_string_ex(&the_var);
|
||||
convert_to_string_ex(the_var);
|
||||
*data_size += Z_STRLEN_P(the_var);
|
||||
break;
|
||||
}
|
||||
@ -751,18 +743,18 @@ end:
|
||||
|
||||
/* {{{ mysqlnd_stmt_execute_store_param_values */
|
||||
static void
|
||||
mysqlnd_stmt_execute_store_param_values(MYSQLND_STMT_DATA * stmt, zval ** copies, zend_uchar * buf, zend_uchar ** p, size_t null_byte_offset)
|
||||
mysqlnd_stmt_execute_store_param_values(MYSQLND_STMT_DATA * stmt, zval * copies, zend_uchar * buf, zend_uchar ** p, size_t null_byte_offset)
|
||||
{
|
||||
unsigned int i;
|
||||
for (i = 0; i < stmt->param_count; i++) {
|
||||
zval * data = (copies && copies[i])? copies[i]: stmt->param_bind[i].zv;
|
||||
zval * data = (copies && !Z_ISUNDEF(copies[i]))? &copies[i]: &stmt->param_bind[i].zv;
|
||||
/* Handle long data */
|
||||
if (stmt->param_bind[i].zv && Z_TYPE_P(data) == IS_NULL) {
|
||||
if (!Z_ISUNDEF(stmt->param_bind[i].zv) && Z_TYPE_P(data) == IS_NULL) {
|
||||
(buf + null_byte_offset)[i/8] |= (zend_uchar) (1 << (i & 7));
|
||||
} else {
|
||||
switch (stmt->param_bind[i].type) {
|
||||
case MYSQL_TYPE_DOUBLE:
|
||||
convert_to_double_ex(&data);
|
||||
convert_to_double_ex(data);
|
||||
float8store(*p, Z_DVAL_P(data));
|
||||
(*p) += 8;
|
||||
break;
|
||||
@ -816,10 +808,9 @@ static enum_func_status
|
||||
mysqlnd_stmt_execute_store_params(MYSQLND_STMT * s, zend_uchar **buf, zend_uchar **p, size_t *buf_len TSRMLS_DC)
|
||||
{
|
||||
MYSQLND_STMT_DATA * stmt = s->data;
|
||||
unsigned int i = 0;
|
||||
zend_uchar * provided_buffer = *buf;
|
||||
size_t data_size = 0;
|
||||
zval **copies = NULL;/* if there are different types */
|
||||
zval *copies = NULL;/* if there are different types */
|
||||
enum_func_status ret = FAIL;
|
||||
int resend_types_next_time = 0;
|
||||
size_t null_byte_offset;
|
||||
|
@ -43,8 +43,8 @@ MYSQLND_METHOD(mysqlnd_result_buffered_zval, initialize_result_set_rest)(MYSQLND
|
||||
const uint64_t row_count = result->row_count;
|
||||
enum_func_status rc;
|
||||
|
||||
zval **data_begin = ((MYSQLND_RES_BUFFERED_ZVAL *) result)->data;
|
||||
zval **data_cursor = data_begin;
|
||||
zval *data_begin = ((MYSQLND_RES_BUFFERED_ZVAL *) result)->data;
|
||||
zval *data_cursor = data_begin;
|
||||
|
||||
DBG_ENTER("mysqlnd_result_buffered_zval::initialize_result_set_rest");
|
||||
|
||||
@ -52,7 +52,7 @@ MYSQLND_METHOD(mysqlnd_result_buffered_zval, initialize_result_set_rest)(MYSQLND
|
||||
DBG_RETURN(ret);
|
||||
}
|
||||
while ((data_cursor - data_begin) < (int)(row_count * field_count)) {
|
||||
if (NULL == data_cursor[0]) {
|
||||
if (Z_ISUNDEF(data_cursor[0])) {
|
||||
rc = result->m.row_decoder(result->row_buffers[(data_cursor - data_begin) / field_count],
|
||||
data_cursor,
|
||||
field_count,
|
||||
@ -70,8 +70,9 @@ MYSQLND_METHOD(mysqlnd_result_buffered_zval, initialize_result_set_rest)(MYSQLND
|
||||
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(data_cursor[i]) >= IS_STRING) {
|
||||
unsigned long len = Z_STRLEN_P(data_cursor[i]);
|
||||
//???? if (Z_TYPE_P(data_cursor[i]) >= IS_STRING) {
|
||||
if (Z_TYPE(data_cursor[i]) == IS_STRING) {
|
||||
unsigned long len = Z_STRLEN(data_cursor[i]);
|
||||
if (meta->fields[i].max_length < len) {
|
||||
meta->fields[i].max_length = len;
|
||||
}
|
||||
@ -99,7 +100,7 @@ MYSQLND_METHOD(mysqlnd_result_buffered_c, initialize_result_set_rest)(MYSQLND_RE
|
||||
|
||||
if (result->initialized_rows < row_count) {
|
||||
zend_uchar * initialized = ((MYSQLND_RES_BUFFERED_C *) result)->initialized;
|
||||
zval ** current_row = mnd_emalloc(field_count * sizeof(zval *));
|
||||
zval * current_row = mnd_emalloc(field_count * sizeof(zval));
|
||||
|
||||
if (!current_row) {
|
||||
DBG_RETURN(FAIL);
|
||||
@ -125,8 +126,9 @@ MYSQLND_METHOD(mysqlnd_result_buffered_c, initialize_result_set_rest)(MYSQLND_RE
|
||||
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) {
|
||||
if (Z_TYPE(current_row[i]) == IS_STRING) {
|
||||
unsigned long len = Z_STRLEN(current_row[i]);
|
||||
if (meta->fields[i].max_length < len) {
|
||||
meta->fields[i].max_length = len;
|
||||
}
|
||||
@ -143,11 +145,11 @@ MYSQLND_METHOD(mysqlnd_result_buffered_c, initialize_result_set_rest)(MYSQLND_RE
|
||||
|
||||
/* {{{ mysqlnd_rset_zval_ptr_dtor */
|
||||
static void
|
||||
mysqlnd_rset_zval_ptr_dtor(zval **zv, enum_mysqlnd_res_type type, zend_bool * copy_ctor_called TSRMLS_DC)
|
||||
mysqlnd_rset_zval_ptr_dtor(zval *zv, enum_mysqlnd_res_type type, zend_bool * copy_ctor_called TSRMLS_DC)
|
||||
{
|
||||
DBG_ENTER("mysqlnd_rset_zval_ptr_dtor");
|
||||
DBG_INF_FMT("type=%u", type);
|
||||
if (!zv || !*zv) {
|
||||
if (!zv) {
|
||||
*copy_ctor_called = FALSE;
|
||||
DBG_ERR_FMT("zv was NULL");
|
||||
DBG_VOID_RETURN;
|
||||
@ -160,13 +162,13 @@ mysqlnd_rset_zval_ptr_dtor(zval **zv, enum_mysqlnd_res_type type, zend_bool * co
|
||||
if (type == MYSQLND_RES_PS_BUF || type == MYSQLND_RES_PS_UNBUF) {
|
||||
*copy_ctor_called = FALSE;
|
||||
; /* do nothing, zval_ptr_dtor will do the job*/
|
||||
} else if (Z_REFCOUNT_PP(zv) > 1) {
|
||||
} else if (Z_REFCOUNTED_P(zv) && Z_REFCOUNT_P(zv) > 1) {
|
||||
/*
|
||||
Not a prepared statement, then we have to
|
||||
call copy_ctor and then zval_ptr_dtor()
|
||||
*/
|
||||
if (Z_TYPE_PP(zv) == IS_STRING) {
|
||||
zval_copy_ctor(*zv);
|
||||
if (Z_TYPE_P(zv) == IS_STRING) {
|
||||
zval_copy_ctor(zv);
|
||||
}
|
||||
*copy_ctor_called = TRUE;
|
||||
} else {
|
||||
@ -176,11 +178,12 @@ mysqlnd_rset_zval_ptr_dtor(zval **zv, enum_mysqlnd_res_type type, zend_bool * co
|
||||
in result set buffers
|
||||
*/
|
||||
*copy_ctor_called = FALSE;
|
||||
if (Z_TYPE_PP(zv) == IS_STRING) {
|
||||
ZVAL_NULL(*zv);
|
||||
if (Z_TYPE_P(zv) == IS_STRING) {
|
||||
ZVAL_NULL(zv);
|
||||
}
|
||||
}
|
||||
DBG_INF_FMT("call the dtor on zval with refc %u", Z_REFCOUNT_PP(zv));
|
||||
|
||||
DBG_INF_FMT("call the dtor on zval with refc %u", Z_REFCOUNTED_P(zv)? Z_REFCOUNT_P(zv) : 0);
|
||||
zval_ptr_dtor(zv);
|
||||
DBG_VOID_RETURN;
|
||||
}
|
||||
@ -266,7 +269,7 @@ MYSQLND_METHOD(mysqlnd_result_unbuffered, free_result)(MYSQLND_RES_UNBUFFERED *
|
||||
static void
|
||||
MYSQLND_METHOD(mysqlnd_result_buffered_zval, free_result)(MYSQLND_RES_BUFFERED_ZVAL * const set TSRMLS_DC)
|
||||
{
|
||||
zval ** data = set->data;
|
||||
zval * data = set->data;
|
||||
|
||||
DBG_ENTER("mysqlnd_result_buffered_zval::free_result");
|
||||
|
||||
@ -278,12 +281,12 @@ MYSQLND_METHOD(mysqlnd_result_buffered_zval, free_result)(MYSQLND_RES_BUFFERED_Z
|
||||
int64_t row;
|
||||
|
||||
for (row = set->row_count - 1; row >= 0; row--) {
|
||||
zval **current_row = data + row * field_count;
|
||||
zval *current_row = data + row * field_count;
|
||||
int64_t col;
|
||||
|
||||
if (current_row != NULL) {
|
||||
for (col = field_count - 1; col >= 0; --col) {
|
||||
if (current_row[col]) {
|
||||
if (!Z_ISUNDEF(current_row[col])) {
|
||||
zend_bool copy_ctor_called;
|
||||
mysqlnd_rset_zval_ptr_dtor(&(current_row[col]), set->ps? MYSQLND_RES_PS_BUF : MYSQLND_RES_NORMAL, ©_ctor_called TSRMLS_CC);
|
||||
if (copy_ctor_called) {
|
||||
@ -804,7 +807,7 @@ MYSQLND_METHOD(mysqlnd_result_unbuffered, fetch_row_c)(MYSQLND_RES * result, voi
|
||||
unsigned long * lengths = result->unbuf->lengths;
|
||||
|
||||
for (i = 0; i < field_count; i++, field++) {
|
||||
zval * data = result->unbuf->last_row_data[i];
|
||||
zval * data = &result->unbuf->last_row_data[i];
|
||||
unsigned int len = (Z_TYPE_P(data) == IS_NULL)? 0:Z_STRLEN_P(data);
|
||||
|
||||
/* BEGIN difference between normal normal fetch and _c */
|
||||
@ -922,12 +925,12 @@ MYSQLND_METHOD(mysqlnd_result_unbuffered, fetch_row)(MYSQLND_RES * result, void
|
||||
unsigned long * lengths = result->unbuf->lengths;
|
||||
|
||||
for (i = 0; i < field_count; i++, field++) {
|
||||
zval * data = result->unbuf->last_row_data[i];
|
||||
zval * data = &result->unbuf->last_row_data[i];
|
||||
unsigned int len = (Z_TYPE_P(data) == IS_NULL)? 0:Z_STRLEN_P(data);
|
||||
|
||||
if (flags & MYSQLND_FETCH_NUM) {
|
||||
Z_ADDREF_P(data);
|
||||
zend_hash_next_index_insert(row_ht, &data, sizeof(zval *), NULL);
|
||||
Z_TRY_ADDREF_P(data);
|
||||
zend_hash_next_index_insert(row_ht, data);
|
||||
}
|
||||
if (flags & MYSQLND_FETCH_ASSOC) {
|
||||
/* zend_hash_quick_update needs length + trailing zero */
|
||||
@ -937,15 +940,11 @@ MYSQLND_METHOD(mysqlnd_result_unbuffered, fetch_row)(MYSQLND_RES * result, void
|
||||
the index is a numeric and convert it to it. This however means constant
|
||||
hashing of the column name, which is not needed as it can be precomputed.
|
||||
*/
|
||||
Z_ADDREF_P(data);
|
||||
Z_TRY_ADDREF_P(data);
|
||||
if (meta->zend_hash_keys[i].is_numeric == FALSE) {
|
||||
zend_hash_quick_update(Z_ARRVAL_P(row),
|
||||
field->name,
|
||||
field->name_length + 1,
|
||||
meta->zend_hash_keys[i].key,
|
||||
(void *) &data, sizeof(zval *), NULL);
|
||||
zend_hash_str_update(Z_ARRVAL_P(row), meta->fields[i].name, meta->fields[i].name_length, data);
|
||||
} else {
|
||||
zend_hash_index_update(Z_ARRVAL_P(row), meta->zend_hash_keys[i].key, (void *) &data, sizeof(zval *), NULL);
|
||||
zend_hash_index_update(Z_ARRVAL_P(row), meta->zend_hash_keys[i].key, data);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1054,10 +1053,10 @@ MYSQLND_METHOD(mysqlnd_result_buffered, fetch_row_c)(MYSQLND_RES * result, void
|
||||
if (set->data_cursor &&
|
||||
(set->data_cursor - set->data) < (result->stored_data->row_count * field_count))
|
||||
{
|
||||
zval **current_row = set->data_cursor;
|
||||
zval *current_row = set->data_cursor;
|
||||
unsigned int i;
|
||||
|
||||
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 = set->m.row_decoder(set->row_buffers[row_num],
|
||||
current_row,
|
||||
@ -1075,8 +1074,9 @@ MYSQLND_METHOD(mysqlnd_result_buffered, fetch_row_c)(MYSQLND_RES * result, void
|
||||
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) {
|
||||
if (Z_TYPE(current_row[i]) == IS_STRING) {
|
||||
unsigned long len = Z_STRLEN(current_row[i]);
|
||||
if (meta->fields[i].max_length < len) {
|
||||
meta->fields[i].max_length = len;
|
||||
}
|
||||
@ -1089,7 +1089,7 @@ MYSQLND_METHOD(mysqlnd_result_buffered, fetch_row_c)(MYSQLND_RES * result, void
|
||||
*row = mnd_malloc(field_count * sizeof(char *));
|
||||
if (*row) {
|
||||
for (i = 0; i < field_count; i++) {
|
||||
zval * data = current_row[i];
|
||||
zval * data = ¤t_row[i];
|
||||
|
||||
set->lengths[i] = (Z_TYPE_P(data) == IS_NULL)? 0:Z_STRLEN_P(data);
|
||||
|
||||
@ -1146,9 +1146,9 @@ MYSQLND_METHOD(mysqlnd_result_buffered_zval, fetch_row)(MYSQLND_RES * result, vo
|
||||
(set->data_cursor - set->data) < (set->row_count * field_count))
|
||||
{
|
||||
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 = set->m.row_decoder(set->row_buffers[row_num],
|
||||
current_row,
|
||||
@ -1166,8 +1166,9 @@ MYSQLND_METHOD(mysqlnd_result_buffered_zval, fetch_row)(MYSQLND_RES * result, vo
|
||||
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_P(current_row[i]) >= IS_STRING) {
|
||||
if (Z_TYPE(current_row[i]) == IS_STRING) {
|
||||
unsigned long len = Z_STRLEN(current_row[i]);
|
||||
if (meta->fields[i].max_length < len) {
|
||||
meta->fields[i].max_length = len;
|
||||
}
|
||||
@ -1176,13 +1177,13 @@ MYSQLND_METHOD(mysqlnd_result_buffered_zval, fetch_row)(MYSQLND_RES * result, vo
|
||||
}
|
||||
|
||||
for (i = 0; i < field_count; i++) {
|
||||
zval * data = current_row[i];
|
||||
zval * data = ¤t_row[i];
|
||||
|
||||
set->lengths[i] = (Z_TYPE_P(data) == IS_NULL)? 0:Z_STRLEN_P(data);
|
||||
|
||||
if (flags & MYSQLND_FETCH_NUM) {
|
||||
Z_ADDREF_P(data);
|
||||
zend_hash_next_index_insert(Z_ARRVAL_P(row), &data, sizeof(zval *), NULL);
|
||||
Z_TRY_ADDREF_P(data);
|
||||
zend_hash_next_index_insert(Z_ARRVAL_P(row), data);
|
||||
}
|
||||
if (flags & MYSQLND_FETCH_ASSOC) {
|
||||
/* zend_hash_quick_update needs length + trailing zero */
|
||||
@ -1192,17 +1193,11 @@ MYSQLND_METHOD(mysqlnd_result_buffered_zval, fetch_row)(MYSQLND_RES * result, vo
|
||||
the index is a numeric and convert it to it. This however means constant
|
||||
hashing of the column name, which is not needed as it can be precomputed.
|
||||
*/
|
||||
Z_ADDREF_P(data);
|
||||
Z_TRY_ADDREF_P(data);
|
||||
if (meta->zend_hash_keys[i].is_numeric == FALSE) {
|
||||
zend_hash_quick_update(Z_ARRVAL_P(row),
|
||||
meta->fields[i].name,
|
||||
meta->fields[i].name_length + 1,
|
||||
meta->zend_hash_keys[i].key,
|
||||
(void *) &data, sizeof(zval *), NULL);
|
||||
zend_hash_str_update(Z_ARRVAL_P(row), meta->fields[i].name, meta->fields[i].name_length, data);
|
||||
} else {
|
||||
zend_hash_index_update(Z_ARRVAL_P(row),
|
||||
meta->zend_hash_keys[i].key,
|
||||
(void *) &data, sizeof(zval *), NULL);
|
||||
zend_hash_index_update(Z_ARRVAL_P(row), meta->zend_hash_keys[i].key, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1237,11 +1232,11 @@ MYSQLND_METHOD(mysqlnd_result_buffered_c, fetch_row)(MYSQLND_RES * result, void
|
||||
|
||||
/* If we haven't read everything */
|
||||
if (set->current_row < set->row_count) {
|
||||
zval **current_row;
|
||||
zval *current_row;
|
||||
enum_func_status rc;
|
||||
unsigned int i;
|
||||
|
||||
current_row = mnd_emalloc(field_count * sizeof(zval *));
|
||||
current_row = mnd_emalloc(field_count * sizeof(zval));
|
||||
if (!current_row) {
|
||||
SET_OOM_ERROR(*result->conn->error_info);
|
||||
DBG_RETURN(FAIL);
|
||||
@ -1267,8 +1262,9 @@ MYSQLND_METHOD(mysqlnd_result_buffered_c, fetch_row)(MYSQLND_RES * result, void
|
||||
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) {
|
||||
if (Z_TYPE(current_row[i]) == IS_STRING) {
|
||||
unsigned long len = Z_STRLEN(current_row[i]);
|
||||
if (meta->fields[i].max_length < len) {
|
||||
meta->fields[i].max_length = len;
|
||||
}
|
||||
@ -1277,13 +1273,13 @@ MYSQLND_METHOD(mysqlnd_result_buffered_c, fetch_row)(MYSQLND_RES * result, void
|
||||
}
|
||||
|
||||
for (i = 0; i < field_count; i++) {
|
||||
zval * data = current_row[i];
|
||||
zval * data = ¤t_row[i];
|
||||
|
||||
set->lengths[i] = (Z_TYPE_P(data) == IS_NULL)? 0:Z_STRLEN_P(data);
|
||||
|
||||
if (flags & MYSQLND_FETCH_NUM) {
|
||||
Z_ADDREF_P(data);
|
||||
zend_hash_next_index_insert(Z_ARRVAL_P(row), &data, sizeof(zval *), NULL);
|
||||
Z_TRY_ADDREF_P(data);
|
||||
zend_hash_next_index_insert(Z_ARRVAL_P(row), data);
|
||||
}
|
||||
if (flags & MYSQLND_FETCH_ASSOC) {
|
||||
/* zend_hash_quick_update needs length + trailing zero */
|
||||
@ -1293,17 +1289,11 @@ MYSQLND_METHOD(mysqlnd_result_buffered_c, fetch_row)(MYSQLND_RES * result, void
|
||||
the index is a numeric and convert it to it. This however means constant
|
||||
hashing of the column name, which is not needed as it can be precomputed.
|
||||
*/
|
||||
Z_ADDREF_P(data);
|
||||
Z_TRY_ADDREF_P(data);
|
||||
if (meta->zend_hash_keys[i].is_numeric == FALSE) {
|
||||
zend_hash_quick_update(Z_ARRVAL_P(row),
|
||||
meta->fields[i].name,
|
||||
meta->fields[i].name_length + 1,
|
||||
meta->zend_hash_keys[i].key,
|
||||
(void *) &data, sizeof(zval *), NULL);
|
||||
zend_hash_str_update(Z_ARRVAL_P(row), meta->fields[i].name, meta->fields[i].name_length, data);
|
||||
} else {
|
||||
zend_hash_index_update(Z_ARRVAL_P(row),
|
||||
meta->zend_hash_keys[i].key,
|
||||
(void *) &data, sizeof(zval *), NULL);
|
||||
zend_hash_index_update(Z_ARRVAL_P(row), meta->zend_hash_keys[i].key, data);
|
||||
}
|
||||
}
|
||||
/*
|
||||
@ -1312,7 +1302,7 @@ MYSQLND_METHOD(mysqlnd_result_buffered_c, fetch_row)(MYSQLND_RES * result, void
|
||||
It also simplifies the handling of Z_ADDREF_P because we don't need to check if only
|
||||
either NUM or ASSOC is set but not both.
|
||||
*/
|
||||
zval_ptr_dtor(&data);
|
||||
zval_ptr_dtor(data);
|
||||
}
|
||||
mnd_efree(current_row);
|
||||
set->current_row++;
|
||||
@ -1531,12 +1521,12 @@ MYSQLND_METHOD(mysqlnd_res, store_result)(MYSQLND_RES * result,
|
||||
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)(set->row_count * meta->field_count * sizeof(zval *)));
|
||||
set->data = mnd_emalloc((size_t)(set->row_count * meta->field_count * sizeof(zval)));
|
||||
if (!set->data) {
|
||||
SET_OOM_ERROR(*conn->error_info);
|
||||
DBG_RETURN(NULL);
|
||||
}
|
||||
memset(set->data, 0, (size_t)(set->row_count * meta->field_count * sizeof(zval *)));
|
||||
memset(set->data, 0, (size_t)(set->row_count * meta->field_count * sizeof(zval)));
|
||||
}
|
||||
/* Position at the first row */
|
||||
set->data_cursor = set->data;
|
||||
@ -1810,7 +1800,8 @@ MYSQLND_METHOD(mysqlnd_res, fetch_into)(MYSQLND_RES * result, const unsigned int
|
||||
Hint Zend how many elements we will have in the hash. Thus it won't
|
||||
extend and rehash the hash constantly.
|
||||
*/
|
||||
mysqlnd_array_init(return_value, mysqlnd_num_fields(result) * 2);
|
||||
ZVAL_NEW_ARR(return_value);
|
||||
array_init_size(return_value, mysqlnd_num_fields(result) * 2);
|
||||
if (FAIL == result->m.fetch_row(result, (void *)return_value, flags, &fetched_anything TSRMLS_CC)) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error while reading a row");
|
||||
zval_dtor(return_value);
|
||||
@ -1861,7 +1852,7 @@ MYSQLND_METHOD(mysqlnd_res, fetch_row_c)(MYSQLND_RES * result TSRMLS_DC)
|
||||
static void
|
||||
MYSQLND_METHOD(mysqlnd_res, fetch_all)(MYSQLND_RES * result, const unsigned int flags, zval *return_value TSRMLS_DC ZEND_FILE_LINE_DC)
|
||||
{
|
||||
zval *row;
|
||||
zval row;
|
||||
ulong i = 0;
|
||||
MYSQLND_RES_BUFFERED *set = result->stored_data;
|
||||
|
||||
@ -1877,16 +1868,16 @@ MYSQLND_METHOD(mysqlnd_res, fetch_all)(MYSQLND_RES * result, const unsigned int
|
||||
}
|
||||
|
||||
/* 4 is a magic value. The cast is safe, if larger then the array will be later extended - no big deal :) */
|
||||
mysqlnd_array_init(return_value, set? (unsigned int) set->row_count : 4);
|
||||
ZVAL_NEW_ARR(return_value);
|
||||
array_init_size(return_value, set? (unsigned int) set->row_count : 4);
|
||||
|
||||
do {
|
||||
MAKE_STD_ZVAL(row);
|
||||
mysqlnd_fetch_into(result, flags, row, MYSQLND_MYSQLI);
|
||||
if (Z_TYPE_P(row) != IS_ARRAY) {
|
||||
mysqlnd_fetch_into(result, flags, &row, MYSQLND_MYSQLI);
|
||||
if (Z_TYPE(row) != IS_ARRAY) {
|
||||
zval_ptr_dtor(&row);
|
||||
break;
|
||||
}
|
||||
add_index_zval(return_value, i++, row);
|
||||
add_index_zval(return_value, i++, &row);
|
||||
} while (1);
|
||||
|
||||
DBG_VOID_RETURN;
|
||||
@ -1899,7 +1890,7 @@ static void
|
||||
MYSQLND_METHOD(mysqlnd_res, fetch_field_data)(MYSQLND_RES * result, unsigned int offset, zval *return_value TSRMLS_DC)
|
||||
{
|
||||
zval row;
|
||||
zval **entry;
|
||||
zval *entry;
|
||||
unsigned int i = 0;
|
||||
|
||||
DBG_ENTER("mysqlnd_res::fetch_field_data");
|
||||
@ -1908,24 +1899,22 @@ MYSQLND_METHOD(mysqlnd_res, fetch_field_data)(MYSQLND_RES * result, unsigned int
|
||||
Hint Zend how many elements we will have in the hash. Thus it won't
|
||||
extend and rehash the hash constantly.
|
||||
*/
|
||||
INIT_PZVAL(&row);
|
||||
mysqlnd_fetch_into(result, MYSQLND_FETCH_NUM, &row, MYSQLND_MYSQL);
|
||||
if (Z_TYPE(row) != IS_ARRAY) {
|
||||
zval_dtor(&row);
|
||||
RETVAL_NULL();
|
||||
DBG_VOID_RETURN;
|
||||
}
|
||||
|
||||
zend_hash_internal_pointer_reset(Z_ARRVAL(row));
|
||||
while (i++ < offset) {
|
||||
zend_hash_move_forward(Z_ARRVAL(row));
|
||||
zend_hash_get_current_data(Z_ARRVAL(row), (void **)&entry);
|
||||
//???entry = zend_hash_get_current_data(Z_ARRVAL(row));
|
||||
}
|
||||
|
||||
zend_hash_get_current_data(Z_ARRVAL(row), (void **)&entry);
|
||||
entry = zend_hash_get_current_data(Z_ARRVAL(row));
|
||||
|
||||
*return_value = **entry;
|
||||
zval_copy_ctor(return_value);
|
||||
Z_SET_REFCOUNT_P(return_value, 1);
|
||||
ZVAL_COPY(return_value, entry);
|
||||
zval_dtor(&row);
|
||||
|
||||
DBG_VOID_RETURN;
|
||||
|
@ -182,14 +182,9 @@ MYSQLND_METHOD(mysqlnd_res_meta, read_metadata)(MYSQLND_RES_METADATA * const met
|
||||
if ((meta->zend_hash_keys[i].is_numeric =
|
||||
mysqlnd_is_key_numeric(field_packet->metadata->name,
|
||||
field_packet->metadata->name_length + 1,
|
||||
&idx)))
|
||||
{
|
||||
&idx))) {
|
||||
meta->zend_hash_keys[i].key = idx;
|
||||
} else {
|
||||
meta->zend_hash_keys[i].key =
|
||||
zend_get_hash_value(field_packet->metadata->name,
|
||||
field_packet->metadata->name_length + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
PACKET_FREE(field_packet);
|
||||
|
||||
|
@ -616,7 +616,7 @@ struct st_mysqlnd_conn_methods
|
||||
};
|
||||
|
||||
/* for decoding - binary or text protocol */
|
||||
typedef enum_func_status (*func_mysqlnd_res__row_decoder)(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ** fields,
|
||||
typedef enum_func_status (*func_mysqlnd_res__row_decoder)(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval * fields,
|
||||
unsigned int field_count, const MYSQLND_FIELD * fields_metadata,
|
||||
zend_bool as_int_or_float, MYSQLND_STATS * stats TSRMLS_DC);
|
||||
|
||||
@ -1035,8 +1035,8 @@ struct st_mysqlnd_buffered_result_zval
|
||||
{
|
||||
def_mysqlnd_buffered_result_parent;
|
||||
|
||||
zval **data;
|
||||
zval **data_cursor;
|
||||
zval *data;
|
||||
zval *data_cursor;
|
||||
};
|
||||
|
||||
|
||||
@ -1053,7 +1053,7 @@ struct st_mysqlnd_unbuffered_result
|
||||
{
|
||||
|
||||
/* For unbuffered (both normal and PS) */
|
||||
zval **last_row_data;
|
||||
zval *last_row_data;
|
||||
MYSQLND_MEMORY_POOL_CHUNK *last_row_buffer;
|
||||
|
||||
/*
|
||||
@ -1098,14 +1098,14 @@ struct st_mysqlnd_res
|
||||
|
||||
struct st_mysqlnd_param_bind
|
||||
{
|
||||
zval *zv;
|
||||
zval zv;
|
||||
zend_uchar type;
|
||||
enum_param_bind_flags flags;
|
||||
};
|
||||
|
||||
struct st_mysqlnd_result_bind
|
||||
{
|
||||
zval *zv;
|
||||
zval zv;
|
||||
zend_bool bound;
|
||||
};
|
||||
|
||||
|
@ -1226,7 +1226,7 @@ static enum_func_status
|
||||
php_mysqlnd_rset_field_read(void * _packet, MYSQLND_CONN_DATA * conn TSRMLS_DC)
|
||||
{
|
||||
/* Should be enough for the metadata of a single row */
|
||||
MYSQLND_PACKET_RES_FIELD *packet= (MYSQLND_PACKET_RES_FIELD *) _packet;
|
||||
MYSQLND_PACKET_RES_FIELD *packet = (MYSQLND_PACKET_RES_FIELD *) _packet;
|
||||
size_t buf_len = conn->net->cmd_buffer.length, total_len = 0;
|
||||
zend_uchar *buf = (zend_uchar *) conn->net->cmd_buffer.buffer;
|
||||
zend_uchar *p = buf;
|
||||
@ -1517,14 +1517,14 @@ php_mysqlnd_read_row_ex(MYSQLND_CONN_DATA * conn, MYSQLND_MEMORY_POOL * result_s
|
||||
|
||||
/* {{{ php_mysqlnd_rowp_read_binary_protocol */
|
||||
enum_func_status
|
||||
php_mysqlnd_rowp_read_binary_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ** fields,
|
||||
php_mysqlnd_rowp_read_binary_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval * fields,
|
||||
unsigned int field_count, const MYSQLND_FIELD * fields_metadata,
|
||||
zend_bool as_int_or_float, MYSQLND_STATS * stats TSRMLS_DC)
|
||||
{
|
||||
unsigned int i;
|
||||
zend_uchar * p = row_buffer->ptr;
|
||||
zend_uchar * null_ptr, bit;
|
||||
zval **current_field, **end_field, **start_field;
|
||||
zend_uchar *p = row_buffer->ptr;
|
||||
zend_uchar *null_ptr, bit;
|
||||
zval *current_field, *end_field, *start_field;
|
||||
|
||||
DBG_ENTER("php_mysqlnd_rowp_read_binary_protocol");
|
||||
|
||||
@ -1540,29 +1540,21 @@ php_mysqlnd_rowp_read_binary_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zv
|
||||
p += (field_count + 9)/8; /* skip null bits */
|
||||
bit = 4; /* first 2 bits are reserved */
|
||||
|
||||
for (i = 0, current_field = start_field; current_field < end_field; current_field++, i++) {
|
||||
DBG_INF("Directly creating zval");
|
||||
MAKE_STD_ZVAL(*current_field);
|
||||
if (!*current_field) {
|
||||
DBG_RETURN(FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0, current_field = start_field; current_field < end_field; current_field++, i++) {
|
||||
enum_mysqlnd_collected_stats statistic;
|
||||
zend_uchar * orig_p = p;
|
||||
|
||||
DBG_INF_FMT("Into zval=%p decoding column %u [%s.%s.%s] type=%u field->flags&unsigned=%u flags=%u is_bit=%u",
|
||||
*current_field, i,
|
||||
current_field, i,
|
||||
fields_metadata[i].db, fields_metadata[i].table, fields_metadata[i].name, fields_metadata[i].type,
|
||||
fields_metadata[i].flags & UNSIGNED_FLAG, fields_metadata[i].flags, fields_metadata[i].type == MYSQL_TYPE_BIT);
|
||||
if (*null_ptr & bit) {
|
||||
DBG_INF("It's null");
|
||||
ZVAL_NULL(*current_field);
|
||||
ZVAL_NULL(current_field);
|
||||
statistic = STAT_BINARY_TYPE_FETCHED_NULL;
|
||||
} else {
|
||||
enum_mysqlnd_field_types type = fields_metadata[i].type;
|
||||
mysqlnd_ps_fetch_functions[type].func(*current_field, &fields_metadata[i], 0, &p TSRMLS_CC);
|
||||
mysqlnd_ps_fetch_functions[type].func(current_field, &fields_metadata[i], 0, &p TSRMLS_CC);
|
||||
|
||||
if (MYSQLND_G(collect_statistics)) {
|
||||
switch (fields_metadata[i].type) {
|
||||
@ -1599,8 +1591,8 @@ php_mysqlnd_rowp_read_binary_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zv
|
||||
}
|
||||
MYSQLND_INC_CONN_STATISTIC_W_VALUE2(stats, statistic, 1,
|
||||
STAT_BYTES_RECEIVED_PURE_DATA_PS,
|
||||
(Z_TYPE_PP(current_field) == IS_STRING)?
|
||||
Z_STRLEN_PP(current_field) : (p - orig_p));
|
||||
(Z_TYPE_P(current_field) == IS_STRING)?
|
||||
Z_STRLEN_P(current_field) : (p - orig_p));
|
||||
|
||||
if (!((bit<<=1) & 255)) {
|
||||
bit = 1; /* to the following byte */
|
||||
@ -1612,15 +1604,16 @@ php_mysqlnd_rowp_read_binary_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zv
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ php_mysqlnd_rowp_read_text_protocol */
|
||||
enum_func_status
|
||||
php_mysqlnd_rowp_read_text_protocol_aux(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ** fields,
|
||||
php_mysqlnd_rowp_read_text_protocol_aux(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval * fields,
|
||||
unsigned int field_count, const MYSQLND_FIELD * fields_metadata,
|
||||
zend_bool as_int_or_float, zend_bool copy_data, MYSQLND_STATS * stats TSRMLS_DC)
|
||||
{
|
||||
unsigned int i;
|
||||
zend_bool last_field_was_string = FALSE;
|
||||
zval **current_field, **end_field, **start_field;
|
||||
zval *current_field, *end_field, *start_field;
|
||||
zend_uchar * p = row_buffer->ptr;
|
||||
size_t data_size = row_buffer->app;
|
||||
zend_uchar * bit_area = (zend_uchar*) row_buffer->ptr + data_size + 1; /* we allocate from here */
|
||||
@ -1633,14 +1626,6 @@ php_mysqlnd_rowp_read_text_protocol_aux(MYSQLND_MEMORY_POOL_CHUNK * row_buffer,
|
||||
|
||||
end_field = (start_field = fields) + field_count;
|
||||
|
||||
for (i = 0, current_field = start_field; current_field < end_field; current_field++, i++) {
|
||||
DBG_INF("Directly creating zval");
|
||||
MAKE_STD_ZVAL(*current_field);
|
||||
if (!*current_field) {
|
||||
DBG_RETURN(FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0, current_field = start_field; current_field < end_field; current_field++, i++) {
|
||||
/* Don't reverse the order. It is significant!*/
|
||||
zend_uchar *this_field_len_pos = p;
|
||||
@ -1665,7 +1650,7 @@ php_mysqlnd_rowp_read_text_protocol_aux(MYSQLND_MEMORY_POOL_CHUNK * row_buffer,
|
||||
|
||||
/* NULL or NOT NULL, this is the question! */
|
||||
if (len == MYSQLND_NULL_LENGTH) {
|
||||
ZVAL_NULL(*current_field);
|
||||
ZVAL_NULL(current_field);
|
||||
last_field_was_string = FALSE;
|
||||
} else {
|
||||
#if defined(MYSQLND_STRING_TO_INT_CONVERSION)
|
||||
@ -1719,7 +1704,7 @@ php_mysqlnd_rowp_read_text_protocol_aux(MYSQLND_MEMORY_POOL_CHUNK * row_buffer,
|
||||
#else
|
||||
_atoi64((char *) p);
|
||||
#endif
|
||||
ZVAL_LONG(*current_field, (long) v); /* the cast is safe */
|
||||
ZVAL_LONG(current_field, (long) v); /* the cast is safe */
|
||||
} else {
|
||||
uint64_t v =
|
||||
#ifndef PHP_WIN32
|
||||
@ -1739,9 +1724,10 @@ php_mysqlnd_rowp_read_text_protocol_aux(MYSQLND_MEMORY_POOL_CHUNK * row_buffer,
|
||||
#error Need fix for this architecture
|
||||
#endif /* SIZEOF */
|
||||
{
|
||||
ZVAL_STRINGL(*current_field, (char *)p, len, 0);
|
||||
//???? ZVAL_STRINGL(current_field, (char *)p, len, 0);
|
||||
ZVAL_STRINGL(current_field, (char *)p, len);
|
||||
} else {
|
||||
ZVAL_LONG(*current_field, (long) v); /* the cast is safe */
|
||||
ZVAL_LONG(current_field, (long) v); /* the cast is safe */
|
||||
}
|
||||
}
|
||||
*(p + len) = save;
|
||||
@ -1749,7 +1735,7 @@ php_mysqlnd_rowp_read_text_protocol_aux(MYSQLND_MEMORY_POOL_CHUNK * row_buffer,
|
||||
zend_uchar save = *(p + len);
|
||||
/* We have to make it ASCIIZ temporarily */
|
||||
*(p + len) = '\0';
|
||||
ZVAL_DOUBLE(*current_field, atof((char *) p));
|
||||
ZVAL_DOUBLE(current_field, atof((char *) p));
|
||||
*(p + len) = save;
|
||||
} else
|
||||
#endif /* MYSQLND_STRING_TO_INT_CONVERSION */
|
||||
@ -1764,24 +1750,34 @@ php_mysqlnd_rowp_read_text_protocol_aux(MYSQLND_MEMORY_POOL_CHUNK * row_buffer,
|
||||
Definitely not nice, _hackish_ :(, but works.
|
||||
*/
|
||||
zend_uchar *start = bit_area;
|
||||
ps_fetch_from_1_to_8_bytes(*current_field, &(fields_metadata[i]), 0, &p, len TSRMLS_CC);
|
||||
ps_fetch_from_1_to_8_bytes(current_field, &(fields_metadata[i]), 0, &p, len TSRMLS_CC);
|
||||
/*
|
||||
We have advanced in ps_fetch_from_1_to_8_bytes. We should go back because
|
||||
later in this function there will be an advancement.
|
||||
*/
|
||||
p -= len;
|
||||
if (Z_TYPE_PP(current_field) == IS_LONG) {
|
||||
bit_area += 1 + sprintf((char *)start, "%ld", Z_LVAL_PP(current_field));
|
||||
ZVAL_STRINGL(*current_field, (char *) start, bit_area - start - 1, copy_data);
|
||||
} else if (Z_TYPE_PP(current_field) == IS_STRING){
|
||||
memcpy(bit_area, Z_STRVAL_PP(current_field), Z_STRLEN_PP(current_field));
|
||||
bit_area += Z_STRLEN_PP(current_field);
|
||||
if (Z_TYPE_P(current_field) == IS_LONG) {
|
||||
bit_area += 1 + sprintf((char *)start, "%ld", Z_LVAL_P(current_field));
|
||||
//???? ZVAL_STRINGL(current_field, (char *) start, bit_area - start - 1, copy_data);
|
||||
ZVAL_STRINGL(current_field, (char *) start, bit_area - start - 1);
|
||||
if (!copy_data) {
|
||||
efree(start);
|
||||
}
|
||||
} else if (Z_TYPE_P(current_field) == IS_STRING){
|
||||
memcpy(bit_area, Z_STRVAL_P(current_field), Z_STRLEN_P(current_field));
|
||||
bit_area += Z_STRLEN_P(current_field);
|
||||
*bit_area++ = '\0';
|
||||
zval_dtor(*current_field);
|
||||
ZVAL_STRINGL(*current_field, (char *) start, bit_area - start - 1, copy_data);
|
||||
zval_dtor(current_field);
|
||||
ZVAL_STRINGL(current_field, (char *) start, bit_area - start - 1);
|
||||
if (!copy_data) {
|
||||
efree(start);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ZVAL_STRINGL(*current_field, (char *)p, len, copy_data);
|
||||
ZVAL_STRINGL(current_field, (char *)p, len);
|
||||
if (!copy_data) {
|
||||
efree(p);
|
||||
}
|
||||
}
|
||||
p += len;
|
||||
last_field_was_string = TRUE;
|
||||
@ -1799,7 +1795,7 @@ php_mysqlnd_rowp_read_text_protocol_aux(MYSQLND_MEMORY_POOL_CHUNK * row_buffer,
|
||||
|
||||
/* {{{ php_mysqlnd_rowp_read_text_protocol_zval */
|
||||
enum_func_status
|
||||
php_mysqlnd_rowp_read_text_protocol_zval(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ** fields,
|
||||
php_mysqlnd_rowp_read_text_protocol_zval(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval * fields,
|
||||
unsigned int field_count, const MYSQLND_FIELD * fields_metadata,
|
||||
zend_bool as_int_or_float, MYSQLND_STATS * stats TSRMLS_DC)
|
||||
{
|
||||
@ -1813,7 +1809,7 @@ php_mysqlnd_rowp_read_text_protocol_zval(MYSQLND_MEMORY_POOL_CHUNK * row_buffer,
|
||||
|
||||
/* {{{ php_mysqlnd_rowp_read_text_protocol_c */
|
||||
enum_func_status
|
||||
php_mysqlnd_rowp_read_text_protocol_c(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ** fields,
|
||||
php_mysqlnd_rowp_read_text_protocol_c(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval * fields,
|
||||
unsigned int field_count, const MYSQLND_FIELD * fields_metadata,
|
||||
zend_bool as_int_or_float, MYSQLND_STATS * stats TSRMLS_DC)
|
||||
{
|
||||
@ -1825,8 +1821,6 @@ php_mysqlnd_rowp_read_text_protocol_c(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zv
|
||||
/* }}} */
|
||||
|
||||
|
||||
|
||||
|
||||
/* {{{ php_mysqlnd_rowp_read */
|
||||
/*
|
||||
if normal statements => packet->fields is created by this function,
|
||||
@ -1907,7 +1901,7 @@ php_mysqlnd_rowp_read(void * _packet, MYSQLND_CONN_DATA * conn TSRMLS_DC)
|
||||
but mostly like old-API unbuffered and thus will populate this array with
|
||||
value.
|
||||
*/
|
||||
packet->fields = (zval **) mnd_pecalloc(packet->field_count, sizeof(zval *),
|
||||
packet->fields = mnd_pecalloc(packet->field_count, sizeof(zval),
|
||||
packet->persistent_alloc);
|
||||
}
|
||||
} else {
|
||||
|
@ -218,7 +218,7 @@ typedef struct st_mysqlnd_packet_res_field {
|
||||
/* Row packet */
|
||||
typedef struct st_mysqlnd_packet_row {
|
||||
MYSQLND_PACKET_HEADER header;
|
||||
zval **fields;
|
||||
zval *fields;
|
||||
uint32_t field_count;
|
||||
zend_bool eof;
|
||||
/*
|
||||
@ -307,16 +307,16 @@ size_t php_mysqlnd_net_store_length_size(uint64_t length);
|
||||
PHPAPI const extern char * const mysqlnd_empty_string;
|
||||
|
||||
|
||||
enum_func_status php_mysqlnd_rowp_read_binary_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ** fields,
|
||||
enum_func_status php_mysqlnd_rowp_read_binary_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval * fields,
|
||||
unsigned int field_count, const MYSQLND_FIELD * fields_metadata,
|
||||
zend_bool as_int_or_float, MYSQLND_STATS * stats TSRMLS_DC);
|
||||
|
||||
|
||||
enum_func_status php_mysqlnd_rowp_read_text_protocol_zval(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ** fields,
|
||||
enum_func_status php_mysqlnd_rowp_read_text_protocol_zval(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval * fields,
|
||||
unsigned int field_count, const MYSQLND_FIELD * fields_metadata,
|
||||
zend_bool as_int_or_float, MYSQLND_STATS * stats TSRMLS_DC);
|
||||
|
||||
enum_func_status php_mysqlnd_rowp_read_text_protocol_c(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ** fields,
|
||||
enum_func_status php_mysqlnd_rowp_read_text_protocol_c(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval * fields,
|
||||
unsigned int field_count, const MYSQLND_FIELD * fields_metadata,
|
||||
zend_bool as_int_or_float, MYSQLND_STATS * stats TSRMLS_DC);
|
||||
|
||||
|
@ -43,31 +43,22 @@ static zend_function_entry mysqlnd_functions[] = {
|
||||
PHPAPI void
|
||||
mysqlnd_minfo_print_hash(zval *values)
|
||||
{
|
||||
zval **values_entry;
|
||||
HashPosition pos_values;
|
||||
zval *values_entry;
|
||||
zend_string *string_key;
|
||||
|
||||
zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(values), &pos_values);
|
||||
while (zend_hash_get_current_data_ex(Z_ARRVAL_P(values), (void **)&values_entry, &pos_values) == SUCCESS) {
|
||||
char *string_key;
|
||||
uint string_key_len;
|
||||
ulong num_key;
|
||||
|
||||
zend_hash_get_current_key_ex(Z_ARRVAL_P(values), &string_key, &string_key_len, &num_key, 0, &pos_values);
|
||||
|
||||
convert_to_string(*values_entry);
|
||||
php_info_print_table_row(2, string_key, Z_STRVAL_PP(values_entry));
|
||||
|
||||
zend_hash_move_forward_ex(Z_ARRVAL_P(values), &pos_values);
|
||||
}
|
||||
ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(values), string_key, values_entry) {
|
||||
convert_to_string(values_entry);
|
||||
php_info_print_table_row(2, string_key->val, Z_STRVAL_P(values_entry));
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ mysqlnd_minfo_dump_plugin_stats */
|
||||
static int
|
||||
mysqlnd_minfo_dump_plugin_stats(void *pDest, void * argument TSRMLS_DC)
|
||||
mysqlnd_minfo_dump_plugin_stats(zval *el, void * argument TSRMLS_DC)
|
||||
{
|
||||
struct st_mysqlnd_plugin_header * plugin_header = *(struct st_mysqlnd_plugin_header **) pDest;
|
||||
struct st_mysqlnd_plugin_header * plugin_header = *(struct st_mysqlnd_plugin_header **)Z_PTR_P(el);
|
||||
if (plugin_header->plugin_stats.values) {
|
||||
char buf[64];
|
||||
zval values;
|
||||
@ -88,12 +79,12 @@ mysqlnd_minfo_dump_plugin_stats(void *pDest, void * argument TSRMLS_DC)
|
||||
|
||||
/* {{{ mysqlnd_minfo_dump_loaded_plugins */
|
||||
static int
|
||||
mysqlnd_minfo_dump_loaded_plugins(void *pDest, void * buf TSRMLS_DC)
|
||||
mysqlnd_minfo_dump_loaded_plugins(zval *el, void * buf TSRMLS_DC)
|
||||
{
|
||||
smart_str * buffer = (smart_str *) buf;
|
||||
struct st_mysqlnd_plugin_header * plugin_header = *(struct st_mysqlnd_plugin_header **) pDest;
|
||||
struct st_mysqlnd_plugin_header * plugin_header = *(struct st_mysqlnd_plugin_header **)Z_PTR_P(el);
|
||||
if (plugin_header->plugin_name) {
|
||||
if (buffer->len) {
|
||||
if (buffer->s) {
|
||||
smart_str_appendc(buffer, ',');
|
||||
}
|
||||
smart_str_appends(buffer, plugin_header->plugin_name);
|
||||
@ -102,23 +93,20 @@ mysqlnd_minfo_dump_loaded_plugins(void *pDest, void * buf TSRMLS_DC)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ mysqlnd_minfo_dump_api_plugins */
|
||||
static void
|
||||
mysqlnd_minfo_dump_api_plugins(smart_str * buffer TSRMLS_DC)
|
||||
{
|
||||
HashTable *ht = mysqlnd_reverse_api_get_api_list(TSRMLS_C);
|
||||
HashPosition pos;
|
||||
MYSQLND_REVERSE_API **ext;
|
||||
|
||||
for (zend_hash_internal_pointer_reset_ex(ht, &pos);
|
||||
zend_hash_get_current_data_ex(ht, (void **) &ext, &pos) == SUCCESS;
|
||||
zend_hash_move_forward_ex(ht, &pos)
|
||||
) {
|
||||
if (buffer->len) {
|
||||
ZEND_HASH_FOREACH_PTR(ht, ext) {
|
||||
if (buffer->s) {
|
||||
smart_str_appendc(buffer, ',');
|
||||
}
|
||||
smart_str_appends(buffer, (*ext)->module->name);
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -163,15 +151,15 @@ PHP_MINFO_FUNCTION(mysqlnd)
|
||||
|
||||
/* loaded plugins */
|
||||
{
|
||||
smart_str tmp_str = {0, 0, 0};
|
||||
smart_str tmp_str = {0};
|
||||
mysqlnd_plugin_apply_with_argument(mysqlnd_minfo_dump_loaded_plugins, &tmp_str);
|
||||
smart_str_0(&tmp_str);
|
||||
php_info_print_table_row(2, "Loaded plugins", tmp_str.c);
|
||||
php_info_print_table_row(2, "Loaded plugins", tmp_str.s->val);
|
||||
smart_str_free(&tmp_str);
|
||||
|
||||
mysqlnd_minfo_dump_api_plugins(&tmp_str TSRMLS_CC);
|
||||
smart_str_0(&tmp_str);
|
||||
php_info_print_table_row(2, "API Extensions", tmp_str.c);
|
||||
php_info_print_table_row(2, "API Extensions", tmp_str.s->val);
|
||||
smart_str_free(&tmp_str);
|
||||
}
|
||||
|
||||
@ -214,6 +202,8 @@ static PHP_GINIT_FUNCTION(mysqlnd)
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ PHP_INI_MH
|
||||
*/
|
||||
static PHP_INI_MH(OnUpdateNetCmdBufferSize)
|
||||
{
|
||||
long long_value = atol(new_value);
|
||||
@ -224,6 +214,8 @@ static PHP_INI_MH(OnUpdateNetCmdBufferSize)
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ PHP_INI_BEGIN
|
||||
*/
|
||||
@ -326,7 +318,6 @@ static PHP_RSHUTDOWN_FUNCTION(mysqlnd)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
static const zend_module_dep mysqlnd_deps[] = {
|
||||
ZEND_MOD_REQUIRED("standard")
|
||||
ZEND_MOD_END
|
||||
|
Loading…
Reference in New Issue
Block a user