On Thu, Jan 25, 2024 at 10:39 PM jian he <jian.universal...@gmail.com> wrote: > > On Thu, Jan 25, 2024 at 7:54 PM Amit Langote <amitlangot...@gmail.com> wrote: > > > > > > > > The problem with returning comp_domain_with_typmod from json_value() > > > seems to be that it's using a text-to-record CoerceViaIO expression > > > picked from JsonExpr.item_coercions, which behaves differently than > > > the expression tree that the following uses: > > > > > > select ('abcd', 42)::comp_domain_with_typmod; > > > row > > > ---------- > > > (abc,42) > > > (1 row) > > > > Oh, it hadn't occurred to me to check what trying to coerce a "string" > > containing the record literal would do: > > > > select '(''abcd'', 42)'::comp_domain_with_typmod; > > ERROR: value too long for type character(3) > > LINE 1: select '(''abcd'', 42)'::comp_domain_with_typmod; > > > > which is the same thing as what the JSON_QUERY() and JSON_VALUE() are > > running into. So, it might be fair to think that the error is not a > > limitation of the SQL/JSON patch but an underlying behavior that it > > has to accept as is. > > > > Hi, I reconciled with these cases. > What bugs me now is the first query of the following 4 cases (for comparison). > SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING char(3) omit quotes); > SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING char(3) keep quotes); > SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING text omit quotes); > SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING text keep quotes); >
based on v39. in ExecEvalJsonCoercion coercion->targettypmod related function calls: json_populate_type calls populate_record_field, then populate_scalar, later will eventually call InputFunctionCallSafe. so I make the following change: --- a/src/backend/executor/execExprInterp.c +++ b/src/backend/executor/execExprInterp.c @@ -4533,7 +4533,7 @@ ExecEvalJsonCoercion(ExprState *state, ExprEvalStep *op, * deed ourselves by calling the input function, that is, after removing * the quotes. */ - if (jb && JB_ROOT_IS_SCALAR(jb) && coercion->omit_quotes) + if ((jb && JB_ROOT_IS_SCALAR(jb) && coercion->omit_quotes) || coercion->targettypmod != -1) now the following two return the same result: `[1,` SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING char(3) omit quotes); SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING char(3) keep quotes);