mirror of
https://github.com/postgres/postgres.git
synced 2026-05-16 03:19:53 -04:00
Fix jsonpath .split_part() to honor silent mode
The jsonpath .split_part() method passed its field-position argument
through numeric_int4(), that can fail hard if called directly.
This commit switches the code to use numeric_int4_safe() with an error
context for soft reporting, so as the overflow and zero field-position
cases can be handled in silent mode.
Oversight in bd4f879a9c.
Author: Chao Li <li.evan.chao@gmail.com>
Reviewed-by: Nazir Bilal Yavuz <byavuz81@gmail.com>
Discussion: https://postgr.es/m/FCF996D0-580B-431C-8DE1-A540C58E444C@gmail.com
This commit is contained in:
parent
61f8a85a57
commit
954e57708e
3 changed files with 34 additions and 3 deletions
|
|
@ -3017,7 +3017,8 @@ executeStringInternalMethod(JsonPathExecContext *cxt, JsonPathItem *jsp,
|
|||
case jpiStrSplitPart:
|
||||
{
|
||||
char *from_str;
|
||||
Numeric n;
|
||||
int32 n;
|
||||
ErrorSaveContext escontext = {T_ErrorSaveContext};
|
||||
|
||||
jspGetLeftArg(jsp, &elem);
|
||||
if (elem.type != jpiString)
|
||||
|
|
@ -3029,13 +3030,25 @@ executeStringInternalMethod(JsonPathExecContext *cxt, JsonPathItem *jsp,
|
|||
if (elem.type != jpiNumeric)
|
||||
elog(ERROR, "invalid jsonpath item type for .split_part()");
|
||||
|
||||
n = jspGetNumeric(&elem);
|
||||
n = numeric_int4_safe(jspGetNumeric(&elem),
|
||||
(Node *) &escontext);
|
||||
if (escontext.error_occurred)
|
||||
RETURN_ERROR(ereport(ERROR,
|
||||
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("field position of jsonpath item method .%s() is out of range for type integer",
|
||||
jspOperationName(jsp->type))));
|
||||
|
||||
if (n == 0)
|
||||
RETURN_ERROR(ereport(ERROR,
|
||||
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("field position of jsonpath item method .%s() must not be zero",
|
||||
jspOperationName(jsp->type))));
|
||||
|
||||
resStr = TextDatumGetCString(DirectFunctionCall3Coll(split_part,
|
||||
DEFAULT_COLLATION_OID,
|
||||
str,
|
||||
CStringGetTextDatum(from_str),
|
||||
DirectFunctionCall1(numeric_int4, NumericGetDatum(n))));
|
||||
Int32GetDatum(n)));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -3073,6 +3073,20 @@ select jsonb_path_query('"abc,def,ghi,jkl"', '$.split_part(",", -2)');
|
|||
"ghi"
|
||||
(1 row)
|
||||
|
||||
select jsonb_path_query('"a,b"', '$.split_part(",", 0)');
|
||||
ERROR: field position of jsonpath item method .split_part() must not be zero
|
||||
select jsonb_path_query('"a,b"', '$.split_part(",", 0)', silent => true);
|
||||
jsonb_path_query
|
||||
------------------
|
||||
(0 rows)
|
||||
|
||||
select jsonb_path_query('"a,b"', '$.split_part(",", 2147483648)');
|
||||
ERROR: field position of jsonpath item method .split_part() is out of range for type integer
|
||||
select jsonb_path_query('"a,b"', '$.split_part(",", 2147483648)', silent => true);
|
||||
jsonb_path_query
|
||||
------------------
|
||||
(0 rows)
|
||||
|
||||
-- Test string methods play nicely together
|
||||
select jsonb_path_query('"hello world"', '$.replace("hello","bye").upper()');
|
||||
jsonb_path_query
|
||||
|
|
|
|||
|
|
@ -721,6 +721,10 @@ select jsonb_path_query('"hello world"', '$.replace("hello","bye") starts with "
|
|||
-- Test .split_part()
|
||||
select jsonb_path_query('"abc~@~def~@~ghi"', '$.split_part("~@~", 2)');
|
||||
select jsonb_path_query('"abc,def,ghi,jkl"', '$.split_part(",", -2)');
|
||||
select jsonb_path_query('"a,b"', '$.split_part(",", 0)');
|
||||
select jsonb_path_query('"a,b"', '$.split_part(",", 0)', silent => true);
|
||||
select jsonb_path_query('"a,b"', '$.split_part(",", 2147483648)');
|
||||
select jsonb_path_query('"a,b"', '$.split_part(",", 2147483648)', silent => true);
|
||||
|
||||
-- Test string methods play nicely together
|
||||
select jsonb_path_query('"hello world"', '$.replace("hello","bye").upper()');
|
||||
|
|
|
|||
Loading…
Reference in a new issue