diff options
author | Sergei Petrunia <sergey@mariadb.com> | 2022-04-22 20:26:14 +0300 |
---|---|---|
committer | Sergei Petrunia <sergey@mariadb.com> | 2022-04-26 15:21:21 +0300 |
commit | 5100b20b15edd93200f34a79d25f1b14e46a677e (patch) | |
tree | 8a74a5f20839ad2378caf6bc794a6813ab6fc5e3 /sql/item_subselect.cc | |
parent | 9b2d36660bbb4f93c6b9e0761c91d57d47f59196 (diff) | |
download | mariadb-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.cc | 11 |
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); |