Commit 2c811505 authored by unknown's avatar unknown

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

  
Reset correctly the LIMIT and the uncacheable flag of a subquery when executing
it via materialization.
parent 35f0faf4
...@@ -2436,16 +2436,6 @@ bool Item_in_subselect::setup_mat_engine() ...@@ -2436,16 +2436,6 @@ bool Item_in_subselect::setup_mat_engine()
if (mat_engine->init(&select_engine->join->fields_list)) if (mat_engine->init(&select_engine->join->fields_list))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
/*
Reset the "LIMIT 1" set in Item_exists_subselect::fix_length_and_dec.
TODO:
Currently we set the subquery LIMIT to infinity, and this is correct
because we forbid at parse time LIMIT inside IN subqueries (see
Item_in_subselect::test_limit). However, once we allow this, here
we should set the correct limit if given in the query.
*/
unit->global_parameters->select_limit= NULL;
engine= mat_engine; engine= mat_engine;
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
} }
......
...@@ -3566,14 +3566,29 @@ bool JOIN::choose_subquery_plan() ...@@ -3566,14 +3566,29 @@ bool JOIN::choose_subquery_plan()
else else
in_subs->exec_method= Item_in_subselect::IN_TO_EXISTS; in_subs->exec_method= Item_in_subselect::IN_TO_EXISTS;
if (in_subs->exec_method == Item_in_subselect::MATERIALIZATION) if (in_subs->exec_method == Item_in_subselect::MATERIALIZATION)
{ {
/* TODO: should we set/unset this flag for both select_lex and its unit? */
in_subs->unit->uncacheable&= ~UNCACHEABLE_DEPENDENT;
select_lex->uncacheable&= ~UNCACHEABLE_DEPENDENT;
// TODO: should we unset the UNCACHEABLE_DEPENDENT flag fro /*
// select_lex->uncacheable; ? Reset the "LIMIT 1" set in Item_exists_subselect::fix_length_and_dec.
// This affects how we execute JOIN::join_free - full or not. TODO:
// inner_join->restore_plan (keyuse, best_positions, best_read) Currently we set the subquery LIMIT to infinity, and this is correct
; because we forbid at parse time LIMIT inside IN subqueries (see
Item_in_subselect::test_limit). However, once we allow this, here
we should set the correct limit if given in the query.
*/
in_subs->unit->global_parameters->select_limit= NULL;
in_subs->unit->set_limit(unit->global_parameters);
/*
Set the limit of this JOIN object as well, because normally its being
set in the beginning of JOIN::optimize, which was already done.
*/
select_limit= in_subs->unit->select_limit_cnt;
// TODO: inner_join->restore_plan (keyuse, best_positions, best_read)
} }
else if (in_subs->exec_method == Item_in_subselect::IN_TO_EXISTS) else if (in_subs->exec_method == Item_in_subselect::IN_TO_EXISTS)
res= in_subs->inject_in_to_exists_cond(this); res= in_subs->inject_in_to_exists_cond(this);
......
...@@ -3115,6 +3115,7 @@ bool st_select_lex::optimize_unflattened_subqueries() ...@@ -3115,6 +3115,7 @@ bool st_select_lex::optimize_unflattened_subqueries()
DBUG_ASSERT(!item_in || (item_in && !item_in->is_min_max_optimized)); DBUG_ASSERT(!item_in || (item_in && !item_in->is_min_max_optimized));
if (item_in && item_in->create_in_to_exists_cond(inner_join)) if (item_in && item_in->create_in_to_exists_cond(inner_join))
return TRUE; return TRUE;
/* 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;
res= inner_join->optimize(); res= inner_join->optimize();
......
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