Skip to content

Commit 0480351

Browse files
committed
fix(mysql): improve update SQL generation for MySql
1 parent 332c368 commit 0480351

4 files changed

Lines changed: 32 additions & 6 deletions

File tree

sqlglot/dialects/mysql.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1340,15 +1340,24 @@ def _update_from_joins_sql(self, expression: exp.Update) -> t.Tuple[str, str]:
13401340
if not from_expr:
13411341
return ("", "")
13421342

1343-
table = from_expr.this.copy()
1343+
# Qualify unqualified columns in SET clause with the target table
1344+
# MySQL requires qualified column names in multi-table UPDATE to avoid ambiguity
1345+
target_table = expression.this
1346+
if isinstance(target_table, exp.Table):
1347+
target_name = target_table.alias_or_name
1348+
for eq in expression.expressions:
1349+
col = eq.this
1350+
if isinstance(col, exp.Column) and not col.table:
1351+
col.set("table", exp.to_identifier(target_name))
1352+
1353+
table = from_expr.this
13441354
nested_joins = table.args.get("joins") or []
13451355
if nested_joins:
13461356
table.set("joins", None)
13471357

13481358
join_sql = self.sql(exp.Join(this=table, on=exp.true()))
13491359
for nested in nested_joins:
13501360
if not nested.args.get("on") and not nested.args.get("using"):
1351-
nested = nested.copy()
13521361
nested.set("on", exp.true())
13531362
join_sql += self.sql(nested)
13541363

sqlglot/generator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2234,8 +2234,8 @@ def _update_from_joins_sql(self, expression: exp.Update) -> t.Tuple[str, str]:
22342234

22352235
def update_sql(self, expression: exp.Update) -> str:
22362236
this = self.sql(expression, "this")
2237-
set_sql = self.expressions(expression, flat=True)
22382237
join_sql, from_sql = self._update_from_joins_sql(expression)
2238+
set_sql = self.expressions(expression, flat=True)
22392239
where_sql = self.sql(expression, "where")
22402240
returning = self.sql(expression, "returning")
22412241
order = self.sql(expression, "order")

tests/dialects/test_mysql.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,11 +195,28 @@ def test_ddl(self):
195195
self.validate_identity("ALTER TABLE t ALTER COLUMN c SET VISIBLE")
196196

197197
def test_update_from_to_join(self):
198+
# MySQL multi-table UPDATE requires qualified columns in SET to avoid ambiguity
198199
self.validate_all(
199-
"UPDATE foo JOIN bar ON TRUE SET a = bar.a WHERE foo.id = bar.id",
200+
"UPDATE foo JOIN bar ON TRUE SET foo.a = bar.a WHERE foo.id = bar.id",
200201
read={
201202
"postgres": "UPDATE foo SET a = bar.a FROM bar WHERE foo.id = bar.id",
202-
"mysql": "UPDATE foo JOIN bar ON TRUE SET a = bar.a WHERE foo.id = bar.id",
203+
"mysql": "UPDATE foo JOIN bar ON TRUE SET foo.a = bar.a WHERE foo.id = bar.id",
204+
},
205+
)
206+
207+
# Multiple columns in SET clause
208+
self.validate_all(
209+
"UPDATE t1 JOIN t2 ON TRUE SET t1.id = t2.id, t1.name = t2.name WHERE t1.x = t2.x",
210+
read={
211+
"postgres": "UPDATE t1 SET id = t2.id, name = t2.name FROM t2 WHERE t1.x = t2.x",
212+
},
213+
)
214+
215+
# Already qualified columns in Postgres should remain qualified
216+
self.validate_all(
217+
"UPDATE t1 JOIN t2 ON TRUE SET t1.id = t2.id WHERE t1.x = t2.x",
218+
read={
219+
"postgres": "UPDATE t1 SET t1.id = t2.id FROM t2 WHERE t1.x = t2.x",
203220
},
204221
)
205222

tests/dialects/test_teradata.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ def test_update(self):
7070
"UPDATE A FROM schema.tableA AS A, (SELECT col1 FROM schema.tableA GROUP BY col1) AS B SET col2 = '' WHERE A.col1 = B.col1",
7171
write={
7272
"teradata": "UPDATE A FROM schema.tableA AS A, (SELECT col1 FROM schema.tableA GROUP BY col1) AS B SET col2 = '' WHERE A.col1 = B.col1",
73-
"mysql": "UPDATE A JOIN `schema`.tableA AS A ON TRUE JOIN (SELECT col1 FROM `schema`.tableA GROUP BY col1) AS B ON TRUE SET col2 = '' WHERE A.col1 = B.col1",
73+
"mysql": "UPDATE A JOIN `schema`.tableA AS A ON TRUE JOIN (SELECT col1 FROM `schema`.tableA GROUP BY col1) AS B ON TRUE SET A.col2 = '' WHERE A.col1 = B.col1",
7474
},
7575
)
7676

0 commit comments

Comments
 (0)