diff options
-rw-r--r-- | sql/sql_select.cc | 5 | ||||
-rw-r--r-- | sql/sql_union.cc | 29 |
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) { |