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

From: Narayanan Venkateswaran <narayananvpostgres(at)gmail(dot)com>
To: theshallow27(at)gmail(dot)com, pgsql-bugs(at)lists(dot)postgresql(dot)org
Cc: 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-14 13:35:50
Message-ID: CAFjuD9dSjMS-spFpx1HqX3ufoyZcTF-cup8=+08-avu6Db2+=Q@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

Hi,

On Tue, Oct 6, 2026 at 11:32 AM Narayanan Venkateswaran
<narayananvpostgres(at)gmail(dot)com> wrote:
>
> Hi,
>
> On Sun, Oct 4, 2026 at 2:46 AM PG Bug reporting form
> <noreply(at)postgresql(dot)org> wrote:
> >
> > The following bug has been logged on the website:
> >
> > Bug reference: 19737
> > Logged by: Shallow
> > Email address: theshallow27(at)gmail(dot)com
> > PostgreSQL version: 18.6
> > Operating system: Linux
> > Description:
> >
> > The documented syntax makes the key/value pair list optional and says that
> > an
> > empty pair list constructs an empty object. However, adding any of the
> > optional
> > clauses without a pair causes a syntax error.
> >
> > **Reproduction:**
> >
> > ```sql
> > SELECT JSON_OBJECT(); -- returns {}
> > SELECT JSON_OBJECT(NULL ON NULL); -- syntax error, SQLSTATE 42601
> > SELECT JSON_OBJECT(ABSENT ON NULL); -- syntax error, SQLSTATE 42601
> > SELECT JSON_OBJECT(WITH UNIQUE KEYS); -- syntax error, SQLSTATE 42601
> > ```
>
> I am able to reproduce this issue on master
>
> postgres=# SELECT JSON_OBJECT();
> json_object
> -------------
> {}
> (1 row)
>
> postgres=# SELECT JSON_OBJECT(RETURNING jsonb);
> json_object
> -------------
> {}
> (1 row)
>
> postgres=# SELECT JSON_OBJECT(NULL ON NULL);
> ERROR: syntax error at or near "ON"
> LINE 1: SELECT JSON_OBJECT(NULL ON NULL);
> ^
> postgres=# SELECT JSON_OBJECT(ABSENT ON NULL);
> ERROR: syntax error at or near "ON"
> LINE 1: SELECT JSON_OBJECT(ABSENT ON NULL);
> ^
> postgres=# SELECT JSON_OBJECT(WITH UNIQUE KEYS);
> ERROR: syntax error at or near "WITH"
> LINE 1: SELECT JSON_OBJECT(WITH UNIQUE KEYS);
> ^
> postgres=# SELECT JSON_OBJECT(ABSENT ON NULL WITH UNIQUE KEYS RETURNING jsonb);
> ERROR: syntax error at or near "ON"
> LINE 1: SELECT JSON_OBJECT(ABSENT ON NULL WITH UNIQUE KEYS RETURNING...
>
> >
> > **Expected result:** Each form with an empty pair list should construct
> > `{}`;
>
> From the Documentation
> (https://www.postgresql.org/docs/current/functions-json.html) this is
> the correct expected result
>
> 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 ] ] ])
>
> Constructs a JSON object of all the key/value pairs given, or an empty
> object if none are given.
>
> > the clauses do not change the result when there are no pairs.
> >
> >
> >
> >
>
> NOTE:
>
> The problems seems to occur only when there are no key value pairs,

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.

Thank you,
Narayanan

> Thank you,
> Narayanan

Attachment Content-Type Size
v1-0001-Allow-NULL-and-UNIQUE-clauses-in-empty-JSON_OBJEC.patch application/octet-stream 5.8 KB

In response to

Browse pgsql-bugs by date

  From Date Subject
Next Message PG Bug reporting form 2026-10-14 14:04:55 BUG #19757: attname in pg_attribute not strictly updated when renaming a column
Previous Message Ayush Tiwari 2026-10-14 12:22:03 Re: BUG #19597: getQuadrant: impossible case is reachable