]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- Fixed bug in common table expression system where if the CTE were
authorMike Bayer <mike_mp@zzzcomputing.com>
Wed, 31 Jul 2013 22:42:58 +0000 (18:42 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 31 Jul 2013 22:44:12 +0000 (18:44 -0400)
used only as an ``alias()`` construct, it would not render using the
WITH keyword.  Also in 0.7.11.
[ticket:2783]

doc/build/changelog/changelog_07.rst
doc/build/changelog/changelog_08.rst
lib/sqlalchemy/sql/compiler.py
lib/sqlalchemy/sql/expression.py
test/sql/test_cte.py

index 99702a2f0c90397d05d60a1ce4283360489524bd..b9601f23fb74960802844fa262b474f275f5a804 100644 (file)
@@ -6,6 +6,14 @@
 .. changelog::
     :version: 0.7.11
 
+    .. change::
+        :tags: sql, bug, cte
+        :tickets: 2783
+
+        Fixed bug in common table expression system where if the CTE were
+        used only as an ``alias()`` construct, it would not render using the
+        WITH keyword.  Also in 0.8.3, 0.7.11.
+
     .. change::
         :tags: bug, sql
         :tickets: 2784
index 47cd32c389ddf9270df9f50be94b68c0ea933af7..b728c31cb40e4d2840c2426bde509d009948716c 100644 (file)
@@ -6,6 +6,14 @@
 .. changelog::
     :version: 0.8.3
 
+    .. change::
+        :tags: sql, bug, cte
+        :tickets: 2783
+
+        Fixed bug in common table expression system where if the CTE were
+        used only as an ``alias()`` construct, it would not render using the
+        WITH keyword.  Also in 0.7.11.
+
     .. change::
         :tags: feature, examples
 
index 85e4916ffd1fafbea077e1384167982fcac30612..5f286a331789139421f1d3b7aa2a823db4fb4135 100644 (file)
@@ -927,12 +927,17 @@ class SQLCompiler(engine.Compiled):
 
         self.ctes_by_name[cte_name] = cte
 
-        if cte.cte_alias:
-            if isinstance(cte.cte_alias, sql._truncated_label):
-                cte_alias = self._truncated_identifier("alias", cte.cte_alias)
-            else:
-                cte_alias = cte.cte_alias
-        if not cte.cte_alias and cte not in self.ctes:
+        if cte._cte_alias is not None:
+            orig_cte = cte._cte_alias
+            if orig_cte not in self.ctes:
+                self.visit_cte(orig_cte)
+            cte_alias_name = cte._cte_alias.name
+            if isinstance(cte_alias_name, sql._truncated_label):
+                cte_alias_name = self._truncated_identifier("alias", cte_alias_name)
+        else:
+            orig_cte = cte
+            cte_alias_name = None
+        if not cte_alias_name and cte not in self.ctes:
             if cte.recursive:
                 self.ctes_recursive = True
             text = self.preparer.format_alias(cte, cte_name)
@@ -955,9 +960,10 @@ class SQLCompiler(engine.Compiled):
                                 self, asfrom=True, **kwargs
                             )
             self.ctes[cte] = text
+
         if asfrom:
-            if cte.cte_alias:
-                text = self.preparer.format_alias(cte, cte_alias)
+            if cte_alias_name:
+                text = self.preparer.format_alias(cte, cte_alias_name)
                 text += " AS " + cte_name
             else:
                 return self.preparer.format_alias(cte, cte_name)
index 45341bba75e42b3b6f105660a0352bb5b7d53835..ce3308ede14fd4d7609593b28e102fd899f3f970 100644 (file)
@@ -4150,10 +4150,10 @@ class CTE(Alias):
     def __init__(self, selectable,
                         name=None,
                         recursive=False,
-                        cte_alias=False,
+                        _cte_alias=None,
                         _restates=frozenset()):
         self.recursive = recursive
-        self.cte_alias = cte_alias
+        self._cte_alias = _cte_alias
         self._restates = _restates
         super(CTE, self).__init__(selectable, name=name)
 
@@ -4162,8 +4162,8 @@ class CTE(Alias):
             self.original,
             name=name,
             recursive=self.recursive,
-            cte_alias=self.name
-        )
+            _cte_alias=self,
+          )
 
     def union(self, other):
         return CTE(
index 28756873f88be4275e265f906d3ce9bdbdf42c4b..5368b9891d057b4b6788d6a5183c64dd67bb6b7c 100644 (file)
@@ -351,3 +351,32 @@ class CTETest(fixtures.TestBase, AssertsCompiledSQL):
             dialect=dialect
         )
 
+
+    def test_all_aliases(self):
+        orders = table('order', column('order'))
+        s = select([orders.c.order]).cte("regional_sales")
+
+        r1 = s.alias()
+        r2 = s.alias()
+
+        s2 = select([r1, r2]).where(r1.c.order > r2.c.order)
+
+        self.assert_compile(
+            s2,
+            'WITH regional_sales AS (SELECT "order"."order" '
+            'AS "order" FROM "order") '
+            'SELECT anon_1."order", anon_2."order" '
+            'FROM regional_sales AS anon_1, '
+            'regional_sales AS anon_2 WHERE anon_1."order" > anon_2."order"'
+        )
+
+        s3 = select([orders]).select_from(orders.join(r1, r1.c.order == orders.c.order))
+
+        self.assert_compile(
+            s3,
+            'WITH regional_sales AS '
+            '(SELECT "order"."order" AS "order" '
+            'FROM "order")'
+            ' SELECT "order"."order" '
+            'FROM "order" JOIN regional_sales AS anon_1 ON anon_1."order" = "order"."order"'
+        )
\ No newline at end of file