| Bug #111511 | CTE missing scope in set queries | ||
|---|---|---|---|
| Submitted: | 21 Jun 2023 8:38 | Modified: | 21 Jun 2023 9:52 |
| Reporter: | Pedro Ferreira | Email Updates: | |
| Status: | Verified | Impact on me: | |
| Category: | MySQL Server: Optimizer | Severity: | S3 (Non-critical) |
| Version: | 8.0.33 | OS: | Ubuntu (22.04) |
| Assigned to: | CPU Architecture: | x86 (x86_64) | |
| Tags: | cte, UNION | ||
[21 Jun 2023 8:38]
Pedro Ferreira
[21 Jun 2023 9:52]
MySQL Verification Team
Hello Pedro Ferreira, Thank you for the report and test case. Verified as described. regards, Umesh
[12 Apr 2024 14:51]
Maxime Conjard
I believe I have found a related issue:
Here is what I have in t2
mysql> select * from t2;
+---+
| a |
+---+
| 1 |
| 2 |
| 3 |
+---+
3 rows in set (0.00 sec)
Resolution of the following query seems to work well:
mysql> (with y(y) as (select 9 )select * from y) union (WITH y(y) as (SELECT * from t2) SELECT * from y);
+---+
| y |
+---+
| 9 |
| 1 |
| 2 |
| 3 |
+---+
4 rows in set (0.00 sec)
as the results are convincing, however printing such a query will yield wrong results, see:
mysql> create view v as (with y(y) as (select 9 )select * from y) union (WITH y(y) as (SELECT * from t2) SELECT * from y);
mysql> select * from v;
+---+
| y |
+---+
| 1 |
| 2 |
| 3 |
+---+
3 rows in set (0.00 sec)
It is likely because:
bool PT_with_clause::contextualize(Parse_context *pc) {
if (super::contextualize(pc)) return true; /* purecov: inspected */
// WITH complements a query expression (a unit).
pc->select->master_unit()->m_with_clause = this;
return false;
}
pc->select->master_unit()->m_with_clause will first point to the cte on the right, and when looking at the rhs, we overwrite with the cte on the right.
During print, we rely on m_with_clause of the select_lex_unit to print the cte, which will be missing the information about the cte on the left.
[12 Apr 2024 14:52]
Maxime Conjard
first point to the cte on the right -> I meant the cte on the left!
[12 Apr 2024 15:00]
Guilhem Bichot
Looking at the Standard, and also from what I remember when I implemented CTEs in MySQL, the syntaxes above are non-compliant and should be blocked. A CTE is to be attached to a query_expression, i.e. a SELECT_LEX_UNIT, i.e. the UNION here ; there's no place in the standard's grammar which would allow it to be inside a parenthesised SELECT part of a UNION, IMHO.
