Commit 1f1990a1 authored by Igor Babaev's avatar Igor Babaev

Fixed bug mdev-10884.

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.
parent 09cbb772
...@@ -7032,3 +7032,54 @@ i ...@@ -7032,3 +7032,54 @@ i
DROP FUNCTION f; DROP FUNCTION f;
DROP VIEW v2,v1; DROP VIEW v2,v1;
DROP TABLE t1; 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;
...@@ -923,3 +923,31 @@ EXECUTE stmt; ...@@ -923,3 +923,31 @@ EXECUTE stmt;
DROP FUNCTION f; DROP FUNCTION f;
DROP VIEW v2,v1; DROP VIEW v2,v1;
DROP TABLE t1; 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;
...@@ -1131,27 +1131,31 @@ bool pushdown_cond_for_derived(THD *thd, Item *cond, TABLE_LIST *derived) ...@@ -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_unit *unit= derived->get_unit();
st_select_lex *sl= unit->first_select(); 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 */ /* 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()) for (; sl; sl= sl->next_select())
{ {
if (sl->cond_pushdown_is_allowed()) if (sl->cond_pushdown_is_allowed())
{ {
any_select_allows_cond_pushdown= true; some_select_allows_cond_pushdown= true;
break; break;
} }
} }
if (!any_select_allows_cond_pushdown) if (!some_select_allows_cond_pushdown)
return false; 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' Build the most restrictive condition extractable from 'cond'
that can be pushed into the derived table 'derived'. that can be pushed into the derived table 'derived'.
......
...@@ -1160,7 +1160,7 @@ class st_select_lex: public st_select_lex_node ...@@ -1160,7 +1160,7 @@ class st_select_lex: public st_select_lex_node
bool have_window_funcs() const { return (window_funcs.elements !=0); } bool have_window_funcs() const { return (window_funcs.elements !=0); }
bool cond_pushdown_is_allowed() const bool cond_pushdown_is_allowed() const
{ return !have_window_funcs() && !olap; } { return !have_window_funcs() && !olap && !explicit_limit; }
private: private:
bool m_non_agg_field_used; bool m_non_agg_field_used;
......
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