summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/main/subselect4.result11
-rw-r--r--mysql-test/main/subselect4.test15
-rw-r--r--sql/item.cc3
-rw-r--r--sql/item_sum.cc1
-rw-r--r--sql/item_sum.h1
5 files changed, 31 insertions, 0 deletions
diff --git a/mysql-test/main/subselect4.result b/mysql-test/main/subselect4.result
index 3bfb755120b..182235c039b 100644
--- a/mysql-test/main/subselect4.result
+++ b/mysql-test/main/subselect4.result
@@ -2898,3 +2898,14 @@ id select_type table type possible_keys key key_len ref rows Extra
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 100
drop table t0, t1, t2;
# End of 10.4 tests
+#
+# MDEV-25631: Crash in st_select_lex::mark_as_dependent with VIEW, aggregate and subquery
+#
+CREATE TABLE t1 (i1 int);
+insert into t1 values (1),(2),(3);
+CREATE VIEW v1 AS
+SELECT t1.i1 FROM (t1 a JOIN t1 ON (t1.i1 = (SELECT t1.i1 FROM t1 b)));
+SELECT 1 FROM (SELECT count(((SELECT i1 FROM v1))) FROM v1) dt ;
+ERROR 21000: Subquery returns more than 1 row
+DROP VIEW v1;
+DROP TABLE t1;
diff --git a/mysql-test/main/subselect4.test b/mysql-test/main/subselect4.test
index a1a4108de37..bd18ec5f5c9 100644
--- a/mysql-test/main/subselect4.test
+++ b/mysql-test/main/subselect4.test
@@ -2398,3 +2398,18 @@ select * from t1 where t1.a in (select t2.a from t2 order by t2.b);
drop table t0, t1, t2;
--echo # End of 10.4 tests
+
+--echo #
+--echo # MDEV-25631: Crash in st_select_lex::mark_as_dependent with VIEW, aggregate and subquery
+--echo #
+
+CREATE TABLE t1 (i1 int);
+insert into t1 values (1),(2),(3); #not important
+CREATE VIEW v1 AS
+SELECT t1.i1 FROM (t1 a JOIN t1 ON (t1.i1 = (SELECT t1.i1 FROM t1 b)));
+
+--error ER_SUBQUERY_NO_1_ROW
+SELECT 1 FROM (SELECT count(((SELECT i1 FROM v1))) FROM v1) dt ;
+
+DROP VIEW v1;
+DROP TABLE t1;
diff --git a/sql/item.cc b/sql/item.cc
index 5cdbf52e829..a4c16c53e5e 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -5608,9 +5608,12 @@ 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->in_sum_func->nest_level_base == select->nest_level_base &&
thd->lex->in_sum_func->nest_level >= select->nest_level)
{
Item::Type ref_type= (*reference)->type();
+ // psergey-todo: check if in_sum_func "has" the same
+ // nest_level_base as we do..
set_if_bigger(thd->lex->in_sum_func->max_arg_level,
select->nest_level);
set_field(*from_field);
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 537eaaf8dcd..23b6f739333 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -92,6 +92,7 @@ bool Item_sum::init_sum_func_check(THD *thd)
/* Save a pointer to object to be used in items for nested set functions */
thd->lex->in_sum_func= this;
nest_level= thd->lex->current_select->nest_level;
+ nest_level_base= thd->lex->current_select->nest_level_base;
ref_by= 0;
aggr_level= -1;
aggr_sel= NULL;
diff --git a/sql/item_sum.h b/sql/item_sum.h
index 118f78ec5c1..10aa658c5e2 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -364,6 +364,7 @@ public:
Item_sum *in_sum_func; /* embedding set function if any */
st_select_lex * aggr_sel; /* select where the function is aggregated */
int8 nest_level; /* number of the nesting level of the set function */
+ st_select_lex_unit *nest_level_base;
int8 aggr_level; /* nesting level of the aggregating subquery */
int8 max_arg_level; /* max level of unbound column references */
int8 max_sum_func_level;/* max level of aggregation for embedded functions */