if self.positional:
kwargs["positional_names"] = self.cte_positional[cte] = []
- text += " AS \n" + cte.original._compiler_dispatch(
- self, asfrom=True, **kwargs
+ text += " AS %s\n%s" % (
+ self._generate_prefixes(cte, cte._prefixes, **kwargs),
+ cte.original._compiler_dispatch(
+ self, asfrom=True, **kwargs
+ ),
)
if cte._suffixes:
return functions.func.system(self.sampling)
-class CTE(Generative, HasSuffixes, Alias):
+class CTE(Generative, HasPrefixes, HasSuffixes, Alias):
"""Represent a Common Table Expression.
The :class:`.CTE` object is obtained using the
recursive=False,
_cte_alias=None,
_restates=frozenset(),
+ _prefixes=None,
_suffixes=None,
):
self.recursive = recursive
self._cte_alias = _cte_alias
self._restates = _restates
+ if _prefixes:
+ self._prefixes = _prefixes
if _suffixes:
self._suffixes = _suffixes
super(CTE, self)._init(selectable, name=name)
name=name,
recursive=self.recursive,
_cte_alias=self,
+ _prefixes=self._prefixes,
_suffixes=self._suffixes,
)
name=self.name,
recursive=self.recursive,
_restates=self._restates.union([self]),
+ _prefixes=self._prefixes,
_suffixes=self._suffixes,
)
name=self.name,
recursive=self.recursive,
_restates=self._restates.union([self]),
+ _prefixes=self._prefixes,
_suffixes=self._suffixes,
)
when combined with RETURNING, as well as a consumer of
CTE rows.
+ .. versionchanged:: 1.1 Added support for UPDATE/INSERT/DELETE as
+ CTE, CTEs added to UPDATE/INSERT/DELETE.
+
SQLAlchemy detects :class:`.CTE` objects, which are treated
similarly to :class:`.Alias` objects, as special elements
to be delivered to the FROM clause of the statement as well
as to a WITH clause at the top of the statement.
- .. versionchanged:: 1.1 Added support for UPDATE/INSERT/DELETE as
- CTE, CTEs added to UPDATE/INSERT/DELETE.
+ For special prefixes such as PostgreSQL "MATERIALIZED" and
+ "NOT MATERIALIZED", the :meth:`.CTE.prefix_with` method may be
+ used to establish these.
+
+ .. versionchanged:: 1.3.13 Added support for prefixes.
+ In particular - MATERIALIZED and NOT MATERIALIZED.
:param name: name given to the common table expression. Like
:meth:`._FromClause.alias`, the name can be left as ``None``
'ON anon_1."order" = "order"."order"',
)
+ def test_prefixes(self):
+ orders = table("order", column("order"))
+ s = select([orders.c.order]).cte("regional_sales")
+ s = s.prefix_with("NOT MATERIALIZED", dialect="postgresql")
+ stmt = select([orders]).where(orders.c.order > s.c.order)
+
+ self.assert_compile(
+ stmt,
+ 'WITH regional_sales AS (SELECT "order"."order" AS "order" '
+ 'FROM "order") SELECT "order"."order" FROM "order", '
+ 'regional_sales WHERE "order"."order" > regional_sales."order"',
+ )
+
+ self.assert_compile(
+ stmt,
+ "WITH regional_sales AS NOT MATERIALIZED "
+ '(SELECT "order"."order" AS "order" '
+ 'FROM "order") SELECT "order"."order" FROM "order", '
+ 'regional_sales WHERE "order"."order" > regional_sales."order"',
+ dialect="postgresql",
+ )
+
def test_suffixes(self):
orders = table("order", column("order"))
s = select([orders.c.order]).cte("regional_sales")