fix(pg-cursor): settle read() when rowCount exceeds remaining rows - #3786
Open
dyk1454683243-sudo wants to merge 1 commit into
Open
dyk1454683243-sudo wants to merge 1 commit into
dyk1454683243-sudo wants to merge 1 commit into
Conversation
CommandComplete means the portal is exhausted, but read() only delivered rows from PortalSuspended or ReadyForQuery. If the client never dispatched ReadyForQuery, an oversized read hung. Settle the in-flight callback (and any queued reads) when the portal is exhausted, and do not start a queued execute while one is already in flight. Co-authored-by: David <dyk1454683243-sudo@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #2949
Problem
cursor.read(rowCount)never called its callback whenrowCountwas larger than the remaining (or total) rows. A table with 100 rows andread(1000)hung instead of returning the leftover rows.PostgreSQL reports portal exhaustion with
CommandComplete, notPortalSuspended.pg-cursoronly delivered the current batch fromPortalSuspendedorReadyForQuery. AfterCommandCompletethe cursor closed the portal and sentSync, then waited forReadyForQuery. If that message was never dispatched to the cursor,read()never settled.A late
RowDescriptioncould also reset a busy cursor to idle and start a queued execute, overwriting the in-flight callback. Queuedread()calls were never drained when the portal was exhausted.Fix
In
packages/pg-cursor:read()as soon asCommandCompletearrives (shorter or empty batch).[]once the portal is exhausted.RowDescription/noDatawhile a read is already in flight.ReadyForQuerycannot deliver the same batch twice.Tests
packages/pg-cursor/test/read-exhaustion.js:read()settles onCommandCompletewithoutReadyForQuery.read().[]after exhaustion.RowDescriptiondoes not overwrite an in-flight oversized read.read(1000)returns 100, then[].read(40)thenread(1000)returns the remaining 60.Claim check
Searched open and recently updated PRs on
brianc/node-postgresanddyk1454683243-sudo/node-postgresfor#2949,cursor.readhang, androwCount. Issue #2949 is still open with no linked closer. No existing PR owns this fix.Verification
packages/pg-cursor: 49 passing (including the new cases)packages/pg-query-stream: 40 passingeslinton the changed files: clean