mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Merge moonbone.local:/work/27219-5.0-opt-mysql
into moonbone.local:/work/27219-bug-5.1 sql/item_subselect.cc: Auto merged sql/item_sum.cc: Auto merged sql/item_sum.h: Auto merged sql/mysql_priv.h: Auto merged sql/sql_lex.cc: Auto merged sql/sql_select.cc: Auto merged mysql-test/r/group_by.result: SCCS merged mysql-test/t/group_by.test: SCCS merged sql/item.cc: SCCS merged sql/sql_lex.h: SCCS merged
This commit is contained in:
@ -68,6 +68,7 @@ bool Item_sum::init_sum_func_check(THD *thd)
|
||||
aggr_sel= NULL;
|
||||
max_arg_level= -1;
|
||||
max_sum_func_level= -1;
|
||||
outer_fields.empty();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -176,6 +177,7 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref)
|
||||
MYF(0));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (in_sum_func)
|
||||
{
|
||||
/*
|
||||
@ -196,6 +198,68 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref)
|
||||
set_if_bigger(in_sum_func->max_sum_func_level, aggr_level);
|
||||
set_if_bigger(in_sum_func->max_sum_func_level, max_sum_func_level);
|
||||
}
|
||||
|
||||
/*
|
||||
Check that non-aggregated fields and sum functions aren't mixed in the
|
||||
same select in the ONLY_FULL_GROUP_BY mode.
|
||||
*/
|
||||
if (outer_fields.elements)
|
||||
{
|
||||
Item_field *field;
|
||||
/*
|
||||
Here we compare the nesting level of the select to which an outer field
|
||||
belongs to with the aggregation level of the sum function. All fields in
|
||||
the outer_fields list are checked.
|
||||
|
||||
If the nesting level is equal to the aggregation level then the field is
|
||||
aggregated by this sum function.
|
||||
If the nesting level is less than the aggregation level then the field
|
||||
belongs to an outer select. In this case if there is an embedding sum
|
||||
function add current field to functions outer_fields list. If there is
|
||||
no embedding function then the current field treated as non aggregated
|
||||
and the select it belongs to is marked accordingly.
|
||||
If the nesting level is greater than the aggregation level then it means
|
||||
that this field was added by an inner sum function.
|
||||
Consider an example:
|
||||
|
||||
select avg ( <-- we are here, checking outer.f1
|
||||
select (
|
||||
select sum(outer.f1 + inner.f1) from inner
|
||||
) from outer)
|
||||
from most_outer;
|
||||
|
||||
In this case we check that no aggregate functions are used in the
|
||||
select the field belongs to. If there are some then an error is
|
||||
raised.
|
||||
*/
|
||||
List_iterator<Item_field> of(outer_fields);
|
||||
while ((field= of++))
|
||||
{
|
||||
SELECT_LEX *sel= field->cached_table->select_lex;
|
||||
if (sel->nest_level < aggr_level)
|
||||
{
|
||||
if (in_sum_func)
|
||||
{
|
||||
/*
|
||||
Let upper function decide whether this field is a non
|
||||
aggregated one.
|
||||
*/
|
||||
in_sum_func->outer_fields.push_back(field);
|
||||
}
|
||||
else
|
||||
sel->full_group_by_flag|= NON_AGG_FIELD_USED;
|
||||
}
|
||||
if (sel->nest_level > aggr_level &&
|
||||
(sel->full_group_by_flag & SUM_FUNC_USED) &&
|
||||
!sel->group_list.elements)
|
||||
{
|
||||
my_message(ER_MIX_OF_GROUP_FUNC_AND_FIELDS,
|
||||
ER(ER_MIX_OF_GROUP_FUNC_AND_FIELDS), MYF(0));
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
aggr_sel->full_group_by_flag|= SUM_FUNC_USED;
|
||||
update_used_tables();
|
||||
thd->lex->in_sum_func= in_sum_func;
|
||||
return FALSE;
|
||||
|
Reference in New Issue
Block a user