diff options
-rw-r--r-- | sql/sql_lex.cc | 39 | ||||
-rw-r--r-- | sql/sql_lex.h | 3 | ||||
-rw-r--r-- | sql/sql_select.cc | 25 |
3 files changed, 44 insertions, 23 deletions
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index bfd24a2491c..445fdf5a7fd 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -3100,11 +3100,20 @@ bool st_select_lex::optimize_unflattened_subqueries() { JOIN *inner_join= sl->join; SELECT_LEX *save_select= un->thd->lex->current_select; + ulonglong save_options; int res; /* We need only 1 row to determine existence */ un->set_limit(un->global_parameters); un->thd->lex->current_select= sl; + save_options= inner_join->select_options; + if (un->outer_select()->options & SELECT_DESCRIBE) + { + /* Optimize the subquery in the context of EXPLAIN. */ + set_explain_type(); + inner_join->select_options= options; + } res= inner_join->optimize(); + inner_join->select_options= save_options; un->thd->lex->current_select= save_select; if (res) return TRUE; @@ -3112,7 +3121,35 @@ bool st_select_lex::optimize_unflattened_subqueries() } } return FALSE; -} +} + + +/** + Set the EXPLAIN type for this subquery. +*/ + +void st_select_lex::set_explain_type() +{ + SELECT_LEX *first= master_unit()->first_select(); + /* drop UNCACHEABLE_EXPLAIN, because it is for internal usage only */ + uint8 is_uncacheable= (uncacheable & ~UNCACHEABLE_EXPLAIN); + + type= ((&master_unit()->thd->lex->select_lex == this) ? + (first_inner_unit() || next_select() ? + "PRIMARY" : "SIMPLE") : + ((this == first) ? + ((linkage == DERIVED_TABLE_TYPE) ? + "DERIVED" : + ((is_uncacheable & UNCACHEABLE_DEPENDENT) ? + "DEPENDENT SUBQUERY" : + (is_uncacheable ? "UNCACHEABLE SUBQUERY" : + "SUBQUERY"))) : + ((is_uncacheable & UNCACHEABLE_DEPENDENT) ? + "DEPENDENT UNION": + is_uncacheable ? "UNCACHEABLE UNION": + "UNION"))); + options|= SELECT_DESCRIBE; +} /** diff --git a/sql/sql_lex.h b/sql/sql_lex.h index d106bfd55fd..7c49d0a407e 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -847,6 +847,9 @@ public: some SQL statements as DELETE do not have a corresponding JOIN object. */ bool optimize_unflattened_subqueries(); + /* Set the EXPLAIN type for this subquery. */ + void set_explain_type(); + private: /* current index hint kind. used in filling up index_hints */ enum index_hint_type current_index_hint_type; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 800458e988b..148a60efadd 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -18832,28 +18832,9 @@ bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result) bool res= 0; SELECT_LEX *first= unit->first_select(); - for (SELECT_LEX *sl= first; - sl; - sl= sl->next_select()) - { - // drop UNCACHEABLE_EXPLAIN, because it is for internal usage only - uint8 uncacheable= (sl->uncacheable & ~UNCACHEABLE_EXPLAIN); - sl->type= (((&thd->lex->select_lex)==sl)? - (sl->first_inner_unit() || sl->next_select() ? - "PRIMARY" : "SIMPLE"): - ((sl == first)? - ((sl->linkage == DERIVED_TABLE_TYPE) ? - "DERIVED": - ((uncacheable & UNCACHEABLE_DEPENDENT) ? - "DEPENDENT SUBQUERY": - (uncacheable?"UNCACHEABLE SUBQUERY": - "SUBQUERY"))): - ((uncacheable & UNCACHEABLE_DEPENDENT) ? - "DEPENDENT UNION": - uncacheable?"UNCACHEABLE UNION": - "UNION"))); - sl->options|= SELECT_DESCRIBE; - } + for (SELECT_LEX *sl= first; sl; sl= sl->next_select()) + sl->set_explain_type(); + if (unit->is_union()) { unit->fake_select_lex->select_number= UINT_MAX; // jost for initialization |