Thread

  1. BUG: jsonpath .split_part() bypasses lax-mode error suppression

    SATYANARAYANA NARLAPURAM <satyanarlapuram@gmail.com> — 2026-04-18T16:31:03Z

    Hi hackers,
    
    The jsonpath string method  .split_part() bypasses lax-mode error
    suppression.
    This is because executeStringInternalMethod() uses
    DirectFunctionCall1(numeric_int4, ...)
    to convert the field number from numeric to int4. This throws
    ereport(ERROR) directly,
    bypassing the jspThrowErrors(cxt) / RETURN_ERROR mechanism that other
    methods
    like .double() use correctly.
    
    Reproduction:
    -- These should return NULL in lax mode, but throw hard ERRORs:
    SELECT '"hello-world"'::jsonb @? '$.split_part("-", 99999999999)';
    SELECT '"hello-world"'::jsonb @? '$.split_part("-", 0)';
    ERROR:  integer out of range
    ERROR:  field position must not be zero
    
    
    Fix by replacing the bare DirectFunctionCall with numeric_int4_safe()
    using ErrorSaveContext to catch overflow, and adding an explicit field==0
    check, both gated behind RETURN_ERROR so errors are properly suppressed
    in lax/silent mode while still raised in strict/non-silent mode.
    
    Thanks,
    Satya
    
  2. Re: BUG: jsonpath .split_part() bypasses lax-mode error suppression

    Dmitry Dolgov <9erthalion6@gmail.com> — 2026-04-19T20:21:07Z

    > On Sat, Apr 18, 2026 at 09:31:03AM -0700, SATYANARAYANA NARLAPURAM wrote:
    > Hi hackers,
    > 
    > The jsonpath string method  .split_part() bypasses lax-mode error
    > suppression.
    > This is because executeStringInternalMethod() uses
    > DirectFunctionCall1(numeric_int4, ...)
    > to convert the field number from numeric to int4. This throws
    > ereport(ERROR) directly,
    > bypassing the jspThrowErrors(cxt) / RETURN_ERROR mechanism that other
    > methods
    > like .double() use correctly.
    > 
    > Reproduction:
    > -- These should return NULL in lax mode, but throw hard ERRORs:
    > SELECT '"hello-world"'::jsonb @? '$.split_part("-", 99999999999)';
    > SELECT '"hello-world"'::jsonb @? '$.split_part("-", 0)';
    > ERROR:  integer out of range
    > ERROR:  field position must not be zero
    
    I don't have a SQL standard at hands, it might be worth checking what SQL/JSON
    says about such situations. But at least from the definition of lax mode, given
    in the documentation, current behavior seems to be correct:
    
    	lax (default) &mdash; the path engine implicitly adapts the queried data to
    	the specified path. Any structural errors that cannot be fixed as described
    	below are suppressed, producing no match.
    
    I.e. only structural errors are suppressed, where a structural error defined as:
    
    	An attempt to access a non-existent member of an object or element of an
    	array is defined as a structural error.
    
    In this case what we have is an error, which happens due to an incorrect
    function argument valye (the second argument of split_part, either out of
    integer bound, or zero for 1 based field counting). It has nothing to do with
    the jsonb document, and hence doesn't fall into "structural errors" category.