mirror of
https://github.com/MariaDB/server.git
synced 2025-01-29 02:05:57 +01:00
Automerge.
This commit is contained in:
commit
3df1ae7a1a
4 changed files with 100 additions and 28 deletions
|
@ -733,4 +733,24 @@ SELECT 1 FROM t1 GROUP BY (DATE(NULL)) WITH ROLLUP;
|
|||
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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_PARAM *param,List<Item> &fields,
|
|||
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;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue