summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/sql_select.cc5
-rw-r--r--sql/sql_union.cc29
2 files changed, 34 insertions, 0 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index fbb5d00e7a8..860a4b7f5dc 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -17299,6 +17299,11 @@ bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
unit->fake_select_lex->options|= SELECT_DESCRIBE;
if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK | SELECT_DESCRIBE)))
res= unit->exec();
+ /*
+ Reset select option. Needed if fake_select_lex is used and not called
+ from select describe.
+ */
+ unit->fake_select_lex->options&= ~SELECT_DESCRIBE;
res|= unit->cleanup();
}
else
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index b0a25c2df97..d0660e8f117 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -511,6 +511,35 @@ bool st_select_lex_unit::exec()
(select_limit_cnt == HA_POS_ERROR || sl->braces) ?
sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
saved_error= sl->join->optimize();
+
+ /*
+ If called by explain statement then we may need to save the original
+ JOIN LAYOUT so that we can display the plan. Otherwise original plan
+ will be replaced by a simple scan on temp table if subquery uses temp
+ table.
+ We check for following conditions to force join_tmp creation
+ 1. This is an EXPLAIN statement, and
+ 2. JOIN not yet saved in JOIN::optimize(), and
+ 3. Not called directly from select_describe(), and
+ 4. Belongs to a subquery that is const, and
+ 5. Need a temp table.
+ */
+ if (thd->lex->describe && // 1
+ !sl->uncacheable && // 2
+ !(sl->join->select_options & SELECT_DESCRIBE) && // 3
+ item && item->const_item()) // 4
+ {
+ /*
+ Force join->join_tmp creation, because this subquery will be
+ replaced by a simple select from the materialization temp table
+ by optimize() called by EXPLAIN and we need to preserve the
+ initial query structure so we can display it.
+ */
+ sl->uncacheable|= UNCACHEABLE_EXPLAIN;
+ sl->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN;
+ if (sl->join->need_tmp && sl->join->init_save_join_tab()) // 5
+ DBUG_RETURN(1);
+ }
}
if (!saved_error)
{