mirror of
https://github.com/postgres/postgres.git
synced 2026-05-16 03:19:53 -04:00
Enforce RETURNING typmod for empty-set JSON_ARRAY(query)
Commit 8d829f5a0 introduced a COALESCE wrapper around the
JSON_ARRAYAGG subquery so that JSON_ARRAY(query) returns '[]' rather
than NULL when the subquery yields no rows, per the SQL/JSON standard.
The empty-array Const used as the COALESCE fallback was, however,
built with typmod -1 and the type input function was likewise invoked
with typmod -1. As a result, any length restriction from the
RETURNING clause was silently bypassed on the empty-set path, while
the non-empty path enforced it via the JSON_ARRAYAGG coercion.
Build the empty-array Const using the typmod of the COALESCE's
non-empty argument, and pass that typmod to OidInputFunctionCall as
well so the value is length-checked at parse time. This makes the
empty-set and non-empty-set paths behave consistently.
Reported-by: Ayush Tiwari <ayushtiwari.slg01@gmail.com>
Author: Richard Guo <guofenglinux@gmail.com>
Discussion: https://postgr.es/m/CAJTYsWXPYqa58YXrU+SQMVonsAhjLS46HNUMU=wO5zm9MgY3_g@mail.gmail.com
This commit is contained in:
parent
a49b9cfd72
commit
9d124a14b3
3 changed files with 35 additions and 4 deletions
|
|
@ -3826,6 +3826,7 @@ transformJsonArrayQueryConstructor(ParseState *pstate,
|
|||
CoalesceExpr *coalesce;
|
||||
Const *empty_const;
|
||||
Oid result_type;
|
||||
int32 result_typmod;
|
||||
Oid typinput;
|
||||
Oid typioparam;
|
||||
int16 typlen;
|
||||
|
|
@ -3904,19 +3905,22 @@ transformJsonArrayQueryConstructor(ParseState *pstate,
|
|||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
|
|
|
|||
|
|
@ -783,6 +783,25 @@ WHERE JSON_ARRAY(
|
|||
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
|
||||
|
|
|
|||
|
|
@ -213,6 +213,14 @@ WHERE JSON_ARRAY(
|
|||
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));
|
||||
|
|
|
|||
Loading…
Reference in a new issue