]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Apply quoting to render_derived() names
authorMike Bayer <mike_mp@zzzcomputing.com>
Thu, 1 Apr 2021 16:46:41 +0000 (12:46 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Thu, 1 Apr 2021 17:41:44 +0000 (13:41 -0400)
Fixed bug in new :meth:`_functions.FunctionElement.render_derived` feature
where column names rendered out explicitly in the alias SQL would not have
proper quoting applied for case sensitive names and other non-alphanumeric
names.

Fixes: #6183
Change-Id: I33e2534affc6e1f449f564750028fd027cb0f352

doc/build/changelog/unreleased_14/6183.rst [new file with mode: 0644]
lib/sqlalchemy/sql/compiler.py
test/dialect/postgresql/test_query.py
test/sql/test_functions.py

diff --git a/doc/build/changelog/unreleased_14/6183.rst b/doc/build/changelog/unreleased_14/6183.rst
new file mode 100644 (file)
index 0000000..ed4a704
--- /dev/null
@@ -0,0 +1,8 @@
+.. change::
+    :tags: bug, sql, postgresql
+    :tickets: 6183
+
+    Fixed bug in new :meth:`_functions.FunctionElement.render_derived` feature
+    where column names rendered out explicitly in the alias SQL would not have
+    proper quoting applied for case sensitive names and other non-alphanumeric
+    names.
index 2762091039314d4b767d0d4cf170f36b761366eb..32530629b467397d1377e42d13cf3d07c5fe8483 100644 (file)
@@ -2662,7 +2662,7 @@ class SQLCompiler(Compiled):
                     ", ".join(
                         "%s%s"
                         % (
-                            col.name,
+                            self.preparer.quote(col.name),
                             " %s"
                             % self.dialect.type_compiler.process(
                                 col.type, **kwargs
index ce64ca16fc55294a36727f0aa8b9369c4e78e3e8..db76f61ffafd348a7aa1007f08b3c3af810fc87b 100644 (file)
@@ -5,6 +5,7 @@ import datetime
 from sqlalchemy import and_
 from sqlalchemy import cast
 from sqlalchemy import Column
+from sqlalchemy import column
 from sqlalchemy import Date
 from sqlalchemy import DateTime
 from sqlalchemy import exc
@@ -1331,3 +1332,24 @@ class TableValuedRoundTripTest(fixtures.TestBase):
             connection.execute(stmt).all(),
             [(14, 1), (41, 2), (7, 3), (54, 4), (9, 5), (49, 6)],
         )
+
+    @testing.only_on(
+        "postgresql+psycopg2",
+        "I cannot get this to run at all on other drivers, "
+        "even selecting from a table",
+    )
+    def test_render_derived_quoting(self, connection):
+        fn = (
+            func.json_to_recordset(  # noqa
+                '[{"CaseSensitive":1,"the % value":"foo"}, '
+                '{"CaseSensitive":"2","the % value":"bar"}]'
+            )
+            .table_valued(
+                column("CaseSensitive", Integer), column("the % value", String)
+            )
+            .render_derived(with_types=True)
+        )
+
+        stmt = select(fn.c.CaseSensitive, fn.c["the % value"])
+
+        eq_(connection.execute(stmt).all(), [(1, "foo"), (2, "bar")])
index c5aca5d7fa87144bf17207e568c3c2472130ed26..43b505c997cdc3f2725af7df007d6dae8ebd1374 100644 (file)
@@ -1638,6 +1638,28 @@ class TableValuedCompileTest(fixtures.TestBase, AssertsCompiledSQL):
             "AS anon_1(a INTEGER, b VARCHAR)",
         )
 
+    def test_named_table_valued_w_quoting(self):
+
+        fn = (
+            func.json_to_recordset(  # noqa
+                '[{"CaseSensitive":1,"the % value":"foo"}, '
+                '{"CaseSensitive":"2","the % value":"bar"}]'
+            )
+            .table_valued(
+                column("CaseSensitive", Integer), column("the % value", String)
+            )
+            .render_derived(with_types=True)
+        )
+
+        stmt = select(fn.c.CaseSensitive, fn.c["the % value"])
+
+        self.assert_compile(
+            stmt,
+            'SELECT anon_1."CaseSensitive", anon_1."the % value" '
+            "FROM json_to_recordset(:json_to_recordset_1) "
+            'AS anon_1("CaseSensitive" INTEGER, "the % value" VARCHAR)',
+        )
+
     def test_named_table_valued_subquery(self):
 
         fn = (