]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Fixed issue when copying ExcludeConstraint
authorFederico Caselli <cfederico87@gmail.com>
Wed, 1 Mar 2023 22:22:46 +0000 (23:22 +0100)
committerFederico Caselli <cfederico87@gmail.com>
Wed, 1 Mar 2023 22:22:46 +0000 (23:22 +0100)
Fixes: #9401
Change-Id: Ie10192348749567110f53ae618fc724f37d1a6a1

doc/build/changelog/unreleased_20/9401.rst [new file with mode: 0644]
lib/sqlalchemy/dialects/postgresql/ext.py
test/dialect/postgresql/test_compiler.py

diff --git a/doc/build/changelog/unreleased_20/9401.rst b/doc/build/changelog/unreleased_20/9401.rst
new file mode 100644 (file)
index 0000000..48d88f5
--- /dev/null
@@ -0,0 +1,5 @@
+.. change::
+    :tags: bug, schema, postgresql
+    :tickets: 9401
+
+    Fixed issue when copying ExcludeConstraint.
index f382af86f350c1bce9a9a9779ef14285e61e81b9..8c09edddacf8419a0fc263b0a91044760f896f64 100644 (file)
@@ -7,7 +7,6 @@
 # mypy: ignore-errors
 from __future__ import annotations
 
-from itertools import zip_longest
 from typing import Any
 from typing import TYPE_CHECKING
 from typing import TypeVar
@@ -256,22 +255,20 @@ class ExcludeConstraint(ColumnCollectionConstraint):
 
         self._render_exprs = [
             (
-                expr if isinstance(expr, elements.ClauseElement) else colexpr,
+                expr if not isinstance(expr, str) else table.c[expr],
                 name,
                 operator,
             )
-            for (expr, name, operator), colexpr in zip_longest(
-                self._render_exprs, self.columns
-            )
+            for expr, name, operator in (self._render_exprs)
         ]
 
     def _copy(self, target_table=None, **kw):
         elements = [
             (
                 schema._copy_expression(expr, self.parent, target_table),
-                self.operators[expr.name],
+                operator,
             )
-            for expr in self.columns
+            for expr, _, operator in self._render_exprs
         ]
         c = self.__class__(
             *elements,
index 2c0dbfccd75d7f5838b0b8c18a081ce8808b99c6..25b02ade9b4de93b19f8416c3d63d895ea3d37c4 100644 (file)
@@ -1135,6 +1135,40 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
             "ALTER TABLE testtbl ADD EXCLUDE USING gist (room WITH =)",
         )
 
+    def test_exclude_constraint_copy_complex(self):
+        m = MetaData()
+        tbl = Table("foo", m, Column("x", Integer), Column("y", Integer))
+        cons = ExcludeConstraint(
+            (tbl.c.x, "*"),
+            (text("x-y"), "%"),
+            (literal_column("x+y"), "$"),
+            (tbl.c.x // tbl.c.y, "??"),
+            (func.power(tbl.c.x, 42), "="),
+            (func.int8range(column("x"), column("y")), "&&"),
+            ("y", "^"),
+        )
+        tbl.append_constraint(cons)
+        expected = (
+            "ALTER TABLE {name} ADD EXCLUDE USING gist "
+            "(x WITH *, x-y WITH %, x+y WITH $, x / y WITH ??, "
+            "power(x, 42) WITH =, int8range(x, y) WITH &&, y WITH ^)"
+        )
+        self.assert_compile(
+            schema.AddConstraint(cons),
+            expected.format(name="foo"),
+            dialect=postgresql.dialect(),
+        )
+        m2 = MetaData()
+        tbl2 = tbl.to_metadata(m2, name="bar")
+        (cons2,) = [
+            c for c in tbl2.constraints if isinstance(c, ExcludeConstraint)
+        ]
+        self.assert_compile(
+            schema.AddConstraint(cons2),
+            expected.format(name="bar"),
+            dialect=postgresql.dialect(),
+        )
+
     def test_exclude_constraint_copy_where_using(self):
         m = MetaData()
         tbl = Table("testtbl", m, Column("room", Integer, primary_key=True))