You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Can the issue be reproduced under both asyncio and uvloop?: Yes
Unexpected behaviour: It seems asyncpg doesn't return the rows returned by a DELETE query rewritten to an UPDATE query by a rule. Perhaps because it's optimizing (the query status is DELETE 0, so perhaps it thinks it doesn't need to return any rows) or something like that? I didn't dive in any further to check if that is indeed what is happening.
Reproduction
importasyncioimportasyncpgasyncdefmain():
connection=awaitasyncpg.connect('postgresql://postgres:password@localhost/test')
asyncdeffetch_print(query, *params):
result=awaitconnection.fetch(query, *params)
i=0forrowinresult:
print(f' - {row}')
i+=1ifi==0:
print(' (no rows returned)')
print('')
# Create table with rule for deletionawaitconnection.execute(''' CREATE TABLE items ( id serial PRIMARY KEY, name text UNIQUE, deleted boolean DEFAULT false ); CREATE RULE softdelete AS ON DELETE TO items DO INSTEAD UPDATE items SET deleted = true WHERE id = OLD.id RETURNING OLD.* ; INSERT INTO items (name) VALUES ('foo'), ('bar') ; ''')
print('Our table has a rule that updates the "deleted" column instead of deleting the row.\n')
# Show contentsprint('We start with 2 rows which are not soft-deleted:')
awaitfetch_print('SELECT * FROM items')
# Try delete (the unexpected case)print('Deleting with RETURNING should give us a row (it does in psql), but we do not get any in asyncpg:')
awaitfetch_print(''' DELETE FROM items WHERE name = $1 RETURNING id ''', 'foo')
# Confirm above query workedprint('But the row is now soft-deleted:')
awaitfetch_print('SELECT * FROM items')
# Workaroundprint('If wrapped in a CTE it does work:')
awaitfetch_print(''' WITH x AS ( DELETE FROM items WHERE name = $1 RETURNING id ) SELECT * FROM x ''', 'bar')
# Confirm above query workedprint('And it is again properly softdeleted:')
awaitfetch_print('SELECT * FROM items')
print('We now delete the rule.\n')
awaitconnection.execute('DROP RULE softdelete ON items')
# Confirm normal delete without rule returns rowsprint('Normal deletion (without the rule) does return rows correctly:')
awaitfetch_print(''' DELETE FROM items RETURNING id ''')
# Confirm above query workedprint('And now both rows are indeed gone:')
awaitfetch_print('SELECT * FROM items')
# Clean up table after we are doneawaitconnection.execute('DROP TABLE items')
awaitconnection.close()
asyncio.run(main())
Output of reproduction
Our table has a rule that updates the "deleted" column instead of deleting the row.
We start with 2 rows which are not soft-deleted:
- <Record id=1 name='foo' deleted=False>
- <Record id=2 name='bar' deleted=False>
Deleting with RETURNING should give us a row (it does in psql), but we do not get any in asyncpg:
(no rows returned)
But the row is now soft-deleted:
- <Record id=2 name='bar' deleted=False>
- <Record id=1 name='foo' deleted=True>
If wrapped in a CTE it does work:
- <Record id=2>
And it is again properly softdeleted:
- <Record id=1 name='foo' deleted=True>
- <Record id=2 name='bar' deleted=True>
We now delete the rule.
Normal deletion (without the rule) does return rows correctly:
- <Record id=1>
- <Record id=2>
And now both rows are indeed gone:
(no rows returned)
In contrast the psql command line tool does show me the resulting rows when the result code is DELETED 0.
Output of psql
test=# DELETE FROM items WHERE name = 'foo' RETURNING id;
id
----
1
(1 row)
DELETE 0
So it is a bit unexpected that asyncpg doesn't return any rows.
The text was updated successfully, but these errors were encountered:
postgres:latest
Docker image)Unexpected behaviour: It seems
asyncpg
doesn't return the rows returned by a DELETE query rewritten to an UPDATE query by a rule. Perhaps because it's optimizing (the query status isDELETE 0
, so perhaps it thinks it doesn't need to return any rows) or something like that? I didn't dive in any further to check if that is indeed what is happening.Reproduction
Output of reproduction
In contrast the
psql
command line tool does show me the resulting rows when the result code isDELETED 0
.Output of
psql
So it is a bit unexpected that
asyncpg
doesn't return any rows.The text was updated successfully, but these errors were encountered: