]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
repair schema_translate_map for schema type use cases
authorMike Bayer <mike_mp@zzzcomputing.com>
Sun, 11 Jul 2021 23:23:40 +0000 (19:23 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sun, 11 Jul 2021 23:23:40 +0000 (19:23 -0400)
Fixed issue where the PostgreSQL ``ENUM`` datatype as embedded in the
``ARRAY`` datatype would fail to emit correctly in create/drop when the
``schema_translate_map`` feature were also in use. Additionally repairs a
related issue where the same ``schema_translate_map`` feature would not
work for the ``ENUM`` datatype in combination with a ``CAST``, that's also
intrinsic to how the ``ARRAY(ENUM)`` combination works on the PostgreSQL
dialect.

Fixes: #6739
Change-Id: I44b1ad4db4af3acbf639aa422c46c22dd3b0d3a6

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

diff --git a/doc/build/changelog/unreleased_14/6739.rst b/doc/build/changelog/unreleased_14/6739.rst
new file mode 100644 (file)
index 0000000..b60402b
--- /dev/null
@@ -0,0 +1,12 @@
+.. change::
+    :tags: bug, postgresql
+    :tickets: 6739
+
+    Fixed issue where the PostgreSQL ``ENUM`` datatype as embedded in the
+    ``ARRAY`` datatype would fail to emit correctly in create/drop when the
+    ``schema_translate_map`` feature were also in use. Additionally repairs a
+    related issue where the same ``schema_translate_map`` feature would not
+    work for the ``ENUM`` datatype in combination with a ``CAST``, that's also
+    intrinsic to how the ``ARRAY(ENUM)`` combination works on the PostgreSQL
+    dialect.
+
index ea2eda902f00d26ac0a2d7ffd2864ce221e95fde..123e6f0fa869153c4d3c1331d9373800079cb2c7 100644 (file)
@@ -2820,7 +2820,6 @@ class PGTypeCompiler(compiler.GenericTypeCompiler):
     def visit_ENUM(self, type_, identifier_preparer=None, **kw):
         if identifier_preparer is None:
             identifier_preparer = self.dialect.identifier_preparer
-
         return identifier_preparer.format_type(type_)
 
     def visit_TIMESTAMP(self, type_, **kw):
@@ -2867,8 +2866,7 @@ class PGTypeCompiler(compiler.GenericTypeCompiler):
 
     def visit_ARRAY(self, type_, **kw):
 
-        # TODO: pass **kw?
-        inner = self.process(type_.item_type)
+        inner = self.process(type_.item_type, **kw)
         return re.sub(
             r"((?: COLLATE.*)?)$",
             (
index 4b3b2c293c6c81a11d643a375873e6757691e908..e92ffcd9a4b80ab14aaac5d5ad1bc6053d777720 100644 (file)
@@ -1497,6 +1497,7 @@ class SQLCompiler(Compiled):
 
     def visit_typeclause(self, typeclause, **kw):
         kw["type_expression"] = typeclause
+        kw["identifier_preparer"] = self.preparer
         return self.dialect.type_compiler.process(typeclause.type, **kw)
 
     def post_process_text(self, text):
index e48de9d21d7411f08e890e8aacdad5078a450967..3b542880f40115daa3c1502cd815b1ab18efcd37 100644 (file)
@@ -249,6 +249,33 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
             "'y', 'z')))",
         )
 
+    def test_cast_enum_schema(self):
+        """test #6739"""
+        e1 = Enum("x", "y", "z", name="somename")
+        e2 = Enum("x", "y", "z", name="somename", schema="someschema")
+
+        stmt = select(cast(column("foo"), e1), cast(column("bar"), e2))
+        self.assert_compile(
+            stmt,
+            "SELECT CAST(foo AS somename) AS foo, "
+            "CAST(bar AS someschema.somename) AS bar",
+        )
+
+    def test_cast_enum_schema_translate(self):
+        """test #6739"""
+        e1 = Enum("x", "y", "z", name="somename")
+        e2 = Enum("x", "y", "z", name="somename", schema="someschema")
+        schema_translate_map = {None: "bat", "someschema": "hoho"}
+
+        stmt = select(cast(column("foo"), e1), cast(column("bar"), e2))
+        self.assert_compile(
+            stmt,
+            "SELECT CAST(foo AS bat.somename) AS foo, "
+            "CAST(bar AS hoho.somename) AS bar",
+            schema_translate_map=schema_translate_map,
+            render_schema_translate=True,
+        )
+
     def test_create_type_schema_translate(self):
         e1 = Enum("x", "y", "z", name="somename")
         e2 = Enum("x", "y", "z", name="somename", schema="someschema")
@@ -285,6 +312,27 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
             render_schema_translate=True,
         )
 
+    def test_create_table_array_embedded_schema_type_schema_translate(self):
+        """test #6739"""
+        e1 = Enum("x", "y", "z", name="somename")
+        e2 = Enum("x", "y", "z", name="somename", schema="someschema")
+        schema_translate_map = {None: "foo", "someschema": "bar"}
+
+        table = Table(
+            "some_table",
+            MetaData(),
+            Column("q", PG_ARRAY(e1)),
+            Column("p", PG_ARRAY(e2)),
+        )
+        from sqlalchemy.schema import CreateTable
+
+        self.assert_compile(
+            CreateTable(table),
+            "CREATE TABLE foo.some_table (q foo.somename[], p bar.somename[])",
+            schema_translate_map=schema_translate_map,
+            render_schema_translate=True,
+        )
+
     def test_create_table_with_tablespace(self):
         m = MetaData()
         tbl = Table(