[SQLite-kit] Keep column UNIQUE when the same column also has a plain index - #6063
Open
soya-miyoshi wants to merge 1 commit into
Open
Conversation
In the SQLite schema serializer, a column declared with `.unique()` loses its UNIQUE constraint when the same column also has a plain, non-unique `index()`. Nothing is emitted in its place, so uniqueness silently disappears from the generated DDL and duplicates become insertable. The `hasUniqueIndex` check exists to avoid emitting an inline UNIQUE on top of a unique index that already enforces the same thing. The predicate, however, never looks at whether the index is unique — it matches any single-column index on that column, so a plain index suppresses the constraint too. Fixed by ignoring non-unique indexes in that lookup. Deduplication against a real `uniqueIndex()` is unchanged. Affects both `generate` and `push` (they share this serializer); the issue was reported against the `push` table-recreate path. Fixes drizzle-team#6060
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #6060
Problem
In the SQLite schema serializer, a column declared with
.unique()silently loses its UNIQUE constraint when the same column also has a plain, non-uniqueindex()declared on it. Nothing is emitted in its place — no inlineUNIQUE, noCREATE UNIQUE INDEX— so uniqueness disappears from the generated DDL and duplicate rows become insertable.This is most visible on the
pushtable-recreate path (__new_<table>+INSERT ... SELECT+DROP+RENAME), where an existing UNIQUE guarantee is dropped without any prompt or warning. It affectsgeneratetoo, since both share the serializer.A sibling
.unique()column without a plain index keeps its constraint, which isolates the trigger to the.unique()+index()combination on the same column — a very common pattern (unique business key + a covering query index).Root cause
fromDrizzleSchemaindrizzle-kit/src/dialects/sqlite/drizzle.tscomputes ahasUniqueIndexflag whose purpose is to avoid emitting an inlineUNIQUEon top of a column that is already covered by auniqueIndex()(which would duplicate the constraint). The predicate, however, never checks whether the matched index is actually unique — it matches any single-column index on that column. So a plainindex()suppresses the inlineUNIQUEjust as auniqueIndex()would, but without providing any replacement enforcement.Fix
Ignore non-unique indexes in that lookup:
Deduplication against a real
uniqueIndex()is unchanged; only plain indexes stop suppressing the constraint.Tests
Added coverage in
drizzle-kit/tests/sqlite/sqlite-constraints.test.tsfor the bug and its neighbors:.unique()+ plainindex()on the same column → keepsUNIQUE.unique()+ realuniqueIndex()on the same column → still deduplicated (no double constraint).unique()column without an index → unaffectedFull file passes:
Notes
beta(1.0.0-rc.4), which is where the reported code path (src/dialects/sqlite/drizzle.ts) lives.