Fixed regression caused by :ticket:`7760` where the new capabilities of
:class:`.TextualSelect` were not fully implemented within the compiler
properly, leading to issues with composed INSERT constructs such as "INSERT
FROM SELECT" and "INSERT...ON CONFLICT" when combined with CTE and textual
statements.
Fixes: #7798
Change-Id: Ia2ce92507e574dd36fd26dd38ec9dd2713584467
(cherry picked from commit
c36965ab211183764357456fff1640418586ed97)
--- /dev/null
+.. change::
+ :tags: bug, sql, regression
+ :tickets: 7798
+
+ Fixed regression caused by :ticket:`7760` where the new capabilities of
+ :class:`.TextualSelect` were not fully implemented within the compiler
+ properly, leading to issues with composed INSERT constructs such as "INSERT
+ FROM SELECT" and "INSERT...ON CONFLICT" when combined with CTE and textual
+ statements.
nesting_level = len(self.stack) if not toplevel else None
text = self._render_cte_clause(nesting_level=nesting_level) + text
+ self.stack.pop(-1)
+
return text
def visit_null(self, expr, **kw):
):
meth()
+ def test_on_conflict_cte_plus_textual(self):
+ """test #7798"""
+
+ bar = table("bar", column("id"), column("attr"), column("foo_id"))
+ s1 = text("SELECT bar.id, bar.attr FROM bar").columns(
+ bar.c.id, bar.c.attr
+ )
+ s2 = (
+ insert(bar)
+ .from_select(list(s1.selected_columns), s1)
+ .on_conflict_do_update(
+ index_elements=[s1.selected_columns.id],
+ set_={"attr": s1.selected_columns.attr},
+ )
+ )
+
+ self.assert_compile(
+ s2,
+ "INSERT INTO bar (id, attr) SELECT bar.id, bar.attr "
+ "FROM bar ON CONFLICT (id) DO UPDATE SET attr = bar.attr",
+ )
+
def test_do_nothing_no_target(self):
i = (
"(SELECT id FROM baz)",
)
+ def test_textual_select_stack_correction(self):
+ """test #7798 , regression from #7760"""
+
+ foo = table("foo", column("id"))
+ bar = table("bar", column("id"), column("attr"), column("foo_id"))
+
+ s1 = text("SELECT id FROM foo").columns(foo.c.id)
+ s2 = text(
+ "SELECT bar.id, bar.attr FROM bar WHERE br.id IN "
+ "(SELECT id FROM baz)"
+ ).columns(bar.c.id, bar.c.attr)
+ s3 = bar.insert().from_select(list(s2.selected_columns), s2)
+ s4 = s3.add_cte(s1.cte(name="baz"))
+
+ self.assert_compile(
+ s4,
+ "WITH baz AS (SELECT id FROM foo) INSERT INTO bar (id, attr) "
+ "SELECT bar.id, bar.attr FROM bar WHERE br.id IN "
+ "(SELECT id FROM baz)",
+ )
+
def test_insert_uses_independent_cte(self):
products = table("products", column("id"), column("price"))