List:Internals« Previous MessageNext Message »
From:eugene Date:October 26 2005 10:59pm
Subject:bk commit into 4.1 tree (evgen:1.2467) BUG#14138
View as plain text  
Below is the list of changes that have just been committed into a local
4.1 repository of evgen. When evgen 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
  1.2467 05/10/27 00:59:51 evgen@stripped +4 -0
  Fix bug #14138 ROLLUP and PROCEDURE ANALYSE() hang server 
  
  Procedure analyse() redefines select's fields_list. setup_copy_fields() assumes
  that fields_list is a part of all_fields_list. Because select have only 
  3 columns and analyse() redefines it to have 10 columns, int overrun in
  setup_copy_fields() occurs and server goes to almost infinite loop.
  
  Because fields_list used not only to send data ad fields types, it's wrong 
  to allow procedure redefine it. This patch separates select's fileds_list 
  and procedure's one. Now if procedure is present, copy of fields_list is 
  created in procedure_fields_list and it is used for sending data and fields.

  mysql-test/t/analyse.test
    1.15 05/10/27 00:58:50 evgen@stripped +25 -0
    Test case for bug #14138  ROLLUP and PROCEDURE ANALYSE() hang server

  mysql-test/r/analyse.result
    1.18 05/10/27 00:58:39 evgen@stripped +26 -0
    Test case for bug #14138  ROLLUP and PROCEDURE ANALYSE() hang server 

  sql/sql_select.h
    1.77 05/10/27 00:58:28 evgen@stripped +1 -0
     Fix bug #14138  ROLLUP and PROCEDURE ANALYSE() hang server
    To JOIN  Added separate fields_list for procedure.

  sql/sql_select.cc
    1.441 05/10/27 00:58:16 evgen@stripped +14 -11
    Fix bug #14138  ROLLUP and PROCEDURE ANALYSE() hang server
    SELECT's fields_list and procedure's fields_list made split. If procedure is defined
then procedure's fields_list is used to send fields and data.

# 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:	evgen
# Host:	moonbone.local
# Root:	/work/14138-bug-4.1-mysql

--- 1.440/sql/sql_select.cc	2005-10-13 18:25:25 +04:00
+++ 1.441/sql/sql_select.cc	2005-10-27 00:58:16 +04:00
@@ -1044,17 +1044,20 @@
 JOIN::exec()
 {
   int      tmp_error;
+  List<Item> *columns_list= &fields_list;
   DBUG_ENTER("JOIN::exec");
   
   error= 0;
   if (procedure)
   {
-    if (procedure->change_columns(fields_list) ||
-	result->prepare(fields_list, unit))
+    procedure_fields_list= fields_list;
+    if (procedure->change_columns(procedure_fields_list) ||
+	result->prepare(procedure_fields_list, unit))
     {
       thd->limit_found_rows= thd->examined_row_count= 0;
       DBUG_VOID_RETURN;
     }
+    columns_list= &procedure_fields_list;
   }
   else if (test(select_options & OPTION_BUFFER_RESULT) &&
            result && result->prepare(fields_list, unit))
@@ -1071,7 +1074,7 @@
 		      (zero_result_cause?zero_result_cause:"No tables used"));
     else
     {
-      result->send_fields(fields_list,1);
+      result->send_fields(*columns_list, 1);
       /*
         We have to test for 'conds' here as the WHERE may not be constant
         even if we don't have any tables for prepared statements or if
@@ -1081,9 +1084,9 @@
           (!conds || conds->val_int()) &&
           (!having || having->val_int()))
       {
-	if (do_send_rows && (procedure ? (procedure->send_row(fields_list) ||
-                                          procedure->end_of_records())
-                                       : result->send_data(fields_list)))
+	if (do_send_rows &&
+            (procedure ? (procedure->send_row(procedure_fields_list) ||
+             procedure->end_of_records()) : result->send_data(fields_list)))
 	  error= 1;
 	else
 	{
@@ -1107,7 +1110,7 @@
 
   if (zero_result_cause)
   {
-    (void) return_zero_rows(this, result, tables_list, fields_list,
+    (void) return_zero_rows(this, result, tables_list, *columns_list,
 			    send_row_on_empty_set(),
 			    select_options,
 			    zero_result_cause,
@@ -5844,13 +5847,13 @@
   JOIN_TAB *join_tab;
   int (*end_select)(JOIN *, struct st_join_table *,bool);
   DBUG_ENTER("do_select");
-
+  List<Item> *columns_list= procedure ? &join->procedure_fields_list :
fields;
   join->procedure=procedure;
   /*
     Tell the client how many fields there are in a row
   */
   if (!table)
-    join->result->send_fields(*fields,1);
+    join->result->send_fields(*columns_list, 1);
   else
   {
     VOID(table->file->extra(HA_EXTRA_WRITE_CACHE));
@@ -5912,7 +5915,7 @@
 	error=(*end_select)(join,join_tab,1);
     }
     else if (join->send_row_on_empty_set())
-      error= join->result->send_data(*join->fields);
+      error= join->result->send_data(*columns_list);
   }
   else
   {
@@ -6611,7 +6614,7 @@
       DBUG_RETURN(0);				// Didn't match having
     error=0;
     if (join->procedure)
-      error=join->procedure->send_row(*join->fields);
+      error=join->procedure->send_row(join->procedure_fields_list);
     else if (join->do_send_rows)
       error=join->result->send_data(*join->fields);
     if (error)

--- 1.76/sql/sql_select.h	2005-06-23 17:13:38 +04:00
+++ 1.77/sql/sql_select.h	2005-10-27 00:58:28 +04:00
@@ -204,6 +204,7 @@
   //Part, shared with list above, emulate following list
   List<Item> tmp_fields_list1, tmp_fields_list2, tmp_fields_list3;
   List<Item> &fields_list; // hold field list passed to mysql_select
+  List<Item> procedure_fields_list;
   int error;
 
   ORDER *order, *group_list, *proc_param; //hold parameters of mysql_select

--- 1.17/mysql-test/r/analyse.result	2005-09-09 18:29:51 +04:00
+++ 1.18/mysql-test/r/analyse.result	2005-10-27 00:58:39 +04:00
@@ -108,3 +108,29 @@
 Field_name	Min_value	Max_value	Min_length	Max_length	Empties_or_zeros	Nulls	Avg_value_or_avg_length	Std	Optimal_fieldtype
 test.t1.d	100000	100000	6	6	0	0	100000	0	MEDIUMINT(6) UNSIGNED NOT NULL
 drop table t1;
+create table t1 (product varchar(32), country_id int not null, year int,
+profit int);
+insert into t1  values ( 'Computer', 2,2000, 1200),
+( 'TV', 1, 1999, 150),
+( 'Calculator', 1, 1999,50),
+( 'Computer', 1, 1999,1500),
+( 'Computer', 1, 2000,1500),
+( 'TV', 1, 2000, 150),
+( 'TV', 2, 2000, 100),
+( 'TV', 2, 2000, 100),
+( 'Calculator', 1, 2000,75),
+( 'Calculator', 2, 2000,75),
+( 'TV', 1, 1999, 100),
+( 'Computer', 1, 1999,1200),
+( 'Computer', 2, 2000,1500),
+( 'Calculator', 2, 2000,75),
+( 'Phone', 3, 2003,10)
+;
+create table t2 (country_id int primary key, country char(20) not null);
+insert into t2 values (1, 'USA'),(2,'India'), (3,'Finland');
+select product, sum(profit),avg(profit) from t1 group by product with rollup procedure
analyse();
+Field_name	Min_value	Max_value	Min_length	Max_length	Empties_or_zeros	Nulls	Avg_value_or_avg_length	Std	Optimal_fieldtype
+test.t1.product	Computer	TV	2	8	0	0	4.2500	NULL	ENUM('Computer','Phone','TV') NOT NULL
+sum(profit)	10	6900	2	4	0	0	1946	2868	ENUM('10','275','600','6900') NOT NULL
+avg(profit)	10.0000	1380.0000	7	9	0	0	394.6875	570.2003	ENUM('10.0000','68.7500','120.0000','1380.0000')
NOT NULL
+drop table t1,t2;

--- 1.14/mysql-test/t/analyse.test	2005-09-09 18:29:52 +04:00
+++ 1.15/mysql-test/t/analyse.test	2005-10-27 00:58:50 +04:00
@@ -57,4 +57,29 @@
 select * from t1 procedure analyse (1,1);
 drop table t1;
 
+#
+# Bug #14138 ROLLUP and PROCEDURE ANALYSE() hang server
+#
+create table t1 (product varchar(32), country_id int not null, year int,
+                 profit int);
+insert into t1  values ( 'Computer', 2,2000, 1200),
+    ( 'TV', 1, 1999, 150),
+    ( 'Calculator', 1, 1999,50),
+    ( 'Computer', 1, 1999,1500),
+    ( 'Computer', 1, 2000,1500),
+    ( 'TV', 1, 2000, 150),
+    ( 'TV', 2, 2000, 100),
+    ( 'TV', 2, 2000, 100),
+    ( 'Calculator', 1, 2000,75),
+    ( 'Calculator', 2, 2000,75),
+    ( 'TV', 1, 1999, 100),
+    ( 'Computer', 1, 1999,1200),
+    ( 'Computer', 2, 2000,1500),
+    ( 'Calculator', 2, 2000,75),
+    ( 'Phone', 3, 2003,10)
+    ;
+create table t2 (country_id int primary key, country char(20) not null); 
+insert into t2 values (1, 'USA'),(2,'India'), (3,'Finland');
+select product, sum(profit),avg(profit) from t1 group by product with rollup procedure
analyse();
+drop table t1,t2;
 # End of 4.1 tests
Thread
bk commit into 4.1 tree (evgen:1.2467) BUG#14138eugene26 Oct