revision-id: 1f8f7d0fa45c00851c408238c6e3b4876a3ad72c (mariadb-10.0.30-188-g1f8f7d0fa45)
parent(s): 4500be78734ea5bcac43162a29465c489cbe1db4
author: Varun Gupta
committer: Varun Gupta
timestamp: 2017-10-03 17:06:10 +0530
message:

MDEV-13905: Condition in pushed index condition is not removed from the WHERE in BNL joins

The index condition pushdown was not removed from the inner tables involved in the join,
so now the index conditon pushdow witll also be removed from cache_select->cond

---
 mysql-test/r/explain.result    | 57 ++++++++++++++++++++++++++++++++++++++++++
 mysql-test/t/explain.test      | 56 +++++++++++++++++++++++++++++++++++++++++
 sql/opt_index_cond_pushdown.cc | 28 +++++++++++++++++++--
 sql/sql_select.cc              |  2 +-
 4 files changed, 140 insertions(+), 3 deletions(-)

diff --git a/mysql-test/r/explain.result b/mysql-test/r/explain.result
index b3c33e3559a..239918415a7 100644
--- a/mysql-test/r/explain.result
+++ b/mysql-test/r/explain.result
@@ -406,4 +406,61 @@ id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	NULL	NULL	NULL	NULL	NULL	NULL	NULL	No tables used
 2	SUBQUERY	t1	system	NULL	NULL	NULL	NULL	1	
 drop table t1, t2;
+#
+#MDEV-13628: ORed condition in pushed index condition is not removed from the WHERE
+#
+create table ten(a int);
+insert into ten values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t0(a int);
+insert into t0 select A.a + B.a* 10 + C.a * 100 from ten A, ten B, ten C;
+create table t1 (key1 int not null, filler char(100));
+insert into t1 select A.a + 1000 *B.a, 'filler-data' from t0 A, ten B;
+alter table t1 add key(key1);
+explain select * from t1 where key1 < 3 or key1 > 99999;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	range	key1	key1	4	NULL	20	Using index condition
+drop table ten,t1,t0;
+#
+#MDEV-13905:Condition in pushed index condition is not removed
+# from the WHERE in BNL joins
+#
+create table ten(a int);
+insert into ten values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table one_k(a int);
+insert into one_k select A.a + B.a* 10 + C.a * 100 from ten A, ten B, ten C;
+create table t10 (
+i0 int, i1 int, i2 int, i3 int, i4 int,
+c1 int, c2 int, c3 int, c4 int,
+index(i0,i1,i2,i3,i4)) engine=myisam;
+insert into t10 select a,a,a,a,a, a,a,a,a from one_k where a> 5;
+create table t11 like t10;
+insert into t11 select * from t10;
+explain
+select * from t10, t11
+where
+t11.i0<10 and t10.i0<10;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t10	range	i0	i0	5	NULL	2	Using index condition
+1	SIMPLE	t11	range	i0	i0	5	NULL	2	Using index condition; Using join buffer (flat, BNL join)
+drop table ten, t10,t11, one_k;
+create table ten(a int);
+insert into ten values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table one_k(a int);
+insert into one_k select A.a + B.a* 10 + C.a * 100 from ten A, ten B, ten C;
+create table t10 (
+i0 int, i1 int, i2 int, i3 int, i4 int,
+c1 int, c2 int, c3 int, c4 int,
+index(i0,i1,i2,i3,i4)) engine=myisam;
+insert into t10 select a,a,a,a,a, a,a,a,a from one_k where a> 5;
+create table t11 like t10;
+insert into t11 select * from t10;
+explain
+select * from t10, t11
+where
+t11.i0<10 and t10.i0<10 and
+((t11.i2 <100 AND t10.i3 <300)  OR (t11.i2<100 AND t10.i3 <300)) ;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t10	range	i0	i0	5	NULL	2	Using index condition
+1	SIMPLE	t11	range	i0	i0	5	NULL	2	Using index condition; Using where; Using join buffer (flat, BNL join)
+drop table ten, t10,t11, one_k;
 # End of 10.1 tests
diff --git a/mysql-test/t/explain.test b/mysql-test/t/explain.test
index d5be354c852..e62cd2b2720 100644
--- a/mysql-test/t/explain.test
+++ b/mysql-test/t/explain.test
@@ -332,4 +332,60 @@ explain replace into t2 select 100, (select a from t1);
 
 drop table t1, t2;
 
+--echo #
+--echo #MDEV-13628: ORed condition in pushed index condition is not removed from the WHERE
+--echo #
+create table ten(a int);
+insert into ten values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t0(a int);
+insert into t0 select A.a + B.a* 10 + C.a * 100 from ten A, ten B, ten C;
+create table t1 (key1 int not null, filler char(100));
+insert into t1 select A.a + 1000 *B.a, 'filler-data' from t0 A, ten B;
+alter table t1 add key(key1);
+explain select * from t1 where key1 < 3 or key1 > 99999;
+drop table ten,t1,t0;
+
+--echo #
+--echo #MDEV-13905:Condition in pushed index condition is not removed
+--echo # from the WHERE in BNL joins
+--echo #
+create table ten(a int);
+insert into ten values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table one_k(a int);
+insert into one_k select A.a + B.a* 10 + C.a * 100 from ten A, ten B, ten C;
+create table t10 (
+i0 int, i1 int, i2 int, i3 int, i4 int,
+c1 int, c2 int, c3 int, c4 int,
+index(i0,i1,i2,i3,i4)) engine=myisam;
+insert into t10 select a,a,a,a,a, a,a,a,a from one_k where a> 5;
+create table t11 like t10;
+insert into t11 select * from t10;
+explain
+select * from t10, t11
+where
+t11.i0<10 and t10.i0<10;
+drop table ten, t10,t11, one_k;
+
+create table ten(a int);
+insert into ten values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+
+create table one_k(a int);
+insert into one_k select A.a + B.a* 10 + C.a * 100 from ten A, ten B, ten C;
+
+create table t10 (
+i0 int, i1 int, i2 int, i3 int, i4 int,
+c1 int, c2 int, c3 int, c4 int,
+index(i0,i1,i2,i3,i4)) engine=myisam;
+insert into t10 select a,a,a,a,a, a,a,a,a from one_k where a> 5;
+
+create table t11 like t10;
+insert into t11 select * from t10;
+
+explain
+select * from t10, t11
+where
+ t11.i0<10 and t10.i0<10 and
+ ((t11.i2 <100 AND t10.i3 <300)  OR (t11.i2<100 AND t10.i3 <300)) ;
+drop table ten, t10,t11, one_k;
+
 --echo # End of 10.1 tests
diff --git a/sql/opt_index_cond_pushdown.cc b/sql/opt_index_cond_pushdown.cc
index d68866a33bb..8d6135f7065 100644
--- a/sql/opt_index_cond_pushdown.cc
+++ b/sql/opt_index_cond_pushdown.cc
@@ -409,7 +409,31 @@ void push_index_cond(JOIN_TAB *tab, uint keyno)
 
       DBUG_EXECUTE("where",
                    print_where(row_cond, "remainder cond", QT_ORDINARY););
-      
+      Item *cache_cond=NULL;
+
+      if (tab->cache_select && tab->cache_select->cond)
+      {
+        cache_cond= tab->idx_cond_fact_out ?
+                  make_cond_remainder(tab->cache_select->cond, tab->table, keyno,
+                          tab->icp_other_tables_ok, TRUE) :
+                  tab->cache_select->cond;
+
+        if (cache_cond)
+        {
+          if (!idx_remainder_cond)
+            tab->cache_select->cond= cache_cond;
+          else
+          {
+          COND *new_cond= new Item_cond_and(cache_cond, idx_remainder_cond);
+          tab->cache_select->cond= new_cond;
+          tab->select_cond->quick_fix_field();
+          ((Item_cond_and*)tab->cache_select->cond)->used_tables_cache=
+            cache_cond->used_tables() | idx_remainder_cond->used_tables();
+          }
+        }
+        else
+          tab->cache_select->cond= idx_remainder_cond;
+      }
       if (row_cond)
       {
         if (!idx_remainder_cond)
@@ -418,7 +442,7 @@ void push_index_cond(JOIN_TAB *tab, uint keyno)
         {
           COND *new_cond= new Item_cond_and(row_cond, idx_remainder_cond);
           tab->select_cond= new_cond;
-	  tab->select_cond->quick_fix_field();
+          tab->select_cond->quick_fix_field();
           ((Item_cond_and*)tab->select_cond)->used_tables_cache= 
             row_cond->used_tables() | idx_remainder_cond->used_tables();
         }
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 7be9bfb7838..5c229f2ee16 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -10997,7 +10997,7 @@ void check_join_cache_usage_for_tables(JOIN *join, ulonglong options,
 
 void JOIN_TAB::remove_redundant_bnl_scan_conds()
 {
-  if (!(select_cond && cache_select && cache &&
+  if (!(select_cond && cache_select && cache_select->cond && cache &&
         (cache->get_join_alg() == JOIN_CACHE::BNL_JOIN_ALG ||
          cache->get_join_alg() == JOIN_CACHE::BNLH_JOIN_ALG)))
     return;
_______________________________________________
commits mailing list
commits@mariadb.org
https://lists.askmonty.org/cgi-bin/mailman/listinfo/commits