diff --git a/src/backend/utils/adt/json.c b/src/backend/utils/adt/json.c
index 1ddb42b4d0..614c30bb30 100644
--- a/src/backend/utils/adt/json.c
+++ b/src/backend/utils/adt/json.c
@@ -2111,10 +2111,73 @@ json_build_object(PG_FUNCTION_ARGS)
 {
 	int			nargs = PG_NARGS();
 	int			i;
-	Datum		arg;
 	const char *sep = "";
 	StringInfo	result;
-	Oid			val_type;
+	bool		variadic = get_fn_expr_variadic(fcinfo->flinfo);
+	Datum	   *elements;
+	bool	   *nulls;
+	Oid		   *val_type;
+
+	/*
+	 * When doing a VARIADIC call, the caller has provided one argument
+	 * made of an array of keys, so deconstruct the array data before
+	 * using it for the next processing. If no VARIADIC call is used,
+	 * just fill in the status data based on all the arguments given by
+	 * the caller.
+	 */
+	if (variadic)
+	{
+		ArrayType  *array_in = PG_GETARG_ARRAYTYPE_P(0);
+		Oid			element_type = ARR_ELEMTYPE(array_in);
+		bool		typbyval;
+		char		typalign;
+		int16		typlen;
+
+		Assert(PG_NARGS() == 1);
+
+		get_typlenbyvalalign(element_type,
+							 &typlen, &typbyval, &typalign);
+		deconstruct_array(array_in, element_type, typlen, typbyval,
+						  typalign, &elements, &nulls,
+						  &nargs);
+
+		/* All the elements of the array have the same type */
+		val_type = (Oid *) palloc0(nargs * sizeof(Oid));
+		for (i = 0; i < nargs; i++)
+			val_type[i] = element_type;
+	}
+	else
+	{
+		nargs = PG_NARGS();
+		nulls = (bool *) palloc0(nargs * sizeof(bool));
+		elements = (Datum *) palloc0(nargs * sizeof(Datum));
+		val_type = (Oid *) palloc0(nargs * sizeof(Oid));
+
+		for (i = 0; i < nargs; i++)
+		{
+			/*
+			 * 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.
+			 */
+			nulls[i] = PG_ARGISNULL(i);
+			val_type[i] = get_fn_expr_argtype(fcinfo->flinfo, i);
+
+			if (val_type[i] == InvalidOid)
+				ereport(ERROR,
+						(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+						 errmsg("could not determine data type for argument %d",
+								i + 1)));
+
+			/* important for value, key cannot being NULL */
+			if (PG_ARGISNULL(i))
+				elements[i] = (Datum) 0;
+			else
+				elements[i] = PG_GETARG_DATUM(i);
+		}
+	}
 
 	if (nargs % 2 != 0)
 		ereport(ERROR,
@@ -2128,52 +2191,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(elements[i], false, result, val_type[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(elements[i + 1], nulls[i + 1], result, val_type[i + 1], false);
 	}
 
 	appendStringInfoChar(result, '}');
@@ -2196,12 +2229,74 @@ 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;
+	bool		variadic = get_fn_expr_variadic(fcinfo->flinfo);
+	Datum	   *elements;
+	bool	   *nulls;
+	Oid		   *val_type;
+
+	/*
+	 * When doing a VARIADIC call, the caller has provided one argument
+	 * made of an array of keys, so deconstruct the array data before
+	 * using it for the next processing. If no VARIADIC call is used,
+	 * just fill in the status data based on all the arguments given by
+	 * the caller.
+	 */
+	if (variadic)
+	{
+		ArrayType  *array_in = PG_GETARG_ARRAYTYPE_P(0);
+		Oid			element_type = ARR_ELEMTYPE(array_in);
+		bool		typbyval;
+		char		typalign;
+		int16		typlen;
+
+		Assert(PG_NARGS() == 1);
+
+		get_typlenbyvalalign(element_type,
+							 &typlen, &typbyval, &typalign);
+		deconstruct_array(array_in, element_type, typlen, typbyval,
+						  typalign, &elements, &nulls,
+						  &nargs);
+
+		/* All the elements of the array have the same type */
+		val_type = (Oid *) palloc0(nargs * sizeof(Oid));
+		for (i = 0; i < nargs; i++)
+			val_type[i] = element_type;
+	}
+	else
+	{
+		nargs = PG_NARGS();
+		nulls = (bool *) palloc0(nargs * sizeof(bool));
+		elements = (Datum *) palloc0(nargs * sizeof(Datum));
+		val_type = (Oid *) palloc0(nargs * sizeof(Oid));
+
+		for (i = 0; i < nargs; i++)
+		{
+			nulls[i] = PG_ARGISNULL(i);
+			val_type[i] = get_fn_expr_argtype(fcinfo->flinfo, 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.
+			 */
+			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))
+				elements[i] = (Datum) 0;
+			else
+				elements[i] = PG_GETARG_DATUM(i);
+		}
+	}
 
 	result = makeStringInfo();
 
@@ -2209,30 +2304,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(elements[i], nulls[i], result, val_type[i], false);
 	}
 
 	appendStringInfoChar(result, ']');
diff --git a/src/backend/utils/adt/jsonb.c b/src/backend/utils/adt/jsonb.c
index 771c05120b..fb9580d4f0 100644
--- a/src/backend/utils/adt/jsonb.c
+++ b/src/backend/utils/adt/jsonb.c
@@ -1171,11 +1171,79 @@ 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;
+	bool		variadic = get_fn_expr_variadic(fcinfo->flinfo);
+	Datum	   *elements;
+	bool	   *nulls;
+	Oid		   *val_type;
+
+	/*
+	 * When doing a VARIADIC call, the caller has provided one argument
+	 * made of an array of keys, so deconstruct the array data before
+	 * using it for the next processing. If no VARIADIC call is used,
+	 * just fill in the status data based on all the arguments given by
+	 * the caller.
+	 */
+	if (variadic)
+	{
+		ArrayType  *array_in = PG_GETARG_ARRAYTYPE_P(0);
+		Oid			element_type = ARR_ELEMTYPE(array_in);
+		bool		typbyval;
+		char		typalign;
+		int16		typlen;
+
+		Assert(PG_NARGS() == 1);
+
+		get_typlenbyvalalign(element_type,
+							 &typlen, &typbyval, &typalign);
+		deconstruct_array(array_in, element_type, typlen, typbyval,
+						  typalign, &elements, &nulls,
+						  &nargs);
+
+		/* All the elements of the array have the same type */
+		val_type = (Oid *) palloc0(nargs * sizeof(Oid));
+		for (i = 0; i < nargs; i++)
+			val_type[i] = element_type;
+	}
+	else
+	{
+		nargs = PG_NARGS();
+		nulls = (bool *) palloc0(nargs * sizeof(bool));
+		elements = (Datum *) palloc0(nargs * sizeof(Datum));
+		val_type = (Oid *) palloc0(nargs * sizeof(Oid));
+
+		for (i = 0; i < nargs; i++)
+		{
+			nulls[i] = PG_ARGISNULL(i);
+			val_type[i] = 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[i] == UNKNOWNOID &&
+				get_fn_expr_arg_stable(fcinfo->flinfo, i))
+			{
+				val_type[i] = TEXTOID;
+
+				/* important for value, key cannot being NULL */
+				if (PG_ARGISNULL(i))
+					elements[i] = (Datum) 0;
+				else
+					elements[i] = CStringGetTextDatum(PG_GETARG_POINTER(i));
+			}
+			else
+				elements[i] = PG_GETARG_DATUM(i);
+
+			if (val_type[i] == InvalidOid || val_type[i] == UNKNOWNOID)
+				ereport(ERROR,
+						(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+						 errmsg("could not determine data type for argument %d",
+								i + 1)));
+		}
+	}
 
 	if (nargs % 2 != 0)
 		ereport(ERROR,
@@ -1189,54 +1257,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(elements[i], false, &result, val_type[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(elements[i + 1], nulls[i + 1], &result, val_type[i + 1], false);
 	}
 
 	result.res = pushJsonbValue(&result.parseState, WJB_END_OBJECT, NULL);
@@ -1266,39 +1295,83 @@ 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;
+	bool		variadic = get_fn_expr_variadic(fcinfo->flinfo);
+	Datum	   *elements;
+	bool	   *nulls;
+	Oid		   *val_type;
 
-	memset(&result, 0, sizeof(JsonbInState));
-
-	result.res = pushJsonbValue(&result.parseState, WJB_BEGIN_ARRAY, NULL);
-
-	for (i = 0; i < nargs; i++)
+	/*
+	 * When doing a VARIADIC call, the caller has provided one argument
+	 * made of an array of keys, so deconstruct the array data before
+	 * using it for the next processing. If no VARIADIC call is used,
+	 * just fill in the status data based on all the arguments given by
+	 * the caller.
+	 */
+	if (variadic)
 	{
-		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))
+		ArrayType  *array_in = PG_GETARG_ARRAYTYPE_P(0);
+		Oid			element_type = ARR_ELEMTYPE(array_in);
+		bool		typbyval;
+		char		typalign;
+		int16		typlen;
+
+		Assert(PG_NARGS() == 1);
+
+		get_typlenbyvalalign(element_type,
+							 &typlen, &typbyval, &typalign);
+		deconstruct_array(array_in, element_type, typlen, typbyval,
+						  typalign, &elements, &nulls,
+						  &nargs);
+
+		/* All the elements of the array have the same type */
+		val_type = (Oid *) palloc0(nargs * sizeof(Oid));
+		for (i = 0; i < nargs; i++)
+			val_type[i] = element_type;
+	}
+	else
+	{
+		nargs = PG_NARGS();
+		nulls = (bool *) palloc0(nargs * sizeof(bool));
+		elements = (Datum *) palloc0(nargs * sizeof(Datum));
+		val_type = (Oid *) palloc0(nargs * sizeof(Oid));
+
+		for (i = 0; i < nargs; i++)
 		{
-			val_type = TEXTOID;
-			if (PG_ARGISNULL(i))
-				arg = (Datum) 0;
+			nulls[i] = PG_ARGISNULL(i);
+			val_type[i] = get_fn_expr_argtype(fcinfo->flinfo, i);
+
+			/* see comments in jsonb_build_object above */
+			if (val_type[i] == UNKNOWNOID &&
+				get_fn_expr_arg_stable(fcinfo->flinfo, i))
+			{
+				val_type[i] = TEXTOID;
+
+				if (PG_ARGISNULL(i))
+					elements[i] = (Datum) 0;
+				else
+					elements[i] = CStringGetTextDatum(PG_GETARG_POINTER(i));
+			}
 			else
-				arg = CStringGetTextDatum(PG_GETARG_POINTER(i));
-		}
-		else
-		{
-			arg = PG_GETARG_DATUM(i);
+				elements[i] = PG_GETARG_DATUM(i);
+
+			if (val_type[i] == InvalidOid || val_type[i] == UNKNOWNOID)
+				ereport(ERROR,
+						(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+						 errmsg("could not determine data type for argument %d",
+								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 + 1)));
-		add_jsonb(arg, PG_ARGISNULL(i), &result, val_type, false);
 	}
 
+	memset(&result, 0, sizeof(JsonbInState));
+
+	result.res = pushJsonbValue(&result.parseState, WJB_BEGIN_ARRAY, NULL);
+
+	for (i = 0; i < nargs; i++)
+		add_jsonb(elements[i], nulls[i], &result, val_type[i], false);
+
 	result.res = pushJsonbValue(&result.parseState, WJB_END_ARRAY, NULL);
 
 	PG_RETURN_POINTER(JsonbValueToJsonb(result.res));
diff --git a/src/test/regress/expected/json.out b/src/test/regress/expected/json.out
index d7abae9867..de13619115 100644
--- a/src/test/regress/expected/json.out
+++ b/src/test/regress/expected/json.out
@@ -1864,6 +1864,42 @@ 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 '{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 +1915,53 @@ 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 '{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 dcea6a47a3..12b4709b10 100644
--- a/src/test/regress/expected/jsonb.out
+++ b/src/test/regress/expected/jsonb.out
@@ -1345,6 +1345,42 @@ 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 '{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 +1396,48 @@ 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:  invalid number of arguments: object must be matched key value pairs
+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:  invalid number of arguments: object must be matched key value pairs
+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 '{a,b,c}'::text[]); -- error
+ERROR:  invalid number of arguments: object must be matched key value pairs
+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 506e3a8fc5..b4f1786caf 100644
--- a/src/test/regress/sql/json.sql
+++ b/src/test/regress/sql/json.sql
@@ -569,6 +569,12 @@ 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 '{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 +582,17 @@ 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 '{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 57fff3bfb3..078e331658 100644
--- a/src/test/regress/sql/jsonb.sql
+++ b/src/test/regress/sql/jsonb.sql
@@ -313,6 +313,12 @@ 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 '{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 +326,17 @@ 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 '{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();
