Loading mysql-test/r/olap.result +60 −0 Original line number Diff line number Diff line Loading @@ -607,6 +607,66 @@ x a sum(b) 2006-07-01 NULL 11 NULL NULL 11 drop table t1; CREATE TABLE t1 (a int, b int); INSERT INTO t1 VALUES (2,10),(3,30),(2,40),(1,10),(2,30),(1,20),(2,10); SELECT a, SUM(b) FROM t1 GROUP BY a WITH ROLLUP; a SUM(b) 1 30 2 90 3 30 NULL 150 SELECT DISTINCT a, SUM(b) FROM t1 GROUP BY a WITH ROLLUP; a SUM(b) 1 30 2 90 3 30 NULL 150 SELECT a, b, COUNT(*) FROM t1 GROUP BY a,b WITH ROLLUP; a b COUNT(*) 1 10 1 1 20 1 1 NULL 2 2 10 2 2 30 1 2 40 1 2 NULL 4 3 30 1 3 NULL 1 NULL NULL 7 SELECT DISTINCT a, b, COUNT(*) FROM t1 GROUP BY a,b WITH ROLLUP; a b COUNT(*) 1 10 1 1 20 1 1 NULL 2 2 10 2 2 30 1 2 40 1 2 NULL 4 3 30 1 3 NULL 1 NULL NULL 7 SELECT 'x', a, SUM(b) FROM t1 GROUP BY 1,2 WITH ROLLUP; x a SUM(b) x 1 30 x 2 90 x 3 30 x NULL 150 NULL NULL 150 SELECT DISTINCT 'x', a, SUM(b) FROM t1 GROUP BY 1,2 WITH ROLLUP; x a SUM(b) x 1 30 x 2 90 x 3 30 x NULL 150 NULL NULL 150 SELECT DISTINCT 'x', a, SUM(b) FROM t1 GROUP BY 1,2 WITH ROLLUP; x a SUM(b) x 1 30 x 2 90 x 3 30 x NULL 150 NULL NULL 150 CREATE TABLE t1(id int, type char(1)); INSERT INTO t1 VALUES (1,"A"),(2,"C"),(3,"A"),(4,"A"),(5,"B"), Loading mysql-test/t/olap.test +19 −3 Original line number Diff line number Diff line Loading @@ -292,6 +292,25 @@ select left(a,10), a, sum(b) from t1 group by 1,2 with rollup; select left(a,10) x, a, sum(b) from t1 group by x,a with rollup; drop table t1; # # Bug #24856: ROLLUP by const item in a query with DISTINCT # CREATE TABLE t1 (a int, b int); INSERT INTO t1 VALUES (2,10),(3,30),(2,40),(1,10),(2,30),(1,20),(2,10); SELECT a, SUM(b) FROM t1 GROUP BY a WITH ROLLUP; SELECT DISTINCT a, SUM(b) FROM t1 GROUP BY a WITH ROLLUP; SELECT a, b, COUNT(*) FROM t1 GROUP BY a,b WITH ROLLUP; SELECT DISTINCT a, b, COUNT(*) FROM t1 GROUP BY a,b WITH ROLLUP; SELECT 'x', a, SUM(b) FROM t1 GROUP BY 1,2 WITH ROLLUP; SELECT DISTINCT 'x', a, SUM(b) FROM t1 GROUP BY 1,2 WITH ROLLUP; SELECT DISTINCT 'x', a, SUM(b) FROM t1 GROUP BY 1,2 WITH ROLLUP; DROP TABLE t1; # End of 4.1 tests # Loading Loading @@ -339,6 +358,3 @@ SELECT * FROM (SELECT a, SUM(a) FROM t1 GROUP BY a WITH ROLLUP) as t; DROP TABLE t1; sql/item_func.h +25 −0 Original line number Diff line number Diff line Loading @@ -719,6 +719,31 @@ class Item_func_max :public Item_func_min_max }; /* Objects of this class are used for ROLLUP queries to wrap up each constant item referred to in GROUP BY list. */ class Item_func_rollup_const :public Item_func { public: Item_func_rollup_const(Item *a) :Item_func(a) { name= a->name; } double val() { return args[0]->val(); } longlong val_int() { return args[0]->val_int(); } String *val_str(String *str) { return args[0]->val_str(str); } const char *func_name() const { return "rollup_const"; } bool const_item() const { return 0; } Item_result result_type() const { return args[0]->result_type(); } void fix_length_and_dec() { collation= args[0]->collation; max_length= args[0]->max_length; decimals=args[0]->decimals; } }; class Item_func_length :public Item_int_func { String value; Loading sql/sql_select.cc +27 −1 Original line number Diff line number Diff line Loading @@ -14540,7 +14540,7 @@ bool JOIN::rollup_init() for (j=0 ; j < fields_list.elements ; j++) rollup.fields[i].push_back(rollup.null_items[i]); } List_iterator_fast<Item> it(all_fields); List_iterator<Item> it(all_fields); Item *item; while ((item= it++)) { Loading @@ -14553,6 +14553,32 @@ 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,0, (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); } } } } if (item->type() == Item::FUNC_ITEM && !found_in_group) Loading Loading
mysql-test/r/olap.result +60 −0 Original line number Diff line number Diff line Loading @@ -607,6 +607,66 @@ x a sum(b) 2006-07-01 NULL 11 NULL NULL 11 drop table t1; CREATE TABLE t1 (a int, b int); INSERT INTO t1 VALUES (2,10),(3,30),(2,40),(1,10),(2,30),(1,20),(2,10); SELECT a, SUM(b) FROM t1 GROUP BY a WITH ROLLUP; a SUM(b) 1 30 2 90 3 30 NULL 150 SELECT DISTINCT a, SUM(b) FROM t1 GROUP BY a WITH ROLLUP; a SUM(b) 1 30 2 90 3 30 NULL 150 SELECT a, b, COUNT(*) FROM t1 GROUP BY a,b WITH ROLLUP; a b COUNT(*) 1 10 1 1 20 1 1 NULL 2 2 10 2 2 30 1 2 40 1 2 NULL 4 3 30 1 3 NULL 1 NULL NULL 7 SELECT DISTINCT a, b, COUNT(*) FROM t1 GROUP BY a,b WITH ROLLUP; a b COUNT(*) 1 10 1 1 20 1 1 NULL 2 2 10 2 2 30 1 2 40 1 2 NULL 4 3 30 1 3 NULL 1 NULL NULL 7 SELECT 'x', a, SUM(b) FROM t1 GROUP BY 1,2 WITH ROLLUP; x a SUM(b) x 1 30 x 2 90 x 3 30 x NULL 150 NULL NULL 150 SELECT DISTINCT 'x', a, SUM(b) FROM t1 GROUP BY 1,2 WITH ROLLUP; x a SUM(b) x 1 30 x 2 90 x 3 30 x NULL 150 NULL NULL 150 SELECT DISTINCT 'x', a, SUM(b) FROM t1 GROUP BY 1,2 WITH ROLLUP; x a SUM(b) x 1 30 x 2 90 x 3 30 x NULL 150 NULL NULL 150 CREATE TABLE t1(id int, type char(1)); INSERT INTO t1 VALUES (1,"A"),(2,"C"),(3,"A"),(4,"A"),(5,"B"), Loading
mysql-test/t/olap.test +19 −3 Original line number Diff line number Diff line Loading @@ -292,6 +292,25 @@ select left(a,10), a, sum(b) from t1 group by 1,2 with rollup; select left(a,10) x, a, sum(b) from t1 group by x,a with rollup; drop table t1; # # Bug #24856: ROLLUP by const item in a query with DISTINCT # CREATE TABLE t1 (a int, b int); INSERT INTO t1 VALUES (2,10),(3,30),(2,40),(1,10),(2,30),(1,20),(2,10); SELECT a, SUM(b) FROM t1 GROUP BY a WITH ROLLUP; SELECT DISTINCT a, SUM(b) FROM t1 GROUP BY a WITH ROLLUP; SELECT a, b, COUNT(*) FROM t1 GROUP BY a,b WITH ROLLUP; SELECT DISTINCT a, b, COUNT(*) FROM t1 GROUP BY a,b WITH ROLLUP; SELECT 'x', a, SUM(b) FROM t1 GROUP BY 1,2 WITH ROLLUP; SELECT DISTINCT 'x', a, SUM(b) FROM t1 GROUP BY 1,2 WITH ROLLUP; SELECT DISTINCT 'x', a, SUM(b) FROM t1 GROUP BY 1,2 WITH ROLLUP; DROP TABLE t1; # End of 4.1 tests # Loading Loading @@ -339,6 +358,3 @@ SELECT * FROM (SELECT a, SUM(a) FROM t1 GROUP BY a WITH ROLLUP) as t; DROP TABLE t1;
sql/item_func.h +25 −0 Original line number Diff line number Diff line Loading @@ -719,6 +719,31 @@ class Item_func_max :public Item_func_min_max }; /* Objects of this class are used for ROLLUP queries to wrap up each constant item referred to in GROUP BY list. */ class Item_func_rollup_const :public Item_func { public: Item_func_rollup_const(Item *a) :Item_func(a) { name= a->name; } double val() { return args[0]->val(); } longlong val_int() { return args[0]->val_int(); } String *val_str(String *str) { return args[0]->val_str(str); } const char *func_name() const { return "rollup_const"; } bool const_item() const { return 0; } Item_result result_type() const { return args[0]->result_type(); } void fix_length_and_dec() { collation= args[0]->collation; max_length= args[0]->max_length; decimals=args[0]->decimals; } }; class Item_func_length :public Item_int_func { String value; Loading
sql/sql_select.cc +27 −1 Original line number Diff line number Diff line Loading @@ -14540,7 +14540,7 @@ bool JOIN::rollup_init() for (j=0 ; j < fields_list.elements ; j++) rollup.fields[i].push_back(rollup.null_items[i]); } List_iterator_fast<Item> it(all_fields); List_iterator<Item> it(all_fields); Item *item; while ((item= it++)) { Loading @@ -14553,6 +14553,32 @@ 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,0, (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); } } } } if (item->type() == Item::FUNC_ITEM && !found_in_group) Loading