Bug #20331 optimizer causes missing results from left (outer) join with where clause
Submitted: 8 Jun 2006 2:54 Modified: 9 Jun 2006 3:53
Reporter: Christian Kissner Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server Severity:S3 (Non-critical)
Version:5.0.22 OS:Linux (Linux Fedora Core 4)
Assigned to: Sveta Smirnova CPU Architecture:Any

[8 Jun 2006 2:54] Christian Kissner
Description:
Since we upgraded from 5.0.18 to 5.0.22, I have an issue with WHERE conditions on LEFT (OUTER) JOINs. 
I generate lots of different joins and clauses and some cause the optimizer to compute an inner join. 

I have created a simplified example where I get different results for "WHERE 1" and "WHERE 1 or 0". 
Note, my real clauses are more complex, I just have the  WHERE 1 in front to programmatically add generated conditions.

Best,
Christian

How to repeat:
CREATE TABLE IF NOT EXISTS a (
  id int(11) NOT NULL,
  KEY id (id)
) TYPE=MyISAM;

INSERT INTO a VALUES (1);
INSERT INTO a VALUES (2);

CREATE TABLE IF NOT EXISTS b (
  a_id int(11) NOT NULL,
  KEY a_id (a_id)
) TYPE=MyISAM;

INSERT INTO b VALUES (2);

SELECT *
FROM a
LEFT OUTER JOIN b ON a.id = b.a_id
WHERE 1;

Result is CORRECT:
+----+------+
| id | a_id |
+----+------+
|  1 | NULL |
|  2 |    2 |
+----+------+

SELECT *
FROM a
LEFT OUTER JOIN b ON a.id = b.a_id
WHERE 1 or 0;

Result is WRONG:
+----+------+
| id | a_id |
+----+------+
|  2 |    2 |
+----+------+

EXPLAIN SELECT * FROM a LEFT OUTER JOIN b ON a.id = b.a_id WHERE 1 ;
+----+-------------+-------+-------+---------------+------+---------+-------------+------+-------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref         | rows | Extra       |
+----+-------------+-------+-------+---------------+------+---------+-------------+------+-------------+
|  1 | SIMPLE      | a     | index | NULL          | id   | 4       | NULL        |    2 | Using index |
|  1 | SIMPLE      | b     | ref   | a_id          | a_id | 4       | cms_be.a.id |    2 | Using index |
+----+-------------+-------+-------+---------------+------+---------+-------------+------+-------------+

EXPLAIN SELECT * FROM a LEFT OUTER JOIN b ON a.id = b.a_id WHERE 1 or 0 ;
+----+-------------+-------+--------+---------------+------+---------+-------+------+-------------+
| id | select_type | table | type   | possible_keys | key  | key_len | ref   | rows | Extra       |
+----+-------------+-------+--------+---------------+------+---------+-------+------+-------------+
|  1 | SIMPLE      | b     | system | a_id          | NULL | NULL    | NULL  |    1 |             |
|  1 | SIMPLE      | a     | ref    | id            | id   | 4       | const |    2 | Using index |
+----+-------------+-------+--------+---------------+------+---------+-------+------+-------------+

Suggested fix:
Fix the optimizer
[8 Jun 2006 23:10] Sveta Smirnova
Thank you for your bug report. This issue has been committed to our
source repository of that product and will be incorporated into the
next release.

If necessary, you can access the source repository and build the latest
available version, including the bugfix, yourself. More information 
about accessing the source trees is available at
    http://www.mysql.com/doc/en/Installing_source_tree.html

Additional info:

Thank you for your help.
I tested it with last 5.0.23 sources and all work fine.
[9 Jun 2006 3:53] Christian Kissner
Wow, awesome turnaround! Thanks!