Thread

Commits

  1. Report undefined jsonpath variable when no variables are supplied

  1. BUG #19458: OOM killer in jsonb_path_exists_opr (@?) with malformed JSONPath containing non-existent variables

    The Post Office <noreply@postgresql.org> — 2026-04-17T11:20:34Z

    The following bug has been logged on the website:
    
    Bug reference:      19458
    Logged by:          Andrey Rachitskiy
    Email address:      pl0h0yp1@gmail.com
    PostgreSQL version: 14.22
    Operating system:   Debian GNU/Linux 12 (bookworm)
    Description:        
    
    Description:
    During fuzzing of the jsonb_path_exists_opr (operator jsonb @? jsonpath, a
    two-argument version of jsonb_path_exists()), a pathological query was
    discovered that causes uncontrolled memory consumption, leading to OOM
    Killer on PostgreSQL versions REL_14/15/16_STABLE.
    On versions 17 and 18, the same query returns a proper error instead of
    crashing the server.
    This bug was found using AFL++ as a fuzzer and LibBlobStamper as a tool for
    creating syntactically correct arguments.
    
    Reproduction:
    Execute the following query:
    ```sql
    select '[3472328296227680304, 3472328296227680304, 3472328296227680304,
    3472328296227680304, 3472328296227680304, 3472328296227680304,
    3472328296227680304, 3472328296227680304, 3472328296227680304,
    3472328296227680304, 3472328296227680304, 3472328296227680304,
    13558284848669739, 3472328296227668016, 3472328296227680304,
    3472328296227680304, 3472328296227680304, 3472328296227680304,
    3472328296227680304, 3472328296227680304, 3472328296227680304,
    3472328296227680304, 3472328296227680304, 3472328296227680304,
    3472328296227680304, 3472328296227680304, 3472328296227680304,
    3472328296227680304, 3472328296227680304, 3472328296227680304,
    3472328296227680304, 3472328296227680304, 3472328296227680304,
    3472328296227680304, 3472328296227680304, 3472328296227680304,
    3472328296227680304, 3472328296227680304, 3472328296227680304,
    3472328296227680304, 3472328296227680304, 3472328296227680304,
    3472328296227680304, 3472328296227680304, 3472328296227680304,
    3472328296227680304, 3472328295419228208, 3472328296227680304,
    3528904766546522246, 3472328296227680304, 3472328296227680304,
    3472328296227680304, 3472328296227680304, 3472328296227680304,
    3472328296227680304, 3472328296227680304, 3472328296227680304,
    3472328296227680304, 3472328296227680304, 3472328296227680304,
    3472328296227680304, 3472328296227680304, 3472328296227680304,
    3472328296227680304, 3472328296227680304, 3472328296227680304,
    3472328296227680304, 3472328296227680304, 3472328296227680304,
    3472328296227680304, 3472328296227680304, 3472328296227680304,
    3472328296227680304, 3472328296227680304, 3472328296227680304,
    3472328296227680304, 3472328296227680304, 3472328296227680304,
    3472328296227680304, 3472328296227680304, 3472328296227680304,
    3472328296227680304, 3472328296227680304, 3472328296227680304,
    3472328296227680304, 3472328296227680304, 3472328296227680304,
    3472328296227680304, 3472328296227680304, 3472328296328343600,
    3472328296227680304, 3472328296227680299, 3472328296227680304,
    3472328296227680304, 3472328296227680304, 3472328296227680304,
    3472328296227680304, 3472328296227680304, 3472328296227680304,
    3472328296227680304, 3472328296227680304, 3472328296227680304,
    3472328296227680304, 3472328296227680304, 3472328296227680304,
    3472328296227680304, 3470920921344127024, 3906362710315511856,
    3472328296228075062, 3472328296227680304, 3472328296227680304,
    3472328296227680304, 3472334893297446960, 3472328090069248816,
    13511005849006128, 3472328296227680304, 3472328296227680304,
    3472328296227680304, 3472328296227680304, 3472328296227680304,
    3472328296227680304, 3472328296227680304, 3472328296227680304,
    3472328296227680304, 3472328296227680304, 3472328296227680304,
    3472328296227680304, 3472328296227680304, 3472328296227680304,
    3472328296227680304, 3472328296227680304, 3472328296227680304,
    3472328296227680304, 3472328296227680304, 3472328296227680304,
    3472328296227680304, 3472328296227680304, 3472328296227680304,
    13563782407139376, 4337019423877509168]'::jsonb @? '(-$?(0 <
    ($"〰〭〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰" - $?(0 < $"〰〰〰〰〰〰〰〰〰〰〰〰〰〰" - $?(0 + $ <
    $"㘰〰㘶〰")."〰〰〰〰")."〰〰〰〰〰〰〰〰") - 0?(+$ < $"〰
    〰〰〰")."ほ〰〰㘰")."〰〰〰〶〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰")'::jsonpath;
    ```
    
    Expected result:
    The query should return an error, as happens on versions 17 and 18:
    ERROR:  could not find jsonpath variable "〰〭〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰"
    
    Actual result (14, 15, 16):
      - Memory consumption grows until the kernel kills the postgres process via
    OOM Killer
      - Client loses connection:
           server closed the connection unexpectedly
           This probably means the server terminated abnormally
           before or while processing the request.
    
    Kernel log:
    516294.487767] Out of memory: Killed process 1135405 (postgres)
    total-vm:13521932kB, anon-rss:9170792kB, file-rss:92kB, shmem-rss:1848kB,
    UID:1002 pgtables:26176kB oom_score_adj:0
    
    --
    Regards,
    Andrey Rachitskiy
    Postgres Professional
    
    
    
    
    
    
  2. Re: BUG #19458: OOM killer in jsonb_path_exists_opr (@?) with malformed JSONPath containing non-existent variables

    Andrey Rachitskiy <pl0h0yp1@gmail.com> — 2026-04-20T13:38:38Z

    I propose a targeted backpatch for REL_14/15/16 in jsonpath_exec.c to align
    missing variable handling with newer branches and prevent pathological
    memory growth on malformed/hostile jsonpath expressions.
    
    Why this is not a full backport
    This is intentionally not a full backport of the REL_17 jsonpath executor
    refactoring (callbacks for variable access, broader executor integration,
    etc.).
    
    Why this still fixes the reported issue
    On REL_14/15/16, with current behavior (missing vars -> null), some crafted
    jsonpath expressions continue deep evaluation and can consume very large
    memory, leading to OOM.
    With this patch, execution fails early on undefined variable, matching
    REL_17 behavior for this case and avoiding runaway memory use.
    
    —
    Regards,
    Andrey Rachitskiy
    Postgres Professional
    
    пт, 17 апр. 2026 г. в 16:21, PG Bug reporting form <noreply@postgresql.org>:
    
    > The following bug has been logged on the website:
    >
    > Bug reference:      19458
    > Logged by:          Andrey Rachitskiy
    > Email address:      pl0h0yp1@gmail.com
    > PostgreSQL version: 14.22
    > Operating system:   Debian GNU/Linux 12 (bookworm)
    > Description:
    >
    > Description:
    > During fuzzing of the jsonb_path_exists_opr (operator jsonb @? jsonpath, a
    > two-argument version of jsonb_path_exists()), a pathological query was
    > discovered that causes uncontrolled memory consumption, leading to OOM
    > Killer on PostgreSQL versions REL_14/15/16_STABLE.
    > On versions 17 and 18, the same query returns a proper error instead of
    > crashing the server.
    > This bug was found using AFL++ as a fuzzer and LibBlobStamper as a tool for
    > creating syntactically correct arguments.
    >
    > Reproduction:
    > Execute the following query:
    > ```sql
    > select '[3472328296227680304, 3472328296227680304, 3472328296227680304,
    > 3472328296227680304, 3472328296227680304, 3472328296227680304,
    > 3472328296227680304, 3472328296227680304, 3472328296227680304,
    > 3472328296227680304, 3472328296227680304, 3472328296227680304,
    > 13558284848669739, 3472328296227668016, 3472328296227680304,
    > 3472328296227680304, 3472328296227680304, 3472328296227680304,
    > 3472328296227680304, 3472328296227680304, 3472328296227680304,
    > 3472328296227680304, 3472328296227680304, 3472328296227680304,
    > 3472328296227680304, 3472328296227680304, 3472328296227680304,
    > 3472328296227680304, 3472328296227680304, 3472328296227680304,
    > 3472328296227680304, 3472328296227680304, 3472328296227680304,
    > 3472328296227680304, 3472328296227680304, 3472328296227680304,
    > 3472328296227680304, 3472328296227680304, 3472328296227680304,
    > 3472328296227680304, 3472328296227680304, 3472328296227680304,
    > 3472328296227680304, 3472328296227680304, 3472328296227680304,
    > 3472328296227680304, 3472328295419228208, 3472328296227680304,
    > 3528904766546522246, 3472328296227680304, 3472328296227680304,
    > 3472328296227680304, 3472328296227680304, 3472328296227680304,
    > 3472328296227680304, 3472328296227680304, 3472328296227680304,
    > 3472328296227680304, 3472328296227680304, 3472328296227680304,
    > 3472328296227680304, 3472328296227680304, 3472328296227680304,
    > 3472328296227680304, 3472328296227680304, 3472328296227680304,
    > 3472328296227680304, 3472328296227680304, 3472328296227680304,
    > 3472328296227680304, 3472328296227680304, 3472328296227680304,
    > 3472328296227680304, 3472328296227680304, 3472328296227680304,
    > 3472328296227680304, 3472328296227680304, 3472328296227680304,
    > 3472328296227680304, 3472328296227680304, 3472328296227680304,
    > 3472328296227680304, 3472328296227680304, 3472328296227680304,
    > 3472328296227680304, 3472328296227680304, 3472328296227680304,
    > 3472328296227680304, 3472328296227680304, 3472328296328343600,
    > 3472328296227680304, 3472328296227680299, 3472328296227680304,
    > 3472328296227680304, 3472328296227680304, 3472328296227680304,
    > 3472328296227680304, 3472328296227680304, 3472328296227680304,
    > 3472328296227680304, 3472328296227680304, 3472328296227680304,
    > 3472328296227680304, 3472328296227680304, 3472328296227680304,
    > 3472328296227680304, 3470920921344127024, 3906362710315511856,
    > 3472328296228075062, 3472328296227680304, 3472328296227680304,
    > 3472328296227680304, 3472334893297446960, 3472328090069248816,
    > 13511005849006128, 3472328296227680304, 3472328296227680304,
    > 3472328296227680304, 3472328296227680304, 3472328296227680304,
    > 3472328296227680304, 3472328296227680304, 3472328296227680304,
    > 3472328296227680304, 3472328296227680304, 3472328296227680304,
    > 3472328296227680304, 3472328296227680304, 3472328296227680304,
    > 3472328296227680304, 3472328296227680304, 3472328296227680304,
    > 3472328296227680304, 3472328296227680304, 3472328296227680304,
    > 3472328296227680304, 3472328296227680304, 3472328296227680304,
    > 13563782407139376, 4337019423877509168]'::jsonb @? '(-$?(0 <
    > ($"〰〭〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰" - $?(0 < $"〰〰〰〰〰〰〰〰〰〰〰〰〰〰" - $?(0 + $ <
    > $"㘰〰㘶〰")."〰〰〰〰")."〰〰〰〰〰〰〰〰") - 0?(+$ < $"〰
    >
    > 〰〰〰")."ほ〰〰㘰")."〰〰〰〶〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰")'::jsonpath;
    > ```
    >
    > Expected result:
    > The query should return an error, as happens on versions 17 and 18:
    > ERROR:  could not find jsonpath variable "〰〭〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰〰"
    >
    > Actual result (14, 15, 16):
    >   - Memory consumption grows until the kernel kills the postgres process
    > via
    > OOM Killer
    >   - Client loses connection:
    >        server closed the connection unexpectedly
    >        This probably means the server terminated abnormally
    >        before or while processing the request.
    >
    > Kernel log:
    > 516294.487767] Out of memory: Killed process 1135405 (postgres)
    > total-vm:13521932kB, anon-rss:9170792kB, file-rss:92kB, shmem-rss:1848kB,
    > UID:1002 pgtables:26176kB oom_score_adj:0
    >
    > --
    > Regards,
    > Andrey Rachitskiy
    > Postgres Professional
    >
    >
    >
    
  3. Re: BUG #19458: OOM killer in jsonb_path_exists_opr (@?) with malformed JSONPath containing non-existent variables

    x4mmm@yandex-team.ru — 2026-04-23T18:55:56Z

    
    > On 20 Apr 2026, at 18:38, Andrey Rachitskiy <pl0h0yp1@gmail.com> wrote:
    > 
    > I propose a targeted backpatch for REL_14/15/16 in jsonpath_exec.c to align missing variable handling with newer branches and prevent pathological memory growth on malformed/hostile jsonpath expressions.
    
    Hi! Thank you for the report and proposed fix. I've took a look into the
    patch.
    
    So we can use vars like this:
    
    # SELECT jsonb_path_exists(
    '{"x": 42}'::jsonb,
    '$ ? ($"threshold" < 50)'::jsonpath,
    '{"threshold": 10}'::jsonb -- HERE go vars
    );
    
    Operator @? is doing the same, but without supplied vars. And this thread
    essentially points to buggy handling of vars:
    
    # SELECT j @? '$"no_such_var"'
    FROM (VALUES
      ('{"important": "data"}'::jsonb),
      ('42'::jsonb),
      ('null'::jsonb),
      ('false'::jsonb)
    ) AS t(j);
     ?column?  
    ----------
     t
     t
     t
     t
    (4 rows)
    
    It basically says that path with value of var "no_such_var" exists everywhere.
    
    I think it's a bug, but we would need a JSON Path expert here.
    
    17+ throws an error, which seems suspicious to me too. @? is expected to
    operate in silent mode. Perhaps, we should just return NULL instead of t.
    By using RETURN_ERROR macro. But it might sound overly invasive for back
    branches.
    
    Even if we are going to throw an error, we can give mode details. I'd suggest
    instead of "could not find jsonpath variable \"%s\"" throwing something like
    "no variables supplied to reference by variable \"%s\"" or something along
    those lines.
    
    
    Besides this, the direction of the fix looks good to me. Thank you!
    
    
    Best regards, Andrey Borodin.
    
    
    
  4. Re: BUG #19458: OOM killer in jsonb_path_exists_opr (@?) with malformed JSONPath containing non-existent variables

    Nikita Malakhov <hukutoc@gmail.com> — 2026-04-28T20:19:15Z

    Hi!
    
    According to the Jsonpath standard, malformed expression should return an
    error,
    but not all cases of malformation are thoroughly described.
    
    When this functionality was developed (Jsonpath and SQL/JSON) the absence
    of the variable was considered as malformation and was decided to throw an
    error
    in threads long time ago. In case this behavior to be a subject for change
    it surely
    should not be backported, but the error-throwing code has to.
    I agree that sometimes Json (-path) functionality provides very little info
    on errors,
    and it could be extended.
    
    Changing this behavior is subject for Hackers and should be approved by Tom
    Lane,
    Adres Freund and other people responsible for including Jsonpath and
    SQL/JSON
    into Postgres.
    
    On Tue, Apr 28, 2026 at 7:51 PM Andrey Borodin <x4mmm@yandex-team.ru> wrote:
    
    >
    >
    > > On 20 Apr 2026, at 18:38, Andrey Rachitskiy <pl0h0yp1@gmail.com> wrote:
    > >
    > > I propose a targeted backpatch for REL_14/15/16 in jsonpath_exec.c to
    > align missing variable handling with newer branches and prevent
    > pathological memory growth on malformed/hostile jsonpath expressions.
    >
    > Hi! Thank you for the report and proposed fix. I've took a look into the
    > patch.
    >
    > So we can use vars like this:
    >
    > # SELECT jsonb_path_exists(
    > '{"x": 42}'::jsonb,
    > '$ ? ($"threshold" < 50)'::jsonpath,
    > '{"threshold": 10}'::jsonb -- HERE go vars
    > );
    >
    > Operator @? is doing the same, but without supplied vars. And this thread
    > essentially points to buggy handling of vars:
    >
    > # SELECT j @? '$"no_such_var"'
    > FROM (VALUES
    >   ('{"important": "data"}'::jsonb),
    >   ('42'::jsonb),
    >   ('null'::jsonb),
    >   ('false'::jsonb)
    > ) AS t(j);
    >  ?column?
    > ----------
    >  t
    >  t
    >  t
    >  t
    > (4 rows)
    >
    > It basically says that path with value of var "no_such_var" exists
    > everywhere.
    >
    > I think it's a bug, but we would need a JSON Path expert here.
    >
    > 17+ throws an error, which seems suspicious to me too. @? is expected to
    > operate in silent mode. Perhaps, we should just return NULL instead of t.
    > By using RETURN_ERROR macro. But it might sound overly invasive for back
    > branches.
    >
    > Even if we are going to throw an error, we can give mode details. I'd
    > suggest
    > instead of "could not find jsonpath variable \"%s\"" throwing something
    > like
    > "no variables supplied to reference by variable \"%s\"" or something along
    > those lines.
    >
    >
    > Besides this, the direction of the fix looks good to me. Thank you!
    >
    >
    > Best regards, Andrey Borodin.
    >
    >
    >
    >
    
    -- 
    Regards,
    Nikita Malakhov
    Postgres Professional
    The Russian Postgres Company
    https://postgrespro.ru/
    
  5. Re: BUG #19458: OOM killer in jsonb_path_exists_opr (@?) with malformed JSONPath containing non-existent variables

    x4mmm@yandex-team.ru — 2026-04-30T12:03:29Z

    
    > On 29 Apr 2026, at 01:19, Nikita Malakhov <hukutoc@gmail.com> wrote:
    > 
    > According to the Jsonpath standard, malformed expression should return an error,
    > but not all cases of malformation are thoroughly described.
    > 
    > When this functionality was developed (Jsonpath and SQL/JSON) the absence
    > of the variable was considered as malformation and was decided to throw an error
    > in threads long time ago. In case this behavior to be a subject for change it surely
    > should not be backported, but the error-throwing code has to.
    
    I think you just explained very well why we throw an error. Your arguments against
    silent mode are valid and we don't need to consider RETURN_ERROR any further.
    
    Current master behavior throws an error, in this thread author propose to backport it.
    This might be behavior change for some users. But it seems to me we have to backport,
    because
    
    SELECT '42'::jsonb @? '$"no_such_var"';
    
    should not return true. What do you think?
    
    
    Best regards, Andrey Borodin.
    
    
    
  6. Re: BUG #19458: OOM killer in jsonb_path_exists_opr (@?) with malformed JSONPath containing non-existent variables

    Nikita Malakhov <hukutoc@gmail.com> — 2026-05-26T11:17:45Z

    Hi!
    
    Sorry for the late answer -  I missed this email.
    No objections against backporting error throwing code, sorry if my
    explanation
    was not clear enough, of course OOM is very bad behavior and should be
    corrected,
    even if this would result in changes for some users (hopefully not).
    My point in the previous message was only against silent mode.
    
    Thanks!
    
    On Thu, Apr 30, 2026 at 3:03 PM Andrey Borodin <x4mmm@yandex-team.ru> wrote:
    
    >
    >
    > > On 29 Apr 2026, at 01:19, Nikita Malakhov <hukutoc@gmail.com> wrote:
    > >
    > > According to the Jsonpath standard, malformed expression should return
    > an error,
    > > but not all cases of malformation are thoroughly described.
    > >
    > > When this functionality was developed (Jsonpath and SQL/JSON) the absence
    > > of the variable was considered as malformation and was decided to throw
    > an error
    > > in threads long time ago. In case this behavior to be a subject for
    > change it surely
    > > should not be backported, but the error-throwing code has to.
    >
    > I think you just explained very well why we throw an error. Your arguments
    > against
    > silent mode are valid and we don't need to consider RETURN_ERROR any
    > further.
    >
    > Current master behavior throws an error, in this thread author propose to
    > backport it.
    > This might be behavior change for some users. But it seems to me we have
    > to backport,
    > because
    >
    > SELECT '42'::jsonb @? '$"no_such_var"';
    >
    > should not return true. What do you think?
    >
    >
    > Best regards, Andrey Borodin.
    
    
    
    -- 
    Regards,
    Nikita Malakhov
    Postgres Professional
    The Russian Postgres Company
    https://postgrespro.ru/
    
  7. Re: BUG #19458: OOM killer in jsonb_path_exists_opr (@?) with malformed JSONPath containing non-existent variables

    x4mmm@yandex-team.ru — 2026-05-31T13:33:06Z

    
    > On 26 May 2026, at 16:17, Nikita Malakhov <hukutoc@gmail.com> wrote:
    > 
    > of course OOM is very bad behavior and should be corrected
    
    I think the biggest problem is not OOM, but incorrect results for query
    SELECT '42'::jsonb @? '$"no_such_var"';
    
    
    Best regards, Andrey Borodin.
    
    
    
    
  8. Re: BUG #19458: OOM killer in jsonb_path_exists_opr (@?) with malformed JSONPath containing non-existent variables

    Amit Langote <amitlangote09@gmail.com> — 2026-06-05T08:58:14Z

    Hi,
    
    Before I dig into the patch properly after the weekend, one question
    on the report itself: has anyone traced why the old path runs away on
    memory? We've characterized it as missing-var, then null, then
    evaluation continues, then OOM, but I don't think the actual growing
    allocation has been pinned down. Mostly want to understand whether the
    same runaway is reachable without a missing variable, since raising
    the error early wouldn't catch those cases.
    
    - Thanks, Amit
    
    
    
    
  9. Re: BUG #19458: OOM killer in jsonb_path_exists_opr (@?) with malformed JSONPath containing non-existent variables

    Andrey Rachitskiy <pl0h0yp1@gmail.com> — 2026-06-05T10:03:11Z

    The growing allocation is leaked temporary JsonValueLists in
    executePredicate() (local lseq/rseq, ~1482–1547) and the arithmetic helpers
    executeBinaryArithmExpr() / executeUnaryArithmExpr() (~1561–1684). Each
    nested comparison or arithmetic subexpression materializes operands via
    executeItemOptUnwrapResult[NoThrow]() → executeNextItem() →
    JsonValueListAppend() (~1165, ~2451), but the interim lists are never freed
    before return. For @? specifically, executeJsonPath() also leaks a local
    vals list in strict exists mode (~579–586).
    
    Missing vars make the AFL case worse by returning null instead of error, so
    evaluation continues deep into nested $?()/comparisons instead of stopping
    at the first $"…" reference. The same leak mechanism is reachable without
    missing vars — Tom Lane demonstrated this on master (5a2043bf713) with $[*]
    ? (@ < $) on a large array.
    
    Our missing-variable patch fixes the reported OOM and the @? semantics bug
    by aborting early. Whether REL_14/15/16 also need a broader fix for interim
    JsonValueList cleanup is beyond what I can confidently propose; I've tried
    to pin down where the growth happens for that discussion.
    
    пт, 5 июн. 2026 г. в 13:58, Amit Langote <amitlangote09@gmail.com>:
    
    > Hi,
    >
    > Before I dig into the patch properly after the weekend, one question
    > on the report itself: has anyone traced why the old path runs away on
    > memory? We've characterized it as missing-var, then null, then
    > evaluation continues, then OOM, but I don't think the actual growing
    > allocation has been pinned down. Mostly want to understand whether the
    > same runaway is reachable without a missing variable, since raising
    > the error early wouldn't catch those cases.
    >
    > - Thanks, Amit
    >
    
  10. Re: BUG #19458: OOM killer in jsonb_path_exists_opr (@?) with malformed JSONPath containing non-existent variables

    Nikita Malakhov <hukutoc@gmail.com> — 2026-06-05T10:57:27Z

    Hi!
    
    Thank you very much for this investigation! I'd take a look into the patch
    after the weekend.
    
    On Fri, Jun 5, 2026 at 1:03 PM Andrey Rachitskiy <pl0h0yp1@gmail.com> wrote:
    
    > The growing allocation is leaked temporary JsonValueLists in
    > executePredicate() (local lseq/rseq, ~1482–1547) and the arithmetic helpers
    > executeBinaryArithmExpr() / executeUnaryArithmExpr() (~1561–1684). Each
    > nested comparison or arithmetic subexpression materializes operands via
    > executeItemOptUnwrapResult[NoThrow]() → executeNextItem() →
    > JsonValueListAppend() (~1165, ~2451), but the interim lists are never freed
    > before return. For @? specifically, executeJsonPath() also leaks a local
    > vals list in strict exists mode (~579–586).
    >
    > Missing vars make the AFL case worse by returning null instead of error,
    > so evaluation continues deep into nested $?()/comparisons instead of
    > stopping at the first $"…" reference. The same leak mechanism is reachable
    > without missing vars — Tom Lane demonstrated this on master (5a2043bf713)
    > with $[*] ? (@ < $) on a large array.
    >
    > Our missing-variable patch fixes the reported OOM and the @? semantics bug
    > by aborting early. Whether REL_14/15/16 also need a broader fix for interim
    > JsonValueList cleanup is beyond what I can confidently propose; I've tried
    > to pin down where the growth happens for that discussion.
    >
    > пт, 5 июн. 2026 г. в 13:58, Amit Langote <amitlangote09@gmail.com>:
    >
    >> Hi,
    >>
    >> Before I dig into the patch properly after the weekend, one question
    >> on the report itself: has anyone traced why the old path runs away on
    >> memory? We've characterized it as missing-var, then null, then
    >> evaluation continues, then OOM, but I don't think the actual growing
    >> allocation has been pinned down. Mostly want to understand whether the
    >> same runaway is reachable without a missing variable, since raising
    >> the error early wouldn't catch those cases.
    >>
    >> - Thanks, Amit
    >>
    >
    
    -- 
    Regards,
    Nikita Malakhov
    Postgres Professional
    The Russian Postgres Company
    https://postgrespro.ru/
    
  11. Re: BUG #19458: OOM killer in jsonb_path_exists_opr (@?) with malformed JSONPath containing non-existent variables

    Amit Langote <amitlangote09@gmail.com> — 2026-06-17T08:27:25Z

    Hi Andrey,
    
    On Fri, Jun 5, 2026 at 7:03 PM Andrey Rachitskiy <pl0h0yp1@gmail.com> wrote:
    > The growing allocation is leaked temporary JsonValueLists in executePredicate() (local lseq/rseq, ~1482–1547) and the arithmetic helpers executeBinaryArithmExpr() / executeUnaryArithmExpr() (~1561–1684). Each nested comparison or arithmetic subexpression materializes operands via executeItemOptUnwrapResult[NoThrow]() → executeNextItem() → JsonValueListAppend() (~1165, ~2451), but the interim lists are never freed before return. For @? specifically, executeJsonPath() also leaks a local vals list in strict exists mode (~579–586).
    >
    > Missing vars make the AFL case worse by returning null instead of error, so evaluation continues deep into nested $?()/comparisons instead of stopping at the first $"…" reference. The same leak mechanism is reachable without missing vars — Tom Lane demonstrated this on master (5a2043bf713) with $[*] ? (@ < $) on a large array.
    >
    > Our missing-variable patch fixes the reported OOM and the @? semantics bug by aborting early. Whether REL_14/15/16 also need a broader fix for interim JsonValueList cleanup is beyond what I can confidently propose; I've tried to pin down where the growth happens for that discussion.
    
    Thanks for that tracedown and for pointing to Tom's commit. The deeper
    interim-JsonValueList leak looks unlikely to get fixed in the back
    branches; Tom's cleanup (5a2043bf713) went only to master.
    
    I'll look at committing the attached revised version of your Apr 20
    patch (same fix, plus a regression test) down to REL_14. Please
    check/test.
    
    -- 
    Thanks, Amit Langote
    
  12. Re: BUG #19458: OOM killer in jsonb_path_exists_opr (@?) with malformed JSONPath containing non-existent variables

    Andrey Rachitskiy <pl0h0yp1@gmail.com> — 2026-06-17T09:57:48Z

    Hi Amit,
    
    I tested patch
    v2-0001-Report-undefined-jsonpath-variable-when-no-variab.patch on:
    
    REL_14_STABLE
    REL_15_STABLE
    REL_16_STABLE
    
    Results:
    The patch applies cleanly on all three branches.
    Regression tests added/affected by the patch pass on all three branches:
    REL_14: all relevant tests passed
    REL_15: all relevant tests passed
    REL_16: all relevant tests passed
    The provided jsonpath reproducer query now consistently returns an error
    about an undefined jsonpath variable on all three branches, which matches
    the expected behavior change from this patch.
    
    Conclusion:
    The patch looks good from the testing side and can be merged.
    
    ср, 17 июн. 2026 г. в 13:27, Amit Langote <amitlangote09@gmail.com>:
    
    > Hi Andrey,
    >
    > On Fri, Jun 5, 2026 at 7:03 PM Andrey Rachitskiy <pl0h0yp1@gmail.com>
    > wrote:
    > > The growing allocation is leaked temporary JsonValueLists in
    > executePredicate() (local lseq/rseq, ~1482–1547) and the arithmetic helpers
    > executeBinaryArithmExpr() / executeUnaryArithmExpr() (~1561–1684). Each
    > nested comparison or arithmetic subexpression materializes operands via
    > executeItemOptUnwrapResult[NoThrow]() → executeNextItem() →
    > JsonValueListAppend() (~1165, ~2451), but the interim lists are never freed
    > before return. For @? specifically, executeJsonPath() also leaks a local
    > vals list in strict exists mode (~579–586).
    > >
    > > Missing vars make the AFL case worse by returning null instead of error,
    > so evaluation continues deep into nested $?()/comparisons instead of
    > stopping at the first $"…" reference. The same leak mechanism is reachable
    > without missing vars — Tom Lane demonstrated this on master (5a2043bf713)
    > with $[*] ? (@ < $) on a large array.
    > >
    > > Our missing-variable patch fixes the reported OOM and the @? semantics
    > bug by aborting early. Whether REL_14/15/16 also need a broader fix for
    > interim JsonValueList cleanup is beyond what I can confidently propose;
    > I've tried to pin down where the growth happens for that discussion.
    >
    > Thanks for that tracedown and for pointing to Tom's commit. The deeper
    > interim-JsonValueList leak looks unlikely to get fixed in the back
    > branches; Tom's cleanup (5a2043bf713) went only to master.
    >
    > I'll look at committing the attached revised version of your Apr 20
    > patch (same fix, plus a regression test) down to REL_14. Please
    > check/test.
    >
    > --
    > Thanks, Amit Langote
    >
    
    
    -- 
    ---
    Regards,
    Andrey Rachitskiy
    Postgres Professional
    
  13. Re: BUG #19458: OOM killer in jsonb_path_exists_opr (@?) with malformed JSONPath containing non-existent variables

    Amit Langote <amitlangote09@gmail.com> — 2026-06-18T06:57:20Z

    On Wed, Jun 17, 2026 at 6:58 PM Andrey Rachitskiy <pl0h0yp1@gmail.com> wrote:
    >
    > Hi Amit,
    >
    > I tested patch v2-0001-Report-undefined-jsonpath-variable-when-no-variab.patch on:
    >
    > REL_14_STABLE
    > REL_15_STABLE
    > REL_16_STABLE
    >
    > Results:
    > The patch applies cleanly on all three branches.
    > Regression tests added/affected by the patch pass on all three branches:
    > REL_14: all relevant tests passed
    > REL_15: all relevant tests passed
    > REL_16: all relevant tests passed
    > The provided jsonpath reproducer query now consistently returns an error about an undefined jsonpath variable on all three branches, which matches the expected behavior change from this patch.
    >
    > Conclusion:
    > The patch looks good from the testing side and can be merged.
    
    Thanks for checking, pushed.
    
    -- 
    Thanks, Amit Langote