On 05/23/2015 04:03 PM, Petr Jelinek wrote:
> On 23/05/15 17:59, David E. Wheeler wrote:
>> On May 22, 2015, at 7:22 PM, Andrew Dunstan <andrew@dunslane.net> wrote:
>>
>>> The proposed flag for jsonb_set (the renamed jsonb_replace) in the
>>> patch I recently published is set to false, meaning that the default
>>> behaviour is to require all elements of the path including the last
>>> to be present. What that does is effectively UPDATE for jsonb. If
>>> the flag is true, then the last element can be absent, in which case
>>> it's created, so this is basically UPSERT for jsonb. The question is
>>> which should be the default. We got into the weeds on this with
>>> suggestions of throwing errors on missing paths, but that's going
>>> nowhere, and I want to get discussion back onto the topic of what
>>> should be the default.
>>
>> Here’s JavaScript in Chrome, FWIW:
>>
>> var f = {}
>> f["foo"][0] = “bar"
>> Uncaught TypeError: Cannot set property '0' of undefined
>> at <anonymous>:2:13
>> at Object.InjectedScript._evaluateOn (<anonymous>:895:140)
>> at Object.InjectedScript._evaluateAndWrap (<anonymous>:828:34)
>> at Object.InjectedScript.evaluate (<anonymous>:694:21)
>>
>
> As I understand it, that's not really the same as what Andrew says.
> The real example of that is
> > var f = {}
> > f["foo"] = “bar"
> > f
> { foo: 'bar' }
Yeah, more or less.
>
> which works fine in JavaScript and most other dynamic languages like
> Python or Perl. So my opinion is that default should be true here.
OK, although Perl at least will autovivify the whole path:
[andrew@emma ~]$ perl -e 'my %x; $x{foo}{bar}{baz} = 1; use Data::Dumper; print Dumper(\%x);' $VAR1 = {
'foo' => { 'bar' => { 'baz' => 1
} } };
But since, as David's example shows, JS doesn't do that we seem to be on
solid ground not doing it either.
>
> Another thing I noticed is that while following looks as expected:
> # select jsonb_set('{"baz":1}'::jsonb, '{foo}', '"bar"', true);
> jsonb_set
> --------------------------
> {"baz": 1, "foo": "bar"}
> (1 row)
>
> If I use empty jsonb object it does not work anymore:
> # select jsonb_set('{}', '{foo}', '"bar"', true);
> jsonb_set
> -----------
> {}
> (1 row)
>
>
Oh, that looks like a bug. Will check. Thanks.
cheers
andrew