@@ -614,8 +614,24 @@ SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc @> '{"tags": ["qu
614
614
The result of a subscripting expression is always of the jsonb data type.
615
615
</para>
616
616
617
+ <para>
618
+ <command>UPDATE</command> statements may use subscripting in the
619
+ <literal>SET</literal> clause to modify <type>jsonb</type> values. Subscript
620
+ paths must be traversible for all affected values insofar as they exist. For
621
+ instance, the path <literal>val['a']['b']['c']</literal> can be traversed all
622
+ the way to <literal>c</literal> if every <literal>val</literal>,
623
+ <literal>val['a']</literal>, and <literal>val['a']['b']</literal> is an
624
+ object. If any <literal>val['a']</literal> or <literal>val['a']['b']</literal>
625
+ is not defined, it will be created as an empty object and filled as
626
+ necessary. However, if any <literal>val</literal> itself or one of the
627
+ intermediary values is defined as a non-object such as a string, number, or
628
+ <literal>jsonb</literal> <literal>null</literal>, traversal cannot proceed so
629
+ an error is raised and the transaction aborted.
630
+ </para>
631
+
617
632
<para>
618
633
An example of subscripting syntax:
634
+
619
635
<programlisting>
620
636
621
637
-- Extract object value by key
@@ -631,6 +647,10 @@ SELECT ('[1, "2", null]'::jsonb)[1];
631
647
-- value must be of the jsonb type as well
632
648
UPDATE table_name SET jsonb_field['key'] = '1';
633
649
650
+ -- This will raise an error if any record's jsonb_field['a']['b'] is something
651
+ -- other than an object. For example, the value {"a": 1} has no 'b' key.
652
+ UPDATE table_name SET jsonb_field['a']['b']['c'] = '1';
653
+
634
654
-- Filter records using a WHERE clause with subscripting. Since the result of
635
655
-- subscripting is jsonb, the value we compare it against must also be jsonb.
636
656
-- The double quotes make "value" also a valid jsonb string.
@@ -639,8 +659,9 @@ SELECT * FROM table_name WHERE jsonb_field['key'] = '"value"';
639
659
640
660
<type>jsonb</type> assignment via subscripting handles a few edge cases
641
661
differently from <literal>jsonb_set</literal>. When a source <type>jsonb</type>
642
- is <literal>NULL</literal>, assignment via subscripting will proceed as if
643
- it was an empty JSON object:
662
+ value is <literal>NULL</literal>, assignment via subscripting will proceed
663
+ as if it was an empty JSON value of the type (object or array) implied by the
664
+ subscript key:
644
665
645
666
<programlisting>
646
667
-- Where jsonb_field was NULL, it is now {"a": 1}
@@ -661,17 +682,19 @@ UPDATE table_name SET jsonb_field[2] = '2';
661
682
</programlisting>
662
683
663
684
A <type>jsonb</type> value will accept assignments to nonexistent subscript
664
- paths as long as the last existing path key is an object or an array. Since
665
- the final subscript is not traversed, it may be an object key. Nested arrays
666
- will be created and <literal>NULL</literal>-padded according to the path until
667
- the value can be placed appropriately.
685
+ paths as long as the last existing element to be traversed is an object or
686
+ array, as implied by the corresponding subscript (the element indicated by
687
+ the last subscript in the path is not traversed and may be anything). Nested
688
+ array and object structures will be created, and in the former case
689
+ <literal>null</literal>-padded, as specified by the subscript path until the
690
+ assigned value can be placed.
668
691
669
692
<programlisting>
670
693
-- Where jsonb_field was {}, it is now {'a': [{'b': 1}]}
671
694
UPDATE table_name SET jsonb_field['a'][0]['b'] = '1';
672
695
673
- -- Where jsonb_field was [], it is now [{'a': 1}]
674
- UPDATE table_name SET jsonb_field[0 ]['a'] = '1';
696
+ -- Where jsonb_field was [], it is now [null, {'a': 1}]
697
+ UPDATE table_name SET jsonb_field[1 ]['a'] = '1';
675
698
</programlisting>
676
699
677
700
</para>
0 commit comments