Re: BUG #19737: Empty `JSON_OBJECT` cannot use documented `ON NULL` or unique-key clauses

From: Narayanan Venkateswaran <narayananvpostgres(at)gmail(dot)com>
To: Nitin Motiani <nitinmotiani(at)google(dot)com>
Cc: theshallow27(at)gmail(dot)com, pgsql-bugs(at)lists(dot)postgresql(dot)org, Dilip Kumar <dilipbalaut(at)gmail(dot)com>
Subject: Re: BUG #19737: Empty `JSON_OBJECT` cannot use documented `ON NULL` or unique-key clauses
Date: 2026-10-19 11:33:18
Message-ID: CAFjuD9dkiT=8yJb251PvShtG3TKWhw9rettm-_Zt9mqf16dmLA@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

Hi Nitin,

Thank you very much for the review!

On Sun, Oct 18, 2026 at 11:45 AM Nitin Motiani <nitinmotiani(at)google(dot)com> wrote:
>
> On Wed, Oct 14, 2026 at 7:06 PM Narayanan Venkateswaran
> <narayananvpostgres(at)gmail(dot)com> wrote:
> >
> >
> > Currently, calling JSON_OBJECT() without key-value arguments fails
> > with a syntax error
> > if modifier clauses like ABSENT ON NULL or WITH UNIQUE KEYS are specified. This
> > happens because the grammar rule in gram.y handling modifier clauses
> > unconditionally
> > required key-value pairs.
> >
> > The attached patch adds conflict-free productions in gram.y to allow empty
> > JSON_OBJECT() calls with NULL, UNIQUE, and RETURNING clauses.
> > Regression tests have also been added to sqljson.sql covering all clause
> > combinations for empty objects.
> >
>
> Thanks for the patch. It seems to work fine. I think it would be good
> to make the same change for JSON_ARRAY.

Thank you for pointing this out, I will look into JSON_ARRAY and
submit a follow up.

That said, please find some replies inline,

>
> One question: The commit message has this line
>
> > The SQL standard permits calling JSON_OBJECT() with no key-value pairs
> > to construct an empty JSON object while still specifying modifier
> > clauses such as NULL-handling (NULL ON NULL / ABSENT ON NULL), key
> > uniqueness constraints (WITH / WITHOUT UNIQUE KEYS), and the output type
> > (RETURNING ...).

>
> Is there any reference for this?

You are right, I checked this link -
https://github.com/ronsavage/SQL/blob/19215adc8639d031a44acad7873c209444b71f1f/sql-2016.ebnf#L2266-L2272

JSON_object_constructor ::=
JSON_OBJECT left_paren
( JSON_name_and_value ( comma JSON_name_and_value )*
JSON_constructor_null_clause?
JSON_key_uniqueness_constraint? )?
JSON_output_clause?
right_paren

JSON_constructor_null_clause? and JSON_key_uniqueness_constraint? are
nested inside the outer ( ... )?
that begins with a required JSON_name_and_value. This implies that
JSON_name_and_value is not optional.

However, this is different from the postgres documentation,

https://www.postgresql.org/docs/devel/functions-json.html#FUNCTIONS-JSON-CREATION-TABLE

json_object ( [ { key_expression { VALUE | ':' } value_expression [
FORMAT JSON [ ENCODING UTF8 ] ] }[, ...] ]
[ { NULL | ABSENT } ON NULL ]
[ { WITH | WITHOUT } UNIQUE [ KEYS ] ]
[ RETURNING data_type [ FORMAT JSON [ ENCODING UTF8 ] ] ])

This treats the key:value as different from the ON NULL and UNIQUE
optional clauses

> I searched for this using an LLM and
> found that the standard doesn't specify it but Oracle etc implement it
> this way.

I will investigate JSON_ARRAY from the perspective of the postgre
documentation and revert back.

>
> Thanks & Regards
> Nitin Motiani,
> Google

Thank you,
Narayanan

In response to

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message George MacKerron 2026-10-19 11:34:41 Re: Inconsistency in psql output with \d+x PATTERN
Previous Message Nitin Motiani 2026-10-19 11:29:58 Re: BUG #19767: pg_get_viewdef prints ORDER BY (- '3'::int4) as (- 3), which reparses as column position -3