"""
# collect CTEs to tack on top of a SELECT
self.ctes = util.OrderedDict()
+ # Detect same CTE references
self.ctes_by_name = {}
self.ctes_recursive = False
if self.positional:
):
self._init_cte_state()
+ cte_level = len(self.stack)
if cte.nesting:
- cte.nesting_level = len(self.stack)
+ cte.nesting_level = cte_level
kwargs["visiting_cte"] = cte
if isinstance(cte.name, elements._truncated_label):
is_new_cte = True
embedded_in_current_named_cte = False
- if cte_name in self.ctes_by_name:
- existing_cte = self.ctes_by_name[cte_name]
+ cte_level_name = (cte_level, cte_name)
+ if cte_level_name in self.ctes_by_name:
+ existing_cte = self.ctes_by_name[cte_level_name]
embedded_in_current_named_cte = visiting_cte is existing_cte
# we've generated a same-named CTE that we are enclosed in,
cte_pre_alias_name = None
if is_new_cte:
- self.ctes_by_name[cte_name] = cte
+ self.ctes_by_name[cte_level_name] = cte
if (
"autocommit" in cte.element._execution_options
dialect="postgresql",
)
+ def test_nesting_cte_in_cte_with_same_name(self):
+ nesting_cte = select([literal(1).label("inner")]).cte(
+ "some_cte", nesting=True
+ )
+ stmt = select(
+ [select([nesting_cte.c.inner.label("outer")]).cte("some_cte")]
+ )
+
+ self.assert_compile(
+ stmt,
+ 'WITH some_cte AS (WITH some_cte AS (SELECT %(param_1)s AS "inner") '
+ 'SELECT some_cte."inner" AS "outer" FROM some_cte) '
+ 'SELECT some_cte."outer" FROM some_cte',
+ dialect="postgresql",
+ )
+
def test_nesting_cte_at_top_level(self):
nesting_cte = select([literal(1).label("val")]).cte(
"nesting_cte", nesting=True