CoalesceExpr *coalesce;
Const *empty_const;
Oid result_type;
+ int32 result_typmod;
Oid typinput;
Oid typioparam;
int16 typlen;
/*
* Wrap in COALESCE so that an empty result set produces '[]' rather than
- * NULL. The empty-array constant is created in the output type so that
- * the COALESCE arguments have consistent types.
+ * NULL. The empty-array constant is created in the output type and
+ * typmod, so that the COALESCE arguments have consistent types and any
+ * length restriction from the RETURNING clause is enforced uniformly
+ * across the empty and non-empty paths.
*/
result_type = exprType(exec_expr);
+ result_typmod = exprTypmod(exec_expr);
getTypeInputInfo(result_type, &typinput, &typioparam);
get_typlenbyval(result_type, &typlen, &typbyval);
empty_const = makeConst(result_type,
- -1,
+ result_typmod,
exprCollation(exec_expr),
(int) typlen,
OidInputFunctionCall(typinput, "[]",
- typioparam, -1),
+ typioparam, result_typmod),
false,
typbyval);
4
(2 rows)
+-- JSON_ARRAY(subquery) RETURNING with a length-restricted output type
+-- Should fail
+SELECT JSON_ARRAY(SELECT 1 RETURNING varchar(1));
+ERROR: value too long for type character varying(1)
+SELECT JSON_ARRAY(SELECT 1 WHERE FALSE RETURNING varchar(1));
+ERROR: value too long for type character varying(1)
+-- Should work
+SELECT JSON_ARRAY(SELECT 1 RETURNING varchar(3));
+ json_array
+------------
+ [1]
+(1 row)
+
+SELECT JSON_ARRAY(SELECT 1 WHERE FALSE RETURNING varchar(2));
+ json_array
+------------
+ []
+(1 row)
+
-- Should fail
SELECT JSON_ARRAY(SELECT FROM (VALUES (1)) foo(i));
ERROR: subquery must return only one column
RETURNING jsonb
) = '[]'::jsonb;
+-- JSON_ARRAY(subquery) RETURNING with a length-restricted output type
+-- Should fail
+SELECT JSON_ARRAY(SELECT 1 RETURNING varchar(1));
+SELECT JSON_ARRAY(SELECT 1 WHERE FALSE RETURNING varchar(1));
+-- Should work
+SELECT JSON_ARRAY(SELECT 1 RETURNING varchar(3));
+SELECT JSON_ARRAY(SELECT 1 WHERE FALSE RETURNING varchar(2));
+
-- Should fail
SELECT JSON_ARRAY(SELECT FROM (VALUES (1)) foo(i));
SELECT JSON_ARRAY(SELECT i, i FROM (VALUES (1)) foo(i));