Skip to content

Commit be6d0bc

Browse files
fix(db): enforce IF EXISTS on DROP INDEX CONCURRENTLY for replay idempotency
Symmetric with the CREATE INDEX CONCURRENTLY rule: a post-COMMIT DROP INDEX CONCURRENTLY replays from the top on failure, so without IF EXISTS it aborts re-dropping an already-gone index. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 84093a2 commit be6d0bc

2 files changed

Lines changed: 14 additions & 0 deletions

File tree

scripts/check-migrations-safety.test.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,13 @@ DROP INDEX CONCURRENTLY IF EXISTS "stale_idx";`
165165
expect(lintSql(sql)).toEqual([])
166166
})
167167

168+
test('DROP INDEX CONCURRENTLY without IF EXISTS is not idempotent', () => {
169+
const sql = `COMMIT;
170+
--> statement-breakpoint
171+
DROP INDEX CONCURRENTLY "stale_idx";`
172+
expect(rules(sql)).toEqual(['error:concurrent-drop-index-not-idempotent'])
173+
})
174+
168175
test('DROP INDEX CONCURRENTLY without a preceding COMMIT errors', () => {
169176
expect(rules('DROP INDEX CONCURRENTLY IF EXISTS "stale_idx";')).toEqual([
170177
'error:concurrent-drop-index-no-commit',

scripts/check-migrations-safety.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,13 @@ function classify(sql: string, createdTables: Set<string>, sawCommit: boolean):
294294
message:
295295
'Plain DROP INDEX takes an ACCESS EXCLUSIVE lock on the table for the whole drop. Use DROP INDEX CONCURRENTLY after a COMMIT; breakpoint (see packages/db/scripts/migrate.ts).',
296296
})
297+
} else if (!/\bIF EXISTS\b/i.test(s)) {
298+
matches.push({
299+
kind: 'error',
300+
rule: 'concurrent-drop-index-not-idempotent',
301+
message:
302+
'DROP INDEX CONCURRENTLY must be IF EXISTS — a failed run replays from the top and would abort re-dropping an already-gone index.',
303+
})
297304
} else if (!sawCommit) {
298305
matches.push({
299306
kind: 'error',

0 commit comments

Comments
 (0)