Commit 682c8a36 authored by unknown's avatar unknown

MDEV-4290:

Fix agregate function resolution in derived tables (no name resolution over a derived table border)
parent 1a7c4ac7
......@@ -2097,3 +2097,31 @@ avg(export_set( 3, 'y', sha(i))) group_concat(d)
0 2008-10-02
0 2010-12-12
drop table t1;
#
# MDEV-4290: crash in st_select_lex::mark_as_dependent
#
create table `t1`(`a` int);
select 1 from t1 v1 right join t1 on count(*);
ERROR HY000: Invalid use of group function
select 1 from t1 order by
(
select 1 from
(
select 1 from t1 v1 right join t1 on count(*)
) v
);
ERROR HY000: Invalid use of group function
insert into t1 values (1),(1),(2),(2);
select count(*) from t1;
count(*)
4
select z from (select count(*) as z from t1) v;
z
4
# next is how it implemented now (may be changed in case of dependent
# derived tables)
select z from (select count(*) as z from t1) v group by 1;
z
4
drop table t1;
# end of 5.3 tests
......@@ -1380,3 +1380,27 @@ insert into t1 values (1, '2008-10-02'), (2, '2010-12-12');
select avg(export_set( 3, 'y', sha(i))), group_concat(d) from t1 group by d order by i;
drop table t1;
--echo #
--echo # MDEV-4290: crash in st_select_lex::mark_as_dependent
--echo #
create table `t1`(`a` int);
--error ER_INVALID_GROUP_FUNC_USE
select 1 from t1 v1 right join t1 on count(*);
--error ER_INVALID_GROUP_FUNC_USE
select 1 from t1 order by
(
select 1 from
(
select 1 from t1 v1 right join t1 on count(*)
) v
);
insert into t1 values (1),(1),(2),(2);
select count(*) from t1;
select z from (select count(*) as z from t1) v;
--echo # next is how it implemented now (may be changed in case of dependent
--echo # derived tables)
select z from (select count(*) as z from t1) v group by 1;
drop table t1;
--echo # end of 5.3 tests
......@@ -353,6 +353,12 @@ struct Name_resolution_context: Sql_alloc
{
(*error_processor)(thd, error_processor_data);
}
st_select_lex *outer_select()
{
return (outer_context ?
outer_context->select_lex :
NULL);
}
};
......
......@@ -53,7 +53,15 @@
bool Item_sum::init_sum_func_check(THD *thd)
{
if (!thd->lex->allow_sum_func)
SELECT_LEX *curr_sel= thd->lex->current_select;
if (!curr_sel->name_visibility_map)
{
for (SELECT_LEX *sl= curr_sel; sl; sl= sl->context.outer_select())
{
curr_sel->name_visibility_map|= (1 << sl-> nest_level);
}
}
if (!(thd->lex->allow_sum_func & curr_sel->name_visibility_map))
{
my_message(ER_INVALID_GROUP_FUNC_USE, ER(ER_INVALID_GROUP_FUNC_USE),
MYF(0));
......@@ -124,8 +132,11 @@ bool Item_sum::init_sum_func_check(THD *thd)
bool Item_sum::check_sum_func(THD *thd, Item **ref)
{
SELECT_LEX *curr_sel= thd->lex->current_select;
nesting_map allow_sum_func= (thd->lex->allow_sum_func &
curr_sel->name_visibility_map);
bool invalid= FALSE;
nesting_map allow_sum_func= thd->lex->allow_sum_func;
DBUG_ASSERT(curr_sel->name_visibility_map); // should be set already
/*
The value of max_arg_level is updated if an argument of the set function
contains a column reference resolved against a subquery whose level is
......@@ -158,7 +169,7 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref)
if (!invalid && aggr_level < 0)
{
aggr_level= nest_level;
aggr_sel= thd->lex->current_select;
aggr_sel= curr_sel;
}
/*
By this moment we either found a subquery where the set function is
......@@ -295,9 +306,9 @@ bool Item_sum::register_sum_func(THD *thd, Item **ref)
{
SELECT_LEX *sl;
nesting_map allow_sum_func= thd->lex->allow_sum_func;
for (sl= thd->lex->current_select->master_unit()->outer_select() ;
for (sl= thd->lex->current_select->context.outer_select() ;
sl && sl->nest_level > max_arg_level;
sl= sl->master_unit()->outer_select() )
sl= sl->context.outer_select())
{
if (aggr_level < 0 && (allow_sum_func & (1 << sl->nest_level)))
{
......
......@@ -1690,6 +1690,7 @@ void st_select_lex::init_select()
merged_into= 0;
m_non_agg_field_used= false;
m_agg_func_used= false;
name_visibility_map= 0;
}
/*
......
......@@ -783,6 +783,9 @@ class st_select_lex: public st_select_lex_node
*/
List<String> *prev_join_using;
/* namp of nesting SELECT visibility (for aggregate functions check) */
nesting_map name_visibility_map;
void init_query();
void init_select();
st_select_lex_unit* master_unit();
......
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