Re: BUG #14849: jsonb_build_object doesn't like VARIADIC calls very much

From: Michael Paquier <michael(dot)paquier(at)gmail(dot)com>
To: Andrew Dunstan <andrew(dot)dunstan(at)2ndquadrant(dot)com>
Cc: Marko Tiikkaja <marko(at)joh(dot)to>, PostgreSQL mailing lists <pgsql-bugs(at)postgresql(dot)org>
Subject: Re: BUG #14849: jsonb_build_object doesn't like VARIADIC calls very much
Date: 2017-10-13 04:29:32
Message-ID: CAB7nPqTP9B_FLDGL=dPx5iGqKTJSENfvD=PoOy=zzC1AmmM55A@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs pgsql-hackers

On Thu, Oct 12, 2017 at 9:38 PM, Andrew Dunstan
<andrew(dot)dunstan(at)2ndquadrant(dot)com> wrote:
> If the case of an explicit VARIADIC parameter doesn't work the same way
> then certainly it's a bug which needs to be fixed, and for which I
> apologise. If you have time to produce a patch I will review it. Your
> plan sounds good.

Okay, thanks for your input.

Looking at fmgr.c, I found about get_fn_expr_variadic which is already
doing all the legwork to detect if a call is variadic or not. Also,
after looking at the code I think that using directly
jsonb_object(text[]) is incorrect. If the caller provides for example
int[] as input data, I think that we ought to allow the result to be
casted as a JSON integer. So I have implemented a patch that fills in
intermediate state data when dong a variadic call and feeds that to
the JSONB constructor.

An interesting side-effect of this patch is that:
=# SELECT jsonb_build_object(VARIADIC '{{1,4},{2,5},{3,6}}'::int[][]);
jsonb_build_object
--------------------------
{"1": 4, "2": 5, "3": 6}
(1 row)
This makes actually things more consistent with json_object(), which
generates the same result:
=# SELECT jsonb_object('{{1,4},{2,5},{3,6}}'::text[]);
jsonb_object
--------------------------------
{"1": "4", "2": "5", "3": "6"}
(1 row)
But jsonb_build_object complains for non-variadic calls:
=# SELECT jsonb_build_object('{1,2}'::int[],'{3,4}'::int[]);
ERROR: 22023: key value must be scalar, not array, composite, or json
LOCATION: datum_to_jsonb, jsonb.c:725
So I tend to think that the patch attached is correct, and that we
ought to not complain back to the user if NDIMS > 1 when doing
variadic calls.

More regression tests are added for json[b]_build_object and
json[b]_build_array to validate all that. When deconstructing the
variadic array, there are similarities between the json and jsonb code
but data type evaluate particularly for UNKNOWNOID is different
between both, so things are better not refactoring into a common
routine IMO. Each _array and _object code path also has slight
differences, and it felt more natural to me to not refactor json.c and
jsonb.c to hold a common routine.

In short, I have nailed things down with the attached patch. What do
you guys think?
--
Michael

Attachment Content-Type Size
json_variadic_v1.patch application/octet-stream 24.9 KB

In response to

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message KES 2017-10-13 08:13:43 Re: Fwd: [BUGS] BUG #14850: Implement optinal additinal parameter for 'justify' date/time function
Previous Message Tom Lane 2017-10-12 16:34:52 Re: Combination of ordered-set aggregate function terminates JDBC connection on PostgreSQL 9.6.5

Browse pgsql-hackers by date

  From Date Subject
Next Message Thomas Munro 2017-10-13 04:37:30 Re: Log LDAP "diagnostic messages"?
Previous Message Tom Lane 2017-10-13 03:22:30 Re: oversight in EphemeralNamedRelation support