Author: ahristov
Date: 2007-03-21 20:07:06 +0100 (Wed, 21 Mar 2007)
New Revision: 243
Modified:
trunk/ext/mysqli/config.m4
trunk/ext/mysqli/mysqli_api.c
trunk/ext/mysqli/mysqli_mysqlnd.h
trunk/ext/mysqli/mysqlnd/mysqlnd.c
trunk/ext/mysqli/mysqlnd/mysqlnd.h
trunk/ext/mysqli/mysqlnd/mysqlnd_ps.c
Log:
Refactor mysqlnd, separate, really, the buffered
from unbuffered sets. A step forward to be able to
preserve (cache) buffered sets.
Modified: trunk/ext/mysqli/config.m4
===================================================================
--- trunk/ext/mysqli/config.m4 2007-03-21 15:24:52 UTC (rev 242)
+++ trunk/ext/mysqli/config.m4 2007-03-21 19:07:06 UTC (rev 243)
@@ -16,7 +16,7 @@
AC_DEFINE(HAVE_MYSQLND, 1, "MySQL native driver support enabled")
extra_sources="mysqlnd/mysqlnd.c mysqlnd/mysqlnd_charset.c
mysqlnd/mysqlnd_wireprotocol.c \
- mysqlnd/mysqlnd_ps.c mysqlnd/mysqlnd_loaddata.c mysqlnd/mysqlnd_alloc.c
mysqlnd/mysqlnd_palloc.c \
+ mysqlnd/mysqlnd_ps.c mysqlnd/mysqlnd_loaddata.c
mysqlnd/mysqlnd_palloc.c \
mysqlnd/mysqlnd_ps_codec.c mysqlnd/mysqlnd_statistics.c mysqlnd/mysqlnd_qcache.c"
elif test "$PHP_MYSQLI" != "no"; then
Modified: trunk/ext/mysqli/mysqli_api.c
===================================================================
--- trunk/ext/mysqli/mysqli_api.c 2007-03-21 15:24:52 UTC (rev 242)
+++ trunk/ext/mysqli/mysqli_api.c 2007-03-21 19:07:06 UTC (rev 243)
@@ -607,7 +607,7 @@
RETURN_FALSE;
}
- if (offset < 0 || offset >= result->row_count) {
+ if (offset < 0 || offset >= mysql_num_rows(result)) {
RETURN_FALSE;
}
Modified: trunk/ext/mysqli/mysqli_mysqlnd.h
===================================================================
--- trunk/ext/mysqli/mysqli_mysqlnd.h 2007-03-21 15:24:52 UTC (rev 242)
+++ trunk/ext/mysqli/mysqli_mysqlnd.h 2007-03-21 19:07:06 UTC (rev 243)
@@ -112,7 +112,7 @@
#define MYSQLI_CLOSE_IMPLICIT MYSQLND_CLOSE_IMPLICIT
#define MYSQLI_CLOSE_DISCONNECTED MYSQLND_CLOSE_DISCONNECTED
-#define mysqli_result_is_unbuffered(r) ((r)->conn)
+#define mysqli_result_is_unbuffered(r) ((r)->unbuf)
#define mysqli_server_status(c) (c)->upsert_status.server_status
#define mysqli_stmt_warning_count(s) mysqlnd_stmt_warning_count((s))
#define mysqli_stmt_server_status(s) (s)->upsert_status.server_status
Modified: trunk/ext/mysqli/mysqlnd/mysqlnd.c
===================================================================
--- trunk/ext/mysqli/mysqlnd/mysqlnd.c 2007-03-21 15:24:52 UTC (rev 242)
+++ trunk/ext/mysqli/mysqlnd/mysqlnd.c 2007-03-21 19:07:06 UTC (rev 243)
@@ -114,15 +114,20 @@
/* {{{ mysqlnd_unbuffered_free_last_data */
void mysqlnd_unbuffered_free_last_data(MYSQLND_RES *result TSRMLS_DC)
{
- if (result->last_row_data) {
+ MYSQLND_RES_UNBUFFERED *unbuf = result->unbuf;
+ if (!unbuf) {
+ return;
+ }
+
+ if (unbuf->last_row_data) {
int i;
zend_bool copy_ctor_called;
for (i = 0; i < result->field_count; i++) {
if (result->type == MYSQLND_RES_PS) {
/* Do nothing, before assigning we will clean */
- zval_ptr_dtor(&result->last_row_data[i]);
+ zval_ptr_dtor(&unbuf->last_row_data[i]);
} else {
- mysqlnd_palloc_zval_ptr_dtor(&(result->last_row_data[i]),
+ mysqlnd_palloc_zval_ptr_dtor(&(unbuf->last_row_data[i]),
result->zval_cache, FALSE,
©_ctor_called TSRMLS_CC);
if (copy_ctor_called) {
@@ -136,13 +141,13 @@
}
}
/* Free last row's zvals */
- efree(result->last_row_data);
- result->last_row_data = NULL;
+ efree(unbuf->last_row_data);
+ unbuf->last_row_data = NULL;
}
- if (result->last_row_buffer) {
+ if (unbuf->last_row_buffer) {
/* Nothing points to this buffer now, free it */
- efree(result->last_row_buffer);
- result->last_row_buffer = NULL;
+ efree(unbuf->last_row_buffer);
+ unbuf->last_row_buffer = NULL;
}
}
/* }}} */
@@ -152,22 +157,22 @@
void mysqlnd_internal_free_result_buffers(MYSQLND_RES *result TSRMLS_DC)
{
int i;
- /* The user has used the old API - mysqlnd_fetch_row() */
- if (result->last_row) {
- efree(result->last_row);
- result->last_row = NULL;
- }
if (!result->data) {
mysqlnd_unbuffered_free_last_data(result TSRMLS_CC);
+ if (result->unbuf) {
+ efree(result->unbuf);
+ result->unbuf = NULL;
+ }
} else {
zval **current_row;
zend_uchar *current_buffer;
+ MYSQLND_RES_BUFFERED *set = result->data;
int j;
- for (i = 0; i < result->row_count; i++) {
- current_row = result->data[i];
- current_buffer = result->row_buffers[i];
+ for (i = 0; i < result->data->row_count; i++) {
+ current_row = set->data[i];
+ current_buffer = set->row_buffers[i];
for (j = 0; j < result->field_count; j++) {
if (result->type == MYSQLND_RES_PS) {
/* For now PS always does create copies when fetching data */
@@ -184,15 +189,18 @@
STAT_COPY_ON_WRITE_SAVED);
}
}
- efree(current_row);
- efree(current_buffer);
+ pefree(current_row, set->persistent);
+ pefree(current_buffer, set->persistent);
}
- efree(result->data);
- efree(result->row_buffers);
+ pefree(set->data, set->persistent);
+ pefree(set->row_buffers, set->persistent);
+ set->data = NULL;
+ set->row_buffers = NULL;
+ set->data_cursor = NULL;
+ set->row_count = 0;
+
+ pefree(set, set->persistent);
result->data = NULL;
- result->row_buffers = NULL;
- result->data_cursor = NULL;
- result->row_count = 0;
}
#ifndef WE_WANT_TO_USE_ROW_BUFFER_IN_ROWP_READ
@@ -1190,12 +1198,14 @@
- first row hs not been read
- last_row has been read
*/
- if ((result->data_cursor == NULL) || result->data_cursor == result->data ||
- ((result->data_cursor - result->data) > result->row_count)) {
+ if (result->data->data_cursor == NULL ||
+ result->data->data_cursor == result->data->data ||
+ ((result->data->data_cursor - result->data->data) >
result->data->row_count))
+ {
return NULL;/* No rows or no more rows */
}
- previous_row = *(result->data_cursor - 1);
+ previous_row = *(result->data->data_cursor - 1);
for (i = 0; i < result->field_count; i++) {
result->lengths[i] = (Z_TYPE_P(previous_row[i]) == IS_NULL)?
0:Z_STRLEN_P(previous_row[i]);
}
@@ -1225,8 +1235,9 @@
php_mysql_packet_row *row_packet = result->row_packet;
unsigned long *lengths = result->lengths;
- if (result->eof_reached) {
+ if (result->unbuf->eof_reached) {
/* No more rows obviously */
+ *fetched_anything = FALSE;
return PASS;
}
if (result->conn->state != CONN_FETCHING_DATA) {
@@ -1244,12 +1255,12 @@
if (PASS == (ret = PACKET_READ(row_packet, result->conn)) &&
!row_packet->eof) {
mysqlnd_unbuffered_free_last_data(result TSRMLS_CC);
- result->last_row_data = row_packet->fields;
- result->last_row_buffer = row_packet->row_buffer;
+ result->unbuf->last_row_data = row_packet->fields;
+ result->unbuf->last_row_buffer = row_packet->row_buffer;
row_packet->fields = NULL;
row_packet->row_buffer = NULL;
- result->row_count++;
+ result->unbuf->row_count++;
*fetched_anything = TRUE;
MYSQLND_INC_CONN_STATISTIC(&result->conn->stats,
STAT_ROWS_FETCHED_FROM_CLIENT);
@@ -1257,7 +1268,7 @@
if (!row_packet->skip_extraction) {
HashTable *row_ht = Z_ARRVAL_P(row);
for (i = 0; i < field_count; i++) {
- zval *data = result->last_row_data[i];
+ zval *data = result->unbuf->last_row_data[i];
int len = (Z_TYPE_P(data) == IS_NULL)? 0:Z_STRLEN_P(data);
if (lengths) {
@@ -1309,7 +1320,7 @@
} else if (row_packet->eof) {
/* Mark the connection as usable again */
- result->eof_reached = TRUE;
+ result->unbuf->eof_reached = TRUE;
result->conn->upsert_status.warning_count = row_packet->warning_count;
result->conn->upsert_status.server_status = row_packet->server_status;
/*
@@ -1355,6 +1366,7 @@
result->type = MYSQLND_RES_NORMAL;
result->m.fetch_row = result->m.fetch_row_normal_unbuffered;
result->m.fetch_lengths = mysqlnd_fetch_lengths_unbuffered;
+ result->unbuf = ecalloc(1, sizeof(MYSQLND_RES_UNBUFFERED));
result->conn = conn->m->get_reference(conn);
/*
@@ -1384,8 +1396,10 @@
zval *row = (zval *) param;
/* If we haven't read everything */
- if (result->data_cursor && (result->data_cursor - result->data) <
result->row_count) {
- zval **current_row = *result->data_cursor;
+ if (result->data->data_cursor &&
+ (result->data->data_cursor - result->data->data) <
result->data->row_count)
+ {
+ zval **current_row = *result->data->data_cursor;
for (i = 0; i < result->field_count; i++) {
zval *data = current_row[i];
@@ -1430,10 +1444,10 @@
}
}
}
- result->data_cursor++;
+ result->data->data_cursor++;
*fetched_anything = TRUE;
} else {
- result->data_cursor = NULL;
+ result->data->data_cursor = NULL;
*fetched_anything = FALSE;
#ifndef MYSQLND_SILENT
php_printf("NO MORE DATA\n ");
@@ -1454,6 +1468,7 @@
unsigned int next_extend = STORE_RESULT_PREALLOCATED_SET, free_rows;
php_mysql_packet_row row_packet;
MYSQLND_RES *result;
+ zend_bool to_cache = FALSE;
if (!conn->current_result) {
return NULL;
@@ -1481,9 +1496,11 @@
/* Create room for 'next_extend' rows */
- result->conn = NULL; /* store result does not reference the connection */
- result->data = emalloc(next_extend * sizeof(zval **));
- result->row_buffers = emalloc(next_extend * sizeof(zend_uchar *));
+ result->conn = NULL; /* store result does not reference the connection */
+ result->data = pecalloc(1, sizeof(MYSQLND_RES_BUFFERED), to_cache);
+ result->data->data = pemalloc(next_extend * sizeof(zval **), to_cache);
+ result->data->row_buffers = pemalloc(next_extend * sizeof(zend_uchar *),
to_cache);
+ result->data->persistent = to_cache;
free_rows = next_extend;
@@ -1498,14 +1515,15 @@
if (!free_rows) {
unsigned long total_rows = free_rows = next_extend = next_extend * 5 / 3; /* extend
with 33% */
- total_rows += result->row_count;
- result->data = erealloc(result->data, total_rows * sizeof(zval **));
- result->row_buffers = erealloc(result->row_buffers, total_rows *
sizeof(zend_uchar *));
+ total_rows += result->data->row_count;
+ result->data->data = perealloc(result->data->data, total_rows *
sizeof(zval **), to_cache);
+ result->data->row_buffers = perealloc(result->data->row_buffers,
+ total_rows * sizeof(zend_uchar *), to_cache);
}
free_rows--;
- current_row = result->data[result->row_count] = row_packet.fields;
- result->row_buffers[result->row_count] = row_packet.row_buffer;
- result->row_count++;
+ current_row = result->data->data[result->data->row_count] =
row_packet.fields;
+ result->data->row_buffers[result->data->row_count] = row_packet.row_buffer;
+ result->data->row_count++;
/* So row_packet's destructor function won't efree() it */
row_packet.fields = NULL;
@@ -1533,7 +1551,7 @@
*/
}
MYSQLND_INC_CONN_STATISTIC_W_VALUE(&conn->stats, STAT_ROWS_FETCHED_FROM_CLIENT,
- result->row_count);
+ result->data->row_count);
/* Finally clean */
if (row_packet.eof) {
@@ -1551,10 +1569,10 @@
if (PASS == ret) {
/* Position at the first row */
- result->data_cursor = result->data;
+ result->data->data_cursor = result->data->data;
/* libmysql's documentation says it should be so for SELECT statements */
- conn->upsert_status.affected_rows = result->row_count;
+ conn->upsert_status.affected_rows = result->data->row_count;
} else {
mysqlnd_internal_free_result_contents(result TSRMLS_CC);
efree(result);
@@ -1577,7 +1595,9 @@
A PS could be prepared - there is metadata and thus a stmt->result but the
fetch_row function isn't actually set (NULL), thus we have to skip these.
*/
- if (!result->data && result->conn && !result->eof_reached
&& result->m.fetch_row) {
+ if (!result->data && result->conn && result->unbuf &&
+ !result->unbuf->eof_reached && result->m.fetch_row)
+ {
/* We have to fetch all data to clean the line */
MYSQLND_INC_CONN_STATISTIC(&result->conn->stats,
result->type == MYSQLND_RES_NORMAL? STAT_FLUSHED_NORMAL_SETS:
@@ -1617,10 +1637,10 @@
}
/* libmysql just moves to the end, it does traversing of a linked list */
- if (row >= result->row_count) {
- result->data_cursor = NULL;
+ if (row >= result->data->row_count) {
+ result->data->data_cursor = NULL;
} else {
- result->data_cursor = result->data + row;
+ result->data->data_cursor = result->data->data + row;
}
return PASS;
@@ -2021,7 +2041,7 @@
mynd_ulonglong _mysqlnd_num_rows(const MYSQLND_RES * const res)
{
/* Be compatible with libmysql. We count row_count, but will return 0 */
- return res->data? res->row_count:0;
+ return res->data? res->data->row_count:0;
}
/* }}} */
@@ -2458,14 +2478,17 @@
ulong i=0;
/* mysqlnd_fetch_all works with buffered resultsets only */
- if (result->conn || !result->row_count || !result->data_cursor ||
- result->data_cursor >= result->data + result->row_count) {
+ if (result->conn || !result->data ||
+ !result->data->row_count || !result->data->data_cursor ||
+ result->data->data_cursor >= result->data->data +
result->data->row_count) {
RETURN_NULL();
}
- mysqlnd_array_init(return_value, result->row_count);
+ mysqlnd_array_init(return_value, result->data->row_count);
- while (result->data_cursor && (result->data_cursor - result->data) <
result->row_count) {
+ while (result->data->data_cursor &&
+ (result->data->data_cursor - result->data->data) <
result->data->row_count)
+ {
MAKE_STD_ZVAL(row);
mysqlnd_fetch_into(result, flags, row);
add_index_zval(return_value, i++, row);
Modified: trunk/ext/mysqli/mysqlnd/mysqlnd.h
===================================================================
--- trunk/ext/mysqli/mysqlnd/mysqlnd.h 2007-03-21 15:24:52 UTC (rev 242)
+++ trunk/ext/mysqli/mysqlnd/mysqlnd.h 2007-03-21 19:07:06 UTC (rev 243)
@@ -697,6 +697,26 @@
};
+typedef struct st_mysqlnd_buffered_result {
+ zval ***data;
+ zval ***data_cursor;
+ zend_uchar **row_buffers;
+ zend_bool persistent;
+ mynd_ulonglong row_count;
+} MYSQLND_RES_BUFFERED;
+
+
+typedef struct st_mysqlnd_unbuffered_result {
+ /* For unbuffered (both normal and PS) */
+ zval **last_row_data;
+ zend_uchar *last_row_buffer;
+
+ mynd_ulonglong row_count;
+
+ zend_bool eof_reached;
+} MYSQLND_RES_UNBUFFERED;
+
+
struct st_mysqlnd_res {
MYSQLND *conn;
enum_mysqlnd_res_type type;
@@ -708,35 +728,17 @@
unsigned int current_field;
/* To be used with store_result() - both normal and PS */
- zval ***data;
- zval ***data_cursor;
- zend_uchar **row_buffers;
+ MYSQLND_RES_BUFFERED * data;
+ MYSQLND_RES_UNBUFFERED * unbuf;
- /* For unbuffered (both normal and PS) */
- zval **last_row_data;
- zend_uchar *last_row_buffer;
-
- /* For old-API myslqnd_fetch_row() */
- MYSQLND_ROW last_row;
-
/*
Column lengths of current row - both buffered and unbuffered.
For buffered results it duplicates the data found in **data
*/
unsigned long *lengths;
- /* To be used with use_result() */
- zend_bool eof_reached;
-
/*
- This is set at once with store_result() or grows with
- use_result(). To check whether the result set is unbuffered
- use 'conn', which is non-NULL in this case.
- */
- mynd_ulonglong row_count;
-
- /*
For future use in php_mysqlnd_rowp_read() .
For one time allocation of the row buffer
*/
@@ -863,7 +865,7 @@
#define mysqlnd_get_proto_info(conn) (conn)->protocol_version
#define mysqlnd_thread_id(conn) (conn)->thread_id
-#define mysqlnd_num_rows(result) ((result)->data? (result)->row_count:0)
+#define mysqlnd_num_rows(result) ((result)->data? (result)->data->row_count:0)
#define mysqlnd_num_fields(result) (result)->field_count
#define mysqlnd_fetch_lengths(result) ((result)->m.fetch_lengths?
(result)->m.fetch_lengths((result)):NULL)
Modified: trunk/ext/mysqli/mysqlnd/mysqlnd_ps.c
===================================================================
--- trunk/ext/mysqli/mysqlnd/mysqlnd_ps.c 2007-03-21 15:24:52 UTC (rev 242)
+++ trunk/ext/mysqli/mysqlnd/mysqlnd_ps.c 2007-03-21 19:07:06 UTC (rev 243)
@@ -65,6 +65,7 @@
int next_extend = 32, free_rows;
php_mysql_packet_row row_packet;
MYSQLND_RES *result;
+ zend_bool to_cache = FALSE;
/* be compliant with libmysql - NULL will turn */
if (!stmt->field_count) {
@@ -100,8 +101,10 @@
result->conn->m->free_reference(result->conn TSRMLS_CC);
result->conn = NULL; /* store result does not reference the connection */
}
- result->data = emalloc(next_extend * sizeof(zval **));
- result->row_buffers = emalloc(next_extend * sizeof(zend_uchar *));
+ result->data = pecalloc(1, sizeof(MYSQLND_RES_BUFFERED), to_cache);
+ result->data->data = pemalloc(next_extend * sizeof(zval **), to_cache);
+ result->data->row_buffers = pemalloc(next_extend * sizeof(zend_uchar *),
to_cache);
+ result->data->persistent= to_cache;
free_rows = next_extend;
@@ -116,14 +119,15 @@
if (!free_rows) {
unsigned long total_rows = free_rows = next_extend = next_extend * 5 / 3; /* extend
with 33% */
- total_rows += result->row_count;
- result->data = erealloc(result->data, total_rows * sizeof(zval **));
- result->row_buffers = erealloc(result->row_buffers, total_rows *
sizeof(zend_uchar *));
+ total_rows += result->data->row_count;
+ result->data->data = perealloc(result->data->data, total_rows *
sizeof(zval **), to_cache);
+ result->data->row_buffers = perealloc(result->data->row_buffers,
+ total_rows * sizeof(zend_uchar *), to_cache);
}
free_rows--;
- current_row = result->data[result->row_count] = row_packet.fields;
- result->row_buffers[result->row_count] = row_packet.row_buffer;
- result->row_count++;
+ current_row = result->data->data[result->data->row_count] =
row_packet.fields;
+ result->data->row_buffers[result->data->row_count] = row_packet.row_buffer;
+ result->data->row_count++;
/* So row_packet's destructor function won't efree() it */
row_packet.fields = NULL;
@@ -162,13 +166,13 @@
if (PASS == ret) {
/* Position at the first row */
- result->data_cursor = result->data;
+ result->data->data_cursor = result->data->data;
stmt->state = MYSQLND_STMT_USE_OR_STORE_CALLED;
/* libmysql API docs say it should be so for SELECT statements */
stmt->upsert_status.affected_rows =
stmt->conn->upsert_status.affected_rows =
- stmt->result->row_count;
+ stmt->result->data->row_count;
} else {
mysqlnd_internal_free_result_contents(stmt->result TSRMLS_CC);
efree(stmt->result);
@@ -499,10 +503,12 @@
MYSQLND_STMT *stmt = (MYSQLND_STMT *) param;
/* If we haven't read everything */
- if (result->data_cursor && (result->data_cursor - result->data) <
result->row_count) {
+ if (result->data->data_cursor &&
+ (result->data->data_cursor - result->data->data) <
result->data->row_count)
+ {
/* The user could have skipped binding - don't crash*/
if (stmt->result_bind) {
- zval **current_row = *result->data_cursor;
+ zval **current_row = *result->data->data_cursor;
for (i = 0; i < result->field_count; i++) {
/* copy the type */
if (stmt->result_bind[i].bound == TRUE) {
@@ -523,10 +529,10 @@
}
}
}
- result->data_cursor++;
+ result->data->data_cursor++;
*fetched_anything = TRUE;
} else {
- result->data_cursor = NULL;
+ result->data->data_cursor = NULL;
*fetched_anything = FALSE;
#ifndef MYSQLND_SILENT
php_printf("NO MORE DATA\n ");
@@ -547,8 +553,9 @@
unsigned int i, field_count = result->field_count;
php_mysql_packet_row *row_packet = result->row_packet;
- if (result->eof_reached) {
+ if (result->unbuf->eof_reached) {
/* No more rows obviously */
+ *fetched_anything = FALSE;
return PASS;
}
if (result->conn->state != CONN_FETCHING_DATA) {
@@ -564,20 +571,20 @@
mysqlnd_unbuffered_free_last_data() before it. The function returns always true.
*/
if (PASS == (ret = PACKET_READ(row_packet, result->conn)) &&
!row_packet->eof) {
- result->row_count++;
+ result->unbuf->row_count++;
*fetched_anything = TRUE;
if (!row_packet->skip_extraction) {
mysqlnd_unbuffered_free_last_data(result TSRMLS_CC);
- result->last_row_data = row_packet->fields;
- result->last_row_buffer = row_packet->row_buffer;
+ result->unbuf->last_row_data = row_packet->fields;
+ result->unbuf->last_row_buffer = row_packet->row_buffer;
row_packet->fields = NULL;
row_packet->row_buffer = NULL;
for (i = 0; i < field_count; i++) {
if (stmt->result_bind[i].bound == TRUE) {
- zval *data = result->last_row_data[i];
+ zval *data = result->unbuf->last_row_data[i];
/*
stmt->result_bind[i].zv has been already destructed
in mysqlnd_unbuffered_free_last_data()
@@ -613,7 +620,7 @@
/* Mark the connection as usable again */
if (row_packet->eof) {
- result->eof_reached = TRUE;
+ result->unbuf->eof_reached = TRUE;
result->conn->upsert_status.warning_count = row_packet->warning_count;
result->conn->upsert_status.server_status = row_packet->server_status;
/*
@@ -659,6 +666,8 @@
result->m.fetch_lengths = NULL; /* makes no sense */
result->zval_cache = NULL;
+ result->unbuf = ecalloc(1, sizeof(MYSQLND_RES_UNBUFFERED));
+
/*
Will be freed in the mysqlnd_internal_free_result_contents() called
by the resource destructor. mysqlnd_fetch_row_unbuffered() expects
@@ -718,15 +727,15 @@
unsigned int i, field_count = result->field_count;
mysqlnd_unbuffered_free_last_data(result TSRMLS_CC);
- result->last_row_data = row_packet->fields;
- result->last_row_buffer = row_packet->row_buffer;
+ result->unbuf->last_row_data = row_packet->fields;
+ result->unbuf->last_row_buffer = row_packet->row_buffer;
row_packet->fields = NULL;
row_packet->row_buffer = NULL;
if (!row_packet->skip_extraction) {
/* 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->last_row_data[i];
+ zval *data = result->unbuf->last_row_data[i];
/*
stmt->result_bind[i].zv has been already destructed
in mysqlnd_unbuffered_free_last_data()
@@ -747,7 +756,7 @@
}
}
}
- result->row_count++;
+ result->unbuf->row_count++;
*fetched_anything = TRUE;
/* We asked for one row, the next one should be EOF, eat it */
ret = PACKET_READ(row_packet, result->conn);
@@ -766,7 +775,7 @@
stmt->conn->upsert_status.server_status =
row_packet->server_status;
- result->eof_reached = row_packet->eof;
+ result->unbuf->eof_reached = row_packet->eof;
}
stmt->upsert_status.warning_count =
stmt->conn->upsert_status.warning_count =
@@ -1203,7 +1212,8 @@
result = mysqlnd_result_init(stmt->field_count, cache);
result->type = MYSQLND_RES_NORMAL;
result->m.fetch_row = result->m.fetch_row_normal_unbuffered;
- result->eof_reached = TRUE;
+ result->unbuf = ecalloc(1, sizeof(MYSQLND_RES_UNBUFFERED));
+ result->unbuf->eof_reached = TRUE;
result->fields= mysqlnd_result_metadata_clone_metadata(stmt->result);
return result;
| Thread |
|---|
| • PHP mysqlnd svn commit: r243 - in trunk/ext/mysqli: . mysqlnd | ahristov | 21 Mar |