diff options
Diffstat (limited to 'ext/mysqlnd/mysqlnd_result.c')
-rw-r--r-- | ext/mysqlnd/mysqlnd_result.c | 87 |
1 files changed, 13 insertions, 74 deletions
diff --git a/ext/mysqlnd/mysqlnd_result.c b/ext/mysqlnd/mysqlnd_result.c index ded48930a5..56969944aa 100644 --- a/ext/mysqlnd/mysqlnd_result.c +++ b/ext/mysqlnd/mysqlnd_result.c @@ -30,9 +30,6 @@ #include "mysqlnd_debug.h" #include "ext/standard/basic_functions.h" -#define START_FREEING_AFTER_X_ROWS 10 -static void mysqlnd_buffered_free_previous_row(MYSQLND_RES *result, int which TSRMLS_DC); - #define MYSQLND_SILENT #ifdef MYSQLND_THREADED @@ -104,18 +101,11 @@ void mysqlnd_res_initialize_result_set_rest(MYSQLND_RES * const result TSRMLS_DC unsigned int field_count = result->meta->field_count; unsigned int row_count = result->stored_data->row_count; DBG_ENTER("mysqlnd_res_initialize_result_set_rest"); - DBG_INF_FMT("before heap=%lu real=%lu", zend_memory_usage(FALSE TSRMLS_CC), zend_memory_usage(TRUE TSRMLS_CC)); if (!data_cursor || row_count == result->stored_data->initialized_rows) { DBG_VOID_RETURN; } while ((data_cursor - data_begin) < (row_count * field_count)) { - if (START_FREEING_AFTER_X_ROWS < ((data_cursor - data_begin) / result->field_count)) { - zval **orig_data_cursor = result->stored_data->data_cursor; - result->stored_data->data_cursor = data_cursor; - mysqlnd_buffered_free_previous_row(result, START_FREEING_AFTER_X_ROWS TSRMLS_CC); - result->stored_data->data_cursor = orig_data_cursor; - } if (NULL == data_cursor[0]) { result->stored_data->initialized_rows++; result->m.row_decoder( @@ -140,7 +130,6 @@ void mysqlnd_res_initialize_result_set_rest(MYSQLND_RES * const result TSRMLS_DC } data_cursor += field_count; } - DBG_INF_FMT("after heap=%lu real=%lu", zend_memory_usage(FALSE TSRMLS_CC), zend_memory_usage(TRUE TSRMLS_CC)); DBG_VOID_RETURN; } /* }}} */ @@ -188,7 +177,7 @@ void mysqlnd_unbuffered_free_last_data(MYSQLND_RES *result TSRMLS_DC) if (unbuf->last_row_buffer) { DBG_INF("Freeing last row buffer"); /* Nothing points to this buffer now, free it */ - mysqlnd_mempool_free_chunk(unbuf->last_row_buffer, TRUE TSRMLS_CC); + unbuf->last_row_buffer->free_chunk(unbuf->last_row_buffer, TRUE TSRMLS_CC); unbuf->last_row_buffer = NULL; } @@ -197,53 +186,6 @@ void mysqlnd_unbuffered_free_last_data(MYSQLND_RES *result TSRMLS_DC) /* }}} */ -/* {{{ mysqlnd_buffered_free_previous_row */ -static -void mysqlnd_buffered_free_previous_row(MYSQLND_RES *result, int which TSRMLS_DC) -{ - MYSQLND_RES_BUFFERED * set = result->stored_data; - - DBG_ENTER("mysqlnd_buffered_free_previous_row"); - - if (!set) { - DBG_VOID_RETURN; - } - - DBG_INF_FMT("which=%d result->field_count=%d data=%p data_cursor=%p", which, result->field_count, set->data, set->data_cursor); - if (set->data_cursor && ((set->data_cursor - (which * result->field_count) ) >= set->data)) { - unsigned int i, ctor_called_count = 0; - zend_bool copy_ctor_called; - MYSQLND_STATS *global_stats = result->conn? &result->conn->stats:NULL; - zval **current_row = set->data_cursor - (which * result->field_count); - - DBG_INF_FMT("%u columns to free", result->field_count); - for (i = 0; i < result->field_count; i++) { - if (current_row[i]) { - mysqlnd_palloc_zval_ptr_dtor(&(current_row[i]), - result->zval_cache, result->type, - ©_ctor_called TSRMLS_CC); - if (copy_ctor_called) { - ctor_called_count++; - } - current_row[i] = NULL; - } - } - DBG_INF_FMT("copy_ctor_called_count=%u", ctor_called_count); - /* By using value3 macros we hold a mutex only once, there is no value2 */ - MYSQLND_INC_CONN_STATISTIC_W_VALUE3(global_stats, - STAT_COPY_ON_WRITE_PERFORMED, - ctor_called_count, - STAT_COPY_ON_WRITE_SAVED, - result->field_count - ctor_called_count, - STAT_COPY_ON_WRITE_PERFORMED, 0); - } - - DBG_VOID_RETURN; -} -/* }}} */ - - - /* {{{ mysqlnd_free_buffered_data */ void mysqlnd_free_buffered_data(MYSQLND_RES *result TSRMLS_DC) { @@ -263,20 +205,21 @@ void mysqlnd_free_buffered_data(MYSQLND_RES *result TSRMLS_DC) for (col = field_count - 1; col >= 0; --col) { zend_bool copy_ctor_called; - if (current_row[col] != NULL) { - mysqlnd_palloc_zval_ptr_dtor(&(current_row[col]), zval_cache, + if (current_row[0] == NULL) { + break;/* row that was never initialized */ + } + mysqlnd_palloc_zval_ptr_dtor(&(current_row[col]), zval_cache, result->type, ©_ctor_called TSRMLS_CC); #if MYSQLND_DEBUG_MEMORY - DBG_INF_FMT("Copy_ctor_called=%d", copy_ctor_called); + DBG_INF_FMT("Copy_ctor_called=%d", copy_ctor_called); #endif - MYSQLND_INC_GLOBAL_STATISTIC(copy_ctor_called? STAT_COPY_ON_WRITE_PERFORMED: - STAT_COPY_ON_WRITE_SAVED); - } + MYSQLND_INC_GLOBAL_STATISTIC(copy_ctor_called? STAT_COPY_ON_WRITE_PERFORMED: + STAT_COPY_ON_WRITE_SAVED); } #if MYSQLND_DEBUG_MEMORY DBG_INF("Freeing current_row & current_buffer"); #endif - mysqlnd_mempool_free_chunk(current_buffer, TRUE TSRMLS_CC); + current_buffer->free_chunk(current_buffer, TRUE TSRMLS_CC); } DBG_INF("Freeing data & row_buffer"); if (set->data) { @@ -354,7 +297,7 @@ void mysqlnd_free_background_buffered_data(MYSQLND_RES *result TSRMLS_DC) #endif pefree(current_row, set->persistent); } - mysqlnd_mempool_free_chunk(current_buffer, TRUE TSRMLS_CC); + current_buffer->free_chunk(current_buffer, TRUE TSRMLS_CC); } DBG_INF("Freeing data & row_buffer"); pefree(set->data, set->persistent); @@ -488,6 +431,8 @@ MYSQLND_METHOD(mysqlnd_res, read_result_metadata)(MYSQLND_RES *result, MYSQLND * result->m.free_result_contents(result TSRMLS_CC); DBG_RETURN(FAIL); } + /* COM_FIELD_LIST is broken and has premature EOF, thus we need to hack here and in mysqlnd_res_meta.c */ + result->field_count = result->meta->field_count; /* 2. Follows an EOF packet, which the client of mysqlnd_read_result_metadata() @@ -1156,10 +1101,6 @@ mysqlnd_fetch_row_buffered(MYSQLND_RES *result, void *param, unsigned int flags, zval **current_row = set->data_cursor; MYSQLND_FIELD *field = result->meta->fields; struct mysqlnd_field_hash_key *zend_hash_key = result->meta->zend_hash_keys; - DBG_INF_FMT("row_num=%u", (set->data_cursor - set->data) / result->meta->field_count); - if (START_FREEING_AFTER_X_ROWS < ((set->data_cursor - set->data) / result->field_count)) { - mysqlnd_buffered_free_previous_row(result, START_FREEING_AFTER_X_ROWS TSRMLS_CC); - } if (NULL == current_row[0]) { uint64_t row_num = (set->data_cursor - set->data) / result->meta->field_count; @@ -1909,7 +1850,6 @@ MYSQLND_METHOD(mysqlnd_res, fetch_into)(MYSQLND_RES *result, unsigned int flags, DBG_ENTER("mysqlnd_res::fetch_into"); DBG_INF_FMT("flags=%u mysqlnd_extension=%d", flags, extension); - DBG_INF_FMT("memory in use: heap_size=%lu real_size=%u", zend_memory_usage(FALSE TSRMLS_CC), zend_memory_usage(TRUE TSRMLS_CC)); if (!result->m.fetch_row) { RETVAL_NULL(); @@ -1921,7 +1861,7 @@ MYSQLND_METHOD(mysqlnd_res, fetch_into)(MYSQLND_RES *result, unsigned int flags, */ mysqlnd_array_init(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/decoding a row"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error while reading a row"); RETVAL_FALSE; } else if (fetched_anything == FALSE) { zval_dtor(return_value); @@ -1939,7 +1879,6 @@ MYSQLND_METHOD(mysqlnd_res, fetch_into)(MYSQLND_RES *result, unsigned int flags, return_value is IS_NULL for no more data and an array for data. Thus it's ok to return here. */ - DBG_INF_FMT("returning: heap_size=%lu real_size=%u", zend_memory_usage(FALSE TSRMLS_CC), zend_memory_usage(TRUE TSRMLS_CC)); DBG_VOID_RETURN; } /* }}} */ |