summaryrefslogtreecommitdiff
path: root/ext/mysqlnd/mysqlnd_result_meta.c
diff options
context:
space:
mode:
authorXinchen Hui <laruence@php.net>2014-06-25 00:42:20 +0800
committerXinchen Hui <laruence@php.net>2014-06-25 00:42:20 +0800
commit8ce23d8f4fc5df0daec05642df8ead016f00fc32 (patch)
tree113281ad36f9f36eb7ad22816d328932a8bfc58a /ext/mysqlnd/mysqlnd_result_meta.c
parent284141ca8fa94dac846d593af0628dbfc719402e (diff)
downloadphp-git-8ce23d8f4fc5df0daec05642df8ead016f00fc32.tar.gz
Don't use zend_string for other fields (only name here is enough)
Diffstat (limited to 'ext/mysqlnd/mysqlnd_result_meta.c')
-rw-r--r--ext/mysqlnd/mysqlnd_result_meta.c87
1 files changed, 58 insertions, 29 deletions
diff --git a/ext/mysqlnd/mysqlnd_result_meta.c b/ext/mysqlnd/mysqlnd_result_meta.c
index 5bd9f0f0b2..d39300991d 100644
--- a/ext/mysqlnd/mysqlnd_result_meta.c
+++ b/ext/mysqlnd/mysqlnd_result_meta.c
@@ -33,26 +33,16 @@ static void
php_mysqlnd_free_field_metadata(MYSQLND_FIELD *meta, zend_bool persistent TSRMLS_DC)
{
if (meta) {
- if (meta->def) {
- STR_RELEASE(meta->def);
- }
- if (meta->name) {
- STR_RELEASE(meta->name);
- }
- if (meta->org_name) {
- STR_RELEASE(meta->org_name);
- }
- if (meta->table) {
- STR_RELEASE(meta->table);
- }
- if (meta->org_table) {
- STR_RELEASE(meta->org_table);
+ if (meta->root) {
+ mnd_pefree(meta->root, persistent);
+ meta->root = NULL;
}
- if (meta->db) {
- STR_RELEASE(meta->db);
+ if (meta->def) {
+ mnd_pefree(meta->def, persistent);
+ meta->def = NULL;
}
- if (meta->catalog) {
- STR_RELEASE(meta->catalog);
+ if (meta->sname) {
+ STR_RELEASE(meta->sname);
}
}
}
@@ -123,6 +113,12 @@ MYSQLND_METHOD(mysqlnd_res_meta, read_metadata)(MYSQLND_RES_METADATA * const met
for (;i < meta->field_count; i++) {
long idx;
+ if (meta->fields[i].root) {
+ /* We re-read metadata for PS */
+ mnd_pefree(meta->fields[i].root, meta->persistent);
+ meta->fields[i].root = NULL;
+ }
+
field_packet->metadata = &(meta->fields[i]);
if (FAIL == PACKET_READ(field_packet, conn)) {
PACKET_FREE(field_packet);
@@ -187,8 +183,8 @@ MYSQLND_METHOD(mysqlnd_res_meta, read_metadata)(MYSQLND_RES_METADATA * const met
/* For BC we have to check whether the key is numeric and use it like this */
if ((meta->zend_hash_keys[i].is_numeric =
- mysqlnd_is_key_numeric(field_packet->metadata->name->val,
- field_packet->metadata->name->len + 1,
+ mysqlnd_is_key_numeric(field_packet->metadata->name,
+ field_packet->metadata->name_length + 1,
&idx))) {
meta->zend_hash_keys[i].key = idx;
}
@@ -270,14 +266,47 @@ MYSQLND_METHOD(mysqlnd_res_meta, clone_metadata)(const MYSQLND_RES_METADATA * co
*/
memcpy(new_fields, orig_fields, (meta->field_count) * sizeof(MYSQLND_FIELD));
for (i = 0; i < meta->field_count; i++) {
- new_fields[i].name = STR_DUP(orig_fields[i].name, persistent);
- new_fields[i].org_name = STR_DUP(orig_fields[i].org_name, persistent);
- new_fields[i].table = STR_DUP(orig_fields[i].table, persistent);
- new_fields[i].org_table = STR_DUP(orig_fields[i].org_table, persistent);
- new_fields[i].db = STR_DUP(orig_fields[i].db, persistent);
- new_fields[i].catalog = STR_DUP(orig_fields[i].catalog, persistent);
+ /* First copy the root, then field by field adjust the pointers */
+ new_fields[i].root = mnd_pemalloc(orig_fields[i].root_len, persistent);
+
+ if (!new_fields[i].root) {
+ goto oom;
+ }
+
+ memcpy(new_fields[i].root, orig_fields[i].root, new_fields[i].root_len);
+
+ if (orig_fields[i].sname) {
+ new_fields[i].sname = STR_COPY(orig_fields[i].sname);
+ new_fields[i].name = new_fields[i].sname->val;
+ new_fields[i].name_length = new_fields[i].sname->len;
+ }
+
+ if (orig_fields[i].org_name && orig_fields[i].org_name != mysqlnd_empty_string) {
+ new_fields[i].org_name = new_fields[i].root +
+ (orig_fields[i].org_name - orig_fields[i].root);
+ }
+ if (orig_fields[i].table && orig_fields[i].table != mysqlnd_empty_string) {
+ new_fields[i].table = new_fields[i].root +
+ (orig_fields[i].table - orig_fields[i].root);
+ }
+ if (orig_fields[i].org_table && orig_fields[i].org_table != mysqlnd_empty_string) {
+ new_fields[i].org_table = new_fields[i].root +
+ (orig_fields[i].org_table - orig_fields[i].root);
+ }
+ if (orig_fields[i].db && orig_fields[i].db != mysqlnd_empty_string) {
+ new_fields[i].db = new_fields[i].root + (orig_fields[i].db - orig_fields[i].root);
+ }
+ if (orig_fields[i].catalog && orig_fields[i].catalog != mysqlnd_empty_string) {
+ new_fields[i].catalog = new_fields[i].root + (orig_fields[i].catalog - orig_fields[i].root);
+ }
+ /* def is not on the root, if allocated at all */
if (orig_fields[i].def) {
- new_fields[i].def = STR_DUP(orig_fields[i].def, persistent);
+ new_fields[i].def = mnd_pemalloc(orig_fields[i].def_length + 1, persistent);
+ if (!new_fields[i].def) {
+ goto oom;
+ }
+ /* copy the trailing \0 too */
+ memcpy(new_fields[i].def, orig_fields[i].def, orig_fields[i].def_length + 1);
}
}
new_meta->current_field = 0;
@@ -306,7 +335,7 @@ MYSQLND_METHOD(mysqlnd_res_meta, fetch_field)(MYSQLND_RES_METADATA * const meta
DBG_RETURN(NULL);
}
DBG_INF_FMT("name=%s max_length=%u",
- meta->fields[meta->current_field].name? meta->fields[meta->current_field].name->val:"",
+ meta->fields[meta->current_field].name? meta->fields[meta->current_field].name:"",
meta->fields[meta->current_field].max_length);
DBG_RETURN(&meta->fields[meta->current_field++]);
}
@@ -320,7 +349,7 @@ MYSQLND_METHOD(mysqlnd_res_meta, fetch_field_direct)(const MYSQLND_RES_METADATA
DBG_ENTER("mysqlnd_res_meta::fetch_field_direct");
DBG_INF_FMT("fieldnr=%u", fieldnr);
DBG_INF_FMT("name=%s max_length=%u",
- meta->fields[meta->current_field].name? meta->fields[meta->current_field].name->val:"",
+ meta->fields[meta->current_field].name? meta->fields[meta->current_field].name:"",
meta->fields[meta->current_field].max_length);
DBG_RETURN(&meta->fields[fieldnr]);
}