Commit e9924777 authored by igor@rurik.mysql.com's avatar igor@rurik.mysql.com

Fixed bug #17164.

If the WHERE condition of a query contained an ORed FALSE term
then the set of tables whose rows cannot serve for null complements
in outer joins was determined incorrectly. It resulted in blocking 
possible conversions of outer joins into joins for such queries.
parent dcceaae8
...@@ -1135,3 +1135,22 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -1135,3 +1135,22 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 4 Using where 1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 4 Using where
1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.a 1 1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.a 1
DROP TABLE t1,t2; DROP TABLE t1,t2;
CREATE TABLE t1 (id int(11) NOT NULL PRIMARY KEY, name varchar(20),
INDEX (name)) ENGINE=InnoDB;
CREATE TABLE t2 (id int(11) NOT NULL PRIMARY KEY, fkey int(11),
FOREIGN KEY (fkey) REFERENCES t2(id)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1,'A1'),(2,'A2'),(3,'B');
INSERT INTO t2 VALUES (1,1),(2,2),(3,2),(4,3),(5,3);
EXPLAIN
SELECT COUNT(*) FROM t2 LEFT JOIN t1 ON t2.fkey = t1.id
WHERE t1.name LIKE 'A%';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index PRIMARY,name name 23 NULL 3 Using where; Using index
1 SIMPLE t2 ref fkey fkey 5 test.t1.id 1 Using where; Using index
EXPLAIN
SELECT COUNT(*) FROM t2 LEFT JOIN t1 ON t2.fkey = t1.id
WHERE t1.name LIKE 'A%' OR FALSE;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index PRIMARY,name name 23 NULL 3 Using where; Using index
1 SIMPLE t2 ref fkey fkey 5 test.t1.id 1 Using where; Using index
DROP TABLE t1,t2;
...@@ -759,3 +759,23 @@ EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t1.a > IF(t1.a = t2.b ...@@ -759,3 +759,23 @@ EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t1.a > IF(t1.a = t2.b
DROP TABLE t1,t2; DROP TABLE t1,t2;
#
# Test for bug #17164: ORed FALSE blocked conversion of outer join into join
#
CREATE TABLE t1 (id int(11) NOT NULL PRIMARY KEY, name varchar(20),
INDEX (name)) ENGINE=InnoDB;
CREATE TABLE t2 (id int(11) NOT NULL PRIMARY KEY, fkey int(11),
FOREIGN KEY (fkey) REFERENCES t2(id)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1,'A1'),(2,'A2'),(3,'B');
INSERT INTO t2 VALUES (1,1),(2,2),(3,2),(4,3),(5,3);
EXPLAIN
SELECT COUNT(*) FROM t2 LEFT JOIN t1 ON t2.fkey = t1.id
WHERE t1.name LIKE 'A%';
EXPLAIN
SELECT COUNT(*) FROM t2 LEFT JOIN t1 ON t2.fkey = t1.id
WHERE t1.name LIKE 'A%' OR FALSE;
DROP TABLE t1,t2;
...@@ -2563,10 +2563,13 @@ Item_cond::fix_fields(THD *thd, Item **ref) ...@@ -2563,10 +2563,13 @@ Item_cond::fix_fields(THD *thd, Item **ref)
(item= *li.ref())->check_cols(1)) (item= *li.ref())->check_cols(1))
return TRUE; /* purecov: inspected */ return TRUE; /* purecov: inspected */
used_tables_cache|= item->used_tables(); used_tables_cache|= item->used_tables();
if (!item->const_item())
{
tmp_table_map= item->not_null_tables(); tmp_table_map= item->not_null_tables();
not_null_tables_cache|= tmp_table_map; not_null_tables_cache|= tmp_table_map;
and_tables_cache&= tmp_table_map; and_tables_cache&= tmp_table_map;
const_item_cache&= item->const_item(); const_item_cache= FALSE;
}
with_sum_func= with_sum_func || item->with_sum_func; with_sum_func= with_sum_func || item->with_sum_func;
if (item->maybe_null) if (item->maybe_null)
maybe_null=1; maybe_null=1;
......
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