aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Dunstan <andrew@dunslane.net>2017-10-25 07:34:00 -0400
committerAndrew Dunstan <andrew@dunslane.net>2017-10-25 07:34:00 -0400
commit18fc4ecf4afafe40bd7e7577bd611e5caf74c9fd (patch)
treedfbb1fcb93d17401d73aa2703dfbf0ccbcea9c58
parentf3c6e8a27a8f8436cada9a42e4f57338ed38c785 (diff)
downloadpostgresql-18fc4ecf4afafe40bd7e7577bd611e5caf74c9fd.tar.gz
postgresql-18fc4ecf4afafe40bd7e7577bd611e5caf74c9fd.zip
Process variadic arguments consistently in json functions
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.
-rw-r--r--src/backend/utils/adt/json.c84
-rw-r--r--src/backend/utils/adt/jsonb.c99
-rw-r--r--src/test/regress/expected/json.out107
-rw-r--r--src/test/regress/expected/jsonb.out105
-rw-r--r--src/test/regress/sql/json.sql21
-rw-r--r--src/test/regress/sql/jsonb.sql22
6 files changed, 306 insertions, 132 deletions
diff --git a/src/backend/utils/adt/json.c b/src/backend/utils/adt/json.c
index 1ddb42b4d08..baf1178995c 100644
--- a/src/backend/utils/adt/json.c
+++ b/src/backend/utils/adt/json.c
@@ -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"
@@ -2111,10 +2112,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,
@@ -2128,52 +2136,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, '}');
@@ -2196,12 +2174,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();
@@ -2209,30 +2194,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, ']');
diff --git a/src/backend/utils/adt/jsonb.c b/src/backend/utils/adt/jsonb.c
index 771c05120bb..7185b4cce53 100644
--- a/src/backend/utils/adt/jsonb.c
+++ b/src/backend/utils/adt/jsonb.c
@@ -3,7 +3,7 @@
* jsonb.c
* I/O routines for jsonb type
*
- * Copyright (c) 2014-2017, PostgreSQL Global Development Group
+ * COPYRIGHT (c) 2014-2017, PostgreSQL Global Development Group
*
* IDENTIFICATION
* src/backend/utils/adt/jsonb.c
@@ -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"
@@ -1171,16 +1172,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));
@@ -1189,54 +1198,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);
@@ -1266,38 +1236,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);
diff --git a/src/test/regress/expected/json.out b/src/test/regress/expected/json.out
index d7abae9867f..9fc91f8d121 100644
--- a/src/test/regress/expected/json.out
+++ b/src/test/regress/expected/json.out
@@ -1864,6 +1864,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
----------------------------------------------------------------------------
@@ -1879,6 +1927,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
diff --git a/src/test/regress/expected/jsonb.out b/src/test/regress/expected/jsonb.out
index dcea6a47a36..eeac2a13c71 100644
--- a/src/test/regress/expected/jsonb.out
+++ b/src/test/regress/expected/jsonb.out
@@ -1345,6 +1345,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
-------------------------------------------------------------------------
@@ -1360,6 +1408,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
diff --git a/src/test/regress/sql/json.sql b/src/test/regress/sql/json.sql
index 506e3a8fc54..598498d40a2 100644
--- a/src/test/regress/sql/json.sql
+++ b/src/test/regress/sql/json.sql
@@ -569,6 +569,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]}');
@@ -576,6 +584,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();
diff --git a/src/test/regress/sql/jsonb.sql b/src/test/regress/sql/jsonb.sql
index 57fff3bfb3e..d0e3f2a1f6d 100644
--- a/src/test/regress/sql/jsonb.sql
+++ b/src/test/regress/sql/jsonb.sql
@@ -313,6 +313,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]}');
@@ -320,7 +328,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();