feat(mysql): translate UPDATE … FROM … syntax to UPDATE … JOIN … when generating MySQL#6655
feat(mysql): translate UPDATE … FROM … syntax to UPDATE … JOIN … when generating MySQL#6655VaggelisD merged 5 commits intotobymao:mainfrom
Conversation
georgesittas
left a comment
There was a problem hiding this comment.
Hey, thanks for the PR @brdbry.
This needs to be cleaned up a bit & the testing coverage needs to be increased, it seems.
…ectly in UPDATE statements
|
Thanks @georgesittas , hopefully this looks a bit better now |
tests/dialects/test_mysql.py
Outdated
| "UPDATE foo JOIN bar ON TRUE SET a = bar.a WHERE foo.id = bar.id", | ||
| read={ | ||
| "postgres": "UPDATE foo SET a = bar.a FROM bar WHERE foo.id = bar.id", | ||
| "mysql": "UPDATE foo JOIN bar ON TRUE SET a = bar.a WHERE foo.id = bar.id", |
There was a problem hiding this comment.
This doesn't seem to work:
mysql> create table t1 as (select 3 as id);
Query OK, 1 row affected (0.015 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> create table t2 as (select 1 as id);
Query OK, 1 row affected (0.012 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> UPDATE t1 JOIN t2 ON TRUE SET id = t2.id;
ERROR 1052 (23000): Column 'id' in field list is ambiguousWe'd need to qualify all non-t2 columns with t1:
mysql> UPDATE t1 JOIN t2 ON TRUE SET t1.id = t2.id;
Query OK, 1 row affected (0.003 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from t1;
+----+
| id |
+----+
| 1 |
+----+
1 row in set (0.001 sec)And the opposite does not work in Postgres to allow for the happy case of not having to qualify columns:
postgres> UPDATE t1 SET t1.id = t2.id FROM t2;
ERROR: column "t1" of relation "t1" does not exist
LINE 1: UPDATE t1 SET t1.id = t2.id FROM t2;There was a problem hiding this comment.
This might be as simple as traversing all exp.Columns and setting col.table with from.this, given that Postgres assumes that t1's columns will all be unqualified while all other columns must be qualified.
This hypothesis will need more testing, of course
There was a problem hiding this comment.
Updated and tested the new generated sql against both MySQL and PG
|
Thanks @VaggelisD, changes made |
| read={ | ||
| "postgres": "UPDATE t1 SET t1.id = t2.id FROM t2 WHERE t1.x = t2.x", | ||
| }, |
There was a problem hiding this comment.
Given that this isn't correct Postgres it'd be better to remove the test; SQLGlot lives by the "garbage in, garbage out" rule so it's not our responsibility to cover such cases.
Extend the MySQL generator so that UPDATE … FROM … statements (not supported by MySQL) are emitted as UPDATE … JOIN …, synthesizing ON TRUE predicates when no join condition is specified, and handling nested/comma joins.
Add test_update_from_to_join to cover the new rendering and adjust a Teradata cross-dialect test expectation to match the JOIN-based MySQL output.