]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
apply quoting to "ON CONSTRAINT" symbol
authorMike Bayer <mike_mp@zzzcomputing.com>
Wed, 30 Jun 2021 13:22:00 +0000 (09:22 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 30 Jun 2021 13:23:02 +0000 (09:23 -0400)
Fixed issue in :meth:`_postgresql.Insert.on_conflict_do_nothing` and
:meth:`_postgresql.Insert.on_conflict_do_update` where the name of a unique
constraint passed as the ``constraint`` parameter would not be properly
quoted if it contained characters which required quoting.

Fixes: #6696
Change-Id: I4ffca9b8c72cef4ed39e2de96831ccc11a620422

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

diff --git a/doc/build/changelog/unreleased_14/6696.rst b/doc/build/changelog/unreleased_14/6696.rst
new file mode 100644 (file)
index 0000000..e1ff871
--- /dev/null
@@ -0,0 +1,9 @@
+.. change::
+    :tags: bug, postgresql
+    :tickets: 6696
+
+    Fixed issue in :meth:`_postgresql.Insert.on_conflict_do_nothing` and
+    :meth:`_postgresql.Insert.on_conflict_do_update` where the name of a unique
+    constraint passed as the ``constraint`` parameter would not be properly
+    quoted if it contained characters which required quoting.
+
index 4c789813290eafd8fb060d1e3af9ba865c243637..4c654a643b04cbde16a03f47e32781cb356dac57 100644 (file)
@@ -2322,7 +2322,9 @@ class PGCompiler(compiler.SQLCompiler):
     def _on_conflict_target(self, clause, **kw):
 
         if clause.constraint_target is not None:
-            target_text = "ON CONSTRAINT %s" % clause.constraint_target
+            target_text = "ON CONSTRAINT %s" % self.preparer.quote(
+                clause.constraint_target
+            )
         elif clause.inferred_target_elements is not None:
             target_text = "(%s)" % ", ".join(
                 (
index 2f91580a93d19446c007c3b4fff84c43db3430b4..e48de9d21d7411f08e890e8aacdad5078a450967 100644 (file)
@@ -28,6 +28,7 @@ from sqlalchemy import Text
 from sqlalchemy import text
 from sqlalchemy import tuple_
 from sqlalchemy import types as sqltypes
+from sqlalchemy import UniqueConstraint
 from sqlalchemy import update
 from sqlalchemy.dialects import postgresql
 from sqlalchemy.dialects.postgresql import aggregate_order_by
@@ -2339,6 +2340,31 @@ class InsertOnConflictTest(fixtures.TestBase, AssertsCompiledSQL):
             "DO UPDATE SET myid = excluded.myid",
         )
 
+    def test_do_nothing_quoted_string_constraint_target(self):
+        """test #6696"""
+        i = insert(self.table1, values=dict(name="foo"))
+        i = i.on_conflict_do_nothing(constraint="Some Constraint Name")
+        self.assert_compile(
+            i,
+            "INSERT INTO mytable (name) VALUES "
+            '(%(name)s) ON CONFLICT ON CONSTRAINT "Some Constraint Name" '
+            "DO NOTHING",
+        )
+
+    def test_do_nothing_quoted_named_constraint_target(self):
+        """test #6696"""
+        i = insert(self.table1, values=dict(name="foo"))
+        unique_constr = UniqueConstraint(
+            self.table1.c.myid, name="Some Constraint Name"
+        )
+        i = i.on_conflict_do_nothing(constraint=unique_constr)
+        self.assert_compile(
+            i,
+            "INSERT INTO mytable (name) VALUES "
+            '(%(name)s) ON CONFLICT ON CONSTRAINT "Some Constraint Name" '
+            "DO NOTHING",
+        )
+
     def test_do_update_index_elements_where_target(self):
         i = insert(self.table1, values=dict(name="foo"))
         i = i.on_conflict_do_update(