List:Commits« Previous MessageNext Message »
From:Alexey Kopytov Date:October 30 2009 4:16pm
Subject:bzr commit into mysql-5.1-bugteam branch (Alexey.Kopytov:3169)
View as plain text  
#At file:///data/src/bzr/bugteam/mysql-5.1-bugteam/ based on revid:joro@stripped

 3169 Alexey Kopytov	2009-10-30 [merge]
      Automerge.

    modified:
      mysql-test/r/olap.result
      mysql-test/t/olap.test
      sql/sql_select.cc
      sql/sql_select.h
=== modified file 'mysql-test/r/olap.result'
--- a/mysql-test/r/olap.result	2007-11-23 08:35:02 +0000
+++ b/mysql-test/r/olap.result	2009-10-30 15:59:06 +0000
@@ -733,4 +733,24 @@ SELECT 1 FROM t1 GROUP BY (DATE(NULL)) W
 1
 1
 DROP TABLE t1;
+#
+# Bug #48131: crash group by with rollup, distinct,
+#             filesort, with temporary tables
+#
+CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY);
+INSERT INTO t1 VALUES (1), (2);
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (100);
+SELECT a, b FROM t1, t2 GROUP BY a, b WITH ROLLUP;
+a	b
+1	100
+1	NULL
+2	100
+2	NULL
+NULL	NULL
+SELECT DISTINCT b FROM t1, t2 GROUP BY a, b WITH ROLLUP;
+b
+100
+NULL
+DROP TABLE t1, t2;
 End of 5.0 tests

=== modified file 'mysql-test/t/olap.test'
--- a/mysql-test/t/olap.test	2007-11-21 16:53:44 +0000
+++ b/mysql-test/t/olap.test	2009-10-30 15:54:53 +0000
@@ -375,4 +375,19 @@ INSERT INTO t1 VALUES(0);
 SELECT 1 FROM t1 GROUP BY (DATE(NULL)) WITH ROLLUP;
 DROP TABLE t1;
 
+--echo #
+--echo # Bug #48131: crash group by with rollup, distinct,
+--echo #             filesort, with temporary tables
+--echo #
+
+CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY);
+INSERT INTO t1 VALUES (1), (2);
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (100);
+
+SELECT a, b FROM t1, t2 GROUP BY a, b WITH ROLLUP;
+SELECT DISTINCT b FROM t1, t2 GROUP BY a, b WITH ROLLUP;
+
+DROP TABLE t1, t2;
+
 --echo End of 5.0 tests

=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc	2009-10-30 14:13:13 +0000
+++ b/sql/sql_select.cc	2009-10-30 16:16:29 +0000
@@ -981,6 +981,12 @@ JOIN::optimize()
     DBUG_RETURN(1);
   }
 
+  if (select_lex->olap == ROLLUP_TYPE && rollup_process_const_fields())
+  {
+    DBUG_PRINT("error", ("Error: rollup_process_fields() failed"));
+    DBUG_RETURN(1);
+  }
+
   /* Remove distinct if only const tables */
   select_distinct= select_distinct && (const_tables != tables);
   thd_proc_info(thd, "preparing");
@@ -1111,7 +1117,7 @@ JOIN::optimize()
        join_tab[const_tables].select->quick->get_type() != 
        QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX))
   {
-    if (group_list &&
+    if (group_list && rollup.state == ROLLUP::STATE_NONE &&
        list_contains_unique_index(join_tab[const_tables].table,
                                  find_field_in_order_list,
                                  (void *) group_list))
@@ -1155,7 +1161,8 @@ JOIN::optimize()
     if (! hidden_group_fields && rollup.state == ROLLUP::STATE_NONE)
       select_distinct=0;
   }
-  else if (select_distinct && tables - const_tables == 1)
+  else if (select_distinct && tables - const_tables == 1 &&
+           rollup.state == ROLLUP::STATE_NONE)
   {
     /*
       We are only using one table. In this case we change DISTINCT to a
@@ -10227,6 +10234,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARA
     for (; cur_group ; cur_group= cur_group->next, key_part_info++)
     {
       Field *field=(*cur_group->item)->get_tmp_table_field();
+      DBUG_ASSERT(field->table == table);
       bool maybe_null=(*cur_group->item)->maybe_null;
       key_part_info->null_bit=0;
       key_part_info->field=  field;
@@ -15663,32 +15671,7 @@ bool JOIN::rollup_init()
       {
         item->maybe_null= 1;
         found_in_group= 1;
-        if (item->const_item())
-        {
-          /*
-            For ROLLUP queries each constant item referenced in GROUP BY list
-            is wrapped up into an Item_func object yielding the same value
-            as the constant item. The objects of the wrapper class are never
-            considered as constant items and besides they inherit all
-            properties of the Item_result_field class.
-            This wrapping allows us to ensure writing constant items
-            into temporary tables whenever the result of the ROLLUP
-            operation has to be written into a temporary table, e.g. when
-            ROLLUP is used together with DISTINCT in the SELECT list.
-            Usually when creating temporary tables for a intermidiate
-            result we do not include fields for constant expressions.
-	  */           
-          Item* new_item= new Item_func_rollup_const(item);
-          if (!new_item)
-            return 1;
-          new_item->fix_fields(thd, (Item **) 0);
-          thd->change_item_tree(it.ref(), new_item);
-          for (ORDER *tmp= group_tmp; tmp; tmp= tmp->next)
-          { 
-            if (*tmp->item == item)
-              thd->change_item_tree(tmp->item, new_item);
-          }
-        }
+        break;
       }
     }
     if (item->type() == Item::FUNC_ITEM && !found_in_group)
@@ -15707,6 +15690,59 @@ bool JOIN::rollup_init()
   }
   return 0;
 }
+
+/**
+   Wrap all constant Items in GROUP BY list.
+
+   For ROLLUP queries each constant item referenced in GROUP BY list
+   is wrapped up into an Item_func object yielding the same value
+   as the constant item. The objects of the wrapper class are never
+   considered as constant items and besides they inherit all
+   properties of the Item_result_field class.
+   This wrapping allows us to ensure writing constant items
+   into temporary tables whenever the result of the ROLLUP
+   operation has to be written into a temporary table, e.g. when
+   ROLLUP is used together with DISTINCT in the SELECT list.
+   Usually when creating temporary tables for a intermidiate
+   result we do not include fields for constant expressions.
+
+   @retval
+     0  if ok
+   @retval
+     1  on error
+*/
+
+bool JOIN::rollup_process_const_fields()
+{
+  ORDER *group_tmp;
+  Item *item;
+  List_iterator<Item> it(all_fields);
+
+  for (group_tmp= group_list; group_tmp; group_tmp= group_tmp->next)
+  {
+    if (!(*group_tmp->item)->const_item())
+      continue;
+    while ((item= it++))
+    {
+      if (*group_tmp->item == item)
+      {
+        Item* new_item= new Item_func_rollup_const(item);
+        if (!new_item)
+          return 1;
+        new_item->fix_fields(thd, (Item **) 0);
+        thd->change_item_tree(it.ref(), new_item);
+        for (ORDER *tmp= group_tmp; tmp; tmp= tmp->next)
+        {
+          if (*tmp->item == item)
+            thd->change_item_tree(tmp->item, new_item);
+        }
+        break;
+      }
+    }
+    it.rewind();
+  }
+  return 0;
+}
   
 
 /**

=== modified file 'sql/sql_select.h'
--- a/sql/sql_select.h	2009-10-14 08:46:50 +0000
+++ b/sql/sql_select.h	2009-10-30 15:59:06 +0000
@@ -512,6 +512,7 @@ public:
   }
 
   bool rollup_init();
+  bool rollup_process_const_fields();
   bool rollup_make_fields(List<Item> &all_fields, List<Item> &fields,
 			  Item_sum ***func);
   int rollup_send_data(uint idx);


Attachment: [text/bzr-bundle] bzr/alexey.kopytov@sun.com-20091030161629-3t1vs6su4q631hu1.bundle
Thread
bzr commit into mysql-5.1-bugteam branch (Alexey.Kopytov:3169)Alexey Kopytov30 Oct