Skip to content

Fix: Do not mutate parameters when serializing in Bind - fixes multiple serialization on retry - #1198

Open
Ne7Le4DeR wants to merge 2 commits into
porsager:masterfrom
Ne7Le4DeR:fix/double-serialization-on-retry
Open

Fix: Do not mutate parameters when serializing in Bind - fixes multiple serialization on retry#1198
Ne7Le4DeR wants to merge 2 commits into
porsager:masterfrom
Ne7Le4DeR:fix/double-serialization-on-retry

Conversation

@Ne7Le4DeR

@Ne7Le4DeR Ne7Le4DeR commented Aug 21, 2026

Copy link
Copy Markdown

Fixes #1197

Bind stored each serialized value back into query.parameters, so when a prepared query was retried after a FetchPreparedStatement or RevalidateCachedQuery error, the already serialized values went through the serializers a second time: json/jsonb objects got stored as JSON strings, boolean true silently flipped to false, and bytea buffers were hex-encoded twice. See #1197 for the full mechanism and a standalone reproduction.

Serialize into a local variable instead and leave query.parameters untouched - the retry itself is unchanged and still transparent, it just binds the original values now.

  • The first commit adds six tests covering both retry routines and all three affected built-in serializers; each fails without the fix.
  • The second commit is the one-line fix.
  • The full test suite passes (ESM run against PostgreSQL 16).

When a prepared query is retried after a FetchPreparedStatement or
RevalidateCachedQuery error, Bind serializes the already serialized
parameters again, corrupting the data:

- json/jsonb values are JSON.stringify'd twice and get stored as strings
- boolean true flips to false ('t' === true is false, so 't' re-serializes to 'f')
- bytea buffers turn into the hex encoding of their previous hex string

The tests cover all three affected built-in serializers on both retry
paths and currently fail; the fix follows in the next commit.
Bind stored each serialized value back into query.parameters, so when a
prepared query was retried after a FetchPreparedStatement or
RevalidateCachedQuery error, the already serialized values went through
the serializers a second time. This corrupted every parameter whose
serializer is not idempotent: json/jsonb objects got stored as JSON
strings, boolean true silently flipped to false and bytea buffers were
hex-encoded twice. Serialize into a local variable instead and leave
query.parameters untouched.
@Ne7Le4DeR
Ne7Le4DeR force-pushed the fix/double-serialization-on-retry branch from 90f68d0 to 7f70f8c Compare August 21, 2026 18:37
@Ne7Le4DeR Ne7Le4DeR changed the title Do not mutate parameters when serializing in Bind - fixes double serialization on retry Fix: Do not mutate parameters when serializing in Bind - fixes double serialization on retry Aug 22, 2026
@Ne7Le4DeR Ne7Le4DeR changed the title Fix: Do not mutate parameters when serializing in Bind - fixes double serialization on retry Fix: Do not mutate parameters when serializing in Bind - fixes multiple serialization on retry Aug 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Parameters are serialized twice when a prepared query is retried - jsonb stored as string, boolean flips to false, bytea double-encoded (3.4.9)

1 participant