summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorSergey Petrunya <psergey@askmonty.org>2010-05-25 10:32:15 +0400
committerSergey Petrunya <psergey@askmonty.org>2010-05-25 10:32:15 +0400
commit62bf7f61245cb1d50a8992a4a1b74df1074d77d3 (patch)
treee4c8e662276d97394a5a22c93a1adbafa0150ee9 /sql
parent5a53be655cd68878fbe8c8bc0a0c3c30aeb98c45 (diff)
downloadmariadb-git-62bf7f61245cb1d50a8992a4a1b74df1074d77d3.tar.gz
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.
Diffstat (limited to 'sql')
-rw-r--r--sql/item_cmpfunc.cc35
-rw-r--r--sql/opt_subselect.cc3
-rw-r--r--sql/sql_select.cc3
3 files changed, 18 insertions, 23 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 22b36233e17..636cf3014a2 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -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.
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index 99272519665..6683b6f39e8 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -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;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 8d1b5f62c49..39f0798f8b2 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -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;
/*