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@
# Test of table elimination feature
......
......@@ -5761,32 +5761,27 @@ Item_field* Item_equal::get_first(Item_field *field)
}
else
{
#if 0
/*
The field is not in SJ-Materialization nest. We must return the first
field that's not embedded in a SJ-Materialization nest.
Example: suppose we have a join order:
field in the join order. The field may be inside a semi-join nest, i.e
a join order may look like this:
SJ-Mat(it1 it2) ot1 ot2
and equality ot2.col = ot1.col = it2.col
If we're looking for best substitute for 'ot2.col', we should pick ot1.col
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
value of it*.*.
psergey-fix-fix: ^^ THAT IS INCORRECT ^^. Pick the first, whatever that
is.
where we're looking what to substitute ot2.col for. In this case we must
still return it1.col, here's a proof why:
First let's note that either it1.col or it2.col participates in
subquery's IN-equality. It can't be otherwise, because materialization is
only applicable to uncorrelated subqueries, so the only way we could
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();
}
// Shouldn't get here.
......
......@@ -237,7 +237,8 @@ int check_and_do_in_subquery_rewrites(JOIN *join)
with jtbm strategy
*/
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->is_flattenable_semijoin= FALSE;
......
......@@ -4287,7 +4287,6 @@ best_access_path(JOIN *join,
double tmp;
ha_rows rec;
bool best_uses_jbuf= FALSE;
Item_in_subselect* jtbm_subselect= s->table->pos_in_table_list->jtbm_subselect;
Loose_scan_opt loose_scan_opt;
DBUG_ENTER("best_access_path");
......@@ -4696,7 +4695,7 @@ best_access_path(JOIN *join,
!((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->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
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