Re: jsonb_set() strictness considered harmful to data

From: Pavel Stehule <pavel(dot)stehule(at)gmail(dot)com>
To: Ariadne Conill <ariadne(at)dereferenced(dot)org>
Cc: Adrian Klaver <adrian(dot)klaver(at)aklaver(dot)com>, "David G(dot) Johnston" <david(dot)g(dot)johnston(at)gmail(dot)com>, Christoph Moench-Tegeder <cmt(at)burggraben(dot)net>, "pgsql-generallists(dot)postgresql(dot)org" <pgsql-general(at)lists(dot)postgresql(dot)org>, feld(at)freebsd(dot)org
Subject: Re: jsonb_set() strictness considered harmful to data
Date: 2019-10-19 04:17:39
Message-ID: CAFj8pRBeetjReCxvb+NkLoY_521J5wELjya12eisz6rnZi87nQ@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general pgsql-hackers

Hi

> What I am talking about is that jsonb_set(..., ..., NULL) returns SQL NULL.
>
> postgres=# \pset null '(null)'
> Null display is "(null)".
> postgres=# select jsonb_set('{"a":1,"b":2,"c":3}'::jsonb, '{a}', NULL);
> jsonb_set
> -----------
> (null)
> (1 row)
>
> This behaviour is basically giving an application developer a loaded
> shotgun and pointing it at their feet. It is not a good design. It
> is a design which has likely lead to many users experiencing
> unintentional data loss.
>

on second hand - PostgreSQL design is one possible that returns additional
information if value was changed or not.

Unfortunately It is very low probably so the design of this function will
be changed - just it is not a bug (although I fully agree, it has different
behave than has other databases and for some usages it is not practical).
Probably there will be some applications that needs NULL result in
situations when value was not changed or when input value has not expected
format. Design using in Postgres allows later customization - you can
implement with COALESCE very simply behave that you want (sure, you have to
know what you do). If Postgres implement design used by MySQL, then there
is not any possibility to react on situation when update is not processed.

Is not hard to implement second function with different name that has
behave that you need and you expect - although it is just

CREATE OR REPLACE FUNCTION jsonb_modify(jsonb, text[], jsonb)
RETURNS jsonb AS $$
SELECT jsonb_set($1, $2, COALESCE($3, "null"::jsonb), true);
$$ LANGUAGE sql;

It is important to understand so JSON NULL is not PostgreSQL NULL. In this
case is not problem in PostgreSQL design because it is consistent with
everything in PG, but in bad expectations. Unfortunately, there are lot of
wrong expectations, and these cannot be covered by Postgres design because
then Postgres will be very not consistent software. You can see - my
function jsonb_modify is what you are expect, and can works for you
perfectly, but from system perspective is not consistent, and very strong
not consistent. Users should not to learn where NULL has different behave
or where NULL is JSON__NULL. Buildin functions should be consistent in
Postgres. It is Postgres, not other databases.

Pavel

> Ariadne
>
>
>

In response to

Responses

Browse pgsql-general by date

  From Date Subject
Next Message David G. Johnston 2019-10-19 05:41:24 Re: jsonb_set() strictness considered harmful to data
Previous Message Ariadne Conill 2019-10-19 02:18:41 Re: jsonb_set() strictness considered harmful to data

Browse pgsql-hackers by date

  From Date Subject
Next Message tsunakawa.takay@fujitsu.com 2019-10-19 05:03:00 Fix of fake unlogged LSN initialization
Previous Message Andrew Gierth 2019-10-19 04:01:04 Re: Backport "WITH ... AS MATERIALIZED" syntax to <12?