Repository navigation
Close the connection when unnamed execute fails before BindComplete - #17
Merged
Merged
Conversation
PostgreSQL does not flush the replies to Parse, Describe and Bind until Execute finishes. A connection lost during a long unnamed statement therefore fails while reading them, and the EOFError escaped with the socket still open: isopen stayed true, reconnect never ran, and every later call failed with EOFError. Close the socket unless the exception is an Error, as readprepareddescription does. A server error still leaves the connection usable. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…o-failure CI: close-socket-on-unnamed-execute-io-failure
quinnj
reviewed
Sep 26, 2026
Member
There was a problem hiding this comment.
[Reviewed by AI] Reviewed b0d3993 against 3c4151e. No blocking findings. The new guard covers the missing ParseComplete/BindComplete failure paths while preserving connections after a fully drained server error.
I ran all 28 scripted-server checks on Julia 1.13 with two threads. Restoring the base exec_unnamed method made eight checks fail and two error; the ParameterDescription and recoverable-server-error controls still passed. I approved the waiting upstream CI run and monitored it to completion: all 16 checks are green at this head, including platform, PostgreSQL-version, authentication, documentation, and coverage checks.
quinnj
referenced
this pull request
Sep 28, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.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.
execute(conn, sql)andexecute(conn, sql, params)can leave a dead connection open. The unnamed statement path sends Parse, Describe, Bind, Execute and Sync together, then reads ParseComplete, the statement description and BindComplete. PostgreSQL does not flush those replies until Execute finishes, so a connection lost during a long statement (a network drop, a pooler or proxy restart) fails in these reads. TheEOFErrorescapes without closing the socket.isopenstaystrue,reconnect=truenever reconnects, and every later call on the connection fails withEOFError.This completes the rule from #2 for the unnamed path: an exception that escapes mid-response must either drain through ReadyForQuery or close the socket. The three reads now close the socket unless the exception is an
Error. That is the same conditionreadprepareddescriptionuses, since anErrormeans the stream is at ReadyForQuery or the socket is already closed. A server error, such as a syntax error, still leaves the connection usable. An interrupt during these reads now also closes the socket, as inwaitfor. The prepared statement path already behaved this way throughwaitfor. No public API or runtime dependency changes.Validation:
test/execute_fake_server.jlclose the connection before ParseComplete, before ParameterDescription and before BindComplete. They check that the socket is closed, that the next call reports the closed connection, and thatreconnect=truereconnects. A control checks that a server error before ParseComplete keeps the connection usable. With the previous method, the ParseComplete, BindComplete and reconnect cases fail. The ParameterDescription case and the server-error control pass either way.SELECT pg_sleep(2). The unnamed path, with and without parameters, leftisopen == trueand failed every later call, including withreconnect=true. The prepared path closed and reconnected.--threads=2on 1.12.7.🤖 Generated with Claude Code