diff options
author | Igor Babaev <igor@askmonty.org> | 2010-12-24 14:36:35 -0800 |
---|---|---|
committer | Igor Babaev <igor@askmonty.org> | 2010-12-24 14:36:35 -0800 |
commit | d9a81475c70aebc1f2542bf0c115b3ebd9649193 (patch) | |
tree | 4a4bfc01d4a13e9c293415be57ee624edb44e7c6 | |
parent | f51a26885faa0106286e63fd15f18dae6f618508 (diff) | |
download | mariadb-git-d9a81475c70aebc1f2542bf0c115b3ebd9649193.tar.gz |
Fixed LP bug#694092.
In some cases the function make_cond_for_index() was mistaken
when detecting index only pushdown conditions for a table:
a pushdown condition that was not index only could be marked
as such.
It happened because the procedure erroneously used the markers
for index only conditions that remained from the calls of
this function that extracted the index conditions for other
tables.
Fixed by erasing index only markers as soon as they are need
anymore.
-rw-r--r-- | mysql-test/r/join_cache.result | 35 | ||||
-rw-r--r-- | mysql-test/t/join_cache.test | 35 | ||||
-rw-r--r-- | sql/opt_index_cond_pushdown.cc | 12 |
3 files changed, 80 insertions, 2 deletions
diff --git a/mysql-test/r/join_cache.result b/mysql-test/r/join_cache.result index 0d2706c7739..3a22dfc8354 100644 --- a/mysql-test/r/join_cache.result +++ b/mysql-test/r/join_cache.result @@ -6056,4 +6056,39 @@ a4 b5 SET SESSION optimizer_switch = 'outer_join_with_cache=off'; SET SESSION join_cache_level = DEFAULT; DROP TABLE t1,t2,t3,t4,t5; +# +# Bug #694092: incorrect detection of index only pushdown conditions +# +CREATE TABLE t1 ( +f1 varchar(10), f3 int(11), PRIMARY KEY (f3) +); +INSERT INTO t1 VALUES ('y',1),('or',5); +CREATE TABLE t2 ( +f3 int(11), f2 varchar(1024), f4 varchar(10), PRIMARY KEY (f3) +); +INSERT INTO t2 VALUES (6,'RPOYT','y'),(10,'JINQE','m'); +SET SESSION join_cache_level = 1; +SET SESSION optimizer_switch = 'index_condition_pushdown=off'; +EXPLAIN +SELECT * FROM t1,t2 +WHERE t1.f1 = t2.f4 AND (t1.f3 = 1 AND t2.f3 = 4 OR t1.f3 = 2 AND t2.f3 = 6); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using where; Using MRR +1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 2 Using where; Using MRR; Using join buffer (flat, BNL join) +SELECT * FROM t1,t2 +WHERE t1.f1 = t2.f4 AND (t1.f3 = 1 AND t2.f3 = 4 OR t1.f3 = 2 AND t2.f3 = 6); +f1 f3 f3 f2 f4 +SET SESSION optimizer_switch = 'index_condition_pushdown=on'; +EXPLAIN +SELECT * FROM t1,t2 +WHERE t1.f1 = t2.f4 AND (t1.f3 = 1 AND t2.f3 = 4 OR t1.f3 = 2 AND t2.f3 = 6); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using MRR +1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using where; Using MRR; Using join buffer (flat, BNL join) +SELECT * FROM t1,t2 +WHERE t1.f1 = t2.f4 AND (t1.f3 = 1 AND t2.f3 = 4 OR t1.f3 = 2 AND t2.f3 = 6); +f1 f3 f3 f2 f4 +SET SESSION join_cache_level = DEFAULT; +SET SESSION optimizer_switch = DEFAULT; +DROP TABLE t1,t2; set @@optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/t/join_cache.test b/mysql-test/t/join_cache.test index 1905297b25b..823af0b929d 100644 --- a/mysql-test/t/join_cache.test +++ b/mysql-test/t/join_cache.test @@ -2700,5 +2700,40 @@ SET SESSION join_cache_level = DEFAULT; DROP TABLE t1,t2,t3,t4,t5; +--echo # +--echo # Bug #694092: incorrect detection of index only pushdown conditions +--echo # + +CREATE TABLE t1 ( + f1 varchar(10), f3 int(11), PRIMARY KEY (f3) +); +INSERT INTO t1 VALUES ('y',1),('or',5); + +CREATE TABLE t2 ( + f3 int(11), f2 varchar(1024), f4 varchar(10), PRIMARY KEY (f3) +); +INSERT INTO t2 VALUES (6,'RPOYT','y'),(10,'JINQE','m'); + +SET SESSION join_cache_level = 1; + +SET SESSION optimizer_switch = 'index_condition_pushdown=off'; +EXPLAIN +SELECT * FROM t1,t2 + WHERE t1.f1 = t2.f4 AND (t1.f3 = 1 AND t2.f3 = 4 OR t1.f3 = 2 AND t2.f3 = 6); +SELECT * FROM t1,t2 + WHERE t1.f1 = t2.f4 AND (t1.f3 = 1 AND t2.f3 = 4 OR t1.f3 = 2 AND t2.f3 = 6); + +SET SESSION optimizer_switch = 'index_condition_pushdown=on'; +EXPLAIN +SELECT * FROM t1,t2 + WHERE t1.f1 = t2.f4 AND (t1.f3 = 1 AND t2.f3 = 4 OR t1.f3 = 2 AND t2.f3 = 6); +SELECT * FROM t1,t2 + WHERE t1.f1 = t2.f4 AND (t1.f3 = 1 AND t2.f3 = 4 OR t1.f3 = 2 AND t2.f3 = 6); + +SET SESSION join_cache_level = DEFAULT; +SET SESSION optimizer_switch = DEFAULT; + +DROP TABLE t1,t2; + # this must be the last command in the file set @@optimizer_switch=@save_optimizer_switch; diff --git a/sql/opt_index_cond_pushdown.cc b/sql/opt_index_cond_pushdown.cc index 6f0210a3d21..9f6cd69663d 100644 --- a/sql/opt_index_cond_pushdown.cc +++ b/sql/opt_index_cond_pushdown.cc @@ -155,7 +155,11 @@ Item *make_cond_for_index(Item *cond, TABLE *table, uint keyno, new_cond->argument_list()->push_back(fix); used_tables|= fix->used_tables(); } - n_marked += test(item->marker == ICP_COND_USES_INDEX_ONLY); + if (test(item->marker == ICP_COND_USES_INDEX_ONLY)) + { + n_marked++; + item->marker= 0; + } } if (n_marked ==((Item_cond*)cond)->argument_list()->elements) cond->marker= ICP_COND_USES_INDEX_ONLY; @@ -184,7 +188,11 @@ Item *make_cond_for_index(Item *cond, TABLE *table, uint keyno, if (!fix) return (COND*) 0; new_cond->argument_list()->push_back(fix); - n_marked += test(item->marker == ICP_COND_USES_INDEX_ONLY); + if (test(item->marker == ICP_COND_USES_INDEX_ONLY)) + { + n_marked++; + item->marker= 0; + } } if (n_marked ==((Item_cond*)cond)->argument_list()->elements) cond->marker= ICP_COND_USES_INDEX_ONLY; |