summaryrefslogtreecommitdiff
path: root/test/sql/test_cte.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2023-01-28 19:50:25 -0500
committerFederico Caselli <cfederico87@gmail.com>2023-01-30 22:28:53 +0100
commitd23dcbaea2a8e000c5fa2ba443e1b683b3b79fa6 (patch)
tree6b89a07b8bda5a469bf6c8dde165101315f571ed /test/sql/test_cte.py
parentb99b0c522ddb94468da27867ddfa1f7e2633c920 (diff)
downloadsqlalchemy-d23dcbaea2a8e000c5fa2ba443e1b683b3b79fa6.tar.gz
don't count / gather INSERT bind names inside of a CTE
Fixed regression related to the implementation for the new "insertmanyvalues" feature where an internal ``TypeError`` would occur in arrangements where a :func:`_sql.insert` would be referred towards inside of another :func:`_sql.insert` via a CTE; made additional repairs for this use case for positional dialects such as asyncpg when using "insertmanyvalues". at the core here is a change to positional insertmanyvalues where we now get exactly the positions for the "manyvalues" within the larger list, allowing non-"manyvalues" on the left and right sides at the same time, not assuming anything about how RETURNING renders etc., since CTEs are in the mix also. Fixes: #9173 Change-Id: I5ff071fbef0d92a2d6046b9c4e609bb008438afd
Diffstat (limited to 'test/sql/test_cte.py')
-rw-r--r--test/sql/test_cte.py66
1 files changed, 66 insertions, 0 deletions
diff --git a/test/sql/test_cte.py b/test/sql/test_cte.py
index 502104dae..4ba4eddfe 100644
--- a/test/sql/test_cte.py
+++ b/test/sql/test_cte.py
@@ -1320,6 +1320,72 @@ class CTETest(fixtures.TestBase, AssertsCompiledSQL):
@testing.combinations(
("default_enhanced",),
("postgresql",),
+ ("postgresql+asyncpg",),
+ )
+ def test_insert_w_cte_in_scalar_subquery(self, dialect):
+ """test #9173"""
+
+ customer = table(
+ "customer",
+ column("id"),
+ column("name"),
+ )
+ order = table(
+ "order",
+ column("id"),
+ column("price"),
+ column("customer_id"),
+ )
+
+ inst = (
+ customer.insert()
+ .values(name="John")
+ .returning(customer.c.id)
+ .cte("inst")
+ )
+
+ stmt = (
+ order.insert()
+ .values(
+ price=1,
+ customer_id=select(inst.c.id).scalar_subquery(),
+ )
+ .add_cte(inst)
+ )
+
+ if dialect == "default_enhanced":
+ self.assert_compile(
+ stmt,
+ "WITH inst AS (INSERT INTO customer (name) VALUES (:param_1) "
+ 'RETURNING customer.id) INSERT INTO "order" '
+ "(price, customer_id) VALUES "
+ "(:price, (SELECT inst.id FROM inst))",
+ dialect=dialect,
+ )
+ elif dialect == "postgresql":
+ self.assert_compile(
+ stmt,
+ "WITH inst AS (INSERT INTO customer (name) "
+ "VALUES (%(param_1)s) "
+ 'RETURNING customer.id) INSERT INTO "order" '
+ "(price, customer_id) "
+ "VALUES (%(price)s, (SELECT inst.id FROM inst))",
+ dialect=dialect,
+ )
+ elif dialect == "postgresql+asyncpg":
+ self.assert_compile(
+ stmt,
+ "WITH inst AS (INSERT INTO customer (name) VALUES ($2) "
+ 'RETURNING customer.id) INSERT INTO "order" '
+ "(price, customer_id) VALUES ($1, (SELECT inst.id FROM inst))",
+ dialect=dialect,
+ )
+ else:
+ assert False
+
+ @testing.combinations(
+ ("default_enhanced",),
+ ("postgresql",),
)
def test_select_from_delete_cte(self, dialect):
t1 = table("table_1", column("id"), column("val"))