Commit 62bf7f61 authored by Sergey Petrunya's avatar Sergey Petrunya

MWL#90: Subqueries: Inside-out execution for non-semijoin materialized...

MWL#90: Subqueries: Inside-out execution for non-semijoin materialized subqueries that are AND-parts of the WHERE
- Code cleanu.
- Make MWL#90 code require @@optimizer_switch='semijoin=on'
- Update test results with the above
- Fork subselect_mat.test - we want to check both semi-join materialization, 
  which now has broader scope and non-semijoin materialization.
parent 5a53be65
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#!@PERL@ #!@PERL@
# Test of table elimination feature # Test of table elimination feature
......
...@@ -5761,32 +5761,27 @@ Item_field* Item_equal::get_first(Item_field *field) ...@@ -5761,32 +5761,27 @@ Item_field* Item_equal::get_first(Item_field *field)
} }
else else
{ {
#if 0
/* /*
The field is not in SJ-Materialization nest. We must return the first The field is not in SJ-Materialization nest. We must return the first
field that's not embedded in a SJ-Materialization nest. field in the join order. The field may be inside a semi-join nest, i.e
Example: suppose we have a join order: a join order may look like this:
SJ-Mat(it1 it2) ot1 ot2 SJ-Mat(it1 it2) ot1 ot2
and equality ot2.col = ot1.col = it2.col where we're looking what to substitute ot2.col for. In this case we must
If we're looking for best substitute for 'ot2.col', we should pick ot1.col still return it1.col, here's a proof why:
and not it2.col, because when we run a join between ot1 and ot2
execution of SJ-Mat(...) has already finished and we can't rely on the First let's note that either it1.col or it2.col participates in
value of it*.*. subquery's IN-equality. It can't be otherwise, because materialization is
psergey-fix-fix: ^^ THAT IS INCORRECT ^^. Pick the first, whatever that only applicable to uncorrelated subqueries, so the only way we could
is. infer "it1.col=ot1.col" is from IN-equality. Ok, so IN-eqality has
it1.col or it2.col on its inner side. it1.col is first such item in the
join order, so it's not possible for SJ-Mat to be
SJ-Materialization-lookup, it is SJ-Materialization-Scan. The scan part
of this strategy will unpack value of it1.col=it2.col into it1.col
(that's the first equal item inside the subquery), and we'll be able to
get it from there. qed.
*/ */
while ((item= it++))
{
TABLE_LIST *emb_nest= item->field->table->pos_in_table_list->embedding;
if (!emb_nest || !emb_nest->sj_mat_info ||
!emb_nest->sj_mat_info->is_used)
{
return item;
}
}
#endif
return fields.head(); return fields.head();
} }
// Shouldn't get here. // Shouldn't get here.
......
...@@ -237,7 +237,8 @@ int check_and_do_in_subquery_rewrites(JOIN *join) ...@@ -237,7 +237,8 @@ int check_and_do_in_subquery_rewrites(JOIN *join)
with jtbm strategy with jtbm strategy
*/ */
if (in_subs->exec_method == Item_in_subselect::MATERIALIZATION && if (in_subs->exec_method == Item_in_subselect::MATERIALIZATION &&
thd->thd_marker.emb_on_expr_nest == (TABLE_LIST*)0x1) thd->thd_marker.emb_on_expr_nest == (TABLE_LIST*)0x1 &&
optimizer_flag(thd, OPTIMIZER_SWITCH_SEMIJOIN))
{ {
in_subs->emb_on_expr_nest= thd->thd_marker.emb_on_expr_nest; in_subs->emb_on_expr_nest= thd->thd_marker.emb_on_expr_nest;
in_subs->is_flattenable_semijoin= FALSE; in_subs->is_flattenable_semijoin= FALSE;
......
...@@ -4287,7 +4287,6 @@ best_access_path(JOIN *join, ...@@ -4287,7 +4287,6 @@ best_access_path(JOIN *join,
double tmp; double tmp;
ha_rows rec; ha_rows rec;
bool best_uses_jbuf= FALSE; bool best_uses_jbuf= FALSE;
Item_in_subselect* jtbm_subselect= s->table->pos_in_table_list->jtbm_subselect;
Loose_scan_opt loose_scan_opt; Loose_scan_opt loose_scan_opt;
DBUG_ENTER("best_access_path"); DBUG_ENTER("best_access_path");
...@@ -4696,7 +4695,7 @@ best_access_path(JOIN *join, ...@@ -4696,7 +4695,7 @@ best_access_path(JOIN *join,
!((s->table->file->ha_table_flags() & HA_TABLE_SCAN_ON_INDEX) && // (3) !((s->table->file->ha_table_flags() & HA_TABLE_SCAN_ON_INDEX) && // (3)
! s->table->covering_keys.is_clear_all() && best_key && !s->quick) &&// (3) ! s->table->covering_keys.is_clear_all() && best_key && !s->quick) &&// (3)
!(s->table->force_index && best_key && !s->quick) && // (4) !(s->table->force_index && best_key && !s->quick) && // (4)
!(best_key && jtbm_subselect)) // (5) !(best_key && s->table->pos_in_table_list->jtbm_subselect)) // (5)
{ // Check full join { // Check full join
ha_rows rnd_records= s->found_records; ha_rows rnd_records= s->found_records;
/* /*
......
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