| Bug #120843 | VIEW and CTE return wrong results with YEAR(), UNION and uncorrelated EXISTS subquery | ||
|---|---|---|---|
| Submitted: | 2 Jul 16:43 | Modified: | 3 Jul 9:14 |
| Reporter: | Xiaoyuan Xie | Email Updates: | |
| Status: | Verified | Impact on me: | |
| Category: | MySQL Server: Optimizer | Severity: | S2 (Serious) |
| Version: | 9.6.0 | OS: | Ubuntu |
| Assigned to: | CPU Architecture: | Any | |
[2 Jul 20:33]
Roy Lyseng
Thank you for the bug report. Results seems consistent in release 9.7, though. Still, I verify this bug since 3651 is outside the value range for data type YEAR.
[3 Jul 4:25]
Georgi Kodinov
Not reproducible anymore with 9.7:
mysql> select version()
-> ;
+-----------+
| version() |
+-----------+
| 9.7.0 |
+-----------+
1 row in set (0.000 sec)
mysql> DROP DATABASE IF EXISTS dd;
Query OK, 0 rows affected, 1 warning (0.001 sec)
mysql> CREATE DATABASE dd;
Query OK, 1 row affected (0.001 sec)
mysql> USE dd;
Database changed
mysql>
mysql> CREATE TABLE a (b DATE);
Query OK, 0 rows affected (0.005 sec)
mysql>
mysql> INSERT INTO a VALUES ('3651-04-29');
Query OK, 1 row affected (0.001 sec)
mysql>
mysql> CREATE VIEW v0 AS
-> SELECT YEAR(b) AS g
-> FROM a
-> UNION
-> SELECT YEAR(0);
Query OK, 0 rows affected (0.001 sec)
mysql>
mysql> SELECT g
-> FROM v0
-> WHERE EXISTS (
-> SELECT 0
-> FROM v0
-> WHERE g
-> );
+------+
| g |
+------+
| 0000 |
| 2000 |
+------+
2 rows in set (0.001 sec)
mysql>
mysql> WITH cte AS (
-> SELECT YEAR(b) AS g
-> FROM a
-> UNION
-> SELECT YEAR(0)
-> )
-> SELECT g
-> FROM cte
-> WHERE EXISTS (
-> SELECT 0
-> FROM cte
-> WHERE g
-> );
+------+
| g |
+------+
| 0000 |
| 2000 |
+------+
2 rows in set (0.001 sec)
mysql>
[3 Jul 6:30]
Roy Lyseng
I verified it because results are still wrong.
[3 Jul 9:14]
Xiaoyuan Xie
Thank you Roy and Georgi for checking this. I understand that the VIEW and CTE results are now consistent in 9.7.0. However, as Roy pointed out, the result still appears to be wrong because `3651` is outside the value range of the `YEAR` data type. My understanding is that `YEAR(b)` for the valid `DATE` value `'3651-04-29'` should produce the numeric year `3651`, but after the `UNION` the result seems to be coerced into a `YEAR`-like type, leading to unexpected values such as `0000` / `2000`. Thanks again for verifying the bug and for the clarification.

Description: A query using a VIEW and an equivalent query using a CTE return different results. Both results appear to be wrong. The VIEW query returns only 0000, while the CTE query returns an empty result set. Based on the semantics of YEAR(), UNION, and EXISTS, the expected result should contain both 3651 and 0000. This looks like a wrong-result bug involving YEAR(), UNION, VIEW/CTE handling, and an uncorrelated EXISTS subquery. How to repeat: mysql> select version(); +-----------+ | version() | +-----------+ | 9.6.0 | +-----------+ DROP DATABASE IF EXISTS dd; CREATE DATABASE dd; USE dd; CREATE TABLE a (b DATE); INSERT INTO a VALUES ('3651-04-29'); CREATE VIEW v0 AS SELECT YEAR(b) AS g FROM a UNION SELECT YEAR(0); SELECT g FROM v0 WHERE EXISTS ( SELECT 0 FROM v0 WHERE g ); WITH cte AS ( SELECT YEAR(b) AS g FROM a UNION SELECT YEAR(0) ) SELECT g FROM cte WHERE EXISTS ( SELECT 0 FROM cte WHERE g ); Actual result: The VIEW query returns: +------+ | g | +------+ | 0000 | +------+ The equivalent CTE query returns: Empty set Expected result: Both queries should return: +------+ | g | +------+ | 3651 | | 0000 | +------+