Skip to content

v3: add a k="q" query payload variant (no c field) for scalar domains #356

Description

@coderdan

Problem

v3 has no scalar query wire shape. Every scalar domain CHECK requires the ciphertext key c, and the RIGHTARG = jsonb operator overloads cast the bound parameter to the domain — so a WHERE-clause needle must be a full stored envelope even though c plays no part in any comparison. Consequences:

  • Clients must run full encryption (record ciphertext + every required term) just to build a query parameter; v2 generated only the one term the predicate needed (e.g. bloom-only {v,k,i,bf} for a match query vs v3's {v,i,c,hm,ob,bf} for text_search).
  • Every scalar query ships a larger parameter and evaluates the domain CHECK on it in-plan (fixed per-execution overhead, visible in the release benchmarks as inflated small-tier deltas).
  • eql-bindings::from_v2_query deliberately refuses scalar targets (UnsupportedQueryTarget) rather than invent a shape ahead of this design.

Proposal (from team discussion 2026-07-03)

Add a k = "q" payload variant with no c field — either accepted by the existing domains' CHECKs (c required only when k != "q"), or as parallel *_query domain types the comparison wrappers accept on the RHS (the pattern eql_v3.jsonb_query already establishes for SteVec needles). from_v2_query can then support scalar targets, and consumers stop paying stored-envelope costs per query.

Note interaction with the jsonb_entry CHECK issue: whatever validates the new variant should be an inline CHECK expression, not a SQL function (domain constraints can't inline them).

Evidence

Parameter shapes recorded in results/query/v3/*_metadata_*.json and the Issues section of v3-regressions-report.md on cipherstash/benches#23.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions