[PATCH] Fix JSON_SERIALIZE() coercion placeholder type for jsonb input

From: Matt Blewitt <mble(at)planetscale(dot)com>
To: pgsql-hackers(at)lists(dot)postgresql(dot)org
Subject: [PATCH] Fix JSON_SERIALIZE() coercion placeholder type for jsonb input
Date: 2026-03-13 11:02:01
Message-ID: CACy-Nv0UaChW+mNd2-iDnsKbuhohymcKtC+xoo-rV1OcCvnK6g@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi folks,

Related to:
https://www.postgresql.org/message-id/03583FE7-A5EE-407C-907D-67865F3F8BFC%40gmail.com

When JSON_SERIALIZE() receives a jsonb-typed argument, the CaseTestExpr
placeholder used to set up coercion was unconditionally assigned JSONOID
(derived from the RETURNING format, which defaults to JS_FORMAT_JSON).
However, the executor passes the input argument value through directly
for JSON_SERIALIZE (see ExecInitExprRec in execExpr.c), so the actual
datum at runtime is jsonb, not json. This type mismatch between the
placeholder and the runtime value caused the wrong coercion path to be
selected.

As Dirkjan mentioned, this results in confusing output.

Attached is a patch to address this, by deriving the placeholder type from
the
actual argument type via exprType(linitial(args)) when the constructor type
is
JSCTOR_JSON_SERIALIZE, rather than from returning->format->format_type.

Added a regression test to ensure JSONB is serialized correctly.

Cheers,

Matt

Attachment Content-Type Size
0001-Fix-JSON_SERIALIZE-coercion-placeholder-type-for-jso.patch application/octet-stream 6.0 KB

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Tomas Vondra 2026-03-13 11:12:25 Re: gistGetFakeLSN() can return incorrect LSNs
Previous Message Aleksander Alekseev 2026-03-13 10:55:44 Re: Define DatumGetInt8 function.