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()
{
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;
}
/**
......
......@@ -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;
......
......@@ -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
......
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