Commit c0579144 authored by unknown's avatar unknown
Browse files

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.


mysql-test/r/join_outer.result:
  Added a test case for bug #17164.
mysql-test/t/join_outer.test:
  Added a test case for bug #17164.
parent 16c47ef4
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -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	t1	eq_ref	PRIMARY	PRIMARY	4	test.t2.a	1	
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;
+20 −0
Original line number Diff line number Diff line
@@ -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;

#
# 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;
+7 −4
Original line number Diff line number Diff line
@@ -2563,10 +2563,13 @@ Item_cond::fix_fields(THD *thd, Item **ref)
	(item= *li.ref())->check_cols(1))
      return TRUE; /* purecov: inspected */
    used_tables_cache|=     item->used_tables();
    if (!item->const_item())
    {
      tmp_table_map= item->not_null_tables();
      not_null_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;
    if (item->maybe_null)
      maybe_null=1;