{{ message }}
fix(postgres): key the type parser cache by wire format - #18330
Open
WikiRik wants to merge 3 commits into
Open
Conversation
Contributor
5 tasks
WikiRik
force-pushed
the
WikiRik/postgres-type-parser-format
branch
from
September 3, 2026 12:47
fe7406f to
582b0e6
Compare
5 tasks
WikiRik
force-pushed
the
WikiRik/postgres-type-parser-format
branch
from
September 3, 2026 13:13
582b0e6 to
c5b5444
Compare
WikiRik
force-pushed
the
WikiRik/postgres-type-parser-format
branch
from
September 3, 2026 16:33
c5b5444 to
3aa3583
Compare
WikiRik
force-pushed
the
WikiRik/postgres-type-parser-format
branch
from
September 3, 2026 17:53
3aa3583 to
b64187d
Compare
`getTypeParser` cached a parser under its OID alone, but pg asks for a parser per OID *and* wire format. Whichever format was requested first therefore won for both: once a text parser was cached, a later binary request for the same OID got that text parser, and vice versa. The dialect's parsers all take a string, so handing one to the binary protocol means it is called with a Buffer. Key the cache by format and OID, and only consult the dialect's parsers for the text format, letting pg's own parsers serve the binary format. The element parsers of arrays and ranges had the same problem from the other direction: the requested format was forwarded to them, so a binary request built an array parser around pg's binary element parser, even though `postgres-array` only ever hands the element parser a string. They are text parsers now, which is the only thing they can be. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EgPPfqYYk6PFGbanp5mAFh
WikiRik
force-pushed
the
WikiRik/postgres-type-parser-format
branch
from
September 3, 2026 20:14
b64187d to
73d2a84
Compare
WikiRik
commented
Sep 3, 2026
Co-authored-by: Rik Smale <13023439+WikiRik@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.

Pull Request Checklist
Description of Changes
Stacked on #18329.
The bug
getTypeParsercached a parser under its OID alone:But
pgasks for a parser per OID and wire format. Whichever format was requested first therefore won for both: once a text parser was cached for an OID, a laterbinaryrequest for the same OID got that text parser back, and vice versa.This matters because the dialect's parsers all take a
string. Handing one to the binary protocol means it gets called with aBuffer.The fix
Key the cache by format and OID, and only consult the dialect's custom parsers for the text format — letting
pg's own parsers serve the binary format:#getCustomTypeParsernow only ever runs for the text format, so it no longer takes aformatparameter.The same bug, from the other direction
The element parsers of arrays and ranges had the mirror-image problem: the requested format was forwarded to them, so a binary request built an array parser wrapped around pg's binary element parser — even though
postgres-arrayonly ever hands the element parser astring. They are text parsers now, which is the only thing they can be.Tests
packages/postgres/src/connection-manager.test.tscovers the cache. The two format-crossover cases are genuine regression tests — verified failing against the parent branch and passing here:40 postgres unit tests passing.
🤖 Generated with Claude Code
https://claude.ai/code/session_01EgPPfqYYk6PFGbanp5mAFh