JSON_SERIALIZE for JSONB returns parts of the internal JSONB representation

From: Dirkjan Bussink <d(dot)bussink(at)gmail(dot)com>
To: pgsql-bugs(at)lists(dot)postgresql(dot)org
Subject: JSON_SERIALIZE for JSONB returns parts of the internal JSONB representation
Date: 2026-03-03 15:02:08
Message-ID: 03583FE7-A5EE-407C-907D-67865F3F8BFC@gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

Hi,

When running a query like this (tested against PostgreSQL 18.3), it shows internals from the JSONB storage:

postgres=# select JSON_SERIALIZE('[1,2,4]'::jsonb);
json_serialize
----------------
\x03
(1 row)

I think this qualifies as a bug? I would expect JSON_SERIALIZE to either work with JSONB and here output the serialized text, so '[1,2,4]', or to error that JSONB is not supported for this function (or that this function can’t even be found for a JSONB argument).

What happens here is that json_out treats the internal bytes from the JSONB representation as a C string.

From src/include/utils/jsonb.h:

* ... For that purpose, both an array and an object begin with a uint32
* header field, which contains an JB_FOBJECT or JB_FARRAY flag.

This is part of the header:

typedef struct JsonbContainer
{
uint32 header; /* number of elements or key/value pairs, and
* flags */
JEntry children[FLEXIBLE_ARRAY_MEMBER];

/* the data for each child node follows. */
} JsonbContainer;

The rest of the header contains the number of elements, in this case a JSON array of 3 elements. So the total header looks like

uint32(JB_FARRAY | 3) == 0x40000003

So this also explains the \x03 output above. What is seen there is the first byte of the header there as little endian, since that is interpreted as a C string with the a 0 byte that happens to be after there.

--
Cheers,

Dirkjan

Browse pgsql-bugs by date

  From Date Subject
Next Message PG Bug reporting form 2026-03-03 19:23:01 BUG #19424: Concurrent PQconnectdb() calls hang on Windows
Previous Message Richard Guo 2026-03-03 14:32:12 Re: BUG #19418: SQL/JSON JSON_VALUE() does not conform to ISO/IEC 9075-2:2023(E) 6.34 <JSON value constructor>