mirror of
https://github.com/MariaDB/server.git
synced 2025-12-24 11:21:21 +03:00
Bug #37348: Crash in or immediately after JOIN::make_sum_func_list
The optimizer pulls up aggregate functions which should be aggregated in
an outer select. At some point it may substitute such a function for a field
in the temporary table. The setup_copy_fields function doesn't take this
into account and may overrun the copy_field buffer.
Fixed by filtering out the fields referenced through the specialized
reference for aggregates (Item_aggregate_ref).
Added an assertion to make sure bugs that cause similar discrepancy
don't go undetected.
mysql-test/r/func_group.result:
Bug #37348: test case
mysql-test/t/func_group.test:
Bug #37348: test case
sql/item.cc:
Bug #37348: Added a way to distinguish Item_aggregate_ref from the other types of refs
sql/item.h:
Bug #37348: Added a way to distinguish Item_aggregate_ref from the other types of refs
sql/sql_select.cc:
Bug #37348:
- Don't consider copying field references
seen through Item_aggregate_ref
- check for discrepancies between the number of expected
fields that need copying and the actual fields copied.
This commit is contained in:
@@ -14804,6 +14804,7 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
|
||||
Item *pos;
|
||||
List_iterator_fast<Item> li(all_fields);
|
||||
Copy_field *copy= NULL;
|
||||
IF_DBUG(Copy_field *copy_start);
|
||||
res_selected_fields.empty();
|
||||
res_all_fields.empty();
|
||||
List_iterator_fast<Item> itr(res_all_fields);
|
||||
@@ -14816,12 +14817,19 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
|
||||
goto err2;
|
||||
|
||||
param->copy_funcs.empty();
|
||||
IF_DBUG(copy_start= copy);
|
||||
for (i= 0; (pos= li++); i++)
|
||||
{
|
||||
Field *field;
|
||||
uchar *tmp;
|
||||
Item *real_pos= pos->real_item();
|
||||
if (real_pos->type() == Item::FIELD_ITEM)
|
||||
/*
|
||||
Aggregate functions can be substituted for fields (by e.g. temp tables).
|
||||
We need to filter those substituted fields out.
|
||||
*/
|
||||
if (real_pos->type() == Item::FIELD_ITEM &&
|
||||
!(real_pos != pos &&
|
||||
((Item_ref *)pos)->ref_type() == Item_ref::AGGREGATE_REF))
|
||||
{
|
||||
Item_field *item;
|
||||
if (!(item= new Item_field(thd, ((Item_field*) real_pos))))
|
||||
@@ -14868,6 +14876,7 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
|
||||
goto err;
|
||||
if (copy)
|
||||
{
|
||||
DBUG_ASSERT (param->field_count > (uint) (copy - copy_start));
|
||||
copy->set(tmp, item->result_field);
|
||||
item->result_field->move_field(copy->to_ptr,copy->to_null_ptr,1);
|
||||
#ifdef HAVE_purify
|
||||
|
||||
Reference in New Issue
Block a user