JSON literals
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.