| Bug #99025 | Incorrect result from CTE subquery with outer reference | ||
|---|---|---|---|
| Submitted: | 22 Mar 2020 20:00 | Modified: | 29 May 2020 18:36 |
| Reporter: | Jonas Staudenmeir | Email Updates: | |
| Status: | Closed | Impact on me: | |
| Category: | MySQL Server: DML | Severity: | S3 (Non-critical) |
| Version: | 8.0.19 | OS: | Ubuntu |
| Assigned to: | CPU Architecture: | x86 | |
| Tags: | regression | ||
[22 Mar 2020 20:00]
Jonas Staudenmeir
[22 Mar 2020 20:53]
MySQL Verification Team
Thank you for the bug report. Looks like a regression:
d:\tmp\mysql-8.0.16-winx64>bin\mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.16 MySQL Community Server - GPL
Copyright (c) 2000, 2019, 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 DATABASE q;
Query OK, 1 row affected (0.01 sec)
mysql> USE q
Database changed
mysql> CREATE TABLE `pages` (
-> `id` int unsigned NOT NULL AUTO_INCREMENT,
-> `parent_id` int unsigned DEFAULT NULL,
-> `active` tinyint(1) NOT NULL,
-> PRIMARY KEY (`id`)
-> ) ENGINE=InnoDB;
Query OK, 0 rows affected (0.03 sec)
mysql>
mysql> INSERT INTO `pages` (`id`, `parent_id`, `active`) VALUES
-> (1,NULL,1),
-> (2,1,0),
-> (3,2,1),
-> (4,3,1);
Query OK, 4 rows affected (0.01 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> SELECT *
-> FROM `pages`
-> WHERE NOT EXISTS (
-> WITH RECURSIVE `cte` AS (
-> (
-> SELECT *
-> FROM `pages` AS `alias`
-> WHERE `alias`.`id` = `pages`.`parent_id`
-> ) UNION ALL (
-> SELECT `alias`.*
-> FROM `pages` AS `alias`
-> INNER JOIN `cte` ON `cte`.`parent_id` = `alias`.`id`
-> )
-> )
-> SELECT *
-> FROM `cte`
-> WHERE `active` = 0
-> )
-> AND `active` = 1;
+----+-----------+--------+
| id | parent_id | active |
+----+-----------+--------+
| 1 | NULL | 1 |
+----+-----------+--------+
1 row in set (0.01 sec)
mysql>
------------------------------------------------------------------------
d:\dbs>d:\dbs\8.0\bin\mysql -uroot --port=3580 -p --local-infile=1 --prompt="mysql 8.0 > " --default-character-set=latin1
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 8.0.20 Source distribution BUILT: 2020-FEB-16
Copyright (c) 2000, 2020, 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 8.0 > USE q
Database changed
mysql 8.0 > SELECT *
-> FROM `pages`
-> WHERE NOT EXISTS (
-> WITH RECURSIVE `cte` AS (
-> (
-> SELECT *
-> FROM `pages` AS `alias`
-> WHERE `alias`.`id` = `pages`.`parent_id`
-> ) UNION ALL (
-> SELECT `alias`.*
-> FROM `pages` AS `alias`
-> INNER JOIN `cte` ON `cte`.`parent_id` = `alias`.`id`
-> )
-> )
-> SELECT *
-> FROM `cte`
-> WHERE `active` = 0
-> )
-> AND `active` = 1;
+----+-----------+--------+
| id | parent_id | active |
+----+-----------+--------+
| 1 | NULL | 1 |
| 4 | 3 | 1 |
+----+-----------+--------+
2 rows in set (0.05 sec)
mysql 8.0 >
[22 Mar 2020 21:02]
MySQL Verification Team
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 8.0.19 MySQL Community Server - GPL
Copyright (c) 2000, 2020, 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 DATABASE q;
Query OK, 1 row affected (0.01 sec)
mysql> USE q
Database changed
mysql> CREATE TABLE `pages` (
-> `id` int unsigned NOT NULL AUTO_INCREMENT,
-> `parent_id` int unsigned DEFAULT NULL,
-> `active` tinyint(1) NOT NULL,
-> PRIMARY KEY (`id`)
-> ) ENGINE=InnoDB;
Query OK, 0 rows affected, 1 warning (0.05 sec)
mysql>
mysql> INSERT INTO `pages` (`id`, `parent_id`, `active`) VALUES
-> (1,NULL,1),
-> (2,1,0),
-> (3,2,1),
-> (4,3,1);
Query OK, 4 rows affected (0.02 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> SELECT *
-> FROM `pages`
-> WHERE NOT EXISTS (
-> WITH RECURSIVE `cte` AS (
-> (
-> SELECT *
-> FROM `pages` AS `alias`
-> WHERE `alias`.`id` = `pages`.`parent_id`
-> ) UNION ALL (
-> SELECT `alias`.*
-> FROM `pages` AS `alias`
-> INNER JOIN `cte` ON `cte`.`parent_id` = `alias`.`id`
-> )
-> )
-> SELECT *
-> FROM `cte`
-> WHERE `active` = 0
-> )
-> AND `active` = 1;
+----+-----------+--------+
| id | parent_id | active |
+----+-----------+--------+
| 1 | NULL | 1 |
| 4 | 3 | 1 |
+----+-----------+--------+
2 rows in set (0.02 sec)
mysql>
[29 May 2020 18:36]
Paul DuBois
Posted by developer: Fixed in 8.0.21. Queries that used a recursive common table expression with an outer reference could return incorrect results.
