summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2010-12-24 14:36:35 -0800
committerIgor Babaev <igor@askmonty.org>2010-12-24 14:36:35 -0800
commitd9a81475c70aebc1f2542bf0c115b3ebd9649193 (patch)
tree4a4bfc01d4a13e9c293415be57ee624edb44e7c6
parentf51a26885faa0106286e63fd15f18dae6f618508 (diff)
downloadmariadb-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.result35
-rw-r--r--mysql-test/t/join_cache.test35
-rw-r--r--sql/opt_index_cond_pushdown.cc12
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;