MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:ahristov Date:February 28 2007 2:42pm
Subject:PHP mysqlnd svn commit: r79 - trunk/ext/mysqli/mysqlnd
View as plain text  
Author: ahristov
Date: 2007-02-28 15:42:48 +0100 (Wed, 28 Feb 2007)
New Revision: 79

Modified:
   trunk/ext/mysqli/mysqlnd/mysqlnd.c
   trunk/ext/mysqli/mysqlnd/mysqlnd.h
   trunk/ext/mysqli/mysqlnd/mysqlnd_ps.c
Log:
Make mysqlnd_stmt_free_result() work and be compatible with
libmysql.

free_result() before store_result() flushes the line. Actually parts
of the code is generic, as PS and non-PS share same packet extraction.
Thus they can share also the line flushing. Not far from being possible
to have PS be used in the old-way - fetching arrays instead of binding.



Modified: trunk/ext/mysqli/mysqlnd/mysqlnd.c
===================================================================
--- trunk/ext/mysqli/mysqlnd/mysqlnd.c	2007-02-28 10:32:02 UTC (rev 78)
+++ trunk/ext/mysqli/mysqlnd/mysqlnd.c	2007-02-28 14:42:48 UTC (rev 79)
@@ -186,21 +186,14 @@
 		result->row_count = 0;
 	}
 
+#ifndef WE_WANT_TO_USE_ROW_BUFFER_IN_ROWP_READ
 	if (result->row_buffer) {
 		efree(result->row_buffer);
 		result->row_buffer = NULL;
 		result->row_buffer_len = 0;
 	}
+#endif
 
-	if (result->row_packet) {
-		if (result->type == MYSQLND_RES_NORMAL) {
-			PACKET_FREE(result->row_packet);
-		} else {
-			PACKET_FREE(result->row_packet);
-		}
-		result->row_packet = NULL;
-	}
-
 	if (result->lengths) {
 		efree(result->lengths);
 		result->lengths = NULL;
@@ -217,6 +210,15 @@
 
 	result->m.free_result_buffers(result);
 
+	if (result->row_packet) {
+		if (result->type == MYSQLND_RES_NORMAL) {
+			PACKET_FREE(result->row_packet);
+		} else {
+			PACKET_FREE(result->row_packet);
+		}
+		result->row_packet = NULL;
+	}
+
 	result->conn = NULL;
 
 	if (meta) {
@@ -1130,7 +1132,7 @@
 		row_packet->fields = NULL;
 		row_packet->row_buffer = NULL;
 
-		if (row) {
+		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];
@@ -1411,7 +1413,7 @@
 	/* Unbuffered sets */
 	if (result->conn && !result->eof_reached) {
 		/* We have to fetch all data to clean the line */
-		while ((PASS == mysqlnd_fetch_row_unbuffered(result, NULL, 0, &fetched_anything
TSRMLS_CC)) &&
+		while ((PASS == result->m.fetch_row(result, NULL, 0, &fetched_anything
TSRMLS_CC)) &&
 			   fetched_anything == TRUE) {
 		}
 	}
@@ -1702,8 +1704,6 @@
 {
 	enum_func_status ret;
 
-
-	
 	switch (conn->state) {
 		case CONN_READY:
 			ret =  mysqlnd_simple_command(conn, COM_QUIT, NULL, 0, PROT_LAST,

Modified: trunk/ext/mysqli/mysqlnd/mysqlnd.h
===================================================================
--- trunk/ext/mysqli/mysqlnd/mysqlnd.h	2007-02-28 10:32:02 UTC (rev 78)
+++ trunk/ext/mysqli/mysqlnd/mysqlnd.h	2007-02-28 14:42:48 UTC (rev 79)
@@ -523,6 +523,7 @@
 	enum_func_status	(*prepare)(MYSQLND_STMT * const stmt, const char * const query,
unsigned int query_len TSRMLS_DC);
 	enum_func_status	(*execute)(MYSQLND_STMT * const stmt TSRMLS_DC);
 	MYSQLND_RES *		(*store_result)(MYSQLND_STMT * const stmt TSRMLS_DC);
+	enum_func_status	(*free_result)(MYSQLND_STMT * const stmt TSRMLS_DC);
 	enum_func_status	(*seek_data)(const MYSQLND_STMT * const stmt, mynd_ulonglong row);
 	enum_func_status	(*close)(MYSQLND_STMT * const stmt TSRMLS_DC); /* private */
 	enum_func_status	(*dtor)(MYSQLND_STMT * const stmt TSRMLS_DC); /* use this for
mysqlnd_stmt_close */
@@ -660,10 +661,12 @@
 	  For future use in php_mysqlnd_rowp_read() .
 	  For one time allocation of the row buffer
 	*/
+#ifndef WE_WANT_TO_USE_ROW_BUFFER_IN_ROWP_READ
 	zend_uchar		*row_buffer;
 	unsigned int 	row_buffer_len;
+#endif
 
-	php_mysql_packet_row	*row_packet;
+	php_mysql_packet_row	*row_packet;	/* Unused for PS */
 
 	/* zval cache */
 	MYSQLND_ZVAL_PCACHE	*zval_cache;
@@ -888,10 +891,11 @@
 
 /* PS */
 #define mysqlnd_stmt_init(conn)				(conn)->m->stmt_init((conn))
-#define mysqlnd_stmt_store_result(stmt)		(stmt)->m->store_result((stmt) TSRMLS_CC)
+#define mysqlnd_stmt_store_result(stmt)		((stmt)->m->store_result((stmt)
TSRMLS_CC)? PASS:FAIL)
 #define mysqlnd_stmt_data_seek(stmt, row)	(stmt)->m->seek_data((stmt), (row))
 #define mysqlnd_stmt_prepare(stmt, q, qlen) (stmt)->m->prepare((stmt), (q), (qlen)
TSRMLS_CC)
 #define mysqlnd_stmt_execute(stmt) 			(stmt)->m->execute((stmt) TSRMLS_CC)
+#define	mysqlnd_stmt_free_result(stmt)		(stmt)->m->free_result((stmt) TSRMLS_CC)
 #define	mysqlnd_stmt_close(stmt)			(stmt)->m->dtor((stmt) TSRMLS_CC)
 
 

Modified: trunk/ext/mysqli/mysqlnd/mysqlnd_ps.c
===================================================================
--- trunk/ext/mysqli/mysqlnd/mysqlnd_ps.c	2007-02-28 10:32:02 UTC (rev 78)
+++ trunk/ext/mysqli/mysqlnd/mysqlnd_ps.c	2007-02-28 14:42:48 UTC (rev 79)
@@ -82,6 +82,7 @@
 	MYSQLND_INC_CONN_STATISTIC(&conn->stats, STAT_PS_BUFFERED_SETS);
 
 	result = stmt->result;
+	result->type			= MYSQLND_RES_PS;
 	result->m.fetch_row		= mysqlnd_fetch_stmt_row_buffered;
 	result->m.fetch_lengths	= NULL;/* makes no sense */
 	result->zval_cache		= NULL;
@@ -161,6 +162,7 @@
 		stmt->state = MYSQLND_STMT_PREPARED;
 	}
 	conn->state = CONN_READY;
+
 	return result;
 }
 /* }}} */
@@ -282,17 +284,15 @@
 		/* Because results reference the connection. */
 		stmt_to_prepare->conn->references++;
 		/* Allocate the result now as it is needed for the reading of metadata */
-		result = mysqlnd_result_init(stmt_to_prepare->field_count, NULL);
+		stmt_to_prepare->result = result =
mysqlnd_result_init(stmt_to_prepare->field_count, NULL);
+		result->conn = stmt_to_prepare->conn;
+
 		result->type = MYSQLND_RES_PS;
 
 		if (FAIL == mysqlnd_read_result_metadata(stmt_to_prepare->conn, result TSRMLS_CC) ||
 			FAIL == mysqlnd_stmt_prepare_read_eof(stmt_to_prepare TSRMLS_CC)) {
-			efree(result);
 			goto fail;
 		}
-		result->conn = stmt_to_prepare->conn;
-
-		stmt_to_prepare->result = result;
 	}
 
 	if (stmt_to_prepare != stmt) {
@@ -303,13 +303,15 @@
 		memcpy(stmt, stmt_to_prepare, sizeof(MYSQLND_STMT));
 		efree(stmt_to_prepare);
 	}
-
+	stmt->state = MYSQLND_STMT_PREPARED;
 	return PASS;
 
 fail:
 	if (stmt_to_prepare != stmt) {
 		stmt_to_prepare->m->dtor(stmt_to_prepare TSRMLS_CC);
 	}
+	stmt->state = MYSQLND_STMT_INITTED;
+
 	return FAIL;
 }
 /* }}} */
@@ -320,10 +322,10 @@
 _mysqlnd_stmt_execute(MYSQLND_STMT * const stmt TSRMLS_DC)
 {
 	enum_func_status ret;
-	zend_bool free_request;
-	zend_uchar *request;
-	size_t request_len;
-	MYSQLND *conn = stmt->conn;
+	MYSQLND		*conn = stmt->conn;
+	zend_uchar	*request;
+	size_t		request_len;
+	zend_bool	free_request;
 
 	SET_ERROR_AFF_ROWS(stmt);
 	SET_ERROR_AFF_ROWS(stmt->conn);
@@ -397,7 +399,8 @@
 		} else if (conn->last_query_type == QUERY_LOAD_LOCAL) {
 			return PASS;
 		}
-	
+
+		stmt->result->type = MYSQLND_RES_PS;
 		stmt->result->field_count = conn->field_count;
 		stmt->result->lengths = NULL;
 		if (stmt->field_count) {
@@ -496,7 +499,7 @@
 		return FAIL;
 	}
 	/* Let the row packet fill our buffer and skip additional malloc + memcpy */
-	row_packet->skip_extraction = FALSE;
+	row_packet->skip_extraction = stmt? TRUE:FALSE;
 
 	/*
 	  If we skip rows (row == NULL) we have to
@@ -510,21 +513,23 @@
 		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];
-				/*
-				  stmt->result_bind[i].zv has been already destructed
-				  in mysqlnd_unbuffered_free_last_data()
-				*/
+		if (!row_packet->skip_extraction) {
+			for (i = 0; i < field_count; i++) {
+				if (stmt->result_bind[i].bound == TRUE) {
+					zval *data = result->last_row_data[i];
+					/*
+					  stmt->result_bind[i].zv has been already destructed
+					  in mysqlnd_unbuffered_free_last_data()
+					*/
 				
-				if (IS_NULL != (Z_TYPE_P(stmt->result_bind[i].zv) = Z_TYPE_P(data)) ) {
-					stmt->result_bind[i].zv->value = data->value;
+					if (IS_NULL != (Z_TYPE_P(stmt->result_bind[i].zv) = Z_TYPE_P(data)) ) {
+						stmt->result_bind[i].zv->value = data->value;
 
-					if ((Z_TYPE_P(data) == IS_STRING || Z_TYPE_P(data) == IS_UNICODE) 
-						 && (result->fields[i].max_length < Z_STRLEN_P(data)))
-					{
-						result->fields[i].max_length = Z_STRLEN_P(data);
+						if ((Z_TYPE_P(data) == IS_STRING || Z_TYPE_P(data) == IS_UNICODE) 
+							 && (result->fields[i].max_length < Z_STRLEN_P(data)))
+						{
+							result->fields[i].max_length = Z_STRLEN_P(data);
+						}
 					}
 				}
 			}
@@ -999,6 +1004,46 @@
 /* }}} */
 
 
+/* {{{ _mysqlnd_stmt_free_result */
+static enum_func_status
+_mysqlnd_stmt_free_result(MYSQLND_STMT * const stmt TSRMLS_DC)
+{
+	if (!stmt->result) {
+		return PASS;
+	}
+
+	if (stmt->state == MYSQLND_STMT_WAITING_USE_OR_STORE) {
+		/* Do implicit use_result and then flush the result */
+		stmt->default_rset_handler = _mysqlnd_stmt_store_result;
+		stmt->default_rset_handler(stmt TSRMLS_CC);
+	}
+
+	if (stmt->state > MYSQLND_STMT_WAITING_USE_OR_STORE) {
+		/* Flush if anything is left and unbuffered set */
+		stmt->result->m.skip_result(stmt->result TSRMLS_CC);
+		/*
+		  Separate the bound variables, which point to the result set, then
+		  destroy the set.
+		*/
+		if (stmt->result_bind) {
+			mysqlnd_stmt_separate_result_bind(stmt);
+		}
+
+		/* Now we can destroy the result set */
+		stmt->result->m.free_result_buffers(stmt->result);
+	}
+
+	/* As the buffers have been freed, we should go back to PREPARED */
+	stmt->state = MYSQLND_STMT_PREPARED;
+
+	/* Line is free! */
+	stmt->conn->state = CONN_READY;
+
+	return PASS;
+}
+/* }}} */
+
+
 /* {{{ mysqlnd_stmt_separate_result_bind */
 void mysqlnd_stmt_separate_result_bind(MYSQLND_STMT *stmt)
 {
@@ -1103,6 +1148,7 @@
 	_mysqlnd_stmt_prepare,
 	_mysqlnd_stmt_execute,
 	_mysqlnd_stmt_store_result,
+	_mysqlnd_stmt_free_result,
 	_mysqlnd_stmt_data_seek,
 	_mysqlnd_stmt_close,
 	_mysqlnd_stmt_dtor,

Thread
PHP mysqlnd svn commit: r79 - trunk/ext/mysqli/mysqlndahristov28 Feb