List:Commits« Previous MessageNext Message »
From:ahristov Date:April 17 2007 11:05am
Subject:PHP mysqlnd svn commit: r326 - trunk/mysqlnd
View as plain text  
Author: ahristov
Date: 2007-04-17 13:05:06 +0200 (Tue, 17 Apr 2007)
New Revision: 326

Modified:
   trunk/mysqlnd/mysqlnd.c
   trunk/mysqlnd/mysqlnd_ps.c
   trunk/mysqlnd/mysqlnd_wireprotocol.c
   trunk/mysqlnd/mysqlnd_wireprotocol.h
Log:
Fix hanging of mysqlnd when error comes as part of result set.
Platform for checking is 
Bug #27876  SF with cyrillic variable name fails during execution

Which returns an error during execution. Thus no second EOF packet comes,
and the error packet wasn't recognised.


Modified: trunk/mysqlnd/mysqlnd.c
===================================================================
--- trunk/mysqlnd/mysqlnd.c	2007-04-17 10:05:50 UTC (rev 325)
+++ trunk/mysqlnd/mysqlnd.c	2007-04-17 11:05:06 UTC (rev 326)
@@ -1361,6 +1361,13 @@
 				}
 			}
 		}
+    } else if (ret == FAIL) {
+        if (row_packet->error_info.error_no) {
+            result->conn->error_info = row_packet->error_info; 
+        }
+    	*fetched_anything = FALSE;
+		result->conn->state = CONN_READY;
+		result->unbuf->eof_reached = TRUE; /* so next time we won't get an error */
 	} else if (row_packet->eof) {
 		/* Mark the connection as usable again */
 
@@ -1610,7 +1617,6 @@
 		conn->upsert_status.warning_count = row_packet.warning_count;
 		conn->upsert_status.server_status = row_packet.server_status;
 	}
-	PACKET_FREE_ALLOCA(row_packet);
 	/* save some memory */
 	if (free_rows) {
 		result->data->data = perealloc(result->data->data,
@@ -1634,11 +1640,13 @@
 		/* libmysql's documentation says it should be so for SELECT statements */
 		conn->upsert_status.affected_rows = result->data->row_count;
 	} else {
-		mysqlnd_internal_free_result_contents(result TSRMLS_CC);
-		efree(result);
+		mysqlnd_internal_free_result(result TSRMLS_CC);
 		result = NULL;
-		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Pretty serious error");
+	    conn->error_info = row_packet.error_info;
 	}
+
+	PACKET_FREE_ALLOCA(row_packet);
+
 	return result;
 }
 /* }}} */

Modified: trunk/mysqlnd/mysqlnd_ps.c
===================================================================
--- trunk/mysqlnd/mysqlnd_ps.c	2007-04-17 10:05:50 UTC (rev 325)
+++ trunk/mysqlnd/mysqlnd_ps.c	2007-04-17 11:05:06 UTC (rev 326)
@@ -150,12 +150,11 @@
 		  transfered above. 
 		*/
 	}
-	/* Finally clean */
 	if (row_packet.eof) {
+		/* Finally clean */
 		conn->upsert_status.warning_count = row_packet.warning_count;
 		conn->upsert_status.server_status = row_packet.server_status;
 	}
-	PACKET_FREE_ALLOCA(row_packet);
 	/* We can realloc here to save some memory, if free_rows > 0 ?*/
 
 	if (conn->upsert_status.server_status & SERVER_MORE_RESULTS_EXISTS) {
@@ -177,11 +176,14 @@
 		mysqlnd_internal_free_result_contents(stmt->result TSRMLS_CC);
 		efree(stmt->result);
 		stmt->result = NULL;
-		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Pretty serious error");
 		stmt->state = MYSQLND_STMT_PREPARED;
+		if (row_packet.error_info.error_no) {
+			conn->error_info = row_packet.error_info;
+		}
 	}
-	conn->state = CONN_READY;
 
+	PACKET_FREE_ALLOCA(row_packet);
+
 	return result;
 }
 /* }}} */

Modified: trunk/mysqlnd/mysqlnd_wireprotocol.c
===================================================================
--- trunk/mysqlnd/mysqlnd_wireprotocol.c	2007-04-17 10:05:50 UTC (rev 325)
+++ trunk/mysqlnd/mysqlnd_wireprotocol.c	2007-04-17 11:05:06 UTC (rev 326)
@@ -717,8 +717,8 @@
 	}
 }
 /* }}} */
+	
 
-
 /* {{{ php_mysqlnd_eof_read */
 static enum_func_status
 php_mysqlnd_eof_read(void *_packet, MYSQLND *conn TSRMLS_DC)
@@ -1252,7 +1252,7 @@
 					if (uns == TRUE && v > 9223372036854775807L)
 #elif SIZEOF_LONG==4
 					if ((uns == TRUE && v > L64(2147483647)) || 
-					    (uns == FALSE && (( L64(2147483647) < (my_int64) v) ||
+						(uns == FALSE && (( L64(2147483647) < (my_int64) v) ||
 						(L64(-2147483648) > (my_int64) v))))
 #endif
 					{
@@ -1279,7 +1279,7 @@
 			  to check if we need to call copy_ctor().
 
 			  XXX: Keep in mind that up there there is an open `else` in
-			       #ifdef MYSQLND_STRING_TO_INT_CONVERSION
+				   #ifdef MYSQLND_STRING_TO_INT_CONVERSION
 			*/
 			if ((perm_bind.is_possibly_blob == TRUE &&
 				packet->fields_metadata[i].charsetnr == MYSQLND_BINARY_CHARSET_NR) ||
@@ -1326,7 +1326,19 @@
 	/* packet->row_buffer is of size 'data_size + 1' */
 	packet->header.size = data_size;
 
-	if ((*(p = packet->row_buffer)) == 0xFE && data_size < 8) { /* EOF */
+	if ((*(p = packet->row_buffer)) == 0xFF) {
+		/*
+		   Error message as part of the result set,
+		   not good but we should not hang. See:
+		   Bug #27876 : SF with cyrillic variable name fails during execution
+		*/
+		ret = FAIL;
+		php_mysqlnd_read_error_from_line(p + 1, data_size - 1,
+										 packet->error_info.error,
+										 sizeof(packet->error_info.error),
+										 &packet->error_info.error_no,
+										 packet->error_info.sqlstate);
+	} else if (*packet->row_buffer == 0xFE && data_size < 8) { /* EOF */
 		packet->eof = TRUE;
 		p++;
 		if (data_size > 1) {
@@ -1335,7 +1347,6 @@
 			packet->server_status = uint2korr(p);
 			/* Seems we have 3 bytes reserved for future use */
 		}
-		goto end;
 	} else {
 		MYSQLND_INC_CONN_STATISTIC(&conn->stats, STAT_ROWS_FETCHED_FROM_SERVER);
 
@@ -1386,9 +1397,9 @@
 	/*
 	  Don't free packet->fields :
 	  - normal queries -> store_result() | fetch_row_unbuffered() will transfer
-	    the ownership and NULL it.
+		the ownership and NULL it.
 	  - PS will pass in it the bound variables, we have to use them! and of course
-	    not free the array. As it is passed to us, we should not clean it ourselves.
+		not free the array. As it is passed to us, we should not clean it ourselves.
 	*/
 	if (!alloca) {
 		efree(p);
@@ -1455,7 +1466,8 @@
 
 	if (0xFF == packet->error_code) {
 		php_mysqlnd_read_error_from_line(p, data_size - 1,
-										 packet->error_info.error, sizeof(packet->error_info.error),
+										 packet->error_info.error,
+										 sizeof(packet->error_info.error),
 										 &packet->error_info.error_no,
 										 packet->error_info.sqlstate);
 		return PASS;

Modified: trunk/mysqlnd/mysqlnd_wireprotocol.h
===================================================================
--- trunk/mysqlnd/mysqlnd_wireprotocol.h	2007-04-17 10:05:50 UTC (rev 325)
+++ trunk/mysqlnd/mysqlnd_wireprotocol.h	2007-04-17 11:05:06 UTC (rev 326)
@@ -258,6 +258,9 @@
 	zend_bool		skip_extraction;
 	zend_bool		binary_protocol;
 	MYSQLND_FIELD	*fields_metadata;
+
+	/* If error packet, we use these */
+	mysqlnd_error_info	error_info;
 };
 
 

Thread
PHP mysqlnd svn commit: r326 - trunk/mysqlndahristov17 Apr