Author: ahristov
Date: 2007-03-14 17:02:58 +0100 (Wed, 14 Mar 2007)
New Revision: 141
Modified:
trunk/ext/mysqli/mysqlnd/mysqlnd.c
trunk/ext/mysqli/mysqlnd/mysqlnd.h
trunk/ext/mysqli/mysqlnd/mysqlnd_palloc.c
trunk/ext/mysqli/mysqlnd/mysqlnd_palloc.h
trunk/ext/mysqli/mysqlnd/mysqlnd_ps_codec.c
trunk/ext/mysqli/mysqlnd/mysqlnd_wireprotocol.c
Log:
Make mysqlnd unicode ready.
Already one test with cyrillic passes (normal statements)
Modified: trunk/ext/mysqli/mysqlnd/mysqlnd.c
===================================================================
--- trunk/ext/mysqli/mysqlnd/mysqlnd.c 2007-03-14 16:01:56 UTC (rev 140)
+++ trunk/ext/mysqli/mysqlnd/mysqlnd.c 2007-03-14 16:02:58 UTC (rev 141)
@@ -171,12 +171,14 @@
if (result->type == MYSQLND_RES_PS) {
/* For now PS always does create copies when fetching data */
zval_ptr_dtor(¤t_row[j]);
+
MYSQLND_INC_CONN_STATISTIC(NULL, STAT_COPY_ON_WRITE_PERFORMED);
} else {
zend_bool copy_ctor_called;
/* Free only if we haven't referenced it */
mysqlnd_palloc_zval_ptr_dtor(&(current_row[j]), result->zval_cache,
FALSE, ©_ctor_called TSRMLS_CC);
+
MYSQLND_INC_CONN_STATISTIC(NULL, copy_ctor_called? STAT_COPY_ON_WRITE_PERFORMED:
STAT_COPY_ON_WRITE_SAVED);
}
@@ -208,12 +210,44 @@
/* }}} */
-/* {{{ mysqlnd_internal_free_result_contents */
-void mysqlnd_internal_free_result_contents(MYSQLND_RES *result TSRMLS_DC)
+/* {{{ mysqlnd_internal_free_result_metadata */
+static
+void mysqlnd_internal_free_result_metadata(MYSQLND_RES *result TSRMLS_DC)
{
int i;
MYSQLND_FIELD *meta = result->fields;
+ if (meta) {
+ i = result->field_count;
+ while (i--) {
+ php_mysqlnd_free_field_metadata(meta++);
+ }
+ efree(result->fields);
+ result->fields = NULL;
+ }
+
+ if (result->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);
+ }
+ }
+ }
+#endif
+ efree(result->zend_hash_keys);
+ result->zend_hash_keys = NULL;
+ }
+
+}
+/* }}} */
+
+
+/* {{{ mysqlnd_internal_free_result_contents */
+void mysqlnd_internal_free_result_contents(MYSQLND_RES *result TSRMLS_DC)
+{
+
result->m.free_result_buffers(result TSRMLS_CC);
if (result->row_packet) {
@@ -227,20 +261,8 @@
result->conn = NULL;
- if (meta) {
- i = result->field_count;
- while (i--) {
- php_mysqlnd_free_field_metadata(meta++);
- }
- efree(result->fields);
- result->fields = NULL;
- }
+ mysqlnd_internal_free_result_metadata(result TSRMLS_CC);
- if (result->zend_hash_keys) {
- efree(result->zend_hash_keys);
- result->zend_hash_keys = NULL;
- }
-
if (result->zval_cache) {
mysqlnd_palloc_free_cache_reference(&result->zval_cache);
}
@@ -574,10 +596,10 @@
return NULL;
}
- if (!host) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Host is not valid");
- return NULL;
+ if (!host || !*host) {
+ host = "localhost";
}
+
if (!port && !socket) {
port = 3306;
}
@@ -770,6 +792,96 @@
/* }}} */
+/* {{{ mysqlnd_handle_numeric */
+/*
+ The following code is stolen from ZE - HANDLE_NUMERIC() macro from zend_hash.c
+ and modified for the needs of mysqlnd.
+*/
+static
+zend_bool mysqlnd_is_key_numeric(char *key, size_t length, long *idx)
+{
+ register char *tmp=key;
+
+ if (*tmp=='-') {
+ tmp++;
+ }
+ if ((*tmp>='0' && *tmp<='9')) {
+ do { /* possibly a numeric index */
+ char *end=key+length-1;
+
+ if (*tmp++=='0' && length>2) { /* don't accept numbers with leading zeros
*/
+ break;
+ }
+ while (tmp<end) {
+ if (!(*tmp>='0' && *tmp<='9')) {
+ break;
+ }
+ tmp++;
+ }
+ if (tmp==end && *tmp=='\0') { /* a numeric index */
+ if (*key=='-') {
+ *idx = strtol(key, NULL, 10);
+ if (*idx!=LONG_MIN) {
+ return TRUE;
+ }
+ } else {
+ *idx = strtol(key, NULL, 10);
+ if (*idx!=LONG_MAX) {
+ return TRUE;
+ }
+ }
+ }
+ } while (0);
+ }
+ return FALSE;
+}
+/* }}} */
+
+
+#if PHP_MAJOR_VERSION >= 6
+/* {{{ mysqlnd_unicode_is_key_numeric */
+static
+zend_bool mysqlnd_unicode_is_key_numeric(UChar *key, size_t length, long *idx)
+{
+ register UChar *tmp=key;
+
+ if (*tmp==0x2D /*'-'*/) {
+ tmp++;
+ }
+ if ((*tmp>=0x30 /*'0'*/ && *tmp<=0x39 /*'9'*/)) { /* possibly a numeric
index */
+ do {
+ UChar *end=key+length-1;
+
+ if (*tmp++==0x30 && length>2) { /* don't accept numbers with leading zeros
*/
+ break;
+ }
+ while (tmp<end) {
+ if (!(*tmp>=0x30 /*'0'*/ && *tmp<=0x39 /*'9'*/)) {
+ break;
+ }
+ tmp++;
+ }
+ if (tmp==end && *tmp==0) { /* a numeric index */
+ if (*key==0x2D /*'-'*/) {
+ *idx = zend_u_strtol(key, NULL, 10);
+ if (*idx!=LONG_MIN) {
+ return TRUE;
+ }
+ } else {
+ *idx = zend_u_strtol(key, NULL, 10);
+ if (*idx!=LONG_MAX) {
+ return TRUE;
+ }
+ }
+ }
+ } while (0);
+ }
+ return FALSE;
+}
+/* }}} */
+#endif
+
+
/* {{{ mysqlnd_read_result_metadata */
enum_func_status
mysqlnd_read_result_metadata(MYSQLND *conn, MYSQLND_RES *result TSRMLS_DC)
@@ -783,32 +895,19 @@
(select *) with altered table. Also for statements which skip the PS
infrastructure.
*/
- if (result->fields) {
- MYSQLND_FIELD *meta = result->fields;
+ mysqlnd_internal_free_result_metadata(result TSRMLS_CC);
- /*
- The last one is zeroed - we do this because
- result->field_count could be more than originally allocated, thus
- we will touch memory which we haven't allocated.
- */
- while (meta->name) {
- php_mysqlnd_free_field_metadata(meta++);
- }
- efree(result->fields);
- result->fields = NULL;
-
- efree(result->zend_hash_keys);
- result->zend_hash_keys = NULL;
- }
/* +1 is to have empty marker at the end */
result->fields = ecalloc(result->field_count + 1, sizeof(MYSQLND_FIELD));
- result->zend_hash_keys = emalloc(result->field_count * sizeof(unsigned long));
+ result->zend_hash_keys = ecalloc(result->field_count,
+ sizeof(struct mysqlnd_field_hash_key));
/* 1. Read all fields metadata */
/* It's safe to reread without freeing */
PACKET_INIT_ALLOCA(field_packet, PROT_RSET_FLD_PACKET);
for (;i < result->field_count; i++) {
+ long idx;
if (result->fields[i].root) {
/* We re-read metadata for PS */
@@ -821,8 +920,42 @@
PACKET_FREE_ALLOCA(field_packet);
goto error;
}
- result->zend_hash_keys[i] = zend_get_hash_value(field_packet.metadata->name,
- field_packet.metadata->name_length + 1);
+
+
+#if PHP_MAJOR_VERSION >= 6
+ if (UG(unicode)) {
+ 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 =
+ mysqlnd_unicode_is_key_numeric(ustr, ulen + 1, &idx)))
+ {
+ result->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);
+ }
+
+ } 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 =
+ mysqlnd_is_key_numeric(field_packet.metadata->name,
+ field_packet.metadata->name_length + 1,
+ &idx)))
+ {
+ result->zend_hash_keys[i].key = idx;
+ } else {
+ result->zend_hash_keys[i].key =
+ zend_get_hash_value(field_packet.metadata->name,
+ field_packet.metadata->name_length + 1);
+ }
+ }
}
PACKET_FREE_ALLOCA(field_packet);
@@ -1168,10 +1301,46 @@
if (flags & MYSQLND_FETCH_ASSOC) {
/* zend_hash_quick_update needs length + trailing zero */
/* QQ: Error handling ? */
- zend_hash_quick_update(row_ht,
- result->fields[i].name, result->fields[i].name_length + 1,
- result->zend_hash_keys[i],
- (void *) &data, sizeof(zval *), NULL);
+ /*
+ zend_hash_quick_update does not check, as add_assoc_zval_ex do, whether
+ 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 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,
+ (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,
+ (void *) &data, sizeof(zval *), NULL);
+ }
+/*
+ if (UG(unicode)) {
+ UChar *ustr;
+ uint ulen;
+
+ zend_string_to_unicode(UG(utf8_conv), &ustr, &ulen,
result->fields[i].name, result->fields[i].name_length TSRMLS_CC);
+ add_u_assoc_zval_ex(row, IS_UNICODE, ZSTR(ustr), ulen + 1, data);
+ efree(ustr);
+ } 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,
+ (void *) &data, sizeof(zval *), NULL);
+*/
+
+ } else {
+ zend_hash_index_update(Z_ARRVAL_P(row), result->zend_hash_keys[i].key,
+ (void *) &data, sizeof(zval *), NULL);
+ }
}
if (result->fields[i].max_length < len) {
result->fields[i].max_length = len;
@@ -1272,10 +1441,30 @@
if (flags & MYSQLND_FETCH_ASSOC) {
/* zend_hash_quick_update needs length + trailing zero */
/* QQ: Error handling ? */
- zend_hash_quick_update(Z_ARRVAL_P(row),
- result->fields[i].name, result->fields[i].name_length + 1,
- result->zend_hash_keys[i],
- (void *) &data, sizeof(zval *), NULL);
+ /*
+ zend_hash_quick_update does not check, as add_assoc_zval_ex do, whether
+ 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 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,
+ (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,
+ (void *) &data, sizeof(zval *), NULL);
+ }
+ } else {
+ zend_hash_index_update(Z_ARRVAL_P(row), result->zend_hash_keys[i].key,
+ (void *) &data, sizeof(zval *), NULL);
+ }
}
}
result->data_cursor++;
Modified: trunk/ext/mysqli/mysqlnd/mysqlnd.h
===================================================================
--- trunk/ext/mysqli/mysqlnd/mysqlnd.h 2007-03-14 16:01:56 UTC (rev 140)
+++ trunk/ext/mysqli/mysqlnd/mysqlnd.h 2007-03-14 16:02:58 UTC (rev 141)
@@ -677,15 +677,25 @@
typedef struct st_php_mysql_packet_row php_mysql_packet_row;
+struct mysqlnd_field_hash_key {
+ zend_bool is_numeric;
+ unsigned long key;
+#if PHP_MAJOR_VERSION >= 6
+ zstr ustr;
+ unsigned int ulen;
+#endif
+};
+
+
struct st_mysqlnd_res {
MYSQLND *conn;
enum_mysqlnd_res_type type;
unsigned int field_count;
/* For metadata functions */
- MYSQLND_FIELD *fields;
- unsigned int current_field;
- unsigned long *zend_hash_keys;
+ MYSQLND_FIELD *fields;
+ struct mysqlnd_field_hash_key *zend_hash_keys;
+ unsigned int current_field;
/* To be used with store_result() - both normal and PS */
zval ***data;
Modified: trunk/ext/mysqli/mysqlnd/mysqlnd_palloc.c
===================================================================
--- trunk/ext/mysqli/mysqlnd/mysqlnd_palloc.c 2007-03-14 16:01:56 UTC (rev 140)
+++ trunk/ext/mysqli/mysqlnd/mysqlnd_palloc.c 2007-03-14 16:02:58 UTC (rev 141)
@@ -36,6 +36,13 @@
#endif
+#if PHP_MAJOR_VERSION < 6
+#define IS_UNICODE_DISABLED (1)
+#else
+#define IS_UNICODE_DISABLED (!UG(unicode))
+#endif
+
+
/* {{{ mysqlnd_palloc_init_cache */
MYSQLND_ZVAL_PCACHE* mysqlnd_palloc_init_cache(unsigned int cache_size)
{
@@ -277,11 +284,12 @@
#endif
/* refcount is always > 1, because we call ZVAL_ADDREF(). Thus test refcount > 2
*/
*copy_ctor_called = FALSE;
+ /* Check whether cache is used and the zval is from the cache */
if (!cache || ((char *)*zv < (char *)cache->block || (char *)*zv > (char
*)cache->last_in_block)) {
/*
This zval is not from the cache block.
- Thus the refcount is -1 than of a zval from the cache, as the
- cache owns the latter.
+ Thus the refcount is -1 than of a zval from the cache,
+ because the zvals from the cache are owned by it.
*/
if (ZVAL_REFCOUNT(*zv) > 1) {
if (ps == FALSE) {
@@ -294,20 +302,22 @@
I suppose we can use UG(unicode) in mysqlnd.c when freeing a result set
to check if we need to call copy_ctor().
*/
-#if PHP_MAJOR_VERSION < 6
- zval_copy_ctor(*zv);
-#else
- if (!UG(unicode)) {
+ if (IS_UNICODE_DISABLED) {
zval_copy_ctor(*zv);
}
-#endif
*copy_ctor_called = TRUE;
} else {
/* For PS we copy stndup() the row buffers, so do nothing here */
}
} else if (ps == FALSE) {
- /* Prevent Zend from freeing PS allocated data */
- ZVAL_NULL(*zv);
+ /*
+ Prevent Zend from freeing PS allocated data.
+ Also don't null in Unicode mode as then the data doesn't point to
+ the internal buffers and we will leak if we do this trick.
+ */
+ if (IS_UNICODE_DISABLED) {
+ ZVAL_NULL(*zv);
+ }
}
zval_ptr_dtor(zv);
return;
@@ -317,28 +327,24 @@
if (ZVAL_REFCOUNT(*zv) > 2) {
/*
Because the zval is first in mysqlnd_zval structure, then we can do
- upcasting from zval to mysqlnd_zval here, because we know that this
+ upcasting from zval to mysqlnd_zval here. Because we know that this
zval is part of our pre-allocated block.
- Now check whether this zval points to ZE allocated memory our to our
- buffers. If so, call copy_ctor() which will do estrndup for strings.
- And nothing for null, int, double.
+ Now check whether this zval points to ZE allocated memory or to our
+ buffers. If it points to the internal buffers, call copy_ctor()
+ which will do estrndup for strings. And nothing for null, int, double.
*/
- if (((mysqlnd_zval *)*zv)->ze_alloced == FALSE) {
+ if (((mysqlnd_zval *)*zv)->copy_alloced_on_result_free == FALSE) {
/*
In Unicode mode the destruction of the zvals should not call
zval_copy_ctor() because then we will leak.
I suppose we can use UG(unicode) in mysqlnd.c when freeing a result set
to check if we need to call copy_ctor().
*/
-#if PHP_MAJOR_VERSION < 6
- zval_copy_ctor(*zv);
-#else
- if (!UG(unicode)) {
- zval_copy_ctor(*zv);
+ if (IS_UNICODE_DISABLED) {
+ zval_copy_ctor(*zv);
}
-#endif
- ((mysqlnd_zval *)*zv)->ze_alloced = TRUE;
+ ((mysqlnd_zval *)*zv)->copy_alloced_on_result_free = TRUE;
*copy_ctor_called = TRUE;
}
/*
@@ -364,11 +370,18 @@
++cache->put_hits;
++cache->free_items;
- if (((mysqlnd_zval *)*zv)->ze_alloced == TRUE) {
+ if (((mysqlnd_zval *)*zv)->copy_alloced_on_result_free == TRUE) {
zval_dtor(*zv);
- ((mysqlnd_zval *)*zv)->ze_alloced = FALSE;
+ ((mysqlnd_zval *)*zv)->copy_alloced_on_result_free = FALSE;
}
ZVAL_DELREF(*zv); /* Make it 1 */
+ if (!IS_UNICODE_DISABLED) {
+ /*
+ When unicode is enabled we copy in rowp_read.
+ Thus we have to clean here.
+ */
+ zval_dtor(*zv);
+ }
ZVAL_NULL(*zv);
*(--cache->free_list->last_added) = (mysqlnd_zval *)*zv;
@@ -399,13 +412,9 @@
LOCK_PCACHE(cache);
for (i = 0; i < cache->max_items; i++) {
- /*
- For PS, could be for Unicode and normal statements too, when
- implemented.
- */
- if (cache->block[i].ze_alloced == TRUE) {
+ if (cache->block[i].copy_alloced_on_result_free == TRUE) {
zval_dtor(&(cache->block[i].zv));
- cache->block[i].ze_alloced = FALSE;
+ cache->block[i].copy_alloced_on_result_free = FALSE;
}
}
UNLOCK_PCACHE(cache);
Modified: trunk/ext/mysqli/mysqlnd/mysqlnd_palloc.h
===================================================================
--- trunk/ext/mysqli/mysqlnd/mysqlnd_palloc.h 2007-03-14 16:01:56 UTC (rev 140)
+++ trunk/ext/mysqli/mysqlnd/mysqlnd_palloc.h 2007-03-14 16:02:58 UTC (rev 141)
@@ -47,7 +47,7 @@
typedef struct st_mysqlnd_zval {
/* Should be first */
zval zv;
- zend_bool ze_alloced;
+ zend_bool copy_alloced_on_result_free;
} mysqlnd_zval;
Modified: trunk/ext/mysqli/mysqlnd/mysqlnd_ps_codec.c
===================================================================
--- trunk/ext/mysqli/mysqlnd/mysqlnd_ps_codec.c 2007-03-14 16:01:56 UTC (rev 140)
+++ trunk/ext/mysqli/mysqlnd/mysqlnd_ps_codec.c 2007-03-14 16:02:58 UTC (rev 141)
@@ -123,12 +123,7 @@
#if PHP_MAJOR_VERSION < 6
ZVAL_STRING(zv, tmp, 0);
#else
- if (UG(unicode)) {
- ZVAL_UTF8_STRINGL(zv, tmp, 10, 0);
- efree(tmp);
- } else {
- ZVAL_STRING(zv, tmp, 0);
- }
+ ZVAL_UTF8_STRINGL(zv, tmp, 10, ZSTR_AUTOFREE);
#endif
} else {
ZVAL_LONG(zv, uval);
@@ -241,15 +236,10 @@
#if PHP_MAJOR_VERSION < 6
ZVAL_STRINGL(zv, to, length, 1);
+ efree(to);
#else
- if (UG(unicode)) {
- ZVAL_UTF8_STRINGL(zv, to, length, ZSTR_DUPLICATE);
- } else {
- ZVAL_STRINGL(zv, to, length, 1);
- }
+ ZVAL_UTF8_STRINGL(zv, to, length, ZSTR_AUTOFREE);
#endif
-
- efree(to);
}
@@ -287,15 +277,10 @@
#if PHP_MAJOR_VERSION < 6
ZVAL_STRINGL(zv, to, length, 1);
+ efree(to);
#else
- if (UG(unicode)) {
- ZVAL_UTF8_STRINGL(zv, to, length, ZSTR_DUPLICATE);
- } else {
- ZVAL_STRINGL(zv, to, length, 1);
- }
+ ZVAL_UTF8_STRINGL(zv, to, length, ZSTR_AUTOFREE);
#endif
-
- efree(to);
}
@@ -341,15 +326,10 @@
#if PHP_MAJOR_VERSION < 6
ZVAL_STRINGL(zv, to, length, 1);
+ efree(to);
#else
- if (UG(unicode)) {
- ZVAL_UTF8_STRINGL(zv, to, length, ZSTR_DUPLICATE);
- } else {
- ZVAL_STRINGL(zv, to, length, 1);
- }
+ ZVAL_UTF8_STRINGL(zv, to, length, ZSTR_AUTOFREE);
#endif
-
- efree(to);
}
@@ -366,11 +346,7 @@
#if PHP_MAJOR_VERSION < 6
ZVAL_STRINGL(zv, (char *)*row, length, 1);
#else
- if (UG(unicode)) {
- ZVAL_UTF8_STRINGL(zv, (char*)*row, length, ZSTR_DUPLICATE);
- } else {
- ZVAL_STRINGL(zv, (char *)*row, length, 1);
- }
+ ZVAL_UTF8_STRINGL(zv, (char*)*row, length, ZSTR_DUPLICATE);
#endif
(*row) += length;
Modified: trunk/ext/mysqli/mysqlnd/mysqlnd_wireprotocol.c
===================================================================
--- trunk/ext/mysqli/mysqlnd/mysqlnd_wireprotocol.c 2007-03-14 16:01:56 UTC (rev 140)
+++ trunk/ext/mysqli/mysqlnd/mysqlnd_wireprotocol.c 2007-03-14 16:02:58 UTC (rev 141)
@@ -1193,8 +1193,9 @@
if (allocated) {
*current_field = (zval *) obj;
} else {
+ /* It's from the cache, so we can upcast here */
*current_field = &((mysqlnd_zval *) obj)->zv;
- ((mysqlnd_zval *) obj)->ze_alloced = FALSE;
+ ((mysqlnd_zval *) obj)->copy_alloced_on_result_free = FALSE;
}
if (current_field > start_field && last_field_was_string) {
@@ -1227,14 +1228,11 @@
Which in turn means that we can free the buffers once we have
stored the result set, if we use store_result(). Also the destruction
of the zvals should not call zval_copy_ctor() because then we will leak.
- I suppose we can use UG(unicode) in mysqlnd.c when freeing a result set
+ I suppose we can use UG(unicode) in mysqlnd.c/mysqlnd_palloc.c when
+ freeing a result set
to check if we need to call copy_ctor().
*/
- if (UG(unicode)) {
- ZVAL_UTF8_STRINGL(*current_field, (char *)p, len, ZSTR_DUPLICATE);
- } else {
- ZVAL_STRINGL(*current_field, (char *)p, len, 0);
- }
+ ZVAL_UTF8_STRINGL(*current_field, (char *)p, len, 0);
#endif
p += len;
last_field_was_string = TRUE;
| Thread |
|---|
| • PHP mysqlnd svn commit: r141 - trunk/ext/mysqli/mysqlnd | ahristov | 14 Mar |