Bug #54110 | Extra rows returned on JOIN of two tables with join_cache_level 5 to 8 | ||
---|---|---|---|
Submitted: | 31 May 2010 15:49 | Modified: | 1 Jun 2010 11:07 |
Reporter: | John Embretsen | Email Updates: | |
Status: | Duplicate | Impact on me: | |
Category: | MySQL Server: Optimizer | Severity: | S3 (Non-critical) |
Version: | bzr_next-mr-opt-backporting | OS: | Any |
Assigned to: | CPU Architecture: | Any | |
Tags: | join_cache_level, optimizer_switch |
[31 May 2010 15:49]
John Embretsen
[31 May 2010 15:53]
John Embretsen
MTR test file which shows this bug
Attachment: bug54110.test (application/octet-stream, text), 2.59 KiB.
[31 May 2010 16:00]
John Embretsen
Diff between servers when running attached test case.
Attachment: bug54110.diff (text/plain), 1.11 KiB.
[1 Jun 2010 9:12]
John Embretsen
Here is what seems to be a closer to minimal repro for this issue. In this case the results change if the query is repeated: DROP TABLE /*! IF EXISTS */ t1; DROP TABLE /*! IF EXISTS */ t2; CREATE TABLE t1 ( `t1_col_varchar_1024` varchar(1024), `t1_col_int` int ) ENGINE=InnoDB; INSERT INTO t1 VALUES ('a',NULL); INSERT INTO t1 VALUES ('b',6); CREATE TABLE t2 ( `t2_col_int_key` int, `t2_col_varchar_1024` varchar(1024), KEY `col_int_key` (`t2_col_int_key`) ) ENGINE=InnoDB; INSERT INTO t2 VALUES (NULL,'m'); INSERT INTO t2 VALUES (NULL,'n'); INSERT INTO t2 VALUES (6,'o'); INSERT INTO t2 VALUES (NULL,'p'); SELECT * FROM t1 LEFT JOIN t2 ON t1 .`t1_col_int` = t2.`t2_col_int_key`; SELECT * FROM t1 LEFT JOIN t2 ON t1 .`t1_col_int` = t2.`t2_col_int_key`; ------------------------ When executed against the backporting branch (JCL=8), the results are (I added EXPLAIN before each query, notice the difference): mysql> EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1 .`t1_col_int` = t2.`t2_col_int_key`; +----+-------------+-------+------+---------------+-------------+---------+--------------------+------+-------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+-------------+---------+--------------------+------+-------------------+ | 1 | SIMPLE | t1 | ALL | NULL | NULL | NULL | NULL | 2 | | | 1 | SIMPLE | t2 | ref | col_int_key | col_int_key | 5 | test.t1.t1_col_int | 1 | Using join buffer | +----+-------------+-------+------+---------------+-------------+---------+--------------------+------+-------------------+ 2 rows in set (0.00 sec) mysql> SELECT * FROM t1 LEFT JOIN t2 ON t1 .`t1_col_int` = t2.`t2_col_int_key`; +---------------------+------------+----------------+---------------------+ | t1_col_varchar_1024 | t1_col_int | t2_col_int_key | t2_col_varchar_1024 | +---------------------+------------+----------------+---------------------+ | a | NULL | NULL | m | | a | NULL | NULL | n | | b | 6 | 6 | o | | a | NULL | NULL | p | +---------------------+------------+----------------+---------------------+ 4 rows in set (0.00 sec) mysql> EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1 .`t1_col_int` = t2.`t2_col_int_key`; +----+-------------+-------+------+---------------+------+---------+------+------+--------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+------+------+--------------------------------+ | 1 | SIMPLE | t1 | ALL | NULL | NULL | NULL | NULL | 2 | | | 1 | SIMPLE | t2 | ALL | col_int_key | NULL | NULL | NULL | 4 | Using where; Using join buffer | +----+-------------+-------+------+---------------+------+---------+------+------+--------------------------------+ 2 rows in set (0.00 sec) mysql> SELECT * FROM t1 LEFT JOIN t2 ON t1 .`t1_col_int` = t2.`t2_col_int_key`; +---------------------+------------+----------------+---------------------+ | t1_col_varchar_1024 | t1_col_int | t2_col_int_key | t2_col_varchar_1024 | +---------------------+------------+----------------+---------------------+ | b | 6 | 6 | o | | a | NULL | NULL | NULL | +---------------------+------------+----------------+---------------------+ 2 rows in set (0.01 sec) I leave it to someone else to confirm what is the correct result.
[1 Jun 2010 9:28]
John Embretsen
This may be related to Bug#52636 (6.0 allowing JOINs on NULL values w/ optimizer_join_cache_level = 5-8), yet to be confirmed.
[1 Jun 2010 11:07]
Guilhem Bichot
The correct results, verified with reasoning and with 5.1, are: - for the original testcase (with F and N tables) NULL NULL NULL NULL as - for the "closer to minimal" testcase: a NULL NULL NULL b 6 6 o - indeed mysql-next-mr-opt-backporting shows wrong results (too many rows). - the patch of BUG#52636 solves this (gives correct results for all join_cache_levels from 0 to 8). Marking as duplicate of BUG#52636.