List:Internals« Previous MessageNext Message »
From:ramil Date:May 31 2005 10:02am
Subject:bk commit into 5.0 tree (ramil:1.1940)
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of ram. When ram 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.1940 05/05/31 15:02:22 ramil@stripped +6 -0
  merging

  sql/sql_select.cc
    1.330 05/05/31 15:02:17 ramil@stripped +0 -0
    merging

  sql/item_sum.cc
    1.145 05/05/31 15:02:17 ramil@stripped +2 -6
    merging

  mysql-test/t/olap.test
    1.17 05/05/31 15:02:17 ramil@stripped +0 -0
    merging

  mysql-test/t/func_gconcat.test
    1.27 05/05/31 15:02:17 ramil@stripped +0 -1
    merging

  mysql-test/r/olap.result
    1.21 05/05/31 15:02:17 ramil@stripped +1 -2
    merging

  mysql-test/r/func_gconcat.result
    1.37 05/05/31 15:02:17 ramil@stripped +14 -14
    merging

# 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:	ramil
# Host:	gw.mysql.r18.ru
# Root:	/usr/home/ram/work/mysql-5.0/RESYNC

--- 1.144/sql/item_sum.cc	2005-05-26 22:54:25 +05:00
+++ 1.145/sql/item_sum.cc	2005-05-31 15:02:17 +05:00
@@ -2611,7 +2611,6 @@
   Item_func_group_concat* grp_item= (Item_func_group_concat*)arg;
   TABLE *table= grp_item->table;
   Item **field_item, **end;
-  char *record= (char*) table->record[0] + table->s->null_bytes;
 
   for (field_item= grp_item->args, end= field_item + grp_item->arg_count_field;
        field_item < end;
@@ -2626,7 +2625,7 @@
     if (field)
     {
       int res;
-      uint offset= (uint) (field->ptr - record);
+      uint offset= field->offset();
       if ((res= field->cmp((char *) key1 + offset, (char *) key2 + offset)))
 	return res;
     }
@@ -2644,8 +2643,6 @@
 {
   Item_func_group_concat* grp_item= (Item_func_group_concat*) arg;
   ORDER **order_item, **end;
-  TABLE *table= grp_item->table;
-  char *record= (char*) table->record[0] + table->s->null_bytes;
 
   for (order_item= grp_item->order, end=order_item+ grp_item->arg_count_order;
        order_item < end;
@@ -2662,7 +2659,7 @@
     if (field)
     {
       int res;
-      uint offset= (uint) (field->ptr - record);
+      uint offset= field->offset();
       if ((res= field->cmp((char *) key1 + offset, (char *) key2 + offset)))
         return (*order_item)->asc ? res : -res;
     }
@@ -2703,7 +2700,6 @@
                   Item_func_group_concat *item)
 {
   TABLE *table= item->table;
-  char *record= (char*) table->record[0] + table->s->null_bytes;
   String tmp((char *)table->record[1], table->s->reclength, default_charset_info), tmp2;
   String *result= &item->result;
   Item **arg= item->args, **arg_end= item->args + item->arg_count_field;
@@ -2727,9 +2723,8 @@
       */
       Field *field= (*arg)->get_tmp_table_field();
       char *save_ptr= field->ptr;
-      uint offset= (uint) (save_ptr - record);
-      DBUG_ASSERT(offset < table->s->reclength);
-      field->ptr= (char *) key + offset;
+      DBUG_ASSERT(field->offset() < item->table->reclength);
+      field->ptr= (char *) key + field->offset();
       res= field->val_str(&tmp,&tmp2);
       field->ptr= save_ptr;
     }
@@ -2908,19 +2903,13 @@
   copy_fields(tmp_table_param);
   copy_funcs(tmp_table_param->items_to_copy);
 
-  for (uint i= 0; i < arg_count_field; i++)
+  for (Item **arg= args, **arg_end= args + arg_count_field;
+       arg < arg_end; arg++)
   {
-    Item *show_item= args[i];
-    if (!show_item->const_item())
-    {
-      /*
-        Here we use real_item as we want the original field data that should
-        be written to table->record[0]
-      */
-      Field *f= show_item->real_item()->get_tmp_table_field();
-      if (f->is_null())
-        return 0;                               // Skip row if it contains null
-    }
+    if (!(*arg)->const_item() &&
+        (*arg)->get_tmp_table_field()->is_null_in_record(
+          (const uchar*) table->record[0]))
+	return 0;				// Skip row if it contains null
   }
 
   null_value= FALSE;
@@ -2989,6 +2978,11 @@
   SELECT_LEX *select_lex= thd->lex->current_select;
   qsort_cmp2 compare_key;
   DBUG_ENTER("Item_func_group_concat::setup");
+
+  if (!(tmp_table_param= new TMP_TABLE_PARAM))
+    return 1;
+  /* We'll convert all blobs to varchar fields in the temporary table */
+  tmp_table_param->convert_blob_length= group_concat_max_len;
 
   /*
     Currently setup() can be called twice. Please add

--- 1.329/sql/sql_select.cc	2005-05-30 21:56:08 +05:00
+++ 1.330/sql/sql_select.cc	2005-05-31 15:02:17 +05:00
@@ -12807,6 +12807,76 @@
   ROLLUP handling
 ****************************************************************************/
 
+/*
+  Replace occurences of group by fields in an expression by ref items
+
+  SYNOPSIS
+    change_group_ref()
+    thd                  reference to the context
+    expr                 expression to make replacement
+    group_list           list of references to group by items
+    changed        out:  returns 1 if item contains a replaced field item 
+     
+  DESCRIPTION
+    The function replaces occurrences of group by fields in expr
+    by ref objects for these fields unless they are under aggregate
+    functions.
+
+  IMPLEMENTATION
+    The function recursively traverses the tree of the expr expression,
+    looks for occurrences of the group by fields that are not under
+    aggregate functions and replaces them for the corresponding ref items.
+
+  NOTES
+    This substitution is needed GROUP BY queries with ROLLUP if
+    SELECT list contains expressions over group by attributes.
+
+  EXAMPLES
+    SELECT a+1 FROM t1 GROUP BY a WITH ROLLUP
+    SELECT SUM(a)+a FROM t1 GROUP BY a WITH ROLLUP 
+    
+  RETURN
+    0	if ok
+    1   on error
+*/
+
+static bool change_group_ref(THD *thd, Item_func *expr, ORDER *group_list,
+                             bool *changed)
+{
+  if (expr->arg_count)
+  {
+    Item **arg,**arg_end;
+    for (arg= expr->arguments(),
+         arg_end= expr->arguments()+expr->arg_count;
+         arg != arg_end; arg++)
+    {
+      Item *item= *arg;
+      if (item->type() == Item::FIELD_ITEM || item->type() == Item::REF_ITEM)
+      {
+        ORDER *group_tmp;
+        for (group_tmp= group_list; group_tmp; group_tmp= group_tmp->next)
+        {
+          if (item->eq(*group_tmp->item,0))
+          {
+            Item *new_item;    
+            if(!(new_item= new Item_ref(group_tmp->item, 0, item->name)))
+              return 1;                                 // fatal_error is set
+            thd->change_item_tree(arg, new_item);
+            *changed= TRUE;
+          }
+        }
+      }
+      else if (item->type() == Item::FUNC_ITEM)
+      {
+        if (change_group_ref(thd, (Item_func *) item, group_list, changed))
+          return 1;
+      }
+    }
+  }
+  return 0;
+}
+
+
 /* Allocate memory needed for other rollup functions */
 
 bool JOIN::rollup_init()
@@ -12851,19 +12921,31 @@
     for (j=0 ; j < fields_list.elements ; j++)
       rollup.fields[i].push_back(rollup.null_items[i]);
   }
-  List_iterator_fast<Item> it(fields_list);
+  List_iterator_fast<Item> it(all_fields);
   Item *item;
   while ((item= it++))
   {
     ORDER *group_tmp;
     for (group_tmp= group_list; group_tmp; group_tmp= group_tmp->next)
     {
-      if (*group_tmp->item == item)
+      if (item->eq(*group_tmp->item,0))
         item->maybe_null= 1;
     }
+    if (item->type() == Item::FUNC_ITEM)
+    {
+      bool changed= 0;
+      if (change_group_ref(thd, (Item_func *) item, group_list, &changed))
+        return 1;
+      /*
+        We have to prevent creation of a field in a temporary table for
+        an expression that contains GROUP BY attributes.
+        Marking the expression item as 'with_sum_func' will ensure this.
+      */ 
+      if (changed)
+        item->with_sum_func= 1;
+    }
   }
   return 0;
-
 }
   
 
@@ -12959,14 +13041,14 @@
 	*(*func)= (Item_sum*) item;
 	(*func)++;
       }
-      else if (real_fields)
+      else 
       {
 	/* Check if this is something that is part of this group by */
 	ORDER *group_tmp;
 	for (group_tmp= start_group, i= pos ;
              group_tmp ; group_tmp= group_tmp->next, i++)
 	{
-	  if (*group_tmp->item == item)
+          if (item->eq(*group_tmp->item,0))
 	  {
             Item_null_result *null_item;
 	    /*

--- 1.20/mysql-test/r/olap.result	2005-05-18 23:06:31 +05:00
+++ 1.21/mysql-test/r/olap.result	2005-05-31 15:02:17 +05:00
@@ -253,7 +253,7 @@
 :Computer:	6900	1380.00000
 :Phone:	10	10.00000
 :TV:	600	120.00000
-:TV:	7785	519.00000
+NULL	7785	519.00000
 select product, country_id , year, sum(profit) from t1 group by product, country_id, year with cube;
 ERROR 42000: This version of MySQL doesn't yet support 'CUBE'
 explain select product, country_id , year, sum(profit) from t1 group by product, country_id, year with cube;
@@ -489,3 +489,69 @@
 5	5	6	5x	10	5
 NULL	8	9	8x	16	8
 DROP TABLE t1;
+CREATE TABLE t1 (a int(11));
+INSERT INTO t1 VALUES (1),(2);
+SELECT a, a+1, SUM(a) FROM t1 GROUP BY a WITH ROLLUP;
+a	a+1	SUM(a)
+1	2	1
+2	3	2
+NULL	NULL	3
+SELECT a+1 FROM t1 GROUP BY a WITH ROLLUP;
+a+1
+2
+3
+NULL
+SELECT a+SUM(a) FROM t1 GROUP BY a WITH ROLLUP;
+a+SUM(a)
+2
+4
+NULL
+SELECT a, a+1 as b FROM t1 GROUP BY a WITH ROLLUP HAVING b > 2;
+a	b
+2	3
+SELECT a, a+1 as b FROM t1 GROUP BY a WITH ROLLUP HAVING a IS NULL;
+a	b
+NULL	NULL
+SELECT a, a+1 as b FROM t1 GROUP BY a WITH ROLLUP HAVING b IS NULL;
+a	b
+NULL	NULL
+SELECT IFNULL(a, 'TEST') FROM t1 GROUP BY a WITH ROLLUP;
+IFNULL(a, 'TEST')
+1
+2
+TEST
+CREATE TABLE t2 (a int, b int);
+INSERT INTO t2 VALUES
+(1,4),
+(2,2), (2,2),
+(4,1), (4,1), (4,1), (4,1),
+(2,1), (2,1);
+SELECT a,b,SUM(b) FROM t2 GROUP BY a,b WITH ROLLUP;
+a	b	SUM(b)
+1	4	4
+1	NULL	4
+2	1	2
+2	2	4
+2	NULL	6
+4	1	4
+4	NULL	4
+NULL	NULL	14
+SELECT a,b,SUM(b), a+b as c FROM t2
+GROUP BY a,b WITH ROLLUP HAVING c IS NULL;
+a	b	SUM(b)	c
+1	NULL	4	NULL
+2	NULL	6	NULL
+4	NULL	4	NULL
+NULL	NULL	14	NULL
+SELECT IFNULL(a, 'TEST'), COALESCE(b, 'TEST') FROM t2 
+GROUP BY a, b WITH ROLLUP;
+IFNULL(a, 'TEST')	COALESCE(b, 'TEST')
+1	4
+1	TEST
+2	1
+2	2
+2	TEST
+4	1
+4	TEST
+TEST	TEST
+DROP TABLE t1,t2;

--- 1.16/mysql-test/t/olap.test	2005-05-18 23:06:31 +05:00
+++ 1.17/mysql-test/t/olap.test	2005-05-31 15:02:17 +05:00
@@ -220,3 +220,33 @@
 
 DROP TABLE t1;
 
+#
+# Tests for bug #7894: ROLLUP over expressions on group by attributes
+#
+
+CREATE TABLE t1 (a int(11));
+INSERT INTO t1 VALUES (1),(2);
+
+SELECT a, a+1, SUM(a) FROM t1 GROUP BY a WITH ROLLUP;
+SELECT a+1 FROM t1 GROUP BY a WITH ROLLUP;
+SELECT a+SUM(a) FROM t1 GROUP BY a WITH ROLLUP;
+SELECT a, a+1 as b FROM t1 GROUP BY a WITH ROLLUP HAVING b > 2;
+SELECT a, a+1 as b FROM t1 GROUP BY a WITH ROLLUP HAVING a IS NULL;
+SELECT a, a+1 as b FROM t1 GROUP BY a WITH ROLLUP HAVING b IS NULL;
+SELECT IFNULL(a, 'TEST') FROM t1 GROUP BY a WITH ROLLUP;
+
+CREATE TABLE t2 (a int, b int);
+INSERT INTO t2 VALUES
+  (1,4),
+  (2,2), (2,2),
+  (4,1), (4,1), (4,1), (4,1),
+  (2,1), (2,1);
+
+SELECT a,b,SUM(b) FROM t2 GROUP BY a,b WITH ROLLUP; 
+SELECT a,b,SUM(b), a+b as c FROM t2
+  GROUP BY a,b WITH ROLLUP HAVING c IS NULL;
+SELECT IFNULL(a, 'TEST'), COALESCE(b, 'TEST') FROM t2 
+  GROUP BY a, b WITH ROLLUP; 
+
+DROP TABLE t1,t2;
+

--- 1.36/mysql-test/r/func_gconcat.result	2005-03-18 01:40:56 +04:00
+++ 1.37/mysql-test/r/func_gconcat.result	2005-05-31 15:02:17 +05:00
@@ -476,3 +476,26 @@
 1	1,1
 2	2,2
 drop table r2;
+create table t1 (d int, a int, b int, c int);
+insert into t1(a,b) values (1,3), (1,4), (1,2), (2,7), (1,1), (1,2), (2,3), (2,3);
+select a, group_concat(b) from t1 group by a with rollup;
+a	group_concat(b)
+1	3,4,2,1,2
+2	7,3,3
+NULL	3,4,2,1,2,7,3,3
+select a, group_concat(distinct b) from t1 group by a with rollup;
+a	group_concat(distinct b)
+1	3,4,2,1
+2	7,3
+NULL	3,4,2,1,7
+select a, group_concat(b order by b) from t1 group by a with rollup;
+a	group_concat(b order by b)
+1	1,2,2,3,4
+2	3,3,7
+NULL	1,2,2,3,3,3,4,7
+select a, group_concat(distinct b order by b) from t1 group by a with rollup;
+a	group_concat(distinct b order by b)
+1	1,2,3,4
+2	3,7
+NULL	1,2,3,4,7
+drop table t1;

--- 1.26/mysql-test/t/func_gconcat.test	2005-03-17 17:51:02 +04:00
+++ 1.27/mysql-test/t/func_gconcat.test	2005-05-31 15:02:17 +05:00
@@ -301,3 +301,14 @@
 select  b x, (select group_concat(x) from r2) from  r2;
 drop table r2;
 
+#
+# Bug #7405: problems with rollup
+#
+
+create table t1 (d int, a int, b int, c int);
+insert into t1(a,b) values (1,3), (1,4), (1,2), (2,7), (1,1), (1,2), (2,3), (2,3);
+select a, group_concat(b) from t1 group by a with rollup;
+select a, group_concat(distinct b) from t1 group by a with rollup;
+select a, group_concat(b order by b) from t1 group by a with rollup;
+select a, group_concat(distinct b order by b) from t1 group by a with rollup;
+drop table t1;
Thread
bk commit into 5.0 tree (ramil:1.1940)ramil31 May