summaryrefslogtreecommitdiff
path: root/sql/item_subselect.cc
diff options
context:
space:
mode:
authorSergei Petrunia <sergey@mariadb.com>2022-04-22 20:26:14 +0300
committerSergei Petrunia <sergey@mariadb.com>2022-04-26 15:21:21 +0300
commit5100b20b15edd93200f34a79d25f1b14e46a677e (patch)
tree8a74a5f20839ad2378caf6bc794a6813ab6fc5e3 /sql/item_subselect.cc
parent9b2d36660bbb4f93c6b9e0761c91d57d47f59196 (diff)
downloadmariadb-git-5100b20b15edd93200f34a79d25f1b14e46a677e.tar.gz
MDEV-26047: MariaDB server crash at Item_subselect::init_expr_cache_tracker
The cause of crash: remove_redundant_subquery_clauses() removes redundant item expressions. The primary goal of this is to remove the subquery items. The removal process unlinks the subquery from SELECT_LEX tree, but does not remove it from SELECT_LEX:::ref_pointer_array or from JOIN::all_fields. Then, setup_subquery_caches() tries to wrap the subquery item in an expression cache, which fails, the first reason for failure being that the item doesn't have a query plan. Solution: do not wrap eliminated items with expression cache. (also added an assert to check that we do not attempt to execute them). This may look like an incomplete fix: why don't we remove any mention of eliminated item everywhere? The difficulties here are: * items can be "un-removed" (see set_fake_select_as_master_processor) * it's difficult to remove an element from ref_pointer_array: Item_ref objects refer to elements of that array, so one can't shift elements in it. Replacing eliminated subselect with a dummy Item doesn't look like a good idea, either.
Diffstat (limited to 'sql/item_subselect.cc')
-rw-r--r--sql/item_subselect.cc11
1 files changed, 11 insertions, 0 deletions
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 7033d38c07b..de9b5dc8438 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -752,6 +752,7 @@ bool Item_subselect::exec()
DBUG_ENTER("Item_subselect::exec");
DBUG_ASSERT(fixed);
+ DBUG_ASSERT(!eliminated);
/*
Do not execute subselect in case of a fatal error
@@ -1313,6 +1314,16 @@ Item* Item_singlerow_subselect::expr_cache_insert_transformer(THD *tmp_thd,
DBUG_ASSERT(thd == tmp_thd);
+ /*
+ Do not create subquery cache if the subquery was eliminated.
+ The optimizer may eliminate subquery items (see
+ eliminate_subselect_processor). However it does not update
+ all query's data structures, so the eliminated item may be
+ still reachable.
+ */
+ if (eliminated)
+ DBUG_RETURN(this);
+
if (expr_cache)
DBUG_RETURN(expr_cache);