</synopsis>
Primitive JSON values are compared using the same
comparison rules as for the underlying
<productname>PostgreSQL</productname> data type. Strings are
compared using the default database collation.
</para>
</sect2>
<sect2 id="jsonb-subscripting">
<title><type>jsonb</type> Subscripting</title>
<para>
The <type>jsonb</type> data type supports array-style subscripting expressions
to extract and modify elements. Nested values can be indicated by chaining
subscripting expressions, following the same rules as the <literal>path</literal>
argument in the <literal>jsonb_set</literal> function. If a <type>jsonb</type>
value is an array, numeric subscripts start at zero, and negative integers count
backwards from the last element of the array. Slice expressions are not supported.
The result of a subscripting expression is always of the jsonb data type.
</para>
<para>
<command>UPDATE</command> statements may use subscripting in the
<literal>SET</literal> clause to modify <type>jsonb</type> values. Subscript
paths must be traversable for all affected values insofar as they exist. For
instance, the path <literal>val['a']['b']['c']</literal> can be traversed all
the way to <literal>c</literal> if every <literal>val</literal>,
<literal>val['a']</literal>, and <literal>val['a']['b']</literal> is an
object. If any <literal>val['a']</literal> or <literal>val['a']['b']</literal>
is not defined, it will be created as an empty object and filled as
necessary. However, if any <literal>val</literal> itself or one of the
intermediary values is defined as a non-object such as a string, number, or
<literal>jsonb</literal> <literal>null</literal>, traversal cannot proceed so
an error is raised and the transaction aborted.
</para>
<para>
An example of subscripting syntax:
<programlisting>
-- Extract object value by key
SELECT ('{"a": 1}'::jsonb)['a'];
-- Extract nested object value by key path
SELECT ('{"a": {"b": {"c": 1}}}'::jsonb)['a']['b']['c'];
-- Extract array element by index
SELECT ('[1, "2", null]'::jsonb)[1];
-- Update object value by key. Note the quotes around '1': the assigned
-- value must be of the jsonb type as well
UPDATE table_name SET jsonb_field['key'] = '1';
-- This will raise an error if any record's jsonb_field['a']['b'] is something
-- other than an object. For example, the value {"a": 1} has a numeric value
-- of the key 'a'.
UPDATE table_name SET jsonb_field['a']['b']['c'] = '1';
-- Filter records using a WHERE clause with subscripting. Since the result of
-- subscripting is jsonb, the value we compare it against must also be jsonb.
-- The double quotes make "value" also a valid jsonb string.
SELECT * FROM table_name WHERE jsonb_field['key'] = '"value"';
</programlisting>
<type>jsonb</type> assignment via subscripting handles a few edge cases
differently from <literal>jsonb_set</literal>. When a source <type>jsonb</type>
value is <literal>NULL</literal>, assignment via subscripting will proceed
as if it was an empty JSON value of the type (object or array) implied by the
subscript key:
<programlisting>
-- Where jsonb_field was NULL, it is now {"a": 1}
UPDATE table_name SET jsonb_field['a'] = '1';
-- Where jsonb_field was NULL, it is now [1]
UPDATE table_name SET jsonb_field[0] = '1';
</programlisting>
If an index is specified for an array containing too few elements,
<literal>NULL</literal> elements will be appended until the index is reachable
and the value can be set.
<programlisting>
-- Where jsonb_field was [], it is now [null, null, 2];
-- where jsonb_field was [0], it is now [0, null, 2]
UPDATE table_name SET jsonb_field[2] = '2';
</programlisting>
A <type>jsonb</type> value will accept assignments to nonexistent subscript
paths as long as the last existing element to be traversed is an object or
array, as implied by the corresponding subscript (the element indicated