summaryrefslogtreecommitdiff
path: root/sql/item_subselect.cc
diff options
context:
space:
mode:
authorOleksandr Byelkin <sanja@mariadb.com>2022-05-03 10:59:54 +0200
committerOleksandr Byelkin <sanja@mariadb.com>2022-05-03 10:59:54 +0200
commit9614fde1aac6ffa4745804342ff70a96b2418e30 (patch)
treed53f4578ce0a6b5cf30f3eef854d50c16fbabcee /sql/item_subselect.cc
parent182b8a29e7a1a0f0fbffeed39518c2c9dc026e13 (diff)
parent70555454b4c224e85383d482411961c7f2eba2e2 (diff)
downloadmariadb-git-9614fde1aac6ffa4745804342ff70a96b2418e30.tar.gz
Merge branch '10.2' into 10.3
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 88db52db13d..2e33a71b8f9 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -763,6 +763,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,
@@ -1272,11 +1273,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
{
@@ -1312,6 +1320,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);