diff options
author | Sergey Petrunya <psergey@askmonty.org> | 2013-11-21 11:19:01 +0400 |
---|---|---|
committer | Sergey Petrunya <psergey@askmonty.org> | 2013-11-21 11:19:01 +0400 |
commit | c4defdc8d971cdcc186de549bae9ac4351c7aade (patch) | |
tree | 520409a9679225a07fbfa908e2932d9ee9d0c454 /sql/opt_subselect.cc | |
parent | 8af289d2b0ac35c5ac76f813cd9e4d5aa5eb6adb (diff) | |
download | mariadb-git-c4defdc8d971cdcc186de549bae9ac4351c7aade.tar.gz |
MDEV-5161: Wrong result (missing rows) with semijoin, LEFT JOIN, ORDER BY, constant table
- Don't pull out a table out of a semi-join if it is on the inner side of an outer join.
- Make join->sort_by_table= get_sort_by_table(...) call after const table detection
is done. That way, the value of join->sort_by_table will match the actual execution.
Which will allow the code in setup_semijoin_dups_elimination() (search for
"Make sure that possible sorting of rows from the head table is not to be employed."
to see that "Using filesort" is going to be used together with Duplicate Elimination (
and change it to Using temporary + Using filesort)
Diffstat (limited to 'sql/opt_subselect.cc')
-rw-r--r-- | sql/opt_subselect.cc | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index d4cb33c759a..0f5a4500353 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -1924,11 +1924,25 @@ int pull_out_semijoin_tables(JOIN *join) } } - table_map pulled_tables= 0; + table_map dep_tables= 0; if (have_join_nest_children) goto skip; + /* + Calculate set of tables within this semi-join nest that have + other dependent tables + */ + child_li.rewind(); + while ((tbl= child_li++)) + { + TABLE *const table= tbl->table; + if (table && + (table->reginfo.join_tab->dependent & + sj_nest->nested_join->used_tables)) + dep_tables|= table->reginfo.join_tab->dependent; + } + /* Action #1: Mark the constant tables to be pulled out */ child_li.rewind(); while ((tbl= child_li++)) @@ -1979,7 +1993,8 @@ int pull_out_semijoin_tables(JOIN *join) child_li.rewind(); while ((tbl= child_li++)) { - if (tbl->table && !(pulled_tables & tbl->table->map)) + if (tbl->table && !(pulled_tables & tbl->table->map) && + !(dep_tables & tbl->table->map)) { if (find_eq_ref_candidate(tbl->table, sj_nest->nested_join->used_tables & |