Skip to content

prisma-next: encrypted-column functional indexes cannot be auto-created (upstream: no expression-index support in the contract) #835

Description

@coderdan

Summary

@cipherstash/prisma-next cannot automatically create the functional indexes that encrypted (EQL v3) columns need. Every encrypted predicate and ORDER BY works without them — but sequential-scans, silently. The indexes must currently be authored by hand as rawSql operations in the migration history.

This is tracked here so it doesn't get lost: the root cause is an upstream Prisma Next limitation — the schema/contract surface cannot express functional (expression) indexes (@@index takes fields, not expressions), so there is nothing the extension pack can hang an index contribution on in the structured schema diff. The upstream issue has been raised with the Prisma Next team.

Current behaviour

  • The adapter emits the encrypted query operators (eqlEq, eqlGt, eqlMatch, eqlAsc, eqlJsonContains, …), all of which lower to the eql_v3.* extractor forms (eq_term, ord_term/ord_term_ore, match_term, …) that structurally match functional indexes.
  • The extension pack's migrations/cipherstash/ contract space installs the EQL bundle — but contributes no per-column index DDL.
  • Users must add a rawSql migration operation per indexed column (CREATE INDEX … USING btree (eql_v3.eq_term(col)), etc. plus ANALYZE), as documented in skills/stash-prisma-next and skills/stash-indexing.

Why it matters

  • The failure mode is invisible: queries return correct results, tests pass, and nothing flags the missing index until the table is big enough for the sequential scan to hurt.
  • The adapter has everything it needs to know which indexes each column wants — the contract carries each column's domain and { castAs, capabilities }, and the domain registry carries the index metadata. The gap is purely that there is no first-class place in the migration plan to put an expression index.

Paths forward (in rough preference order)

  1. Upstream: Prisma Next grows support for expression/functional indexes in the contract + planner (the raised upstream issue). The extension pack could then contribute one index per capability per encrypted column automatically, the same way it contributes the EQL install.
  2. Interim, ours: the extension pack (or a stash command) generates the rawSql index operations from the contract — the user still commits a migration, but nobody hand-writes extractor expressions. This would also close the "which expression is right for which domain" discoverability gap.
  3. Status quo, documented: hand-authored rawSql recipes (what the skills document today). Acceptable short-term; this issue exists so it doesn't quietly become the permanent answer.

Related

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions