Details
-
Task
-
Status: Open (View Workflow)
-
Major
-
Resolution: Unresolved
-
None
-
None
Description
Follow-up to MDEV-29919, which implemented the MySQL 8.0.19-compatible row alias for INSERT ... ON DUPLICATE KEY UPDATE. The alias currently resolves only in expressions directly in the ODKU list, not inside subqueries there:
CREATE TABLE t1 (a INT PRIMARY KEY, b INT); |
INSERT INTO t1 VALUES (1,10); |
|
|
INSERT INTO t1 VALUES (1,40) AS new |
ON DUPLICATE KEY UPDATE b = (SELECT new.b + 3); |
-- MySQL 8: works, b = 43
|
-- MariaDB: ERROR 1054: Unknown column 'new.b' in 'SELECT' |
The old-style VALUES(b) works in the same position, so this is a gap in the VALUES() equivalence.
Cause: the alias substitution in Item_field::fix_fields() is gated on thd->where == THD_WHERE::UPDATE_CLAUSE, which holds while resolving the ODKU expressions themselves but is overwritten during a subquery's own resolution pass.
MySQL's resolution order, verified experimentally: a real table with the alias's name always wins; the row alias is a last-resort fallback:
CREATE TABLE new (b INT); INSERT INTO new VALUES (999); |
INSERT INTO t1 VALUES (1,50) AS new |
ON DUPLICATE KEY UPDATE b = (SELECT MAX(new.b) FROM new); |
-- MySQL 8: b = 999 (table wins, not the alias) |
Proposed approach: replace the thd->where gate with a LEX flag set while resolving the ODKU update values (same pattern as LEX::use_only_table_context), and perform the alias substitution only after normal resolution (find_field_in_tables, select-list lookup, fix_outer_field) fails — so real tables always shadow the alias, matching MySQL. Must be verified not to leak into RETURNING or the VALUES clause, and the derived-table rejection from MDEV-29919 must be preserved.
Attachments
Issue Links
- relates to
-
MDEV-29919 Support MYSQL Syntax for INSERT ON DUPLICATE KEY UPDATE
-
- In Review
-