Skip to content

Make EQL reinstall safe: rebuild indexes and reject unsafe dependencies #918

Description

@coderdan

Problem

EQL intentionally reinstalls its disposable eql_v3 and eql_v3_internal schemas with DROP SCHEMA ... CASCADE. Encrypted data remains safe because every data-bearing column domain lives in public, but PostgreSQL also removes customer-owned objects that depend on disposable EQL functions or types.

Functional search indexes then disappear silently and queries fall back to sequential scans. Policies, constraints, views, generated expressions, triggers, and unknown dependency classes are more dangerous because their meaning cannot be safely reconstructed automatically.

Decision

Keep the EQL v2 persistence boundary. Do not introduce object-by-object upgrade scripts or per-release schemas.

Design: docs/superpowers/specs/2026-08-31-eql-safe-reinstall-design.md
ADR: docs/adr/0001-eql-data-survives-disposable-schema-reinstall.md

Implementation

Teach stash eql upgrade and force-install to use one safe-reinstall protocol:

  1. Acquire an advisory lifecycle lock.
  2. Discover dependency paths from eql_v3 and eql_v3_internal to customer-owned objects.
  3. Allowlist reconstructable functional indexes and capture complete pg_get_indexdef() definitions.
  4. Abort before mutation for any policy, constraint, view, generated expression, trigger, or unknown dependency; print the complete inventory.
  5. Execute the shipped installer transactionally.
  6. Recreate captured indexes and ANALYZE affected tables.
  7. Verify every index exists, is valid/ready, matches its definition, and engages through EQL validation.
  8. Exit non-zero with exact recovery SQL if reconstruction fails.

Acceptance criteria

  • Reinstall with no external dependencies succeeds.
  • Supported functional indexes are captured, rebuilt, and verified.
  • Unique, partial, quoted-name, non-public-schema, partitioned, included-column, tablespace, and storage-parameter cases are tested and allowlisted or rejected before mutation.
  • Policies, constraints, views, generated columns, triggers, and unknown dependencies abort before schema drop.
  • Installer failure leaves the previous installation and indexes intact.
  • Reconstruction failure is loud, actionable, and safe to retry.
  • The command never reports success with a captured index missing or invalid.

Related work

#959 proves install, uninstall, and reinstall never lose encrypted data. This issue owns derived indexes and every non-data dependency affected by disposable schema replacement.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions