mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
MDEV-4290:
Fix agregate function resolution in derived tables (no name resolution over a derived table border)
This commit is contained in:
parent
1a7c4ac7ae
commit
682c8a36ca
6 changed files with 78 additions and 5 deletions
|
@ -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 @@ public:
|
|||
*/
|
||||
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();
|
||||
|
|
Loading…
Reference in a new issue