summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/sql_lex.cc39
-rw-r--r--sql/sql_lex.h3
-rw-r--r--sql/sql_select.cc25
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