diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2023-01-28 19:50:25 -0500 |
|---|---|---|
| committer | Federico Caselli <cfederico87@gmail.com> | 2023-01-30 22:28:53 +0100 |
| commit | d23dcbaea2a8e000c5fa2ba443e1b683b3b79fa6 (patch) | |
| tree | 6b89a07b8bda5a469bf6c8dde165101315f571ed /test/sql/test_cte.py | |
| parent | b99b0c522ddb94468da27867ddfa1f7e2633c920 (diff) | |
| download | sqlalchemy-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.py | 66 |
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")) |
