summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2022-01-06 00:31:42 -0800
committerIgor Babaev <igor@askmonty.org>2022-01-10 09:12:17 -0800
commit7692cec5b0811c09f09b1f6215fc07163ad0db3a (patch)
tree072652c67be400f9b6ec31ce5167db1232d90f06
parent6dec0332fbdb6ca58c46284c7139735f137e2a81 (diff)
downloadmariadb-git-7692cec5b0811c09f09b1f6215fc07163ad0db3a.tar.gz
MDEV-25631 Crash executing query with VIEW, aggregate and subquery
This bug could cause a crash of the server for queries with a derived table whose specification contained the set function using a subquery over a view as its only argument. The crash could happen if the specification of the view contained an outer reference. In this case the aggregation select could be determined incorrectly. The crash also could be observed if a CTE is used instead of the view, but only for queries having at least two references to the CTE.
-rw-r--r--mysql-test/r/view.result18
-rw-r--r--mysql-test/t/view.test20
-rw-r--r--sql/item.cc5
3 files changed, 43 insertions, 0 deletions
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result
index d278eb1f870..4edbabf11cc 100644
--- a/mysql-test/r/view.result
+++ b/mysql-test/r/view.result
@@ -6844,5 +6844,23 @@ drop view v1;
CREATE VIEW v1 AS select `t1`.`12345678901234567890123456789012345678901234567890123456789012345` AS `Name_exp_1` from (select '12345678901234567890123456789012345678901234567890123456789012345') `t1`;
drop view v1;
#
+# MDEV-25631: view with outer reference in select used
+# as argument of set function
+#
+create table t1 (c int);
+insert into t1 values (1);
+create view v1 as select c from t1 where (select t1.c from t1 t) = 1;
+select * from (select sum((select * from v1)) as r) dt;
+r
+1
+with cte as (select c from t1 where (select t1.c from t1 t) = 1)
+select * from (select sum((select * from cte)) as r) dt1
+union
+select * from (select sum((select * from cte)) as r) dt2;
+r
+1
+drop view v1;
+drop table t1;
+#
# End of 10.2 tests
#
diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test
index 4fb1806fac9..6265a514783 100644
--- a/mysql-test/t/view.test
+++ b/mysql-test/t/view.test
@@ -6575,8 +6575,28 @@ drop view v1;
eval CREATE VIEW v1 AS $definition;
+
drop view v1;
--echo #
+--echo # MDEV-25631: view with outer reference in select used
+--echo # as argument of set function
+--echo #
+
+create table t1 (c int);
+insert into t1 values (1);
+create view v1 as select c from t1 where (select t1.c from t1 t) = 1;
+
+select * from (select sum((select * from v1)) as r) dt;
+
+with cte as (select c from t1 where (select t1.c from t1 t) = 1)
+select * from (select sum((select * from cte)) as r) dt1
+union
+select * from (select sum((select * from cte)) as r) dt2;
+
+drop view v1;
+drop table t1;
+
+--echo #
--echo # End of 10.2 tests
--echo #
diff --git a/sql/item.cc b/sql/item.cc
index 32bcd282401..6e5d2ee45a2 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -5266,6 +5266,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
max_arg_level for the function if it's needed.
*/
if (thd->lex->in_sum_func &&
+ thd->lex == context->select_lex->parent_lex &&
thd->lex->in_sum_func->nest_level >= select->nest_level)
{
Item::Type ref_type= (*reference)->type();
@@ -5291,6 +5292,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
(Item_ident*) (*reference) :
0), false);
if (thd->lex->in_sum_func &&
+ thd->lex == context->select_lex->parent_lex &&
thd->lex->in_sum_func->nest_level >= select->nest_level)
{
set_if_bigger(thd->lex->in_sum_func->max_arg_level,
@@ -5619,6 +5621,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
if (!thd->lex->current_select->no_wrap_view_item &&
thd->lex->in_sum_func &&
+ thd->lex == select->parent_lex &&
thd->lex->in_sum_func->nest_level ==
select->nest_level)
set_if_bigger(thd->lex->in_sum_func->max_arg_level,
@@ -7704,6 +7707,7 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
max_arg_level for the function if it's needed.
*/
if (thd->lex->in_sum_func &&
+ thd->lex == context->select_lex->parent_lex &&
thd->lex->in_sum_func->nest_level >=
last_checked_context->select_lex->nest_level)
set_if_bigger(thd->lex->in_sum_func->max_arg_level,
@@ -7727,6 +7731,7 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
max_arg_level for the function if it's needed.
*/
if (thd->lex->in_sum_func &&
+ thd->lex == context->select_lex->parent_lex &&
thd->lex->in_sum_func->nest_level >=
last_checked_context->select_lex->nest_level)
set_if_bigger(thd->lex->in_sum_func->max_arg_level,