summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/build/changelog/unreleased_14/7281.rst8
-rw-r--r--lib/sqlalchemy/dialects/mysql/base.py2
-rw-r--r--test/dialect/mysql/test_compiler.py4
-rw-r--r--test/dialect/mysql/test_on_duplicate.py12
4 files changed, 20 insertions, 6 deletions
diff --git a/doc/build/changelog/unreleased_14/7281.rst b/doc/build/changelog/unreleased_14/7281.rst
new file mode 100644
index 000000000..a5ca9a162
--- /dev/null
+++ b/doc/build/changelog/unreleased_14/7281.rst
@@ -0,0 +1,8 @@
+.. change::
+ :tags: bug, mysql
+ :tickets: 7281
+ :versions: 2.0.0b1
+
+ Fixed issue in MySQL :meth:`_mysql.Insert.on_duplicate_key_update` which
+ would render the wrong column name when an expression were used in a VALUES
+ expression. Pull request courtesy Cristian Sabaila.
diff --git a/lib/sqlalchemy/dialects/mysql/base.py b/lib/sqlalchemy/dialects/mysql/base.py
index 4827df12f..684f35c5f 100644
--- a/lib/sqlalchemy/dialects/mysql/base.py
+++ b/lib/sqlalchemy/dialects/mysql/base.py
@@ -1302,7 +1302,7 @@ class MySQLCompiler(compiler.SQLCompiler):
and obj.table is on_duplicate.inserted_alias
):
obj = literal_column(
- "VALUES(" + self.preparer.quote(column.name) + ")"
+ "VALUES(" + self.preparer.quote(obj.name) + ")"
)
return obj
else:
diff --git a/test/dialect/mysql/test_compiler.py b/test/dialect/mysql/test_compiler.py
index 708039f94..ba162b490 100644
--- a/test/dialect/mysql/test_compiler.py
+++ b/test/dialect/mysql/test_compiler.py
@@ -1110,12 +1110,12 @@ class InsertOnDuplicateTest(fixtures.TestBase, AssertsCompiledSQL):
)
stmt = stmt.on_duplicate_key_update(
bar=func.coalesce(stmt.inserted.bar),
- baz=stmt.inserted.baz + "some literal",
+ baz=stmt.inserted.baz + "some literal" + stmt.inserted.bar,
)
expected_sql = (
"INSERT INTO foos (id, bar) VALUES (%s, %s), (%s, %s) ON "
"DUPLICATE KEY UPDATE bar = coalesce(VALUES(bar)), "
- "baz = (concat(VALUES(baz), %s))"
+ "baz = (concat(concat(VALUES(baz), %s), VALUES(bar)))"
)
self.assert_compile(
stmt,
diff --git a/test/dialect/mysql/test_on_duplicate.py b/test/dialect/mysql/test_on_duplicate.py
index 65d5b8364..5a4e6ca8d 100644
--- a/test/dialect/mysql/test_on_duplicate.py
+++ b/test/dialect/mysql/test_on_duplicate.py
@@ -100,13 +100,19 @@ class OnDuplicateTest(fixtures.TablesTest):
conn.execute(insert(foos).values(dict(id=1, bar="b", baz="bz")))
stmt = insert(foos).values([dict(id=1, bar="ab"), dict(id=2, bar="b")])
stmt = stmt.on_duplicate_key_update(
- bar=func.concat(stmt.inserted.bar, "_foo")
+ bar=func.concat(stmt.inserted.bar, "_foo"),
+ baz=func.concat(stmt.inserted.bar, "_", foos.c.baz),
)
result = conn.execute(stmt)
eq_(result.inserted_primary_key, (None,))
eq_(
- conn.execute(foos.select().where(foos.c.id == 1)).fetchall(),
- [(1, "ab_foo", "bz", False)],
+ conn.execute(foos.select()).fetchall(),
+ [
+ # first entry triggers ON DUPLICATE
+ (1, "ab_foo", "ab_bz", False),
+ # second entry must be an insert
+ (2, "b", None, False),
+ ],
)
def test_on_duplicate_key_update_preserve_order(self, connection):