| From: | Ewan Young <kdbase(dot)hack(at)gmail(dot)com> |
|---|---|
| To: | PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org> |
| Cc: | Michael Paquier <michael(at)paquier(dot)xyz>, Chao Li <li(dot)evan(dot)chao(at)gmail(dot)com> |
| Subject: | Fix jsonpath .decimal() to honor silent mode |
| Date: | 2026-07-01 07:52:51 |
| Message-ID: | CAON2xHMaigKABiyPBBq3Sjd3gp7uWMJXnnMHt=s85V1ij3KP1w@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Hi
The jsonpath .decimal() method handles an invalid precision/scale
inconsistently in silent mode,
depending only on which internal check happens to catch it:
-- precision too large for int4: caught softly, suppressed
SELECT jsonb_path_query('1.5', '$.decimal(12345678901)', '{}', true);
jsonb_path_query
------------------
(0 rows)
-- precision in int4 range but outside NUMERIC's 1..1000: hard error
SELECT jsonb_path_query('1.5', '$.decimal(1001)', '{}', true);
ERROR: NUMERIC precision 1001 must be between 1 and 1000
Both are the same kind of mistake (a precision the user cannot use),
both are in silent mode, yet
one returns no rows and the other throws. The same hard error also
escapes the @? and @@ operators,
which are documented to suppress datetime and numeric errors:
SELECT '1.5'::jsonb @? '$.decimal(0)';
ERROR: NUMERIC precision 0 must be between 1 and 1000
.decimal(-1) and .decimal(0) behave like the .decimal(1001) case.
The cause is in executeItemOptUnwrapTarget() (jsonpath_exec.c). The
precision and scale
are converted with numeric_int4_safe() using an ErrorSaveContext, so
an int4-overflowing
precision is reported softly. But the subsequent typmod construction
calls numerictypmodin()
through DirectFunctionCall1() with no ErrorSaveContext, so an
out-of-range NUMERIC
precision/scale throws a hard error that silent mode cannot trap.
Every other error path
in .decimal() (the numeric_int4_safe() conversions and the
numeric_in() value coercion) already
reports softly; only the numerictypmodin() call was left bare. This
dates back to 66ea94e8e606.
This is the same direction taken by 954e57708ea6, which made the
sibling jsonpath .split_part()
method honor silent mode.
The attached patch validates precision and scale against their valid
ranges before calling
numerictypmodin(), reporting any violation via RETURN_ERROR() so
silent mode is honored;
after the pre-check numerictypmodin() can no longer throw. In
non-silent mode the message
becomes method-specific and consistent with the other .decimal() errors:
ERROR: precision of jsonpath item method .decimal() must be between 1 and 1000
If reviewers would rather push the ErrorSaveContext down into
numerictypmodin() (or a shared helper)
instead of pre-validating in the caller, I'm happy to reshape it that way.
--
Regards,
Ewan Young
| Attachment | Content-Type | Size |
|---|---|---|
| v1-0001-Fix-jsonpath-decimal-to-honor-silent-mode.patch | application/octet-stream | 6.5 KB |
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Ewan Young | 2026-07-01 08:20:39 | Re: Prevent crash when calling pgstat functions with unregistered stats kind |
| Previous Message | Henson Choi | 2026-07-01 07:49:11 | Re: Tighten pg_uhc_verifychar() to enforce CP949 lead/trail byte ranges |