Re: BUG #19735: `jsonb_object_agg_unique_strict` drops a JSONB `null` value as if it were SQL NULL - Mailing list pgsql-bugs

From Dmitry Dolgov
Subject Re: BUG #19735: `jsonb_object_agg_unique_strict` drops a JSONB `null` value as if it were SQL NULL
Date
Msg-id asYJhYbXXBPV_D5x@ddolgov-thinkpadt14sgen1.rmtde.csb
Whole thread
In response to Re: BUG #19735: `jsonb_object_agg_unique_strict` drops a JSONB `null` value as if it were SQL NULL  (shihao zhong <zhong950419@gmail.com>)
List pgsql-bugs
> On Sun, Oct 04, 2026 at 03:38:11PM -0400, shihao zhong wrote:
> 
> I can reproduce this on master. The same happens with all the
> skip_nulls paths, such as jsonb_object_agg_strict(), and JSON_OBJECT()
> and JSON_OBJECTAGG() using ABSENT ON NULL RETURNING jsonb. The jsonb
> array versions keep the value, jsonb_agg_strict('null'::jsonb) returns
> [null].
> 
> Is dropping JSON nulls here intended? I looked at the old threads
> where skip_nulls was discussed [1][2], they are only about SQL NULLs.
> The docs just say "null".

Hm, that's annoying. My gut feeling is that for jsonb it was intended to
skip JSON nulls -- the aggregation functions prepares a state first time
to use it on the subsequent rounds, and JsonbParseState.skip_nulls
inside it clearly refers to JSON nulls:

    bool        skip_nulls;        /* Skip null object fields */

It also makes sense from the user perspective, since applications that
use jsonb more often have to deal with JSON nulls rather than SQL NULLs.
So it's reasonable to have functionality to deal with a frequent case,
instead of requiring to call jsonb_typeof on every element.

Now, for json version it seems to be different, as it's state
JsonAggState does not have anything like that, and consequently refers
to the problem as "NULL values".

In the end we have two problems at hand:

* The aggregation functions documentation needs to be more clear which
  nulls are meant there. Currently it's JSON null and SQL NULL for jsonb
  functions, and SQL NULL for json functions.

* It would be great to unify the experience for both jsonb and json
  functions. Unfortunately it looks like independently from the decision
  (whether to make all functions skip JSON nulls and SQL NULLs or SQL
  NULLs only), the solution probably would not be pretty, as there will
  be need to categorize every incoming element. I'm inclined to make
  both sets of functions to skip both JSON null and SQL NULL.



pgsql-bugs by date:

Previous
From: Rahul
Date:
Subject: Re: BUG #19733: Row not visible to a new snapshot after its transactional logical decoding message has been streamed
Next
From: Zhijie Hou
Date:
Subject: Re: Streaming decoding fails with "unexpected table_index_fetch_tuple call during logical decoding" when a relation has a TOASTed conbin (follow-up to BUG #18641)