Bug #90877 | Wrong result from WHERE EXISTS on an ordered subquery | ||
---|---|---|---|
Submitted: | 15 May 2018 21:35 | Modified: | 16 May 2018 14:05 |
Reporter: | Alan Curry | Email Updates: | |
Status: | Not a Bug | Impact on me: | |
Category: | MySQL Server: Optimizer | Severity: | S3 (Non-critical) |
Version: | 5.7.22 | OS: | Any |
Assigned to: | CPU Architecture: | x86 |
[15 May 2018 21:35]
Alan Curry
[15 May 2018 22:48]
MySQL Verification Team
8.0.11: Enter password: ********** Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 8 Server version: 8.0.11 MySQL Community Server - GPL Copyright (c) 2000, 2018, 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> use test Database changed mysql> CREATE TABLE `bugdemo_assignment` ( -> `id` int NOT NULL AUTO_INCREMENT, -> `user_id` int, -> `location_id` int, -> `year` int, -> PRIMARY KEY (`id`), -> KEY `k1` (`year`,`user_id`) -> ); Query OK, 0 rows affected (0.18 sec) mysql> mysql> CREATE TABLE `bugdemo_score` ( -> `event_type` int, -> `event_subtype` int, -> `user_id` int, -> `year` int -> ); Query OK, 0 rows affected (0.06 sec) mysql> mysql> INSERT INTO `bugdemo_assignment` (`user_id`, `location_id`, `year`) -> VALUES -> (10,50,2016), -> (10,50,2017); Query OK, 2 rows affected (0.02 sec) Records: 2 Duplicates: 0 Warnings: 0 mysql> mysql> INSERT INTO `bugdemo_score` (`event_subtype`, `event_type`, `user_id`, `year`) -> VALUES -> (0,1,10,2016), -> (1,2,10,2016), -> (2,2,10,2016), -> (3,2,10,2016), -> (4,2,10,2016), -> (5,2,10,2016), -> (6,2,10,2016), -> (7,2,10,2016), -> (8,2,10,2016), -> (9,2,10,2016), -> (10,2,10,2016), -> (11,2,10,2016); Query OK, 12 rows affected (0.02 sec) Records: 12 Duplicates: 0 Warnings: 0 mysql> SELECT `s2016`.`user_id` -> FROM -> ( -> SELECT `s`.`user_id` -> FROM `bugdemo_score` `s` -> LEFT JOIN `bugdemo_assignment` `a` -> ON `a`.`user_id` = `s`.`user_id` AND `a`.`year` = `s`.`year` -> WHERE `a`.`location_id` = 50 AND `s`.`user_id` = 10 -> ORDER BY `s`.`user_id`, `s`.`event_subtype` -> ) `s2016` -> WHERE EXISTS( -> SELECT 1 -> FROM `bugdemo_assignment` `a2017` -> WHERE `a2017`.`year` = 2017 -> AND `a2017`.`user_id` = `s2016`.`user_id` -> AND `a2017`.`location_id` = 50 -> ); +---------+ | user_id | +---------+ | 10 | | 10 | | 10 | | 10 | | 10 | | 10 | | 10 | | 10 | | 10 | | 10 | | 10 | | 10 | +---------+ 12 rows in set (0.01 sec) mysql>
[15 May 2018 23:03]
MySQL Verification Team
C:\tmp\mysql-5.7.22-winx64>bin\mysql -uroot -p test Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 3 Server version: 5.7.22 MySQL Community Server (GPL) Copyright (c) 2000, 2018, 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> CREATE TABLE `bugdemo_assignment` ( -> `id` int NOT NULL AUTO_INCREMENT, -> `user_id` int, -> `location_id` int, -> `year` int, -> PRIMARY KEY (`id`), -> KEY `k1` (`year`,`user_id`) -> ); Query OK, 0 rows affected (0.05 sec) mysql> mysql> CREATE TABLE `bugdemo_score` ( -> `event_type` int, -> `event_subtype` int, -> `user_id` int, -> `year` int -> ); Query OK, 0 rows affected (0.05 sec) mysql> mysql> INSERT INTO `bugdemo_assignment` (`user_id`, `location_id`, `year`) -> VALUES -> (10,50,2016), -> (10,50,2017); Query OK, 2 rows affected (0.01 sec) Records: 2 Duplicates: 0 Warnings: 0 mysql> mysql> INSERT INTO `bugdemo_score` (`event_subtype`, `event_type`, `user_id`, `year`) -> VALUES -> (0,1,10,2016), -> (1,2,10,2016), -> (2,2,10,2016), -> (3,2,10,2016), -> (4,2,10,2016), -> (5,2,10,2016), -> (6,2,10,2016), -> (7,2,10,2016), -> (8,2,10,2016), -> (9,2,10,2016), -> (10,2,10,2016), -> (11,2,10,2016); Query OK, 12 rows affected (0.00 sec) Records: 12 Duplicates: 0 Warnings: 0 mysql> mysql> SELECT `s2016`.`user_id` -> FROM -> ( -> SELECT `s`.`user_id` -> FROM `bugdemo_score` `s` -> LEFT JOIN `bugdemo_assignment` `a` -> ON `a`.`user_id` = `s`.`user_id` AND `a`.`year` = `s`.`year` -> WHERE `a`.`location_id` = 50 AND `s`.`user_id` = 10 -> ORDER BY `s`.`user_id`, `s`.`event_subtype` -> ) `s2016` -> WHERE EXISTS( -> SELECT 1 -> FROM `bugdemo_assignment` `a2017` -> WHERE `a2017`.`year` = 2017 -> AND `a2017`.`user_id` = `s2016`.`user_id` -> AND `a2017`.`location_id` = 50 -> ); Empty set (0.00 sec) mysql> SELECT `s2016`.`user_id` -> FROM -> ( -> SELECT `s`.`user_id` -> FROM `bugdemo_score` `s` -> LEFT JOIN `bugdemo_assignment` `a` -> ON `a`.`user_id` = `s`.`user_id` AND `a`.`year` = `s`.`year` -> WHERE `a`.`location_id` = 50 AND `s`.`user_id` = 10 -> ORDER BY `s`.`user_id`, `s`.`event_subtype` Limit 12 -> ) `s2016` -> WHERE EXISTS( -> SELECT 1 -> FROM `bugdemo_assignment` `a2017` -> WHERE `a2017`.`year` = 2017 -> AND `a2017`.`user_id` = `s2016`.`user_id` -> AND `a2017`.`location_id` = 50 -> ); +---------+ | user_id | +---------+ | 10 | | 10 | | 10 | | 10 | | 10 | | 10 | | 10 | | 10 | | 10 | | 10 | | 10 | | 10 | +---------+ 12 rows in set (0.00 sec) mysql>
[16 May 2018 13:15]
MySQL Verification Team
HI, Thank you very much for your report. However, this is not a bug. Simply, you have to set one switch properly. This was fixed in 8.0 !!!! MySQL 8.0 returns 100 % the correct result. But, if you are looking at the EXPLAIN, it is totally different: id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY s NULL ALL NULL NULL NULL NULL 12 10.00 Using where; Using filesort 1 PRIMARY a NULL ref k1 k1 10 bug.s.year,const 1 50.00 Using where 3 DEPENDENT SUBQUERY a2017 NULL ref k1 k1 10 const,func 1 50.00 Using index condition; Using where If you, however, set optimiser's switch to : derived_merge=off' then 5.7 works just fine ...... this is the output from SELECT and from the EXPLAIN SELECT: user_id 10 10 10 10 10 10 10 10 10 10 10 10 id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY <derived2> NULL ALL NULL NULL NULL NULL 2 100.00 Using where 3 DEPENDENT SUBQUERY a2017 NULL ref k1 k1 10 const,s2016.user_id 1 50.00 Using where 2 DERIVED s NULL ALL NULL NULL NULL NULL 12 10.00 Using where; Using filesort 2 DERIVED a NULL ref k1 k1 10 bug.s.year,const 1 50.00 Using where This is because 8.0 has this switch set permanently to OFF. 5.7 will remain as it is, since 8.0 has got features which enable it to function properly without changing the switch. Hence, not a bug.
[16 May 2018 14:05]
Alan Curry
It's not a bug because it doesn't happen in some non-default configuration? This seems like an extreme definition of "not a bug". The query is well-defined, and the output is not what it should be. Optimizations that change output are bugs.
[16 May 2018 14:56]
MySQL Verification Team
Possibly, but as I wrote, this is too complex to be fixed in 5.7, which is why it is fixed in 8.0. We can not bring infra-structure from 8.0 back to 5.7 as it is not possible. However, that switch is very well documented.
[2 Aug 2018 22:51]
Sveta Smirnova
Sinisa, I do not believe changing optimizer_switch should affect results somehow (unless query fails under SQL mode ONLY_FULL_GROUP_BY)
[3 Aug 2018 12:23]
MySQL Verification Team
Once again ... This bug is fixed in 8.0. Fix is too complex to be ported back to 5.7.