Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions migrations/0001_add_query_indexes.down.sql

This file was deleted.

24 changes: 0 additions & 24 deletions migrations/0001_add_query_indexes.up.sql

This file was deleted.

9 changes: 9 additions & 0 deletions migrations/0003_drop_redundant_query_indexes.down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
-- 0003_drop_redundant_query_indexes.down.sql
--
-- Deliberately empty, as with 0002.
--
-- 0003 drops indexes that duplicate ones AutoMigrate maintains. Recreating them
-- would restore the duplication this migration exists to remove, so a truthful
-- revert does nothing. The indexes that matter were never dropped.

SELECT 1;
29 changes: 29 additions & 0 deletions migrations/0003_drop_redundant_query_indexes.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
-- 0003_drop_redundant_query_indexes.up.sql
--
-- Removes the indexes 0001_add_query_indexes created, and deletes that
-- migration. They duplicate indexes GORM's AutoMigrate already creates from
-- struct tags on the models:
--
-- ModelDocument.ModelProjectID index:docScope,priority:1
-- ModelDocument.ModelCollectionID index:docScope,priority:2
-- ModelDocument.CreatedAt index:docScope,priority:3
-- ModelCollection.ModelProjectID index
-- ModelSchema.ModelCollectionID index
--
-- AutoMigrate emits "docScope"; 0001 emitted "idx_restcol_documents_docscope".
-- Same three columns, different names — so 0001's CREATE INDEX IF NOT EXISTS
-- never matched, and applying it produced a second index over identical
-- columns. Six indexes where three suffice, costing write throughput and disk
-- for no read benefit. Measured, see FootprintAI/grandturks#986.
--
-- Only the migration-created names are dropped here. The AutoMigrate ones are
-- the real indexes and must stay; the two sets are distinguishable because
-- GORM quotes the hyphenated table name (idx_restcol-collections_...) where
-- 0001 used underscores (idx_restcol_collections_...).
--
-- A no-op on any environment that never applied 0001, which on the evidence in
-- grandturks#984 is most of them.

DROP INDEX IF EXISTS idx_restcol_documents_docscope;
DROP INDEX IF EXISTS idx_restcol_collections_model_project_id;
DROP INDEX IF EXISTS idx_restcol_collections_schema_model_collection_id;
22 changes: 21 additions & 1 deletion migrations/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ migrate -path migrations \
`psql` also works for quick one-off application:

```bash
psql "$DATABASE_URL" -f migrations/0001_add_query_indexes.up.sql
psql "$DATABASE_URL" -f migrations/0002_purge_soft_deleted_documents.up.sql
```

## Writing a new migration
Expand All @@ -58,3 +58,23 @@ baseline/snapshot migration matching the current live schema, and deciding how
to handle the existing AutoMigrate state. Track that as a separate project.

[golang-migrate]: https://github.com/golang-migrate/migrate

## What is here, and what is deliberately not

| | |
|---|---|
| `0002_purge_soft_deleted_documents` | erases document rows tombstoned before DeleteDocument became a hard delete (#137). Irreversible; its down migration is a documented no-op |
| `0003_drop_redundant_query_indexes` | removes the indexes `0001` used to create |

**There is no `0001`.** It added query indexes that GORM's `AutoMigrate` already
creates from `index:` struct tags on the models — the same columns under
different names, so its `CREATE INDEX IF NOT EXISTS` never matched and applying
it produced a second index over each. It was deleted rather than fixed: a
migration that re-declares what the models already declare is a second source of
truth for the same schema, and the models win.

Do not re-add index migrations for indexes struct tags can express. Add a
migration when the change is one struct tags *cannot* describe — a backfill, a
data purge, an index built concurrently, a column rewrite.

Numbering is not reused: `0003` follows `0002` even though `0001` is gone.
Loading