Bug #79194 Wrong result on outer join with uncorrelated subquery, derived_merge
| Submitted: | 9 Nov 2015 21:37 | Modified: | 6 Jan 2016 17:01 |
|---|---|---|---|
| Reporter: | Elena Stepanova | Email Updates: | |
| Status: | Closed | Impact on me: | |
| Category: | MySQL Server: Optimizer | Severity: | S3 (Non-critical) |
| Version: | 5.7.9 | OS: | Any |
| Assigned to: | CPU Architecture: | Any | |
| Tags: | regression | ||
[9 Nov 2015 21:56]
MySQL Verification Team
Thank you for the bug report. Only 5.7 affected:
C:\dbs>c:\dbs\5.7\bin\mysql -uroot -p --port=3570 --prompt="mysql 5.7 > "
Enter password: ******
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.10 Source distribution PULL: 2015-NOV-07
Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql 5.7 > USE test
Database changed
mysql 5.7 > CREATE TABLE t1 (a INT, KEY(a));
Query OK, 0 rows affected (0.03 sec)
mysql 5.7 > INSERT INTO t1 VALUES (1), (NULL);
Query OK, 2 rows affected (0.01 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql 5.7 >
mysql 5.7 > CREATE TABLE t2 (b INT, KEY(b));
Query OK, 0 rows affected (0.03 sec)
mysql 5.7 > INSERT INTO t2 VALUES (7), (NULL), (1), (5), (8), (6), (4), (0), (3), (NULL);
Query OK, 10 rows affected (0.01 sec)
Records: 10 Duplicates: 0 Warnings: 0
mysql 5.7 >
mysql 5.7 > CREATE TABLE t3 (c INT);
Query OK, 0 rows affected (0.03 sec)
mysql 5.7 > INSERT INTO t3 VALUES (NULL), (1), (5);
Query OK, 3 rows affected (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql 5.7 >
mysql 5.7 > # The inner join returns a correct result
mysql 5.7 > SELECT t3.* FROM t2 INNER JOIN t3 ON (b = c);
+------+
| c |
+------+
| 1 |
| 5 |
+------+
2 rows in set (0.00 sec)
mysql 5.7 >
mysql 5.7 > SELECT * FROM t1 LEFT JOIN (
-> SELECT t3.* FROM t2 INNER JOIN t3 ON (b = c)
-> ) AS sq ON (a <= sq.c);
+------+------+
| a | c |
+------+------+
| NULL | NULL |
| 1 | NULL |
+------+------+
2 rows in set (0.00 sec)
====================================================================
5.6:
C:\dbs>5.6\bin\mysql -uroot -p test
Enter password: ******
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 33
Server version: 5.6.27-log MySQL Community Server (GPL)
Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> SELECT * FROM t1 LEFT JOIN (
-> SELECT t3.* FROM t2 INNER JOIN t3 ON (b = c)
-> ) AS sq ON (a <= sq.c);
+------+------+
| a | c |
+------+------+
| 1 | 1 |
| 1 | 5 |
| NULL | NULL |
+------+------+
3 rows in set (0.00 sec)
[6 Jan 2016 17:01]
Paul DuBois
Noted in 5.7.11, 5.8.0 changelogs. With the derived_merge flag of the optimizer_switch system variable enabled, queries that used a derived table on the inner side of an outer join could return incorrect results.
Portions of this website are copyright © 2001, 2002 The PHP Group
Page generated in 0.050 sec. using MySQL 8.4.7-u6-cloud
Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the
respective copyright holders.
It is not reviewed in advance
by Oracle and does not necessarily represent the opinion of
Oracle or any other party.
Description: For the test case provided in 'How to repeat' section: MySQL [test]> SELECT * FROM t1 LEFT JOIN ( -> SELECT t3.* FROM t2 INNER JOIN t3 ON (b = c) -> ) AS sq ON (a <= sq.c); +------+------+ | a | c | +------+------+ | NULL | NULL | | 1 | NULL | +------+------+ 2 rows in set (0.00 sec) Expected result: MySQL [test]> SELECT * FROM t1 LEFT JOIN ( -> SELECT t3.* FROM t2 INNER JOIN t3 ON (b = c) -> ) AS sq ON (a <= sq.c); +------+------+ | a | c | +------+------+ | 1 | 1 | | 1 | 5 | | NULL | NULL | +------+------+ 3 rows in set (0.00 sec) Switching off derived_merge makes the problem go away. The subquery produces the expected result: MySQL [test]> SELECT t3.* FROM t2 INNER JOIN t3 ON (b = c); +------+ | c | +------+ | 1 | | 5 | +------+ 2 rows in set (0.00 sec) How to repeat: CREATE TABLE t1 (a INT, KEY(a)); INSERT INTO t1 VALUES (1), (NULL); CREATE TABLE t2 (b INT, KEY(b)); INSERT INTO t2 VALUES (7), (NULL), (1), (5), (8), (6), (4), (0), (3), (NULL); CREATE TABLE t3 (c INT); INSERT INTO t3 VALUES (NULL), (1), (5); # The inner join returns a correct result SELECT t3.* FROM t2 INNER JOIN t3 ON (b = c); SELECT * FROM t1 LEFT JOIN ( SELECT t3.* FROM t2 INNER JOIN t3 ON (b = c) ) AS sq ON (a <= sq.c); DROP TABLE t1, t2, t3;