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