Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wMcaw-000DzP-3C for pgsql-hackers@arkaria.postgresql.org; Tue, 12 May 2026 02:11:39 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wMcav-002t0N-1L for pgsql-hackers@arkaria.postgresql.org; Tue, 12 May 2026 02:11:37 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wMcav-002t0E-02 for pgsql-hackers@lists.postgresql.org; Tue, 12 May 2026 02:11:37 +0000 Received: from mail-pl1-x631.google.com ([2607:f8b0:4864:20::631]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wMcas-000000008Q7-25rF for pgsql-hackers@lists.postgresql.org; Tue, 12 May 2026 02:11:36 +0000 Received: by mail-pl1-x631.google.com with SMTP id d9443c01a7336-2b4583f0a1aso31940515ad.3 for ; Mon, 11 May 2026 19:11:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1778551893; x=1779156693; darn=lists.postgresql.org; h=to:cc:date:message-id:subject:mime-version:from:from:to:cc:subject :date:message-id:reply-to; bh=Ew3aHIzV7avhNDKZaLgUWN9ZzDJhIXy4dT1QfkaRfqw=; b=mLMvyBfzPxpocbuct0g37es+A3Rc/cQ8iAEdkBQFGidaJn5bBjiTXLZoJkniNptJWh SYOWWrxAMVajh9App3s09TKWMvjTVOflKXWxT+eyfeFK8Tj1kR7SRAKX9zilbGIXsONS K2yDmRZVY24r2PzQAUPY8XDqYC8OpnlHz3tvacio81ZKtK2gx6n5vKShgEeUfHgPMXRY 9hFWu0y2cnhW0+c5i70/v+yssC4/oHqd9lFnyLmY2gLFBFyg2AIlEVSvTvD4w81OpoYF bdZccNeNw/Vs8lDnPZoPwdJaUuOKrzjACqCXaSmJzlOIuXsTIXlxvz86YVtYL02IIr1M sIow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778551893; x=1779156693; h=to:cc:date:message-id:subject:mime-version:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Ew3aHIzV7avhNDKZaLgUWN9ZzDJhIXy4dT1QfkaRfqw=; b=lQa5m66ZEx7lW4OIjB0326gE1C57xIK8SPoUF8XrSXyjeJPQu197e4WigTnDN1nsMY iEyOdzdS7BkNYR5PFldNKVk3YunyljlhbjNqusGutmUuLR1OxOaa67eW6mp+xrsJRpHA 5o1BwiePq6cgpojNkrPiMjxu9HpBvOBrHveoKHgs7YG9kn4i+XjRHCZ4NTNawwQXXamP B0armEuzY2/EVz+811E7OdFew6iJh0lW/yC8kLEAx2agG1SjNrBAvVXAo3sxPqwAmajs FeAScqk3CfSdy7JUaWMLPV/M/XTgyV7pr5tjQW+6TgsBAHZ21bEaoGyvObiuKdCDltwz qgbQ== X-Gm-Message-State: AOJu0YzFO9pM6q5BRjFloGP6XWqOSexHJpy8s/JD4FrYo9QAEVFJF8US IlI5qA5bazmO+7HmMs/DLpzuR9ngGjpDDF00tA4uyOw6E0PHYkS1/m3x9YlLqm/Ck0I= X-Gm-Gg: Acq92OHttLqY/6jZNSSZO9cs/fLs0QCN8p/VCyuObpxThQKY3ozQRgSJiDi3r2ho5gV oNwtlsnKZ+NN1L5qnTsmooPiQaM9yeQ8+j5AuFktvPM1Z8NJSt7hzHf8miJY15csUx20qoQvQHX /SAWQsT291DN5If4tNnd3Sr+Nn580OIbuhF4T+xUKqpGjjO4wMPbB3g6DQBSa4YCHCGh5c1PNK4 2nHa21DD8a5Fm5qwbXQdKIaYUCWhE5EYrC4caDjs020w5k6Nb3CSXM4bhDAhNIrvfidhn5ysUqX BG6bL/CjSJrzVYpCKacTiR+9iDUX1TkwgX3c+IAVv5x0ZhglHoVoUYrs8UevJ5gwtmOrHxcbWuV IKKvzj09n03KkWEtTtEuo/rwAuYe5xyU92F9HdjyJzVVsWMVKCXoWx5eHOQQk/ebzQN3/cWgVkP KGkM3I8+eBakrUcdbQaRIKScN2DX8Gflc= X-Received: by 2002:a17:903:3dce:b0:2bc:db91:f5a7 with SMTP id d9443c01a7336-2bcdb91f663mr38982865ad.11.1778551893128; Mon, 11 May 2026 19:11:33 -0700 (PDT) Received: from smtpclient.apple ([45.32.121.103]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2baf1d52f1bsm120739805ad.37.2026.05.11.19.11.30 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 11 May 2026 19:11:32 -0700 (PDT) From: Chao Li Content-Type: multipart/mixed; boundary="Apple-Mail=_2771DB79-66D0-4922-87C9-0A2BE276CF00" Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3864.400.21\)) Subject: Fix jsonpath .split_part() to honor silent mode Message-Id: Date: Tue, 12 May 2026 10:10:53 +0800 Cc: Florents Tselai , Andrew Dunstan To: PostgreSQL Hackers X-Mailer: Apple Mail (2.3864.400.21) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --Apple-Mail=_2771DB79-66D0-4922-87C9-0A2BE276CF00 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 Hi, While testing the new json_path method split_part(), I noticed that it = doesn=E2=80=99t honor silent mode. I think this is a v19-new bug. This is a simple repro: ``` evantest=3D# select jsonb_path_query('"a,b"', '$.split_part(",", 0)'); ERROR: field position must not be zero evantest=3D# select jsonb_path_query('"a,b"', '$.split_part(",", 0)', = silent =3D> true); ERROR: field position must not be zero evantest=3D# select jsonb_path_query('"a,b"', '$.split_part(",", = 2147483648)'); ERROR: integer out of range evantest=3D# select jsonb_path_query('"a,b"', '$.split_part(",", = 2147483648)', silent =3D> true); ERROR: integer out of range ``` As a comparison, an existing method such as .decimal() suppresses = similar argument errors in silent mode: ``` evantest=3D# select jsonb_path_query('12.3', = '$.decimal(12345678901,1)'); ERROR: precision of jsonpath item method .decimal() is out of range for = type integer evantest=3D# select jsonb_path_query('12.3', '$.decimal(12345678901,1)', = silent =3D> true); jsonb_path_query ------------------ (0 rows) ``` After looking into the code, I think the root cause is that .decimal() = uses numeric_int4_safe() to parse integer arguments, while the = .split_part() path in executeStringInternalMethod() uses numeric_int4() = directly, which raises an error immediately for invalid values. The attached patch fixes this by switching the .split_part() path to use = numeric_int4_safe() and report the argument errors through the jsonpath = error handling mechanism. Please see the attached patch for details. Best regards, -- Chao Li (Evan) HighGo Software Co., Ltd. https://www.highgo.com/ --Apple-Mail=_2771DB79-66D0-4922-87C9-0A2BE276CF00 Content-Disposition: attachment; filename=v1-0001-Fix-jsonpath-.split_part-to-honor-silent-mode.patch Content-Type: application/octet-stream; x-unix-mode=0644; name="v1-0001-Fix-jsonpath-.split_part-to-honor-silent-mode.patch" Content-Transfer-Encoding: quoted-printable =46rom=20f75ae350b7a1b3398cffda315d00943890c92292=20Mon=20Sep=2017=20= 00:00:00=202001=0AFrom:=20"Chao=20Li=20(Evan)"=20=0A= Date:=20Tue,=2012=20May=202026=2009:54:35=20+0800=0ASubject:=20[PATCH=20= v1]=20Fix=20jsonpath=20.split_part()=20to=20honor=20silent=20mode=0A=0A= The=20jsonpath=20.split_part()=20method=20passed=20its=20field-position=20= argument=0Athrough=20numeric_int4()=20and=20then=20called=20split_part()=20= directly.=20=20As=20a=0Aresult,=20int4=20overflow=20and=20zero=20= field-position=20errors=20were=20thrown=20outside=0Ajsonpath's=20= RETURN_ERROR()=20path,=20so=20they=20were=20not=20suppressed=20when=0A= jsonpath=20functions=20were=20called=20with=20silent=20=3D>=20true.=0A=0A= Fix=20this=20by=20converting=20the=20numeric=20argument=20with=20= numeric_int4_safe()=20and=0Achecking=20for=20a=20zero=20field=20position=20= in=20jsonpath_exec.c,=20reporting=20both=0Aerrors=20through=20= RETURN_ERROR().=0A=0AAdd=20regression=20tests=20for=20zero=20and=20= out-of-range=20field=20positions,=20including=0Asilent=20mode.=0A=0A= Author:=20Chao=20Li=20=0AReviewed-by:=0ADiscussion:=20= https://postgr.es/m/=0A---=0A=20src/backend/utils/adt/jsonpath_exec.c=20=20= =20=20=20=20=20=20|=2019=20++++++++++++++++---=0A=20= src/test/regress/expected/jsonb_jsonpath.out=20|=2014=20++++++++++++++=0A= =20src/test/regress/sql/jsonb_jsonpath.sql=20=20=20=20=20=20|=20=204=20= ++++=0A=203=20files=20changed,=2034=20insertions(+),=203=20deletions(-)=0A= =0Adiff=20--git=20a/src/backend/utils/adt/jsonpath_exec.c=20= b/src/backend/utils/adt/jsonpath_exec.c=0Aindex=20= 0ec9b4df2ef..6cc2acb4254=20100644=0A---=20= a/src/backend/utils/adt/jsonpath_exec.c=0A+++=20= b/src/backend/utils/adt/jsonpath_exec.c=0A@@=20-3017,7=20+3017,8=20@@=20= executeStringInternalMethod(JsonPathExecContext=20*cxt,=20JsonPathItem=20= *jsp,=0A=20=09=09case=20jpiStrSplitPart:=0A=20=09=09=09{=0A=20=09=09=09=09= char=09=20=20=20*from_str;=0A-=09=09=09=09Numeric=09=09n;=0A+=09=09=09=09= int32=09=09n;=0A+=09=09=09=09ErrorSaveContext=20escontext=20=3D=20= {T_ErrorSaveContext};=0A=20=0A=20=09=09=09=09jspGetLeftArg(jsp,=20= &elem);=0A=20=09=09=09=09if=20(elem.type=20!=3D=20jpiString)=0A@@=20= -3029,13=20+3030,25=20@@=20= executeStringInternalMethod(JsonPathExecContext=20*cxt,=20JsonPathItem=20= *jsp,=0A=20=09=09=09=09if=20(elem.type=20!=3D=20jpiNumeric)=0A=20=09=09=09= =09=09elog(ERROR,=20"invalid=20jsonpath=20item=20type=20for=20= .split_part()");=0A=20=0A-=09=09=09=09n=20=3D=20jspGetNumeric(&elem);=0A= +=09=09=09=09n=20=3D=20numeric_int4_safe(jspGetNumeric(&elem),=0A+=09=09=09= =09=09=09=09=09=09=20=20(Node=20*)=20&escontext);=0A+=09=09=09=09if=20= (escontext.error_occurred)=0A+=09=09=09=09=09RETURN_ERROR(ereport(ERROR,=0A= +=09=09=09=09=09=09=09=09=09=09=20= errcode(ERRCODE_INVALID_PARAMETER_VALUE),=0A+=09=09=09=09=09=09=09=09=09=09= =20errmsg("field=20position=20of=20jsonpath=20item=20method=20.%s()=20is=20= out=20of=20range=20for=20type=20integer",=0A+=09=09=09=09=09=09=09=09=09=09= =09=09jspOperationName(jsp->type))));=0A+=0A+=09=09=09=09if=20(n=20=3D=3D=20= 0)=0A+=09=09=09=09=09RETURN_ERROR(ereport(ERROR,=0A+=09=09=09=09=09=09=09= =09=09=09=20errcode(ERRCODE_INVALID_PARAMETER_VALUE),=0A+=09=09=09=09=09=09= =09=09=09=09=20errmsg("field=20position=20of=20jsonpath=20item=20method=20= .%s()=20must=20not=20be=20zero",=0A+=09=09=09=09=09=09=09=09=09=09=09=09= jspOperationName(jsp->type))));=0A=20=0A=20=09=09=09=09resStr=20=3D=20= TextDatumGetCString(DirectFunctionCall3Coll(split_part,=0A=20=09=09=09=09= =09=09=09=09=09=09=09=09=09=09=09=09=09=20DEFAULT_COLLATION_OID,=0A=20=09= =09=09=09=09=09=09=09=09=09=09=09=09=09=09=09=09=20str,=0A=20=09=09=09=09= =09=09=09=09=09=09=09=09=09=09=09=09=09=20CStringGetTextDatum(from_str),=0A= -=09=09=09=09=09=09=09=09=09=09=09=09=09=09=09=09=09=20= DirectFunctionCall1(numeric_int4,=20NumericGetDatum(n))));=0A+=09=09=09=09= =09=09=09=09=09=09=09=09=09=09=09=09=09=20Int32GetDatum(n)));=0A=20=09=09= =09=09break;=0A=20=09=09=09}=0A=20=09=09default:=0Adiff=20--git=20= a/src/test/regress/expected/jsonb_jsonpath.out=20= b/src/test/regress/expected/jsonb_jsonpath.out=0Aindex=20= afa6c4cb529..81efebc3d0f=20100644=0A---=20= a/src/test/regress/expected/jsonb_jsonpath.out=0A+++=20= b/src/test/regress/expected/jsonb_jsonpath.out=0A@@=20-3073,6=20+3073,20=20= @@=20select=20jsonb_path_query('"abc,def,ghi,jkl"',=20'$.split_part(",",=20= -2)');=0A=20=20"ghi"=0A=20(1=20row)=0A=20=0A+select=20= jsonb_path_query('"a,b"',=20'$.split_part(",",=200)');=0A+ERROR:=20=20= field=20position=20of=20jsonpath=20item=20method=20.split_part()=20must=20= not=20be=20zero=0A+select=20jsonb_path_query('"a,b"',=20= '$.split_part(",",=200)',=20silent=20=3D>=20true);=0A+=20= jsonb_path_query=20=0A+------------------=0A+(0=20rows)=0A+=0A+select=20= jsonb_path_query('"a,b"',=20'$.split_part(",",=202147483648)');=0A= +ERROR:=20=20field=20position=20of=20jsonpath=20item=20method=20= .split_part()=20is=20out=20of=20range=20for=20type=20integer=0A+select=20= jsonb_path_query('"a,b"',=20'$.split_part(",",=202147483648)',=20silent=20= =3D>=20true);=0A+=20jsonb_path_query=20=0A+------------------=0A+(0=20= rows)=0A+=0A=20--=20Test=20string=20methods=20play=20nicely=20together=0A= =20select=20jsonb_path_query('"hello=20world"',=20= '$.replace("hello","bye").upper()');=0A=20=20jsonb_path_query=20=0Adiff=20= --git=20a/src/test/regress/sql/jsonb_jsonpath.sql=20= b/src/test/regress/sql/jsonb_jsonpath.sql=0Aindex=20= d3a38c57791..c1f4ab5422e=20100644=0A---=20= a/src/test/regress/sql/jsonb_jsonpath.sql=0A+++=20= b/src/test/regress/sql/jsonb_jsonpath.sql=0A@@=20-721,6=20+721,10=20@@=20= select=20jsonb_path_query('"hello=20world"',=20'$.replace("hello","bye")=20= starts=20with=20"=0A=20--=20Test=20.split_part()=0A=20select=20= jsonb_path_query('"abc~@~def~@~ghi"',=20'$.split_part("~@~",=202)');=0A=20= select=20jsonb_path_query('"abc,def,ghi,jkl"',=20'$.split_part(",",=20= -2)');=0A+select=20jsonb_path_query('"a,b"',=20'$.split_part(",",=20= 0)');=0A+select=20jsonb_path_query('"a,b"',=20'$.split_part(",",=200)',=20= silent=20=3D>=20true);=0A+select=20jsonb_path_query('"a,b"',=20= '$.split_part(",",=202147483648)');=0A+select=20= jsonb_path_query('"a,b"',=20'$.split_part(",",=202147483648)',=20silent=20= =3D>=20true);=0A=20=0A=20--=20Test=20string=20methods=20play=20nicely=20= together=0A=20select=20jsonb_path_query('"hello=20world"',=20= '$.replace("hello","bye").upper()');=0A--=20=0A2.50.1=20(Apple=20= Git-155)=0A=0A= --Apple-Mail=_2771DB79-66D0-4922-87C9-0A2BE276CF00--