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

From Narayanan Venkateswaran
Subject Re: BUG #19737: Empty `JSON_OBJECT` cannot use documented `ON NULL` or unique-key clauses
Date
Msg-id CAFjuD9ehcFRN4M1QkJDQq0Asr8v+8dVWcGPc5Z7ENEpy-iA5fg@mail.gmail.com
Whole thread
In response to BUG #19737: Empty `JSON_OBJECT` cannot use documented `ON NULL` or unique-key clauses  (PG Bug reporting form <noreply@postgresql.org>)
List pgsql-bugs
Hi,

On Sun, Oct 4, 2026 at 2:46 AM PG Bug reporting form
<noreply@postgresql.org> wrote:
>
> The following bug has been logged on the website:
>
> Bug reference:      19737
> Logged by:          Shallow
> Email address:      theshallow27@gmail.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,
the following works,

CASE 1: Standard with values

postgres=# SELECT JSON_OBJECT('id': 007, 'name': 'VN');
        json_object
---------------------------
 {"id" : 7, "name" : "VN"}
(1 row)

CASE 2: NULL ON NULL

postgres=# SELECT JSON_OBJECT('a': 1, 'b': NULL NULL ON NULL);
      json_object
-----------------------
 {"a" : 1, "b" : null}
(1 row)

CASE 3 : ABSENT ON NULL

postgres=# SELECT JSON_OBJECT('a': 1, 'b': NULL ABSENT ON NULL);
 json_object
-------------
 {"a" : 1}
(1 row)

postgres=# SELECT JSON_OBJECT('id': 10, 'email': NULL, 'active': true
ABSENT ON NULL);
         json_object
------------------------------
 {"id" : 10, "active" : true}
(1 row)

CASE 4 : WITH AND WITHOUT UNIQUE KEYS

postgres=# SELECT JSON_OBJECT('k': 1, 'k': 2 WITHOUT UNIQUE KEYS);
    json_object
--------------------
 {"k" : 1, "k" : 2}
(1 row)

postgres=# SELECT JSON_OBJECT('k': 1, 'k': 2 WITH UNIQUE KEYS);
ERROR:  duplicate JSON object key value: "k"
postgres=# SELECT JSON_OBJECT('k1': 1, 'k2': 2 WITH UNIQUE KEYS);
     json_object
----------------------
 {"k1" : 1, "k2" : 2}
(1 row)

CASE 5 : Returning Objects

postgres=# SELECT pg_typeof(JSON_OBJECT('a': 1 RETURNING jsonb));
 pg_typeof
-----------
 jsonb
(1 row)

postgres=# SELECT pg_typeof(JSON_OBJECT('a': 1 RETURNING text));
 pg_typeof
-----------
 text
(1 row)

Thank you,
Narayanan



pgsql-bugs by date:

Previous
From: Fujii Masao
Date:
Subject: Re: 42P16 error when dropping and adding column
Next
From: "Hayato Kuroda (Fujitsu)"
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)