summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <sanja@askmonty.org>2013-05-03 16:07:13 +0300
committerunknown <sanja@askmonty.org>2013-05-03 16:07:13 +0300
commit682c8a36ca503f53db50628463424f205b609ab0 (patch)
tree2d99dc5d2696f3441d0a694f5da8ec9b09cbe9eb
parent1a7c4ac7ae5534381285f501afadae297cff3e4c (diff)
downloadmariadb-git-682c8a36ca503f53db50628463424f205b609ab0.tar.gz
MDEV-4290:
Fix agregate function resolution in derived tables (no name resolution over a derived table border)
-rw-r--r--mysql-test/r/func_group.result28
-rw-r--r--mysql-test/t/func_group.test24
-rw-r--r--sql/item.h6
-rw-r--r--sql/item_sum.cc21
-rw-r--r--sql/sql_lex.cc1
-rw-r--r--sql/sql_lex.h3
6 files changed, 78 insertions, 5 deletions
diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result
index bd77f800f67..5fa37f577e9 100644
--- a/mysql-test/r/func_group.result
+++ b/mysql-test/r/func_group.result
@@ -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
diff --git a/mysql-test/t/func_group.test b/mysql-test/t/func_group.test
index fef4d3b1de2..9f0d7e102da 100644
--- a/mysql-test/t/func_group.test
+++ b/mysql-test/t/func_group.test
@@ -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
diff --git a/sql/item.h b/sql/item.h
index 1e35c7839de..1938273c261 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -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);
+ }
};
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 3f2020efeb5..489c0f1c23e 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -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)))
{
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 5bacb675644..ab50ad99c28 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -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;
}
/*
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index a3240d3bcab..4b4496a7df8 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -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();