Commit 77c03bcf authored by unknown's avatar unknown

MWL#89: Cost-based choice between Materialization and IN->EXISTS transformation

Improved handling of EXPLAIN statements for subqueries.
This patch specifically solves the problem when EXPLAIN reports:
  "const row not found"
instead of
  "no matching row in const table".
parent 8ec5e13f
...@@ -3100,11 +3100,20 @@ bool st_select_lex::optimize_unflattened_subqueries() ...@@ -3100,11 +3100,20 @@ bool st_select_lex::optimize_unflattened_subqueries()
{ {
JOIN *inner_join= sl->join; JOIN *inner_join= sl->join;
SELECT_LEX *save_select= un->thd->lex->current_select; SELECT_LEX *save_select= un->thd->lex->current_select;
ulonglong save_options;
int res; int res;
/* We need only 1 row to determine existence */ /* We need only 1 row to determine existence */
un->set_limit(un->global_parameters); un->set_limit(un->global_parameters);
un->thd->lex->current_select= sl; 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(); res= inner_join->optimize();
inner_join->select_options= save_options;
un->thd->lex->current_select= save_select; un->thd->lex->current_select= save_select;
if (res) if (res)
return TRUE; return TRUE;
...@@ -3115,6 +3124,34 @@ bool st_select_lex::optimize_unflattened_subqueries() ...@@ -3115,6 +3124,34 @@ bool st_select_lex::optimize_unflattened_subqueries()
} }
/**
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;
}
/** /**
A routine used by the parser to decide whether we are specifying a full A routine used by the parser to decide whether we are specifying a full
partitioning or if only partitions to add or to split. partitioning or if only partitions to add or to split.
......
...@@ -847,6 +847,9 @@ public: ...@@ -847,6 +847,9 @@ public:
some SQL statements as DELETE do not have a corresponding JOIN object. some SQL statements as DELETE do not have a corresponding JOIN object.
*/ */
bool optimize_unflattened_subqueries(); bool optimize_unflattened_subqueries();
/* Set the EXPLAIN type for this subquery. */
void set_explain_type();
private: private:
/* current index hint kind. used in filling up index_hints */ /* current index hint kind. used in filling up index_hints */
enum index_hint_type current_index_hint_type; enum index_hint_type current_index_hint_type;
......
...@@ -18832,28 +18832,9 @@ bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result) ...@@ -18832,28 +18832,9 @@ bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
bool res= 0; bool res= 0;
SELECT_LEX *first= unit->first_select(); SELECT_LEX *first= unit->first_select();
for (SELECT_LEX *sl= first; for (SELECT_LEX *sl= first; sl; sl= sl->next_select())
sl; sl->set_explain_type();
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;
}
if (unit->is_union()) if (unit->is_union())
{ {
unit->fake_select_lex->select_number= UINT_MAX; // jost for initialization unit->fake_select_lex->select_number= UINT_MAX; // jost for initialization
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment