mirror of
https://github.com/postgres/postgres.git
synced 2025-11-07 19:06:32 +03:00
SQL/JSON: Always coerce JsonExpr result at runtime
Instead of looking up casts at parse time for converting the result of JsonPath* query functions to the specified or the default RETURNING type, always perform the conversion at runtime using either the target type's input function or the function json_populate_type(). There are two motivations for this change: 1. json_populate_type() coerces to types with typmod such that any string values that exceed length limit cause an error instead of silent truncation, which is necessary to be standard-conforming. 2. It was possible to end up with a cast expression that doesn't support soft handling of errors causing bugs in the of handling ON ERROR clause. JsonExpr.coercion_expr which would store the cast expression is no longer necessary, so remove. Bump catversion because stored rules change because of the above removal. Reported-by: Alvaro Herrera <alvherre@alvh.no-ip.org> Reviewed-by: Jian He <jian.universality@gmail.com> Discussion: Discussion: https://postgr.es/m/202405271326.5a5rprki64aw%40alvherre.pgsql
This commit is contained in:
@@ -53,7 +53,9 @@ SELECT JSON_VALUE(jsonb '"1.23"', '$' RETURNING int ERROR ON ERROR);
|
||||
SELECT JSON_VALUE(jsonb '"aaa"', '$');
|
||||
SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING text);
|
||||
SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING char(5));
|
||||
SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING char(2) ERROR ON ERROR);
|
||||
SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING char(2));
|
||||
SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING char(3) ERROR ON ERROR);
|
||||
SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING json);
|
||||
SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING jsonb);
|
||||
SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING json ERROR ON ERROR);
|
||||
@@ -188,10 +190,11 @@ SELECT JSON_QUERY(jsonb '"aaa"', '$' RETURNING json OMIT QUOTES ERROR ON ERROR);
|
||||
SELECT JSON_QUERY(jsonb '"aaa"', '$' RETURNING bytea FORMAT JSON OMIT QUOTES ERROR ON ERROR);
|
||||
|
||||
-- Behavior when a RETURNING type has typmod != -1
|
||||
SELECT JSON_QUERY(jsonb '"aaa"', '$' RETURNING char(2));
|
||||
SELECT JSON_QUERY(jsonb '"aaa"', '$' RETURNING char(2) OMIT QUOTES);
|
||||
SELECT JSON_QUERY(jsonb '"aaa"', '$.a' RETURNING char(2) OMIT QUOTES DEFAULT 'bbb' ON EMPTY);
|
||||
SELECT JSON_QUERY(jsonb '"aaa"', '$.a' RETURNING char(2) OMIT QUOTES DEFAULT '"bbb"'::jsonb ON EMPTY);
|
||||
SELECT JSON_QUERY(jsonb '"aaa"', '$' RETURNING char(3) ERROR ON ERROR);
|
||||
SELECT JSON_QUERY(jsonb '"aaa"', '$' RETURNING char(3));
|
||||
SELECT JSON_QUERY(jsonb '"aaa"', '$' RETURNING char(3) OMIT QUOTES ERROR ON ERROR);
|
||||
SELECT JSON_QUERY(jsonb '"aaa"', '$.a' RETURNING char(2) OMIT QUOTES DEFAULT 'bb' ON EMPTY);
|
||||
SELECT JSON_QUERY(jsonb '"aaa"', '$.a' RETURNING char(2) OMIT QUOTES DEFAULT '"bb"'::jsonb ON EMPTY);
|
||||
|
||||
-- OMIT QUOTES behavior should not be specified when WITH WRAPPER used:
|
||||
-- Should fail
|
||||
@@ -235,7 +238,6 @@ SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING jsonb);
|
||||
SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING jsonb FORMAT JSON);
|
||||
SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING text);
|
||||
SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING char(10));
|
||||
SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING char(3));
|
||||
SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING text FORMAT JSON);
|
||||
SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING bytea);
|
||||
SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING bytea FORMAT JSON);
|
||||
@@ -464,3 +466,16 @@ SELECT JSON_QUERY(jsonb 'null', '$xyz' PASSING 1 AS xyz);
|
||||
SELECT JSON_EXISTS(jsonb '1', '$' DEFAULT 1 ON ERROR);
|
||||
SELECT JSON_VALUE(jsonb '1', '$' EMPTY ON ERROR);
|
||||
SELECT JSON_QUERY(jsonb '1', '$' TRUE ON ERROR);
|
||||
|
||||
-- Test implicit coercion domain over fixed-legth type specified in RETURNING
|
||||
CREATE DOMAIN queryfuncs_char2 AS char(2);
|
||||
CREATE DOMAIN queryfuncs_char2_chk AS char(2) CHECK (VALUE NOT IN ('12'));
|
||||
SELECT JSON_QUERY(jsonb '123', '$' RETURNING queryfuncs_char2 ERROR ON ERROR);
|
||||
SELECT JSON_QUERY(jsonb '123', '$' RETURNING queryfuncs_char2 DEFAULT '1' ON ERROR);
|
||||
SELECT JSON_QUERY(jsonb '123', '$' RETURNING queryfuncs_char2_chk ERROR ON ERROR);
|
||||
SELECT JSON_QUERY(jsonb '123', '$' RETURNING queryfuncs_char2_chk DEFAULT '1' ON ERROR);
|
||||
SELECT JSON_VALUE(jsonb '123', '$' RETURNING queryfuncs_char2 ERROR ON ERROR);
|
||||
SELECT JSON_VALUE(jsonb '123', '$' RETURNING queryfuncs_char2 DEFAULT 1 ON ERROR);
|
||||
SELECT JSON_VALUE(jsonb '123', '$' RETURNING queryfuncs_char2_chk ERROR ON ERROR);
|
||||
SELECT JSON_VALUE(jsonb '123', '$' RETURNING queryfuncs_char2_chk DEFAULT 1 ON ERROR);
|
||||
DROP DOMAIN queryfuncs_char2, queryfuncs_char2_chk;
|
||||
|
||||
Reference in New Issue
Block a user