1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-27 18:02:13 +03:00

Bug#27333: subquery grouped for aggregate of outer

query / no aggregate of subquery
 The optimizer counts the aggregate functions that 
 appear as top level expressions (in all_fields) in 
 the current subquery. Later it makes a list of these
 that it uses to actually execute the aggregates in
 end_send_group().
 That count is used in several places as a flag whether
 there are aggregates functions.
 While collecting the above info it must not consider
 aggregates that are not aggregated in the current 
 context. It must treat them as normal expressions 
 instead. Not doing that leads to incorrect data about
 the query, e.g. running a query that actually has no
 aggregate functions as if it has some (and hence is
 expected to return only one row).
 Fixed by ignoring the aggregates that are not aggregated
 in the current context. 
 One other smaller omission discovered and fixed in the 
 process : the place of aggregation was not calculated for
 user defined functions. Fixed by calling 
 Item_sum::init_sum_func_check() and 
 Item_sum::check_sum_func() as it's done for the rest of 
 the aggregate functions.
This commit is contained in:
gkodinov/kgeorge@magare.gmz
2007-06-29 10:39:17 +03:00
parent a90ff73738
commit 38172240e3
7 changed files with 119 additions and 25 deletions

View File

@ -611,7 +611,7 @@ JOIN::prepare(Item ***rref_pointer_array,
goto err; /* purecov: inspected */
/* Init join struct */
count_field_types(&tmp_table_param, all_fields, 0);
count_field_types(select_lex, &tmp_table_param, all_fields, 0);
ref_pointer_array_size= all_fields.elements*sizeof(Item*);
this->group= group_list != 0;
unit= unit_arg;
@ -1766,7 +1766,7 @@ JOIN::exec()
if (make_simple_join(curr_join, curr_tmp_table))
DBUG_VOID_RETURN;
calc_group_buffer(curr_join, group_list);
count_field_types(&curr_join->tmp_table_param,
count_field_types(select_lex, &curr_join->tmp_table_param,
curr_join->tmp_all_fields1,
curr_join->select_distinct && !curr_join->group_list);
curr_join->tmp_table_param.hidden_field_count=
@ -1886,11 +1886,13 @@ JOIN::exec()
if (make_simple_join(curr_join, curr_tmp_table))
DBUG_VOID_RETURN;
calc_group_buffer(curr_join, curr_join->group_list);
count_field_types(&curr_join->tmp_table_param, *curr_all_fields, 0);
count_field_types(select_lex, &curr_join->tmp_table_param,
*curr_all_fields, 0);
}
if (procedure)
count_field_types(&curr_join->tmp_table_param, *curr_all_fields, 0);
count_field_types(select_lex, &curr_join->tmp_table_param,
*curr_all_fields, 0);
if (curr_join->group || curr_join->tmp_table_param.sum_func_count ||
(procedure && (procedure->flags & PROC_GROUP)))
@ -13678,8 +13680,8 @@ next_item:
*****************************************************************************/
void
count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields,
bool reset_with_sum_func)
count_field_types(SELECT_LEX *select_lex, TMP_TABLE_PARAM *param,
List<Item> &fields, bool reset_with_sum_func)
{
List_iterator<Item> li(fields);
Item *field;
@ -13697,18 +13699,22 @@ count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields,
if (! field->const_item())
{
Item_sum *sum_item=(Item_sum*) field->real_item();
if (!sum_item->quick_group)
param->quick_group=0; // UDF SUM function
param->sum_func_count++;
param->func_count++;
if (!sum_item->depended_from() ||
sum_item->depended_from() == select_lex)
{
if (!sum_item->quick_group)
param->quick_group=0; // UDF SUM function
param->sum_func_count++;
for (uint i=0 ; i < sum_item->arg_count ; i++)
{
if (sum_item->args[0]->real_item()->type() == Item::FIELD_ITEM)
param->field_count++;
else
param->func_count++;
}
for (uint i=0 ; i < sum_item->arg_count ; i++)
{
if (sum_item->args[0]->real_item()->type() == Item::FIELD_ITEM)
param->field_count++;
else
param->func_count++;
}
}
param->func_count++;
}
}
else
@ -14170,7 +14176,9 @@ bool JOIN::make_sum_func_list(List<Item> &field_list, List<Item> &send_fields,
func= sum_funcs;
while ((item=it++))
{
if (item->type() == Item::SUM_FUNC_ITEM && !item->const_item())
if (item->type() == Item::SUM_FUNC_ITEM && !item->const_item() &&
(!((Item_sum*) item)->depended_from() ||
((Item_sum *)item)->depended_from() == select_lex))
*func++= (Item_sum*) item;
}
if (before_group_by && rollup.state == ROLLUP::STATE_INITED)
@ -14752,7 +14760,10 @@ bool JOIN::rollup_make_fields(List<Item> &fields_arg, List<Item> &sel_fields,
ref_array= ref_array_start;
}
if (item->type() == Item::SUM_FUNC_ITEM && !item->const_item())
if (item->type() == Item::SUM_FUNC_ITEM && !item->const_item() &&
(!((Item_sum*) item)->depended_from() ||
((Item_sum *)item)->depended_from() == select_lex))
{
/*
This is a top level summary function that must be replaced with