Skip to content

Data: build declared indexes CONCURRENTLY on Postgres#81

Merged
jwicks31 merged 1 commit into
mainfrom
claude/concurrent-index
Jun 13, 2026
Merged

Data: build declared indexes CONCURRENTLY on Postgres#81
jwicks31 merged 1 commit into
mainfrom
claude/concurrent-index

Conversation

@jwicks31

Copy link
Copy Markdown
Owner

What

Final operator item from the roadmap. Declaring an index on a large, live collection shouldn't block writes — so on Postgres the documents expression index is now built and dropped with CREATE/DROP INDEX CONCURRENTLY. SQLite keeps plain CREATE/DROP INDEX (different locking model, single-VM).

How

  • Dialect gains createIndex(name, expr) / dropIndex(name) so the keyword set is per-backend (CONCURRENTLY only on Postgres).
  • setIndexes drops its surrounding transaction — CREATE INDEX CONCURRENTLY can't run inside one — and instead runs the declaration update + index DDL as sequential autocommit statements (each db.run is its own implicit transaction on Postgres). The shared physical index is still dropped only once the last project undeclares it.

Verification

  • SQLite 66/66 — the index unit tests still find the expected expression index (json_extract(...)) in sqlite_master, and the shared-index refcount behavior is unchanged.
  • Postgres 48/48 (Postgres 16) — the declared-indexes HTTP test exercises the CONCURRENTLY path end-to-end (declare → query → reconcile → drop). It would fail with "cannot run inside a transaction block" if this were mis-wired, so green proves it.
  • Docs + the README roadmap updated — this clears the planned "next" list; what remains is the larger/later tier (identity/JWT, webhooks, per-project AI config, npm+GHCR publish).

https://claude.ai/code/session_018efxvWw3MRjdtvE5xgBqya


Generated by Claude Code

Declaring an index on a large, live collection shouldn't block writes. On
Postgres the documents expression index is now created/dropped with
CREATE/DROP INDEX CONCURRENTLY; SQLite keeps plain CREATE/DROP INDEX.

- Dialect gains createIndex(name, expr)/dropIndex(name) so the keyword set is
  per-backend. setIndexes drops its surrounding transaction (CONCURRENTLY can't
  run in one) and runs the declaration update + index DDL as sequential
  autocommit statements; the shared physical index is still dropped only once the
  last project undeclares it.

Verification: 66/66 SQLite (the index unit tests still see the expected
expression index in sqlite_master), 48/48 Postgres 16 — the declared-indexes
HTTP test exercises the CONCURRENTLY path (which errors inside a txn if
mis-wired). Docs + roadmap updated.
@jwicks31 jwicks31 merged commit c101626 into main Jun 13, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants