Commit f9ac5b43 authored by igor@olga.mysql.com's avatar igor@olga.mysql.com

Merge olga.mysql.com:/home/igor/mysql-4.1-opt

into  olga.mysql.com:/home/igor/dev-opt/mysql-5.0-opt-bug24856
parents 7505fc82 395d8751
...@@ -607,6 +607,66 @@ x a sum(b) ...@@ -607,6 +607,66 @@ x a sum(b)
2006-07-01 NULL 11 2006-07-01 NULL 11
NULL NULL 11 NULL NULL 11
drop table t1; 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)); CREATE TABLE t1(id int, type char(1));
INSERT INTO t1 VALUES INSERT INTO t1 VALUES
(1,"A"),(2,"C"),(3,"A"),(4,"A"),(5,"B"), (1,"A"),(2,"C"),(3,"A"),(4,"A"),(5,"B"),
......
...@@ -292,6 +292,25 @@ select left(a,10), a, sum(b) from t1 group by 1,2 with rollup; ...@@ -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; select left(a,10) x, a, sum(b) from t1 group by x,a with rollup;
drop table t1; 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 # End of 4.1 tests
# #
...@@ -339,6 +358,3 @@ SELECT * FROM (SELECT a, SUM(a) FROM t1 GROUP BY a WITH ROLLUP) as t; ...@@ -339,6 +358,3 @@ SELECT * FROM (SELECT a, SUM(a) FROM t1 GROUP BY a WITH ROLLUP) as t;
DROP TABLE t1; DROP TABLE t1;
...@@ -719,6 +719,31 @@ class Item_func_max :public Item_func_min_max ...@@ -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 class Item_func_length :public Item_int_func
{ {
String value; String value;
......
...@@ -14540,7 +14540,7 @@ bool JOIN::rollup_init() ...@@ -14540,7 +14540,7 @@ bool JOIN::rollup_init()
for (j=0 ; j < fields_list.elements ; j++) for (j=0 ; j < fields_list.elements ; j++)
rollup.fields[i].push_back(rollup.null_items[i]); rollup.fields[i].push_back(rollup.null_items[i]);
} }
List_iterator_fast<Item> it(all_fields); List_iterator<Item> it(all_fields);
Item *item; Item *item;
while ((item= it++)) while ((item= it++))
{ {
...@@ -14553,6 +14553,32 @@ bool JOIN::rollup_init() ...@@ -14553,6 +14553,32 @@ bool JOIN::rollup_init()
{ {
item->maybe_null= 1; item->maybe_null= 1;
found_in_group= 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) if (item->type() == Item::FUNC_ITEM && !found_in_group)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment