Keep portal open when H is last with B or E in the sequence - #1332
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
|
Nice. Could you add some node tests as well to make sure this works end-to-end? |
Against a pre-fix binary, 3 of the 4 fail with the reported error, including
|
|
Almost good to go, just would be good to remove the |
|
@levkk I have taken the alternative route, making the solution simpler really. |
|
Aaah! Beautiful. |
Problem
In
pooler_mode = "transaction", a client that ends an extended-query batch withFlushbeforeExecuteloses its portal:This breaks the node-postgres cursor/streaming stack deterministically;
pg-cursor,pg-query-stream,knex .stream(), and anything layered on them (TypeORM/Sequelize streaming). They open withParse/Bind/Describe/Flushand noExecute, which is legal: it reads theRowDescriptionbefore deciding to pull rows.Closes #1330
Root cause
FlushandSyncwere treated as the same boundary. They aren't:Flush= push pending output; the batch continues.Sync= the batch is over; close the implicit transaction, drop portals, sendReadyForQuery.Fix
Reuse the existing pin mechanism (advisory locks, manual pin) with a third reason: the client is mid extended-protocol unit.
Behavior changes
Sync. Same exposure as a client that sendsBEGINand goes idle;client_idle_in_transaction_timeoutgoverns it (default infinite, unchanged).sv_locked. Accurate, but new in that metric.Tests
Unit;
opens_portal():P B D H-> true,P D H-> false,E H-> true,B E S-> false,S-> false.Integration (
frontend::client::test), red before this change with the reported34000:test_flush_after_bind_keeps_portal— the pg-cursor opening sequencetest_flush_portal_paging_stays_pinned—Execute/Flushpaging; pin survives several batchestest_flush_portal_released_on_terminate— client walks away mid-batch, backend returns to the pooltest_parse_describe_flush_bind_execute_close_sync— now assertsserver_assignment_count == 2, locking in that the Parse-only path still releases