stash-indexing
Indexing Encrypted Columns (EQL v3)
Encrypted columns can be indexed, and on any non-trivial table they should be. The model is one rule, uniform across every encrypted domain: index a functional expression over the column's term extractor — never an operator class on the column itself. The extractors are inlinable SQL functions, so bare-form predicates (WHERE col = $1, WHERE col < $1, col @@ $1) engage the index with no query rewriting.
This covers EQL v3 — the bundle stash eql install applies (@cipherstash/eql). An integration that is otherwise correct (encrypted at rest, searchable, exact round-trip) but has no index on its encrypted predicates will sequential-scan every encrypted query; that is the default outcome unless you put these indexes in place — the integrations emit query operators, not index DDL (see Where the Index DDL Goes).
When to Use This Skill
- Writing or reviewing a schema migration that adds or changes an encrypted (
eql_v3_*) column. - Deciding which indexes an encrypted column supports — or explaining why a column has none.
- An encrypted query is slow, or
EXPLAINshows aSeq Scanwhere you expected an index. stash eql validatereports "No functional index overeql_v3.…" for a queryable column.- Answering whether encrypted columns can be indexed on Supabase or managed PostgreSQL (yes — see the superuser section).
Which Columns Support Which Index
Capability is fixed by the column's domain type, chosen at schema definition via the types.* factories. N ranges over the numeric-and-time base types Integer, Smallint, Bigint, Date, Timestamp, Numeric, Real, Double; text is listed separately because its ordering domains behave differently (see the note below the table). <t> is the lowercase SQL name (eql_v3_integer_eq, eql_v3_text_ord, …).