summaryrefslogtreecommitdiff
path: root/sql/item_subselect.cc
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2022-05-09 22:04:06 +0200
committerSergei Golubchik <serg@mariadb.org>2022-05-09 22:04:06 +0200
commitef781162ff2eb97f405b19dc150ab674e91dbc05 (patch)
tree63b897dece50ab65652174af4cd0aabd8f3a8505 /sql/item_subselect.cc
parente9af6b2a4d8750c32d4953f08f8bc5f2e33cb9e3 (diff)
parent16cebed54065ad9e18953aa86d48f6007d53c2d3 (diff)
downloadmariadb-git-ef781162ff2eb97f405b19dc150ab674e91dbc05.tar.gz
Merge branch '10.4' into 10.5
Diffstat (limited to 'sql/item_subselect.cc')
-rw-r--r--sql/item_subselect.cc26
1 files changed, 22 insertions, 4 deletions
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index cf02e401111..07105960257 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -809,6 +809,7 @@ bool Item_subselect::exec()
DBUG_ENTER("Item_subselect::exec");
DBUG_ASSERT(fixed);
+ DBUG_ASSERT(!eliminated);
DBUG_EXECUTE_IF("Item_subselect",
Item::Print print(this,
@@ -1318,11 +1319,18 @@ bool Item_singlerow_subselect::fix_length_and_dec()
}
unsigned_flag= value->unsigned_flag;
/*
- If there are not tables in subquery then ability to have NULL value
- depends on SELECT list (if single row subquery have tables then it
- always can be NULL if there are not records fetched).
+ If the subquery has no tables (1) and is not a UNION (2), like:
+
+ (SELECT subq_value)
+
+ then its NULLability is the same as subq_value's NULLability.
+
+ (1): A subquery that uses a table will return NULL when the table is empty.
+ (2): A UNION subquery will return NULL if it produces a "Subquery returns
+ more than one row" error.
*/
- if (engine->no_tables())
+ if (engine->no_tables() &&
+ engine->engine_type() != subselect_engine::UNION_ENGINE)
maybe_null= engine->may_be_null();
else
{
@@ -1358,6 +1366,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);