]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Fixed issue in visit_on_duplicate_key_update within a composed expression
authorCristian Sabaila <cristian.sabaila@geotogether.com>
Wed, 3 Nov 2021 01:39:08 +0000 (21:39 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 3 Nov 2021 02:27:32 +0000 (22:27 -0400)
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.

Fixes: #7281
Closes: #7285
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/7285
Pull-request-sha: 3e6ad6f2fecc6ae36a10a5a34b5d3d393483edbb

Change-Id: I83377c20eae6358fead9e7e361127938e538a71c

doc/build/changelog/unreleased_14/7281.rst [new file with mode: 0644]
lib/sqlalchemy/dialects/mysql/base.py
test/dialect/mysql/test_compiler.py
test/dialect/mysql/test_on_duplicate.py

diff --git a/doc/build/changelog/unreleased_14/7281.rst b/doc/build/changelog/unreleased_14/7281.rst
new file mode 100644 (file)
index 0000000..a5ca9a1
--- /dev/null
@@ -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.
index 4827df12f1cef06b60d246662465fa6c9130d88a..684f35c5f8b92446b73c5158f277abc563f9a749 100644 (file)
@@ -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:
index 708039f943e302746313fc1ac03f61987d7a8bac..ba162b49020686aad019ec99f30d7ca6cafc8ed6 100644 (file)
@@ -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,
index 65d5b8364e7df44ac00101fdcbe174b91f5e01de..5a4e6ca8d5cc10cf6d9898404103c5cf709b99dc 100644 (file)
@@ -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):