diff options
author | Igor Babaev <igor@askmonty.org> | 2016-09-25 17:28:49 -0700 |
---|---|---|
committer | Igor Babaev <igor@askmonty.org> | 2016-09-25 17:29:10 -0700 |
commit | 1f1990a1612669af731363b4d0bacf2d2ce5adbd (patch) | |
tree | 2910046747e47a32857f4ab57cba7705ef17dfd5 | |
parent | 09cbb772ebf6bdf10ea7e2bd4ba833d36e7e5b8f (diff) | |
download | mariadb-git-mariadb-10.2.2.tar.gz |
Fixed bug mdev-10884.mariadb-10.2.2
If a materialized derived table / view is specified by a unit
with SELECTs containing ORDER BY ... LIMIT then condition pushdown
cannot be done for these SELECTs.
If a materialized derived table / view is specified by a unit
containing global ORDER BY ... LIMIT then condition pushdown
cannot be done for this unit.
-rw-r--r-- | mysql-test/r/derived_cond_pushdown.result | 51 | ||||
-rw-r--r-- | mysql-test/t/derived_cond_pushdown.test | 28 | ||||
-rw-r--r-- | sql/sql_derived.cc | 26 | ||||
-rw-r--r-- | sql/sql_lex.h | 2 |
4 files changed, 95 insertions, 12 deletions
diff --git a/mysql-test/r/derived_cond_pushdown.result b/mysql-test/r/derived_cond_pushdown.result index 91c6e629821..3922a7d0360 100644 --- a/mysql-test/r/derived_cond_pushdown.result +++ b/mysql-test/r/derived_cond_pushdown.result @@ -7032,3 +7032,54 @@ i DROP FUNCTION f; DROP VIEW v2,v1; DROP TABLE t1; +# +# MDEV-10884: condition pushdown into derived specified by +# 1. unit with SELECT containing ORDER BY ... LIMIT +# 2. unit containing global ORDER BY ... LIMIT +# +create table t1(a int); +insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +select a from t1 order by a limit 5; +a +0 +1 +2 +3 +4 +set statement optimizer_switch='condition_pushdown_for_derived=off' for +select * from (select a from t1 order by a limit 5) t where t.a not in (1,2,3); +a +0 +4 +set statement optimizer_switch='condition_pushdown_for_derived=on' for +select * from (select a from t1 order by a limit 5) t where t.a not in (1,2,3); +a +0 +4 +select a from t1 where a < 4 union select a from t1 where a > 5 +order by a limit 5; +a +0 +1 +2 +3 +6 +set statement optimizer_switch='condition_pushdown_for_derived=off' for +select * from +(select a from t1 where a < 4 union select a from t1 where a > 5 +order by a limit 5) t where t.a not in (2,9); +a +0 +1 +3 +6 +set statement optimizer_switch='condition_pushdown_for_derived=on' for +select * from +(select a from t1 where a < 4 union select a from t1 where a > 5 +order by a limit 5) t where t.a not in (2,9); +a +0 +1 +3 +6 +drop table t1; diff --git a/mysql-test/t/derived_cond_pushdown.test b/mysql-test/t/derived_cond_pushdown.test index 141c705aa18..9aef1d768be 100644 --- a/mysql-test/t/derived_cond_pushdown.test +++ b/mysql-test/t/derived_cond_pushdown.test @@ -923,3 +923,31 @@ EXECUTE stmt; DROP FUNCTION f; DROP VIEW v2,v1; DROP TABLE t1; + +--echo # +--echo # MDEV-10884: condition pushdown into derived specified by +--echo # 1. unit with SELECT containing ORDER BY ... LIMIT +--echo # 2. unit containing global ORDER BY ... LIMIT +--echo # + +create table t1(a int); +insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +select a from t1 order by a limit 5; + +set statement optimizer_switch='condition_pushdown_for_derived=off' for +select * from (select a from t1 order by a limit 5) t where t.a not in (1,2,3); +set statement optimizer_switch='condition_pushdown_for_derived=on' for +select * from (select a from t1 order by a limit 5) t where t.a not in (1,2,3); + +select a from t1 where a < 4 union select a from t1 where a > 5 + order by a limit 5; +set statement optimizer_switch='condition_pushdown_for_derived=off' for +select * from +(select a from t1 where a < 4 union select a from t1 where a > 5 + order by a limit 5) t where t.a not in (2,9); +set statement optimizer_switch='condition_pushdown_for_derived=on' for +select * from +(select a from t1 where a < 4 union select a from t1 where a > 5 + order by a limit 5) t where t.a not in (2,9); + +drop table t1; diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 85a85b9c3b2..0b67b952056 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -1131,27 +1131,31 @@ bool pushdown_cond_for_derived(THD *thd, Item *cond, TABLE_LIST *derived) st_select_lex_unit *unit= derived->get_unit(); st_select_lex *sl= unit->first_select(); + /* Do not push conditions into constant derived */ + if (unit->executed) + return false; + + /* Do not push conditions into recursive with tables */ + if (derived->is_recursive_with_table()) + return false; + + /* Do not push conditions into unit with global ORDER BY ... LIMIT */ + if (unit->fake_select_lex && unit->fake_select_lex->explicit_limit) + return false; + /* Check whether any select of 'unit' allows condition pushdown */ - bool any_select_allows_cond_pushdown= false; + bool some_select_allows_cond_pushdown= false; for (; sl; sl= sl->next_select()) { if (sl->cond_pushdown_is_allowed()) { - any_select_allows_cond_pushdown= true; + some_select_allows_cond_pushdown= true; break; } } - if (!any_select_allows_cond_pushdown) + if (!some_select_allows_cond_pushdown) return false; - /* Do not push conditions into constant derived */ - if (unit->executed) - return false; - - /* Do not push conditions into recursive with tables */ - if (derived->is_recursive_with_table()) - return false; - /* Build the most restrictive condition extractable from 'cond' that can be pushed into the derived table 'derived'. diff --git a/sql/sql_lex.h b/sql/sql_lex.h index e499cc794a1..6387b6d1c2d 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1160,7 +1160,7 @@ public: bool have_window_funcs() const { return (window_funcs.elements !=0); } bool cond_pushdown_is_allowed() const - { return !have_window_funcs() && !olap; } + { return !have_window_funcs() && !olap && !explicit_limit; } private: bool m_non_agg_field_used; |