Author: ahristov
Date: 2007-03-21 22:02:29 +0100 (Wed, 21 Mar 2007)
New Revision: 245
Modified:
trunk/ext/mysqli/mysqlnd/mysqlnd.c
trunk/ext/mysqli/mysqlnd/mysqlnd.h
trunk/ext/mysqli/mysqlnd/mysqlnd_ps.c
Log:
Extract the result metadata in a separate structure :)
Modified: trunk/ext/mysqli/mysqlnd/mysqlnd.c
===================================================================
--- trunk/ext/mysqli/mysqlnd/mysqlnd.c 2007-03-21 19:10:02 UTC (rev 244)
+++ trunk/ext/mysqli/mysqlnd/mysqlnd.c 2007-03-21 21:02:29 UTC (rev 245)
@@ -224,31 +224,37 @@
void mysqlnd_internal_free_result_metadata(MYSQLND_RES *result TSRMLS_DC)
{
int i;
- MYSQLND_FIELD *meta = result->fields;
+ MYSQLND_RES_METADATA *meta = result->meta;
+ MYSQLND_FIELD *fields;
- if (meta) {
+ if (!meta) {
+ return;
+ }
+
+ if ((fields = meta->fields)) {
i = result->field_count;
while (i--) {
- php_mysqlnd_free_field_metadata(meta++);
+ php_mysqlnd_free_field_metadata(fields++);
}
- efree(result->fields);
- result->fields = NULL;
+ efree(meta->fields);
+ meta->fields = NULL;
}
- if (result->zend_hash_keys) {
+ if (meta->zend_hash_keys) {
#if PHP_MAJOR_VERSION >= 6
if (UG(unicode)) {
for (i = 0; i < result->field_count; i++) {
- if (result->zend_hash_keys[i].ustr.v) {
- efree(result->zend_hash_keys[i].ustr.v);
+ if (meta->zend_hash_keys[i].ustr.v) {
+ efree(meta->zend_hash_keys[i].ustr.v);
}
}
}
#endif
- efree(result->zend_hash_keys);
- result->zend_hash_keys = NULL;
+ efree(meta->zend_hash_keys);
+ meta->zend_hash_keys = NULL;
}
-
+ efree(result->meta);
+ result->meta = NULL;
}
/* }}} */
@@ -918,9 +924,10 @@
mysqlnd_internal_free_result_metadata(result TSRMLS_CC);
/* +1 is to have empty marker at the end */
- result->fields = ecalloc(result->field_count + 1, sizeof(MYSQLND_FIELD));
- result->zend_hash_keys = ecalloc(result->field_count,
- sizeof(struct mysqlnd_field_hash_key));
+ result->meta = ecalloc(1, sizeof(MYSQLND_RES_METADATA));
+ result->meta->fields = ecalloc(result->field_count + 1, sizeof(MYSQLND_FIELD));
+ result->meta->zend_hash_keys = ecalloc(result->field_count,
+ sizeof(struct mysqlnd_field_hash_key));
/* 1. Read all fields metadata */
@@ -929,13 +936,13 @@
for (;i < result->field_count; i++) {
long idx;
- if (result->fields[i].root) {
+ if (result->meta->fields[i].root) {
/* We re-read metadata for PS */
- efree(result->fields[i].root);
- result->fields[i].root = NULL;
+ efree(result->meta->fields[i].root);
+ result->meta->fields[i].root = NULL;
}
- field_packet.metadata = &(result->fields[i]);
+ field_packet.metadata = &(result->meta->fields[i]);
if (FAIL == PACKET_READ_ALLOCA(field_packet, conn)) {
PACKET_FREE_ALLOCA(field_packet);
goto error;
@@ -947,31 +954,31 @@
UChar *ustr;
int ulen;
zend_string_to_unicode(UG(utf8_conv), &ustr, &ulen,
- result->fields[i].name,
- result->fields[i].name_length TSRMLS_CC);
- if ((result->zend_hash_keys[i].is_numeric =
+ result->meta->fields[i].name,
+ result->meta->fields[i].name_length TSRMLS_CC);
+ if ((result->meta->zend_hash_keys[i].is_numeric =
mysqlnd_unicode_is_key_numeric(ustr, ulen + 1, &idx)))
{
- result->zend_hash_keys[i].key = idx;
+ result->meta->zend_hash_keys[i].key = idx;
efree(ustr);
} else {
- result->zend_hash_keys[i].ustr.u = ustr;
- result->zend_hash_keys[i].ulen = ulen;
- result->zend_hash_keys[i].key = zend_u_get_hash_value(IS_UNICODE, ZSTR(ustr), ulen
+ 1);
+ result->meta->zend_hash_keys[i].ustr.u = ustr;
+ result->meta->zend_hash_keys[i].ulen = ulen;
+ result->meta->zend_hash_keys[i].key = zend_u_get_hash_value(IS_UNICODE,
ZSTR(ustr), ulen + 1);
}
} else
#endif
{
/* For BC we have to check whether the key is numeric and use it like this */
- if ((result->zend_hash_keys[i].is_numeric =
+ if ((result->meta->zend_hash_keys[i].is_numeric =
mysqlnd_is_key_numeric(field_packet.metadata->name,
field_packet.metadata->name_length + 1,
&idx)))
{
- result->zend_hash_keys[i].key = idx;
+ result->meta->zend_hash_keys[i].key = idx;
} else {
- result->zend_hash_keys[i].key =
+ result->meta->zend_hash_keys[i].key =
zend_get_hash_value(field_packet.metadata->name,
field_packet.metadata->name_length + 1);
}
@@ -1292,28 +1299,31 @@
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.
*/
- if (result->zend_hash_keys[i].is_numeric == FALSE) {
+ if (result->meta->zend_hash_keys[i].is_numeric == FALSE) {
#if PHP_MAJOR_VERSION >= 6
if (UG(unicode)) {
zend_u_hash_quick_update(Z_ARRVAL_P(row), IS_UNICODE,
- result->zend_hash_keys[i].ustr, result->zend_hash_keys[i].ulen + 1,
- result->zend_hash_keys[i].key,
+ result->meta->zend_hash_keys[i].ustr,
+ result->meta->zend_hash_keys[i].ulen + 1,
+ result->meta->zend_hash_keys[i].key,
(void *) &data, sizeof(zval *), NULL);
} else
#endif
{
zend_hash_quick_update(Z_ARRVAL_P(row),
- result->fields[i].name, result->fields[i].name_length + 1,
- result->zend_hash_keys[i].key,
+ result->meta->fields[i].name,
+ result->meta->fields[i].name_length + 1,
+ result->meta->zend_hash_keys[i].key,
(void *) &data, sizeof(zval *), NULL);
}
} else {
- zend_hash_index_update(Z_ARRVAL_P(row), result->zend_hash_keys[i].key,
+ zend_hash_index_update(Z_ARRVAL_P(row),
+ result->meta->zend_hash_keys[i].key,
(void *) &data, sizeof(zval *), NULL);
}
}
- if (result->fields[i].max_length < len) {
- result->fields[i].max_length = len;
+ if (result->meta->fields[i].max_length < len) {
+ result->meta->fields[i].max_length = len;
}
}
}
@@ -1377,7 +1387,7 @@
PACKET_INIT(result->row_packet, PROT_ROW_PACKET, php_mysql_packet_row *);
result->row_packet->field_count = result->field_count;
result->row_packet->binary_protocol = FALSE;
- result->row_packet->fields_metadata = result->fields;
+ result->row_packet->fields_metadata = result->meta->fields;
result->lengths = emalloc(result->field_count * sizeof(unsigned long));
/* No multithreading issues as we don't share the connection :) */
@@ -1423,23 +1433,26 @@
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.
*/
- if (result->zend_hash_keys[i].is_numeric == FALSE) {
+ if (result->meta->zend_hash_keys[i].is_numeric == FALSE) {
#if PHP_MAJOR_VERSION >= 6
if (UG(unicode)) {
zend_u_hash_quick_update(Z_ARRVAL_P(row), IS_UNICODE,
- result->zend_hash_keys[i].ustr, result->zend_hash_keys[i].ulen + 1,
- result->zend_hash_keys[i].key,
+ result->meta->zend_hash_keys[i].ustr,
+ result->meta->zend_hash_keys[i].ulen + 1,
+ result->meta->zend_hash_keys[i].key,
(void *) &data, sizeof(zval *), NULL);
} else
#endif
{
zend_hash_quick_update(Z_ARRVAL_P(row),
- result->fields[i].name, result->fields[i].name_length + 1,
- result->zend_hash_keys[i].key,
+ result->meta->fields[i].name,
+ result->meta->fields[i].name_length + 1,
+ result->meta->zend_hash_keys[i].key,
(void *) &data, sizeof(zval *), NULL);
}
} else {
- zend_hash_index_update(Z_ARRVAL_P(row), result->zend_hash_keys[i].key,
+ zend_hash_index_update(Z_ARRVAL_P(row),
+ result->meta->zend_hash_keys[i].key,
(void *) &data, sizeof(zval *), NULL);
}
}
@@ -1507,7 +1520,7 @@
PACKET_INIT_ALLOCA(row_packet, PROT_ROW_PACKET);
row_packet.field_count = result->field_count;
row_packet.binary_protocol = FALSE;
- row_packet.fields_metadata = result->fields;
+ row_packet.fields_metadata = result->meta->fields;
/* Let the row packet fill our buffer and skip additional malloc + memcpy */
while (FAIL != (ret = PACKET_READ_ALLOCA(row_packet, conn)) && !row_packet.eof)
{
int i;
@@ -1516,7 +1529,9 @@
if (!free_rows) {
unsigned long total_rows = free_rows = next_extend = next_extend * 5 / 3; /* extend
with 33% */
total_rows += result->data->row_count;
- result->data->data = perealloc(result->data->data, total_rows *
sizeof(zval **), to_cache);
+ 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);
}
@@ -1538,9 +1553,9 @@
*/
if (Z_TYPE_P(current_row[i]) != IS_NULL &&
(len = Z_STRLEN_P(current_row[i])) &&
- result->fields[i].max_length < len)
+ result->meta->fields[i].max_length < len)
{
- result->fields[i].max_length = len;
+ result->meta->fields[i].max_length = len;
}
}
/*
@@ -2059,9 +2074,9 @@
static MYSQLND_FIELD *
_mysqlnd_fetch_field(MYSQLND_RES * const result)
{
- if (result->current_field >= result->field_count)
+ if (!result->meta || result->meta->current_field >= result->field_count)
return NULL;
- return &result->fields[result->current_field++];
+ return &result->meta->fields[result->meta->current_field++];
}
/* }}} */
@@ -2070,7 +2085,7 @@
static MYSQLND_FIELD *
_mysqlnd_fetch_field_direct(const MYSQLND_RES * const result, MYSQLND_FIELD_OFFSET
fieldnr)
{
- return &result->fields[fieldnr];
+ return result->meta? &result->meta->fields[fieldnr]:NULL;
}
/* }}} */
@@ -2079,8 +2094,11 @@
static MYSQLND_FIELD_OFFSET
_mysqlnd_field_seek(MYSQLND_RES * const result, MYSQLND_FIELD_OFFSET field_offset)
{
- MYSQLND_FIELD_OFFSET return_value = result->current_field;
- result->current_field = field_offset;
+ MYSQLND_FIELD_OFFSET return_value = 0;
+ if (result->meta) {
+ return_value = result->meta->current_field;
+ result->meta->current_field = field_offset;
+ }
return return_value;
}
/* }}} */
@@ -2090,7 +2108,7 @@
static MYSQLND_FIELD_OFFSET
_mysqlnd_field_tell(const MYSQLND_RES * const result)
{
- return result->current_field;
+ return result->meta? result->meta->current_field:0;
}
/* }}} */
Modified: trunk/ext/mysqli/mysqlnd/mysqlnd.h
===================================================================
--- trunk/ext/mysqli/mysqlnd/mysqlnd.h 2007-03-21 19:10:02 UTC (rev 244)
+++ trunk/ext/mysqli/mysqlnd/mysqlnd.h 2007-03-21 21:02:29 UTC (rev 245)
@@ -697,6 +697,13 @@
};
+typedef struct st_mysqlnd_result_metadata {
+ MYSQLND_FIELD *fields;
+ struct mysqlnd_field_hash_key *zend_hash_keys;
+ unsigned int current_field;
+} MYSQLND_RES_METADATA;
+
+
typedef struct st_mysqlnd_buffered_result {
zval ***data;
zval ***data_cursor;
@@ -717,15 +724,19 @@
} MYSQLND_RES_UNBUFFERED;
+
struct st_mysqlnd_res {
MYSQLND *conn;
enum_mysqlnd_res_type type;
unsigned int field_count;
/* For metadata functions */
+ MYSQLND_RES_METADATA * meta;
+#if A0
MYSQLND_FIELD *fields;
struct mysqlnd_field_hash_key *zend_hash_keys;
unsigned int current_field;
+#endif
/* To be used with store_result() - both normal and PS */
MYSQLND_RES_BUFFERED * data;
@@ -871,9 +882,9 @@
#define mysqlnd_fetch_lengths(result) ((result)->m.fetch_lengths?
(result)->m.fetch_lengths((result)):NULL)
#define mysqlnd_field_seek(result, ofs) (result)->m.seek_field((result), (ofs))
-#define mysqlnd_field_tell(result) (result)->current_field
+#define mysqlnd_field_tell(result) ((result)->meta? (result)->current_field:0)
#define mysqlnd_fetch_field(result) (result)->m.fetch_field((result))
-#define mysqlnd_fetch_field_direct(result,fnr) &((result)->fields[(fnr)])
+#define mysqlnd_fetch_field_direct(result,fnr) ((result)->meta?
&((result)->fields[(fnr)]:NULL)
/* mysqlnd metadata */
#define mysqlnd_get_client_info() MYSQLND_VERSION
Modified: trunk/ext/mysqli/mysqlnd/mysqlnd_ps.c
===================================================================
--- trunk/ext/mysqli/mysqlnd/mysqlnd_ps.c 2007-03-21 19:10:02 UTC (rev 244)
+++ trunk/ext/mysqli/mysqlnd/mysqlnd_ps.c 2007-03-21 21:02:29 UTC (rev 245)
@@ -111,7 +111,7 @@
PACKET_INIT_ALLOCA(row_packet, PROT_ROW_PACKET);
row_packet.field_count = stmt->field_count;
row_packet.binary_protocol = TRUE;
- row_packet.fields_metadata = stmt->result->fields;
+ row_packet.fields_metadata = stmt->result->meta->fields;
/* Let the row packet fill our buffer and skip additional malloc + memcpy */
while (FAIL != (ret = PACKET_READ_ALLOCA(row_packet, conn)) && !row_packet.eof)
{
int i;
@@ -137,8 +137,8 @@
for (i = 0; i < row_packet.field_count; i++) {
if (Z_TYPE_P(current_row[i]) >= IS_STRING) {
unsigned long len = Z_STRLEN_P(current_row[i]);
- if (result->fields[i].max_length < len) {
- result->fields[i].max_length = len;
+ if (result->meta->fields[i].max_length < len) {
+ result->meta->fields[i].max_length = len;
}
}
}
@@ -599,9 +599,9 @@
|| Z_TYPE_P(data) == IS_UNICODE
#endif
)
- && (result->fields[i].max_length < Z_STRLEN_P(data)))
+ && (result->meta->fields[i].max_length < Z_STRLEN_P(data)))
{
- result->fields[i].max_length = Z_STRLEN_P(data);
+ result->meta->fields[i].max_length = Z_STRLEN_P(data);
}
}
}
@@ -676,7 +676,7 @@
PACKET_INIT(result->row_packet, PROT_ROW_PACKET, php_mysql_packet_row *);
result->row_packet->field_count = result->field_count;
result->row_packet->binary_protocol = TRUE;
- result->row_packet->fields_metadata = stmt->result->fields;
+ result->row_packet->fields_metadata = stmt->result->meta->fields;
result->lengths = NULL;
stmt->state = MYSQLND_STMT_USE_OR_STORE_CALLED;
@@ -748,9 +748,9 @@
|| Z_TYPE_P(data) == IS_UNICODE
#endif
)
- && (result->fields[i].max_length < Z_STRLEN_P(data)))
+ && (result->meta->fields[i].max_length < Z_STRLEN_P(data)))
{
- result->fields[i].max_length = Z_STRLEN_P(data);
+ result->meta->fields[i].max_length = Z_STRLEN_P(data);
}
}
}
@@ -1152,12 +1152,14 @@
/* {{{ mysqlnd_result_metadata_clone_metadata */
static
-MYSQLND_FIELD * mysqlnd_result_metadata_clone_metadata(MYSQLND_RES * const result)
+MYSQLND_RES_METADATA * mysqlnd_result_metadata_clone_metadata(MYSQLND_RES * const result)
{
unsigned int i;
/* +1 is to have empty marker at the end */
+ MYSQLND_RES_METADATA *ret = emalloc(sizeof(MYSQLND_RES_METADATA));
MYSQLND_FIELD *new_meta = ecalloc(result->field_count + 1, sizeof(MYSQLND_FIELD));
- MYSQLND_FIELD *original_meta = result->fields;
+ MYSQLND_FIELD *original_meta = result->meta->fields;
+ size_t len = result->field_count * sizeof(struct mysqlnd_field_hash_key);
/*
This will copy also the strings and the root, which we will have
@@ -1184,8 +1186,14 @@
memcpy(new_meta[i].def, original_meta[i].def, original_meta[i].def_length + 1);
}
}
+ ret->current_field = 0;
- return new_meta;
+ ret->fields = new_meta;
+
+ ret->zend_hash_keys = emalloc(len);
+ memcpy(ret->zend_hash_keys, result->meta->zend_hash_keys, len);
+
+ return ret;
}
/* }}} */
@@ -1214,7 +1222,7 @@
result->m.fetch_row = result->m.fetch_row_normal_unbuffered;
result->unbuf = ecalloc(1, sizeof(MYSQLND_RES_UNBUFFERED));
result->unbuf->eof_reached = TRUE;
- result->fields= mysqlnd_result_metadata_clone_metadata(stmt->result);
+ result->meta = mysqlnd_result_metadata_clone_metadata(stmt->result);
return result;
}
| Thread |
|---|
| • PHP mysqlnd svn commit: r245 - trunk/ext/mysqli/mysqlnd | ahristov | 21 Mar |