]> granicus.if.org Git - php/commitdiff
MFH:
authorAndrey Hristov <andrey@php.net>
Thu, 28 May 2009 11:47:48 +0000 (11:47 +0000)
committerAndrey Hristov <andrey@php.net>
Thu, 28 May 2009 11:47:48 +0000 (11:47 +0000)
Fix a bug with mysqlnd_fetch_field(_direct()). With mysqlnd the optimised
function was called, which however, doesn't respect that during store the
raw data is not unpacked, to be lazy. The data is unpacked to zvals later,
during every row fetch. However, this way max_length won't be calculated
correctly. So, if a mysqlnd_fetch_field(_direct) call comes we need to
unpack everything and then calculate max_length...and that is expensive,
defies our lazy unpacking optimisation.

ext/mysqlnd/mysqlnd.h
ext/mysqlnd/mysqlnd_debug.c
ext/mysqlnd/mysqlnd_result.c

index 2d9a1985e869081096c01f36007cef2ddda0e904..99fedc9ef8e9928596ced0062540394eeb2e4d8a 100644 (file)
@@ -158,8 +158,8 @@ PHPAPI enum_func_status _mysqlnd_poll(MYSQLND **r_array, MYSQLND **e_array, MYSQ
 #define mysqlnd_field_seek(result, ofs)                        (result)->m.seek_field((result), (ofs))
 #define mysqlnd_field_tell(result)                             ((result)->meta? (result)->meta->current_field:0)
 #define mysqlnd_fetch_field(result)                            (result)->m.fetch_field((result) TSRMLS_CC)
-#define mysqlnd_fetch_field_direct(result,fnr) ((result)->meta? &((result)->meta->fields[(fnr)]):NULL)
-#define mysqlnd_fetch_fields(result)                   ((result)->meta? (result)->meta->fields: NULL)
+#define mysqlnd_fetch_field_direct(result,fnr) (result)->m.fetch_field_direct((result), (fnr) TSRMLS_CC)
+#define mysqlnd_fetch_fields(result)                   (result)->m.fetch_fields((result) TSRMLS_CC)
 
 /* mysqlnd metadata */
 #define mysqlnd_get_client_info()              MYSQLND_VERSION
index b83e18d0d3d1283efa9a6acd2c279df65bcbd930..a0527488506c36469065b56d3c920a3974cf4b7f 100644 (file)
@@ -815,7 +815,7 @@ void * _mysqlnd_perealloc(void *ptr, size_t new_size, zend_bool persistent MYSQL
        if (persistent == FALSE) {
                DBG_INF_FMT("after : %lu", zend_memory_usage(persistent TSRMLS_CC));
        }
-       MYSQLND_INC_GLOBAL_STATISTIC(persistent? STAT_MEM_EREALLOC_COUNT:STAT_MEM_REALLOC_COUNT);
+       MYSQLND_INC_GLOBAL_STATISTIC(persistent? STAT_MEM_REALLOC_COUNT:STAT_MEM_EREALLOC_COUNT);
        if (MYSQLND_G(collect_memory_statistics)) {
                enum mysqlnd_collected_stats s1 = persistent? STAT_MEM_REALLOC_COUNT:STAT_MEM_EREALLOC_COUNT;
                enum mysqlnd_collected_stats s2 = persistent? STAT_MEM_REALLOC_AMMOUNT:STAT_MEM_EREALLOC_AMMOUNT;
index e2c8c2c0af92c7f8f2958d2937402fcfffd6e37f..f791fd0fb5ba0c768e02feef6c327fa7ee376aed 100644 (file)
@@ -1736,6 +1736,16 @@ MYSQLND_METHOD(mysqlnd_res, fetch_field)(MYSQLND_RES * const result TSRMLS_DC)
 {
        DBG_ENTER("mysqlnd_res::fetch_field");
        if (result->meta) {
+               /*
+                 We optimize the result set, so we don't convert all the data from raw buffer format to
+                 zval arrays during store. In the case someone doesn't read all the lines this will
+                 save time. However, when a metadata call is done, we need to calculate max_length.
+                 We don't have control whether max_length will be used, unfortunately. Otherwise we
+                 could have been able to skip that step.
+                 Well, if the mysqli API switches from returning stdClass to class like mysqli_field_metadata,
+                 then we can have max_length as dynamic property, which will be calculated during runtime and
+                 not during mysqli_fetch_field() time.
+               */
                if (result->stored_data && (result->stored_data->initialized_rows < result->stored_data->row_count)) {
                        /* we have to initialize the rest to get the updated max length */
                        mysqlnd_res_initialize_result_set_rest(result TSRMLS_CC);
@@ -1754,6 +1764,16 @@ MYSQLND_METHOD(mysqlnd_res, fetch_field_direct)(MYSQLND_RES * const result,
 {
        DBG_ENTER("mysqlnd_res::fetch_field_direct");
        if (result->meta) {
+               /*
+                 We optimize the result set, so we don't convert all the data from raw buffer format to
+                 zval arrays during store. In the case someone doesn't read all the lines this will
+                 save time. However, when a metadata call is done, we need to calculate max_length.
+                 We don't have control whether max_length will be used, unfortunately. Otherwise we
+                 could have been able to skip that step.
+                 Well, if the mysqli API switches from returning stdClass to class like mysqli_field_metadata,
+                 then we can have max_length as dynamic property, which will be calculated during runtime and
+                 not during mysqli_fetch_field_direct() time.
+               */
                if (result->stored_data && (result->stored_data->initialized_rows < result->stored_data->row_count)) {
                        /* we have to initialized the rest to get the updated max length */
                        mysqlnd_res_initialize_result_set_rest(result TSRMLS_CC);