Commit d9a81475 authored by Igor Babaev's avatar Igor Babaev

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.
parent f51a2688
......@@ -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;
......@@ -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;
......@@ -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;
......
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