Skip to content

Fix compilation error with migration file when CREATE UNIQUE INDEX referenced by FOREIGN KEY #732

Merged
AlecKazakova merged 9 commits intosqldelight:masterfrom
griffio:fix-create-unique-index-foreign-key
Mar 18, 2026
Merged

Fix compilation error with migration file when CREATE UNIQUE INDEX referenced by FOREIGN KEY #732
AlecKazakova merged 9 commits intosqldelight:masterfrom
griffio:fix-create-unique-index-foreign-key

Conversation

@griffio
Copy link
Copy Markdown
Contributor

@griffio griffio commented Dec 19, 2025

Fixes sqldelight/sqldelight#4503

Compile error Table table_b does not have a unique index on columns occurs because CREATE UNIQUE INDEX is filtered out of the schema statements used in the check.

This foreign key check could be an ⚔️ edge case where the schema contributor processing needs to include statements (index stmt) that are defined after the statement (table stmt) that triggers the lookup. By design, a statement cannot see tables, views defined later in the same file.

🔮 Attempt to fix migration files using CREATE UNIQUE INDEX and FOREIGN KEY references

This small fix on containingFile.schema<SqlCreateIndexStmt>(this) to remove this (e.g table_b in example below) allows all the schema statements in a containingFile to be accessible not just statements up-to table_b.

This fix now allows a couple of options:

Single migration file - previously even this failed to compile

CREATE TABLE table_a(
    id INTEGER PRIMARY KEY
);

CREATE TABLE table_b(
    id   INTEGER PRIMARY KEY,
    a_id INTEGER NOT NULL REFERENCES table_a (id)
);

CREATE UNIQUE INDEX uk_table_b_a_id_id ON table_b (a_id, id);

-- test that unique index can be validated in same migration file
CREATE TABLE table_c (
    id   INTEGER PRIMARY KEY,
    a_id INTEGER NOT NULL REFERENCES table_a (id),
    b_id INTEGER DEFAULT NULL,
    FOREIGN KEY (a_id, b_id) REFERENCES table_b (a_id, id)
)

Split statements across migrations, however table_b must be in same file as unique index as only includes statements from files with a smaller migration order value.

CREATE TABLE table_a(
    id INTEGER PRIMARY KEY
);

CREATE TABLE table_b(
    id   INTEGER PRIMARY KEY,
    a_id INTEGER NOT NULL REFERENCES table_a (id)
);

CREATE UNIQUE INDEX uk_table_b_a_id_id ON table_b (a_id, id);

More tables with FOREIGN KEY references

-- test that unique index can be validated from external migration file
CREATE TABLE table_c (
    id   INTEGER PRIMARY KEY,
    a_id INTEGER NOT NULL REFERENCES table_a (id),
    b_id INTEGER DEFAULT NULL,
    FOREIGN KEY (a_id, b_id) REFERENCES table_b (a_id, id)
)

Note:
💥 The blast radius of this change is minimized to foreign key index checks and doesn't change the "by design" processing of schema in com.alecstrong.sql.psi.core.SqlFileBase


  • CHANGELOG.md's "Unreleased" section has been updated, if applicable.

Migrations fix.
When checking foreign key unique index constraints are valid, include SqlCreateIndexStmts.
This will only work when the `CREATE UNIQUE INDEX` resides in the same file as the constraint table.
The FOREIGN KEY table can be either in the same file or external.
The CREATE UNIQUE INDEX must be in the same file as the REFERENCES table
@griffio griffio marked this pull request as ready for review March 17, 2026 20:13
@griffio
Copy link
Copy Markdown
Contributor Author

griffio commented Mar 17, 2026

Thanks, needs 🧜 to merge as unable to in this project.

@AlecKazakova AlecKazakova merged commit 6c6b84b into sqldelight:master Mar 18, 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.

Failure to compile with Foreign Key

2 participants