diff options
author | Igor Babaev <igor@askmonty.org> | 2013-02-07 21:46:02 -0800 |
---|---|---|
committer | Igor Babaev <igor@askmonty.org> | 2013-02-07 21:46:02 -0800 |
commit | 48aee4595708bebc04a6c8e640bbf6f55ce4e33c (patch) | |
tree | dda97027aea0087f227d2fd2faf633f5e1de1076 /sql/opt_subselect.cc | |
parent | 746152959a8787f3c7cf6b1c710fc1ee6c54419f (diff) | |
download | mariadb-git-48aee4595708bebc04a6c8e640bbf6f55ce4e33c.tar.gz |
Fixed bug mdev-3995.
This bug happened because the executor tried to use a wrong
TABLE REF object when building access keys. It constructed
keys from fields of a materialized table from a ref object
created to construct keys from the fields of the underlying
base table. This could happen only when materialized table
was created for a non-correlated IN subquery and only
when the materialized table used for lookups.
In this case we are guaranteed to be able to construct the
keys from the fields of tables that would be outer tables
for the tables of the IN subquery.
The patch makes sure that no ref objects constructed from
fields of materialized lookup tables are to be used.
Diffstat (limited to 'sql/opt_subselect.cc')
-rw-r--r-- | sql/opt_subselect.cc | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index 4591888307e..568297ba277 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -2526,6 +2526,10 @@ void advance_sj_state(JOIN *join, table_map remaining_tables, uint idx, /* Mark strategy as used */ (*strategy)->mark_used(); pos->sj_strategy= sj_strategy; + if (sj_strategy == SJ_OPT_MATERIALIZE) + join->sjm_lookup_tables |= handled_fanout; + else + join->sjm_lookup_tables &= ~handled_fanout; *current_read_time= read_time; *current_record_count= rec_count; join->cur_dups_producing_tables &= ~handled_fanout; @@ -3050,6 +3054,13 @@ void restore_prev_sj_state(const table_map remaining_tables, const JOIN_TAB *tab, uint idx) { TABLE_LIST *emb_sj_nest; + + if (tab->emb_sj_nest) + { + table_map subq_tables= tab->emb_sj_nest->sj_inner_tables; + tab->join->sjm_lookup_tables &= ~subq_tables; + } + if ((emb_sj_nest= tab->emb_sj_nest)) { /* If we're removing the last SJ-inner table, remove the sj-nest */ @@ -3227,6 +3238,7 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join) uint tablenr; table_map remaining_tables= 0; table_map handled_tabs= 0; + join->sjm_lookup_tables= 0; for (tablenr= table_count - 1 ; tablenr != join->const_tables - 1; tablenr--) { POSITION *pos= join->best_positions + tablenr; @@ -3252,6 +3264,7 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join) first= tablenr - sjm->tables + 1; join->best_positions[first].n_sj_tables= sjm->tables; join->best_positions[first].sj_strategy= SJ_OPT_MATERIALIZE; + join->sjm_lookup_tables|= s->table->map; } else if (pos->sj_strategy == SJ_OPT_MATERIALIZE_SCAN) { |