]> granicus.if.org Git - postgresql/commitdiff
Process variadic arguments consistently in json functions
authorAndrew Dunstan <andrew@dunslane.net>
Wed, 25 Oct 2017 11:34:00 +0000 (07:34 -0400)
committerAndrew Dunstan <andrew@dunslane.net>
Wed, 25 Oct 2017 11:49:13 +0000 (07:49 -0400)
json_build_object and json_build_array and the jsonb equivalents did not
correctly process explicit VARIADIC arguments. They are modified to use
the new extract_variadic_args() utility function which abstracts away
the details of the call method.

Michael Paquier, reviewed by Tom Lane and Dmitry Dolgov.

Backpatch to 9.5 for the jsonb fixes and 9.4 for the json fixes, as
that's where they originated.

src/backend/utils/adt/json.c
src/backend/utils/adt/jsonb.c
src/test/regress/expected/json.out
src/test/regress/expected/jsonb.out
src/test/regress/sql/json.sql
src/test/regress/sql/jsonb.sql

index eafca14be4d7af276a8a3dd05b987774233a7cf4..a25e7058f74b82f795da4e33a2d69d090a072694 100644 (file)
@@ -17,6 +17,7 @@
 #include "access/transam.h"
 #include "catalog/pg_type.h"
 #include "executor/spi.h"
+#include "funcapi.h"
 #include "lib/stringinfo.h"
 #include "libpq/pqformat.h"
 #include "mb/pg_wchar.h"
@@ -2106,10 +2107,17 @@ json_build_object(PG_FUNCTION_ARGS)
 {
        int                     nargs = PG_NARGS();
        int                     i;
-       Datum           arg;
        const char *sep = "";
        StringInfo      result;
-       Oid                     val_type;
+       Datum      *args;
+       bool       *nulls;
+       Oid                *types;
+
+       /* fetch argument values to build the object */
+       nargs = extract_variadic_args(fcinfo, 0, false, &args, &types, &nulls);
+
+       if (nargs < 0)
+               PG_RETURN_NULL();
 
        if (nargs % 2 != 0)
                ereport(ERROR,
@@ -2123,52 +2131,22 @@ json_build_object(PG_FUNCTION_ARGS)
 
        for (i = 0; i < nargs; i += 2)
        {
-               /*
-                * Note: since json_build_object() is declared as taking type "any",
-                * the parser will not do any type conversion on unknown-type literals
-                * (that is, undecorated strings or NULLs).  Such values will arrive
-                * here as type UNKNOWN, which fortunately does not matter to us,
-                * since unknownout() works fine.
-                */
                appendStringInfoString(result, sep);
                sep = ", ";
 
                /* process key */
-               val_type = get_fn_expr_argtype(fcinfo->flinfo, i);
-
-               if (val_type == InvalidOid)
-                       ereport(ERROR,
-                                       (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-                                        errmsg("could not determine data type for argument %d",
-                                                       i + 1)));
-
-               if (PG_ARGISNULL(i))
+               if (nulls[i])
                        ereport(ERROR,
                                        (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                                         errmsg("argument %d cannot be null", i + 1),
                                         errhint("Object keys should be text.")));
 
-               arg = PG_GETARG_DATUM(i);
-
-               add_json(arg, false, result, val_type, true);
+               add_json(args[i], false, result, types[i], true);
 
                appendStringInfoString(result, " : ");
 
                /* process value */
-               val_type = get_fn_expr_argtype(fcinfo->flinfo, i + 1);
-
-               if (val_type == InvalidOid)
-                       ereport(ERROR,
-                                       (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-                                        errmsg("could not determine data type for argument %d",
-                                                       i + 2)));
-
-               if (PG_ARGISNULL(i + 1))
-                       arg = (Datum) 0;
-               else
-                       arg = PG_GETARG_DATUM(i + 1);
-
-               add_json(arg, PG_ARGISNULL(i + 1), result, val_type, false);
+               add_json(args[i + 1], nulls[i + 1], result, types[i + 1], false);
        }
 
        appendStringInfoChar(result, '}');
@@ -2191,12 +2169,19 @@ json_build_object_noargs(PG_FUNCTION_ARGS)
 Datum
 json_build_array(PG_FUNCTION_ARGS)
 {
-       int                     nargs = PG_NARGS();
+       int                     nargs;
        int                     i;
-       Datum           arg;
        const char *sep = "";
        StringInfo      result;
-       Oid                     val_type;
+       Datum      *args;
+       bool       *nulls;
+       Oid                *types;
+
+       /* fetch argument values to build the array */
+       nargs = extract_variadic_args(fcinfo, 0, false, &args, &types, &nulls);
+
+       if (nargs < 0)
+               PG_RETURN_NULL();
 
        result = makeStringInfo();
 
@@ -2204,30 +2189,9 @@ json_build_array(PG_FUNCTION_ARGS)
 
        for (i = 0; i < nargs; i++)
        {
-               /*
-                * Note: since json_build_array() is declared as taking type "any",
-                * the parser will not do any type conversion on unknown-type literals
-                * (that is, undecorated strings or NULLs).  Such values will arrive
-                * here as type UNKNOWN, which fortunately does not matter to us,
-                * since unknownout() works fine.
-                */
                appendStringInfoString(result, sep);
                sep = ", ";
-
-               val_type = get_fn_expr_argtype(fcinfo->flinfo, i);
-
-               if (val_type == InvalidOid)
-                       ereport(ERROR,
-                                       (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-                                        errmsg("could not determine data type for argument %d",
-                                                       i + 1)));
-
-               if (PG_ARGISNULL(i))
-                       arg = (Datum) 0;
-               else
-                       arg = PG_GETARG_DATUM(i);
-
-               add_json(arg, PG_ARGISNULL(i), result, val_type, false);
+               add_json(args[i], nulls[i], result, types[i], false);
        }
 
        appendStringInfoChar(result, ']');
index a39d084ce8f9ec6ab16130fae5d0d94eb7bb7f73..70ee928e58de9c3de534c476b4adafa39e7d092e 100644 (file)
@@ -16,6 +16,7 @@
 #include "access/htup_details.h"
 #include "access/transam.h"
 #include "catalog/pg_type.h"
+#include "funcapi.h"
 #include "libpq/pqformat.h"
 #include "parser/parse_coerce.h"
 #include "utils/builtins.h"
@@ -1170,16 +1171,24 @@ to_jsonb(PG_FUNCTION_ARGS)
 Datum
 jsonb_build_object(PG_FUNCTION_ARGS)
 {
-       int                     nargs = PG_NARGS();
+       int                     nargs;
        int                     i;
-       Datum           arg;
-       Oid                     val_type;
        JsonbInState result;
+       Datum      *args;
+       bool       *nulls;
+       Oid                *types;
+
+       /* build argument values to build the object */
+       nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);
+
+       if (nargs < 0)
+               PG_RETURN_NULL();
 
        if (nargs % 2 != 0)
                ereport(ERROR,
                                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-                                errmsg("invalid number of arguments: object must be matched key value pairs")));
+                                errmsg("argument list must have even number of elements"),
+                                errhint("The arguments of jsonb_build_object() must consist of alternating keys and values.")));
 
        memset(&result, 0, sizeof(JsonbInState));
 
@@ -1188,54 +1197,15 @@ jsonb_build_object(PG_FUNCTION_ARGS)
        for (i = 0; i < nargs; i += 2)
        {
                /* process key */
-
-               if (PG_ARGISNULL(i))
+               if (nulls[i])
                        ereport(ERROR,
                                        (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                                         errmsg("argument %d: key must not be null", i + 1)));
-               val_type = get_fn_expr_argtype(fcinfo->flinfo, i);
-
-               /*
-                * turn a constant (more or less literal) value that's of unknown type
-                * into text. Unknowns come in as a cstring pointer.
-                */
-               if (val_type == UNKNOWNOID && get_fn_expr_arg_stable(fcinfo->flinfo, i))
-               {
-                       val_type = TEXTOID;
-                       arg = CStringGetTextDatum(PG_GETARG_POINTER(i));
-               }
-               else
-               {
-                       arg = PG_GETARG_DATUM(i);
-               }
-               if (val_type == InvalidOid || val_type == UNKNOWNOID)
-                       ereport(ERROR,
-                                       (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-                          errmsg("could not determine data type for argument %d", i + 1)));
 
-               add_jsonb(arg, false, &result, val_type, true);
+               add_jsonb(args[i], false, &result, types[i], true);
 
                /* process value */
-
-               val_type = get_fn_expr_argtype(fcinfo->flinfo, i + 1);
-               /* see comments above */
-               if (val_type == UNKNOWNOID && get_fn_expr_arg_stable(fcinfo->flinfo, i + 1))
-               {
-                       val_type = TEXTOID;
-                       if (PG_ARGISNULL(i + 1))
-                               arg = (Datum) 0;
-                       else
-                               arg = CStringGetTextDatum(PG_GETARG_POINTER(i + 1));
-               }
-               else
-               {
-                       arg = PG_GETARG_DATUM(i + 1);
-               }
-               if (val_type == InvalidOid || val_type == UNKNOWNOID)
-                       ereport(ERROR,
-                                       (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-                          errmsg("could not determine data type for argument %d", i + 2)));
-               add_jsonb(arg, PG_ARGISNULL(i + 1), &result, val_type, false);
+               add_jsonb(args[i + 1], nulls[i + 1], &result, types[i + 1], false);
        }
 
        result.res = pushJsonbValue(&result.parseState, WJB_END_OBJECT, NULL);
@@ -1265,38 +1235,25 @@ jsonb_build_object_noargs(PG_FUNCTION_ARGS)
 Datum
 jsonb_build_array(PG_FUNCTION_ARGS)
 {
-       int                     nargs = PG_NARGS();
+       int                     nargs;
        int                     i;
-       Datum           arg;
-       Oid                     val_type;
        JsonbInState result;
+       Datum      *args;
+       bool       *nulls;
+       Oid                *types;
+
+       /* build argument values to build the array */
+       nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);
+
+       if (nargs < 0)
+               PG_RETURN_NULL();
 
        memset(&result, 0, sizeof(JsonbInState));
 
        result.res = pushJsonbValue(&result.parseState, WJB_BEGIN_ARRAY, NULL);
 
        for (i = 0; i < nargs; i++)
-       {
-               val_type = get_fn_expr_argtype(fcinfo->flinfo, i);
-               /* see comments in jsonb_build_object above */
-               if (val_type == UNKNOWNOID && get_fn_expr_arg_stable(fcinfo->flinfo, i))
-               {
-                       val_type = TEXTOID;
-                       if (PG_ARGISNULL(i))
-                               arg = (Datum) 0;
-                       else
-                               arg = CStringGetTextDatum(PG_GETARG_POINTER(i));
-               }
-               else
-               {
-                       arg = PG_GETARG_DATUM(i);
-               }
-               if (val_type == InvalidOid || val_type == UNKNOWNOID)
-                       ereport(ERROR,
-                                       (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-                          errmsg("could not determine data type for argument %d", i + 1)));
-               add_jsonb(arg, PG_ARGISNULL(i), &result, val_type, false);
-       }
+               add_jsonb(args[i], nulls[i], &result, types[i], false);
 
        result.res = pushJsonbValue(&result.parseState, WJB_END_ARRAY, NULL);
 
index efcdc4141e322294c005507ca726db91bb0022af..7217d4005c37edd357cc260c97b02b4030a986c9 100644 (file)
@@ -1444,6 +1444,54 @@ SELECT json_build_array('a',1,'b',1.2,'c',true,'d',null,'e',json '{"x": 3, "y":
  ["a", 1, "b", 1.2, "c", true, "d", null, "e", {"x": 3, "y": [1,2,3]}]
 (1 row)
 
+SELECT json_build_array('a', NULL); -- ok
+ json_build_array 
+------------------
+ ["a", null]
+(1 row)
+
+SELECT json_build_array(VARIADIC NULL::text[]); -- ok
+ json_build_array 
+------------------
+(1 row)
+
+SELECT json_build_array(VARIADIC '{}'::text[]); -- ok
+ json_build_array 
+------------------
+ []
+(1 row)
+
+SELECT json_build_array(VARIADIC '{a,b,c}'::text[]); -- ok
+ json_build_array 
+------------------
+ ["a", "b", "c"]
+(1 row)
+
+SELECT json_build_array(VARIADIC ARRAY['a', NULL]::text[]); -- ok
+ json_build_array 
+------------------
+ ["a", null]
+(1 row)
+
+SELECT json_build_array(VARIADIC '{1,2,3,4}'::text[]); -- ok
+   json_build_array   
+----------------------
+ ["1", "2", "3", "4"]
+(1 row)
+
+SELECT json_build_array(VARIADIC '{1,2,3,4}'::int[]); -- ok
+ json_build_array 
+------------------
+ [1, 2, 3, 4]
+(1 row)
+
+SELECT json_build_array(VARIADIC '{{1,4},{2,5},{3,6}}'::int[][]); -- ok
+  json_build_array  
+--------------------
+ [1, 4, 2, 5, 3, 6]
+(1 row)
+
 SELECT json_build_object('a',1,'b',1.2,'c',true,'d',null,'e',json '{"x": 3, "y": [1,2,3]}');
                              json_build_object                              
 ----------------------------------------------------------------------------
@@ -1459,6 +1507,65 @@ SELECT json_build_object(
  {"a" : {"b" : false, "c" : 99}, "d" : {"e" : [9,8,7], "f" : {"relkind":"r","name":"pg_class"}}}
 (1 row)
 
+SELECT json_build_object('{a,b,c}'::text[]); -- error
+ERROR:  argument list must have even number of elements
+HINT:  The arguments of json_build_object() must consist of alternating keys and values.
+SELECT json_build_object('{a,b,c}'::text[], '{d,e,f}'::text[]); -- error, key cannot be array
+ERROR:  key value must be scalar, not array, composite, or json
+SELECT json_build_object('a', 'b', 'c'); -- error
+ERROR:  argument list must have even number of elements
+HINT:  The arguments of json_build_object() must consist of alternating keys and values.
+SELECT json_build_object(NULL, 'a'); -- error, key cannot be NULL
+ERROR:  argument 1 cannot be null
+HINT:  Object keys should be text.
+SELECT json_build_object('a', NULL); -- ok
+ json_build_object 
+-------------------
+ {"a" : null}
+(1 row)
+
+SELECT json_build_object(VARIADIC NULL::text[]); -- ok
+ json_build_object 
+-------------------
+(1 row)
+
+SELECT json_build_object(VARIADIC '{}'::text[]); -- ok
+ json_build_object 
+-------------------
+ {}
+(1 row)
+
+SELECT json_build_object(VARIADIC '{a,b,c}'::text[]); -- error
+ERROR:  argument list must have even number of elements
+HINT:  The arguments of json_build_object() must consist of alternating keys and values.
+SELECT json_build_object(VARIADIC ARRAY['a', NULL]::text[]); -- ok
+ json_build_object 
+-------------------
+ {"a" : null}
+(1 row)
+
+SELECT json_build_object(VARIADIC ARRAY[NULL, 'a']::text[]); -- error, key cannot be NULL
+ERROR:  argument 1 cannot be null
+HINT:  Object keys should be text.
+SELECT json_build_object(VARIADIC '{1,2,3,4}'::text[]); -- ok
+   json_build_object    
+------------------------
+ {"1" : "2", "3" : "4"}
+(1 row)
+
+SELECT json_build_object(VARIADIC '{1,2,3,4}'::int[]); -- ok
+ json_build_object  
+--------------------
+ {"1" : 2, "3" : 4}
+(1 row)
+
+SELECT json_build_object(VARIADIC '{{1,4},{2,5},{3,6}}'::int[][]); -- ok
+      json_build_object      
+-----------------------------
+ {"1" : 4, "2" : 5, "3" : 6}
+(1 row)
+
 -- empty objects/arrays
 SELECT json_build_array();
  json_build_array 
index 497b0d93ef0ed2fe70ca919e89957f5433a2a907..7452622afb39dca15d746c6600db3b58313b3526 100644 (file)
@@ -1336,6 +1336,54 @@ SELECT jsonb_build_array('a',1,'b',1.2,'c',true,'d',null,'e',json '{"x": 3, "y":
  ["a", 1, "b", 1.2, "c", true, "d", null, "e", {"x": 3, "y": [1, 2, 3]}]
 (1 row)
 
+SELECT jsonb_build_array('a', NULL); -- ok
+ jsonb_build_array 
+-------------------
+ ["a", null]
+(1 row)
+
+SELECT jsonb_build_array(VARIADIC NULL::text[]); -- ok
+ jsonb_build_array 
+-------------------
+(1 row)
+
+SELECT jsonb_build_array(VARIADIC '{}'::text[]); -- ok
+ jsonb_build_array 
+-------------------
+ []
+(1 row)
+
+SELECT jsonb_build_array(VARIADIC '{a,b,c}'::text[]); -- ok
+ jsonb_build_array 
+-------------------
+ ["a", "b", "c"]
+(1 row)
+
+SELECT jsonb_build_array(VARIADIC ARRAY['a', NULL]::text[]); -- ok
+ jsonb_build_array 
+-------------------
+ ["a", null]
+(1 row)
+
+SELECT jsonb_build_array(VARIADIC '{1,2,3,4}'::text[]); -- ok
+  jsonb_build_array   
+----------------------
+ ["1", "2", "3", "4"]
+(1 row)
+
+SELECT jsonb_build_array(VARIADIC '{1,2,3,4}'::int[]); -- ok
+ jsonb_build_array 
+-------------------
+ [1, 2, 3, 4]
+(1 row)
+
+SELECT jsonb_build_array(VARIADIC '{{1,4},{2,5},{3,6}}'::int[][]); -- ok
+ jsonb_build_array  
+--------------------
+ [1, 4, 2, 5, 3, 6]
+(1 row)
+
 SELECT jsonb_build_object('a',1,'b',1.2,'c',true,'d',null,'e',json '{"x": 3, "y": [1,2,3]}');
                            jsonb_build_object                            
 -------------------------------------------------------------------------
@@ -1351,6 +1399,63 @@ SELECT jsonb_build_object(
  {"a": {"b": false, "c": 99}, "d": {"e": [9, 8, 7], "f": {"name": "pg_class", "relkind": "r"}}}
 (1 row)
 
+SELECT jsonb_build_object('{a,b,c}'::text[]); -- error
+ERROR:  argument list must have even number of elements
+HINT:  The arguments of jsonb_build_object() must consist of alternating keys and values.
+SELECT jsonb_build_object('{a,b,c}'::text[], '{d,e,f}'::text[]); -- error, key cannot be array
+ERROR:  key value must be scalar, not array, composite, or json
+SELECT jsonb_build_object('a', 'b', 'c'); -- error
+ERROR:  argument list must have even number of elements
+HINT:  The arguments of jsonb_build_object() must consist of alternating keys and values.
+SELECT jsonb_build_object(NULL, 'a'); -- error, key cannot be NULL
+ERROR:  argument 1: key must not be null
+SELECT jsonb_build_object('a', NULL); -- ok
+ jsonb_build_object 
+--------------------
+ {"a": null}
+(1 row)
+
+SELECT jsonb_build_object(VARIADIC NULL::text[]); -- ok
+ jsonb_build_object 
+--------------------
+(1 row)
+
+SELECT jsonb_build_object(VARIADIC '{}'::text[]); -- ok
+ jsonb_build_object 
+--------------------
+ {}
+(1 row)
+
+SELECT jsonb_build_object(VARIADIC '{a,b,c}'::text[]); -- error
+ERROR:  argument list must have even number of elements
+HINT:  The arguments of jsonb_build_object() must consist of alternating keys and values.
+SELECT jsonb_build_object(VARIADIC ARRAY['a', NULL]::text[]); -- ok
+ jsonb_build_object 
+--------------------
+ {"a": null}
+(1 row)
+
+SELECT jsonb_build_object(VARIADIC ARRAY[NULL, 'a']::text[]); -- error, key cannot be NULL
+ERROR:  argument 1: key must not be null
+SELECT jsonb_build_object(VARIADIC '{1,2,3,4}'::text[]); -- ok
+  jsonb_build_object  
+----------------------
+ {"1": "2", "3": "4"}
+(1 row)
+
+SELECT jsonb_build_object(VARIADIC '{1,2,3,4}'::int[]); -- ok
+ jsonb_build_object 
+--------------------
+ {"1": 2, "3": 4}
+(1 row)
+
+SELECT jsonb_build_object(VARIADIC '{{1,4},{2,5},{3,6}}'::int[][]); -- ok
+    jsonb_build_object    
+--------------------------
+ {"1": 4, "2": 5, "3": 6}
+(1 row)
+
 -- empty objects/arrays
 SELECT jsonb_build_array();
  jsonb_build_array 
index 603288bd1a1ef6d67a5ad4873790dcc024c2821f..46919c500df9942c5f704ce6335786eb080cda0d 100644 (file)
@@ -422,6 +422,14 @@ select value, json_typeof(value)
 -- json_build_array, json_build_object, json_object_agg
 
 SELECT json_build_array('a',1,'b',1.2,'c',true,'d',null,'e',json '{"x": 3, "y": [1,2,3]}');
+SELECT json_build_array('a', NULL); -- ok
+SELECT json_build_array(VARIADIC NULL::text[]); -- ok
+SELECT json_build_array(VARIADIC '{}'::text[]); -- ok
+SELECT json_build_array(VARIADIC '{a,b,c}'::text[]); -- ok
+SELECT json_build_array(VARIADIC ARRAY['a', NULL]::text[]); -- ok
+SELECT json_build_array(VARIADIC '{1,2,3,4}'::text[]); -- ok
+SELECT json_build_array(VARIADIC '{1,2,3,4}'::int[]); -- ok
+SELECT json_build_array(VARIADIC '{{1,4},{2,5},{3,6}}'::int[][]); -- ok
 
 SELECT json_build_object('a',1,'b',1.2,'c',true,'d',null,'e',json '{"x": 3, "y": [1,2,3]}');
 
@@ -429,6 +437,19 @@ SELECT json_build_object(
        'a', json_build_object('b',false,'c',99),
        'd', json_build_object('e',array[9,8,7]::int[],
            'f', (select row_to_json(r) from ( select relkind, oid::regclass as name from pg_class where relname = 'pg_class') r)));
+SELECT json_build_object('{a,b,c}'::text[]); -- error
+SELECT json_build_object('{a,b,c}'::text[], '{d,e,f}'::text[]); -- error, key cannot be array
+SELECT json_build_object('a', 'b', 'c'); -- error
+SELECT json_build_object(NULL, 'a'); -- error, key cannot be NULL
+SELECT json_build_object('a', NULL); -- ok
+SELECT json_build_object(VARIADIC NULL::text[]); -- ok
+SELECT json_build_object(VARIADIC '{}'::text[]); -- ok
+SELECT json_build_object(VARIADIC '{a,b,c}'::text[]); -- error
+SELECT json_build_object(VARIADIC ARRAY['a', NULL]::text[]); -- ok
+SELECT json_build_object(VARIADIC ARRAY[NULL, 'a']::text[]); -- error, key cannot be NULL
+SELECT json_build_object(VARIADIC '{1,2,3,4}'::text[]); -- ok
+SELECT json_build_object(VARIADIC '{1,2,3,4}'::int[]); -- ok
+SELECT json_build_object(VARIADIC '{{1,4},{2,5},{3,6}}'::int[][]); -- ok
 
 -- empty objects/arrays
 SELECT json_build_array();
index c6716841344c3744e1ef0908355305ed36b993c8..ada80174ec43ae61283d05a47b8c71e2a64fc639 100644 (file)
@@ -307,6 +307,14 @@ SELECT jsonb_typeof('"1.0"') AS string;
 -- jsonb_build_array, jsonb_build_object, jsonb_object_agg
 
 SELECT jsonb_build_array('a',1,'b',1.2,'c',true,'d',null,'e',json '{"x": 3, "y": [1,2,3]}');
+SELECT jsonb_build_array('a', NULL); -- ok
+SELECT jsonb_build_array(VARIADIC NULL::text[]); -- ok
+SELECT jsonb_build_array(VARIADIC '{}'::text[]); -- ok
+SELECT jsonb_build_array(VARIADIC '{a,b,c}'::text[]); -- ok
+SELECT jsonb_build_array(VARIADIC ARRAY['a', NULL]::text[]); -- ok
+SELECT jsonb_build_array(VARIADIC '{1,2,3,4}'::text[]); -- ok
+SELECT jsonb_build_array(VARIADIC '{1,2,3,4}'::int[]); -- ok
+SELECT jsonb_build_array(VARIADIC '{{1,4},{2,5},{3,6}}'::int[][]); -- ok
 
 SELECT jsonb_build_object('a',1,'b',1.2,'c',true,'d',null,'e',json '{"x": 3, "y": [1,2,3]}');
 
@@ -314,7 +322,19 @@ SELECT jsonb_build_object(
        'a', jsonb_build_object('b',false,'c',99),
        'd', jsonb_build_object('e',array[9,8,7]::int[],
            'f', (select row_to_json(r) from ( select relkind, oid::regclass as name from pg_class where relname = 'pg_class') r)));
-
+SELECT jsonb_build_object('{a,b,c}'::text[]); -- error
+SELECT jsonb_build_object('{a,b,c}'::text[], '{d,e,f}'::text[]); -- error, key cannot be array
+SELECT jsonb_build_object('a', 'b', 'c'); -- error
+SELECT jsonb_build_object(NULL, 'a'); -- error, key cannot be NULL
+SELECT jsonb_build_object('a', NULL); -- ok
+SELECT jsonb_build_object(VARIADIC NULL::text[]); -- ok
+SELECT jsonb_build_object(VARIADIC '{}'::text[]); -- ok
+SELECT jsonb_build_object(VARIADIC '{a,b,c}'::text[]); -- error
+SELECT jsonb_build_object(VARIADIC ARRAY['a', NULL]::text[]); -- ok
+SELECT jsonb_build_object(VARIADIC ARRAY[NULL, 'a']::text[]); -- error, key cannot be NULL
+SELECT jsonb_build_object(VARIADIC '{1,2,3,4}'::text[]); -- ok
+SELECT jsonb_build_object(VARIADIC '{1,2,3,4}'::int[]); -- ok
+SELECT jsonb_build_object(VARIADIC '{{1,4},{2,5},{3,6}}'::int[][]); -- ok
 
 -- empty objects/arrays
 SELECT jsonb_build_array();