List:Commits« Previous MessageNext Message »
From:ahristov Date:March 21 2007 9:02pm
Subject:PHP mysqlnd svn commit: r245 - trunk/ext/mysqli/mysqlnd
View as plain text  
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/mysqlndahristov21 Mar