]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Fixed bug when using multi-table UPDATE where a supplemental
authorMike Bayer <mike_mp@zzzcomputing.com>
Tue, 2 Jul 2013 22:24:58 +0000 (18:24 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 2 Jul 2013 22:25:35 +0000 (18:25 -0400)
table is a SELECT with its own bound parameters, where the positioning
of the bound parameters would be reversed versus the statement
itself when using MySQL's special syntax.
[ticket:2768]

doc/build/changelog/changelog_08.rst
lib/sqlalchemy/sql/compiler.py
test/sql/test_update.py

index f4dd923d6e743aa1ebe950db07fd8132723b5fde..29da708fca3a95a7ea807cdaa20013316cfc2904 100644 (file)
@@ -6,6 +6,15 @@
 .. changelog::
     :version: 0.8.2
 
+    .. change::
+        :tags: bug, mysql
+        :tickets: 2768
+
+        Fixed bug when using multi-table UPDATE where a supplemental
+        table is a SELECT with its own bound parameters, where the positioning
+        of the bound parameters would be reversed versus the statement
+        itself when using MySQL's special syntax.
+
     .. change::
         :tags: bug, sqlite
         :tickets: 2764
index 3de59ca90ead169a9c6ffc4655083dd1fa83afbb..ef935cfa691b3785987f6cc00a9b94c20198bfbc 100644 (file)
@@ -1461,8 +1461,6 @@ class SQLCompiler(engine.Compiled):
 
         extra_froms = update_stmt._extra_froms
 
-        colparams = self._get_colparams(update_stmt, extra_froms)
-
         text = "UPDATE "
 
         if update_stmt._prefixes:
@@ -1472,6 +1470,8 @@ class SQLCompiler(engine.Compiled):
         table_text = self.update_tables_clause(update_stmt, update_stmt.table,
                                                extra_froms, **kw)
 
+        colparams = self._get_colparams(update_stmt, extra_froms)
+
         if update_stmt._hints:
             dialect_hints = dict([
                 (table, hint_text)
index a8df86cd2186bd0e8b0d6c955d5d9f81f7fe714b..b8e2d837ebec48b04e2b54c583cc2807878a7a5b 100644 (file)
@@ -1,6 +1,7 @@
 from sqlalchemy import *
 from sqlalchemy import testing
 from sqlalchemy.dialects import mysql
+from sqlalchemy.engine import default
 from sqlalchemy.testing import AssertsCompiledSQL, eq_, fixtures
 from sqlalchemy.testing.schema import Table, Column
 
@@ -222,6 +223,44 @@ class UpdateTest(_UpdateFromTestBase, fixtures.TablesTest, AssertsCompiledSQL):
         self.assert_compile(table1.update().values({expr: 'bar'}),
             'UPDATE mytable SET foo(myid)=:param_1')
 
+    def test_update_bound_ordering(self):
+        """test that bound parameters between the UPDATE and FROM clauses
+        order correctly in different SQL compilation scenarios.
+
+        """
+        table1 = self.tables.mytable
+        table2 = self.tables.myothertable
+        sel = select([table2]).where(table2.c.otherid == 5).alias()
+        upd = table1.update().\
+                    where(table1.c.name == sel.c.othername).\
+                    values(name='foo')
+
+        dialect = default.DefaultDialect()
+        dialect.positional = True
+        self.assert_compile(
+            upd,
+            "UPDATE mytable SET name=:name FROM (SELECT "
+            "myothertable.otherid AS otherid, "
+            "myothertable.othername AS othername "
+            "FROM myothertable "
+            "WHERE myothertable.otherid = :otherid_1) AS anon_1 "
+            "WHERE mytable.name = anon_1.othername",
+            checkpositional=('foo', 5),
+            dialect=dialect
+        )
+
+        self.assert_compile(
+            upd,
+            "UPDATE mytable, (SELECT myothertable.otherid AS otherid, "
+            "myothertable.othername AS othername "
+            "FROM myothertable "
+            "WHERE myothertable.otherid = %s) AS anon_1 SET mytable.name=%s "
+            "WHERE mytable.name = anon_1.othername",
+            checkpositional=(5, 'foo'),
+            dialect=mysql.dialect()
+        )
+
+
 
 class UpdateFromCompileTest(_UpdateFromTestBase, fixtures.TablesTest,
                             AssertsCompiledSQL):