Fix jsonpath .split_part() to honor silent mode

First seen: 2026-05-12 02:10:53+00:00 · Messages: 2 · Participants: 2

Latest Update

2026-05-14 · claude-opus-4-6

Fix jsonpath .split_part() to Honor Silent Mode

Core Problem

PostgreSQL's jsonpath execution engine has a well-established contract: when silent => true is passed to jsonpath query functions (jsonb_path_query, jsonb_path_exists, jsonb_path_match, etc.), errors from invalid inputs or out-of-range arguments should be suppressed, returning empty results instead of throwing exceptions. This is architecturally critical because jsonpath is defined by the SQL/JSON standard, and the silent/lax mode semantics dictate that type errors and argument errors are treated as "no match" rather than hard failures — enabling robust querying over heterogeneous JSON data without requiring the caller to pre-validate every value.

The bug reported here is that the split_part() jsonpath method, newly introduced in PostgreSQL v19, violates this contract. Two specific failure modes are identified:

  1. Zero field position: $.split_part(",", 0) raises ERROR: field position must not be zero even in silent mode.
  2. Integer overflow: $.split_part(",", 2147483648) raises ERROR: integer out of range even in silent mode.

Both cases should return zero rows when silent => true.

Root Cause Analysis

The issue traces to how integer arguments are parsed from jsonpath numeric literals inside the executor. The jsonpath executor processes method arguments as Numeric values internally (since jsonpath literals are parsed as numeric), and these must be converted to int4 for methods that require integer parameters.

PostgreSQL provides two conversion paths:

The existing .decimal() method already correctly uses numeric_int4_safe() to parse its precision and scale arguments, then routes any conversion failure through the jsonpath error reporting mechanism (RETURN_ERROR()), which respects the silent flag. The .split_part() implementation, being newer code, missed this pattern and called numeric_int4() directly — a classic oversight when adding new methods to an existing framework.

Proposed Fix

The patch makes a targeted change in executeStringInternalMethod() (likely in src/backend/utils/adt/jsonpath_exec.c):

  1. Replace the call to numeric_int4() with numeric_int4_safe() for parsing the field position argument of .split_part().
  2. Check the boolean return value of numeric_int4_safe().
  3. On failure (overflow), route the error through the jsonpath error reporting infrastructure (RETURN_ERROR() macro or equivalent), which checks whether silent mode is active and either suppresses the error (returning empty) or re-raises it as appropriate.
  4. Similarly handle the zero-position check through the same error reporting path rather than a direct ereport(ERROR, ...).

This is a minimal, low-risk fix that aligns .split_part() with the established pattern used by .decimal() and other methods.

Architectural Implications

This bug highlights an important maintainability concern in the jsonpath executor: every new method added must carefully use the "safe" variants of type conversion functions and route all errors through the jsonpath error handling mechanism. There is no compile-time enforcement of this — it relies entirely on developer discipline and code review. As more jsonpath methods are added (v19 appears to have added several string methods), this class of bug becomes increasingly likely.

A potential future improvement would be to centralize argument parsing into a shared helper (e.g., jspGetIntArg()) that always uses safe conversion and always routes errors through the jsonpath error handler, making it impossible for individual method implementations to accidentally bypass silent mode.

Assessment

This is a clear, well-diagnosed bug with a straightforward fix. The reporter correctly identified not just the symptom but the exact root cause (the difference between numeric_int4() and numeric_int4_safe()), provided a clean reproduction case, and submitted a patch. The confirming review validates both the diagnosis and the fix. This should be a quick commit for v19 before release or in an early minor release.