fix: enforce case-insensitive PAT title uniqueness by AmanGIT07 · Pull Request #1489 · raystack/frontier
2-3: The drop-then-create pattern is safe due to implicit transaction wrapping, but a safer approach is still recommended.
In this codebase, migrations using golang-migrate/v4 with PostgreSQL execute multiple semicolon-separated statements within an implicit single transaction. The two statements in this migration (DROP and CREATE) will be atomic, so the index will not be left in an unprotected state if the CREATE fails.
However, the suggested approach (CREATE with a temporary name first, then DROP the old index, then RENAME) remains preferable because it:
- Validates the new index can be built before removing the old one
- Eliminates the brief intermediate state where the constraint doesn't exist, even if transactional
- Is more resilient to future framework or implementation changes
The actual risk here is data validation: if existing data contains case-insensitive duplicates (e.g., records with titles "Test" and "test" for the same user_id and org_id), the CREATE UNIQUE INDEX will fail and the migration will be marked dirty. Verify no such duplicates exist before deploying.
Safer migration ordering
--- Replace case-sensitive unique index with case-insensitive one -DROP INDEX IF EXISTS idx_user_pats_unique_title; -CREATE UNIQUE INDEX idx_user_pats_unique_title ON user_pats(user_id, org_id, LOWER(title)) WHERE deleted_at IS NULL; +CREATE UNIQUE INDEX idx_user_pats_unique_title_ci + ON user_pats(user_id, org_id, LOWER(title)) + WHERE deleted_at IS NULL; +DROP INDEX IF EXISTS idx_user_pats_unique_title; +ALTER INDEX idx_user_pats_unique_title_ci RENAME TO idx_user_pats_unique_title;