JSON literals
This page documents the preview version (v2.23). Preview includes features under active development and is for development and testing only. For production, use the stable version (v2024.1). To learn more, see Versioning.
This section shows that the literal for both a jsonb value and a json value, as these are used both in SQL statements and in PL/pgSQL code, is the enquoted and appropriately typecast RFC 7159-compliant text value that represents the JSON value.
The mutual relationship between a JSON value and its ::text typecast is an instance of the general rule that governs the mutual relationship between a value of any data type and its ::text typecast. This general rule is explained in the section The text typecast of a value, the literal for that value, and how they are related.
This DO block follows, for jsonb, the same pattern that is used in that section for a variety of different data types. See also the section ::jsonb and ::json and ::text (typecast).
create type t as (f1 int, f2 text, f3 boolean, f4 text[]);
do $body$
declare
v1 constant int := 42;
v2 constant text := 'a';
v3 constant boolean := true;
v4 constant text[] := array['x', 'y', 'z'];
v5 constant t := (v1, v2, v3, v4);
original constant jsonb not null := to_jsonb(v5);
text_cast constant text not null := original::text;
recreated constant jsonb not null := text_cast::jsonb;
begin
assert
(recreated = original),
'assert failed';
raise info 'jsonb: %', text_cast;
end;
$body$;
See the account of the to_jsonb() function. The DO block produces this output (after manually stripping the "INFO:" prompt):
jsonb: {"f1": 42, "f2": "a", "f3": true, "f4": ["x", "y", "z"]}
It shows that the "non-lossy round trip rule" holds here too:
jsonbvalue to text typecast and back tojsonbvalue
And it shows that the ::text typecast of a jsonb value that has been constructed bottom-up from SQL values conforms to RFC 7159.
The next block follows the same pattern for json. However, the ASSERT must be written differently because the = operator has no overload for json.
do $body$
declare
v1 constant int := 42;
v2 constant text := 'a';
v3 constant boolean := true;
v4 constant text[] := array['x', 'y', 'z'];
v5 constant t := (v1, v2, v3, v4);
original constant json not null := to_json(v5)::jsonb;
text_cast constant text not null := original::text;
recreated constant json not null := text_cast::json;
begin
assert
(recreated::jsonb = original::jsonb),
'assert failed';
raise info 'json: %', text_cast;
end;
$body$;
The output is the same as the DO block for jsonb produces. It shows that the same "non-lossy round trip" rule holds for a json value too.
Recall (see the Synopsis section) that a json value is stored as a text value, annotated with the fact of what the data type is, and that whitespace in such a value is semantically insignificant. (The jsonb data type stores a parsed representation of the document hierarchy of subvalues in an appropriate internal format.) This has no effect on the reliability of the "non-lossy round trip" rule. However, it means that a round trip json value to jsonb value to json value might be lossy because, unless the json value happens to use whitespace just as the ::text typecast of a jsonb value does, the recreated json value will have different whitespace from the original json value.