]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Quote cte alias if needed
authorEric Atkin <eatkin@omnisolutions.biz>
Thu, 22 Feb 2018 19:16:14 +0000 (14:16 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Thu, 22 Feb 2018 20:06:01 +0000 (15:06 -0500)
Fixed bug where CTE expressions would not have their name or alias name
quoted when the given name is case sensitive or otherwise requires quoting.
Pull request courtesy Eric Atkin.

Fixes: #4197
Change-Id: Ib8573e82b9a1ca94b50c7c5d73ee98b79465d689
Pull-request: https://github.com/zzzeek/sqlalchemy/pull/426

doc/build/changelog/unreleased_12/4197.rst [new file with mode: 0644]
lib/sqlalchemy/sql/compiler.py
test/sql/test_cte.py

diff --git a/doc/build/changelog/unreleased_12/4197.rst b/doc/build/changelog/unreleased_12/4197.rst
new file mode 100644 (file)
index 0000000..6e24c46
--- /dev/null
@@ -0,0 +1,7 @@
+.. change::
+    :tags: bug, sql
+    :tickets: 4197
+
+    Fixed bug where CTE expressions would not have their name or alias name
+    quoted when the given name is case sensitive or otherwise requires quoting.
+    Pull request courtesy Eric Atkin.
index 560585cabd72e0ab8969a895b8c32d5fc0889079..be41e80c5bc2ab5045a408667c30b12c057037be 100644 (file)
@@ -1427,6 +1427,8 @@ class SQLCompiler(Compiled):
         if asfrom:
             if cte_alias_name:
                 text = self.preparer.format_alias(cte, cte_alias_name)
+                if self.preparer._requires_quotes(cte_name):
+                    cte_name = self.preparer.quote(cte_name)
                 text += self.get_render_as_alias_suffix(cte_name)
             else:
                 return self.preparer.format_alias(cte, cte_name)
index f33516cc2098e04fc8c1aa1071b83d659ce18aaf..aadd470e8dfbff316d81bc04dd0704ef9312dfd0 100644 (file)
@@ -4,7 +4,7 @@ from sqlalchemy.sql import table, column, select, func, literal, exists, and_
 from sqlalchemy.dialects import mssql
 from sqlalchemy.engine import default
 from sqlalchemy.exc import CompileError
-
+from sqlalchemy.sql.elements import quoted_name
 
 class CTETest(fixtures.TestBase, AssertsCompiledSQL):
 
@@ -319,6 +319,47 @@ class CTETest(fixtures.TestBase, AssertsCompiledSQL):
             '(SELECT "CTE".id AS id FROM "CTE") AS anon_2'
         )
 
+    def test_named_alias_no_quote(self):
+        cte = select([literal(1).label("id")]).cte(name='CTE')
+
+        s1 = select([cte.c.id]).alias(name="no_quotes")
+
+        s = select([s1])
+        self.assert_compile(
+            s,
+            'WITH "CTE" AS (SELECT :param_1 AS id) '
+            'SELECT no_quotes.id FROM '
+            '(SELECT "CTE".id AS id FROM "CTE") AS no_quotes'
+        )
+
+    def test_named_alias_quote(self):
+        cte = select([literal(1).label("id")]).cte(name='CTE')
+
+        s1 = select([cte.c.id]).alias(name="Quotes Required")
+
+        s = select([s1])
+        self.assert_compile(
+            s,
+            'WITH "CTE" AS (SELECT :param_1 AS id) '
+            'SELECT "Quotes Required".id FROM '
+            '(SELECT "CTE".id AS id FROM "CTE") AS "Quotes Required"'
+        )
+
+    def test_named_alias_disable_quote(self):
+        cte = select([literal(1).label("id")]).cte(
+            name=quoted_name('CTE', quote=False))
+
+        s1 = select([cte.c.id]).alias(
+            name=quoted_name("DontQuote", quote=False))
+
+        s = select([s1])
+        self.assert_compile(
+            s,
+            'WITH CTE AS (SELECT :param_1 AS id) '
+            'SELECT DontQuote.id FROM '
+            '(SELECT CTE.id AS id FROM CTE) AS DontQuote'
+        )
+
     def test_positional_binds(self):
         orders = table('orders',
                        column('order'),