Skip to content

EQL v3 jsonb_path_query does not aggregate array entries #977

Open

Description

@tobyhede

eql_v3.jsonb_path_query returns one row per matching array entry. Downstream
array operations therefore receive a single entry instead of one gathered array
document; for example, a two-element array can report a length of one.

EQL v2 gathered entries sharing the array selector before returning them. The v3
surface needs equivalent container-based aggregation while preserving domain
typing and scalar path-query behaviour.

Acceptance criteria

  • A path query selecting a two-element encrypted array returns one array result.
  • jsonb_array_length(jsonb_path_query(...)) returns two for that result.
  • jsonb_array_elements expands the gathered result exactly once.
  • The JSON path functions remain inlinable and have regression coverage for
    planner shape as well as correctness.
  • The fix follows the umbrella array wire contract and does not reintroduce an
    unauthenticated array marker.

Activity

  1. coderdan commented on Oct 21, 2026

    @coderdan
    Contributor

    Noting how the EQL v4 json_tree family (#1288, #1325, #1329) answers the same need, since it does not reuse the v3 path.

    eql_v4.json_tree_path_query(doc, selector) is deliberately one row per matching entry, like v3 here, because every element of an array shares its parent's selector. Gathering is a separate operation: eql_v4.json_tree_subtree(doc, token) returns the array's elements and everything beneath them from one client-derived token, and the client reassembles the array in order from the rows (each node's ciphertext carries its label and child count). So a two-element array comes back as one array value, and jsonb_array_length on it is two. The v4 path functions stay inlinable SQL; the walk is a recursive CTE and the PR's benchmarks record its cost.

    v3 jsonb_path_query is unchanged by that work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions