I wrote:
> Surely #> with a K-element path ought to act the same as K invocations
> of the -> operator ... and zero invocations would result in just having
> the original input object, no?
Poking at that some more ...
regression=# select '{"a": {"b":{"c": "foo"}}}'::json #> '{a}';
?column?
--------------------
{"b":{"c": "foo"}}
(1 row)
regression=# select '{"a": {"b":{"c": "foo"}}}'::json #> '{a,b}';
?column?
--------------
{"c": "foo"}
(1 row)
regression=# select '{"a": {"b":{"c": "foo"}}}'::json #> '{a,b,c}';
?column?
----------
"foo"
(1 row)
regression=# select '{"a": {"b":{"c": "foo"}}}'::json #> '{a,b,c,d}';
?column?
----------
(1 row)
That comports with successive applications of -> up to the last step,
where you'd get an error instead of NULL:
regression=# select '"foo"'::json -> 'd';
ERROR: cannot extract element from a scalar
Is there a reason for these to behave inconsistently, and if not, which
behavior should we standardize on? Considering that you get NULL not an
error for extracting a nonexistent element from an object, I think there
is some case to be made for saying that returning NULL is the more
convenient behavior. Of course one can also argue for wanting this
operator to throw errors if the JSON structure doesn't match the
operation, but it seems like we've chosen to prefer being lax.
regards, tom lane