List:Commits« Previous MessageNext Message »
From:kgeorge Date:November 1 2006 10:59am
Subject:bk commit into 4.1 tree (gkodinov:1.2536) BUG#19216
View as plain text  
Below is the list of changes that have just been committed into a local
4.1 repository of kgeorge. When kgeorge does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2006-11-01 12:59:25+02:00, gkodinov@stripped +4 -0
  Bug #19216: Client crashes on long SELECT
   When sending column info the server was using a limited
   function not capable of sending more than 2 byte int
   to send the column count that is sent in front of the 
   column data.
   The client was allocating a block large enough to hold
   as many columns as the count is and then was storing
   all the columns in a sequence without checking if the 
   allocated block is large enough to hold them.
   Fixed the server to send correctly column counts
   larger than 64k.
   Fixed the client to count the incoming columns first
   and then allocate enough space to accommodate them all. 

  mysql-test/t/mysql_client.test@stripped, 2006-11-01 12:59:16+02:00, gkodinov@stripped +16 -0
    Bug #19216: Client crashes on long SELECT
     - test case

  sql-common/client.c@stripped, 2006-11-01 12:59:18+02:00, gkodinov@stripped +6 -0
    Bug #19216: Client crashes on long SELECT
     - fixed the client to react correctly on
       older servers (without the fix).

  sql/protocol.cc@stripped, 2006-11-01 12:59:17+02:00, gkodinov@stripped +6 -6
    Bug #19216: Client crashes on long SELECT
     - renamed the function for bether comprehention
       and made it local
     - used the right (non-local) function to transfer 
       the column count 

  sql/protocol.h@stripped, 2006-11-01 12:59:17+02:00, gkodinov@stripped +0 -1
    Bug #19216: Client crashes on long SELECT
     - made optimized net_store_length local

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	gkodinov
# Host:	macbook.gmz
# Root:	/Users/kgeorge/mysql/work/B19216-4.1-opt

--- 1.105/sql/protocol.cc	2006-01-18 21:50:26 +02:00
+++ 1.106/sql/protocol.cc	2006-11-01 12:59:17 +02:00
@@ -416,7 +416,7 @@
   ulonglong for bigger numbers.
 */
 
-char *net_store_length(char *pkg, uint length)
+static char *net_store_length_fast(char *pkg, uint length)
 {
   uchar *packet=(uchar*) pkg;
   if (length < 251)
@@ -439,7 +439,7 @@
 
 char *net_store_data(char *to,const char *from, uint length)
 {
-  to=net_store_length(to,length);
+  to=net_store_length_fast(to,length);
   memcpy(to,from,length);
   return to+length;
 }
@@ -448,7 +448,7 @@
 {
   char buff[20];
   uint length=(uint) (int10_to_str(from,buff,10)-buff);
-  to=net_store_length(to,length);
+  to=net_store_length_fast(to,length);
   memcpy(to,buff,length);
   return to+length;
 }
@@ -457,7 +457,7 @@
 {
   char buff[22];
   uint length=(uint) (longlong10_to_str(from,buff,10)-buff);
-  to=net_store_length(to,length);
+  to=net_store_length_fast(to,length);
   memcpy(to,buff,length);
   return to+length;
 }
@@ -520,7 +520,7 @@
 
   if (flag & 1)
   {				// Packet with number of elements
-    char *pos=net_store_length(buff, (uint) list->elements);
+    char *pos=net_store_length(buff, list->elements);
     (void) my_net_write(&thd->net, buff,(uint) (pos-buff));
   }
 
@@ -648,7 +648,7 @@
 {
   char *pos;
   char buff[20];
-  pos=net_store_length(buff, (uint) list->elements);
+  pos=net_store_length(buff, list->elements);
   pos=net_store_length(pos, records);
   return my_net_write(&thd->net, buff,(uint) (pos-buff));
 }

--- 1.93/sql-common/client.c	2006-09-27 15:49:13 +03:00
+++ 1.94/sql-common/client.c	2006-11-01 12:59:18 +02:00
@@ -1157,7 +1157,13 @@
   MYSQL_ROWS	*row;
   MYSQL_FIELD	*field,*result;
   ulong lengths[9];				/* Max of fields */
+  ulong field_count= 0;
   DBUG_ENTER("unpack_fields");
+
+  /* there can be more fields then the count is */
+  for (row=data->data; row ; row = row->next,field++)
+    field_count++;
+  fields= max(fields, field_count);
 
   field= result= (MYSQL_FIELD*) alloc_root(alloc,
 					   (uint) sizeof(*field)*fields);

--- 1.22/sql/protocol.h	2005-05-04 16:05:53 +03:00
+++ 1.23/sql/protocol.h	2006-11-01 12:59:17 +02:00
@@ -177,7 +177,6 @@
 	     const char *info=0);
 void send_eof(THD *thd, bool no_flush=0);
 bool send_old_password_request(THD *thd);
-char *net_store_length(char *packet,uint length);
 char *net_store_data(char *to,const char *from, uint length);
 char *net_store_data(char *to,int32 from);
 char *net_store_data(char *to,longlong from);

--- 1.3/mysql-test/t/mysql_client.test	2006-08-16 20:55:15 +03:00
+++ 1.4/mysql-test/t/mysql_client.test	2006-11-01 12:59:16 +02:00
@@ -33,3 +33,19 @@
 #
 --exec echo 'help' | $MYSQL   >  $MYSQLTEST_VARDIR/tmp/bug20328.tmp
 --exec echo 'help ' | $MYSQL  >  $MYSQLTEST_VARDIR/tmp/bug20328.tmp
+
+#
+# Bug #19216: Client crashes on long SELECT
+#
+--exec echo "select" > $MYSQLTEST_VARDIR/tmp/b19216.tmp
+let $i= 3400;
+while ($i)
+{
+  --exec echo "'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a'," >> $MYSQLTEST_VARDIR/tmp/b19216.tmp
+  dec $i;
+}
+
+--exec echo "'b';" >> $MYSQLTEST_VARDIR/tmp/b19216.tmp
+--disable_query_log
+--exec $MYSQL < $MYSQLTEST_VARDIR/tmp/b19216.tmp >/dev/null
+--enable_query_log
Thread
bk commit into 4.1 tree (gkodinov:1.2536) BUG#19216kgeorge1 Nov