fix: order modified foreign keys after added unique constraints#475
fix: order modified foreign keys after added unique constraints#475meesvandongen wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds regression coverage and updates dependency ordering to ensure tables that add UNIQUE/PK constraints are processed before tables whose modified foreign keys reference them.
Changes:
- Extend
topologicallySortModifiedTablesto treat modified FKs as dependencies on newly added UNIQUE/PK constraints. - Add a unit test covering “modified FK depends on added UNIQUE” ordering.
- Add new testdata fixtures (old/new schema + diff/plan outputs) for two related dependency scenarios.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| testdata/diff/dependency/issue_modified_fk_to_new_unique_reverse_order/plan.txt | Adds expected human-readable plan output fixture for reverse-order scenario. |
| testdata/diff/dependency/issue_modified_fk_to_new_unique_reverse_order/plan.sql | Adds expected SQL plan fixture for reverse-order scenario. |
| testdata/diff/dependency/issue_modified_fk_to_new_unique_reverse_order/plan.json | Adds expected JSON plan fixture for reverse-order scenario. |
| testdata/diff/dependency/issue_modified_fk_to_new_unique_reverse_order/old.sql | Adds “before” schema fixture for reverse-order scenario. |
| testdata/diff/dependency/issue_modified_fk_to_new_unique_reverse_order/new.sql | Adds “after” schema fixture for reverse-order scenario. |
| testdata/diff/dependency/issue_modified_fk_to_new_unique_reverse_order/diff.sql | Adds expected diff SQL fixture for reverse-order scenario. |
| testdata/diff/dependency/issue_modified_fk_to_new_unique/plan.txt | Adds expected human-readable plan output fixture for non-prefixed tables scenario. |
| testdata/diff/dependency/issue_modified_fk_to_new_unique/plan.sql | Adds expected SQL plan fixture for non-prefixed tables scenario. |
| testdata/diff/dependency/issue_modified_fk_to_new_unique/plan.json | Adds expected JSON plan fixture for non-prefixed tables scenario. |
| testdata/diff/dependency/issue_modified_fk_to_new_unique/old.sql | Adds “before” schema fixture for non-prefixed tables scenario. |
| testdata/diff/dependency/issue_modified_fk_to_new_unique/new.sql | Adds “after” schema fixture for non-prefixed tables scenario. |
| testdata/diff/dependency/issue_modified_fk_to_new_unique/diff.sql | Adds expected diff SQL fixture for non-prefixed tables scenario. |
| internal/diff/topological_test.go | Adds regression test for ordering modified FK table after referenced table with newly added UNIQUE. |
| internal/diff/topological.go | Updates modified-table topological sort to consider dependencies from modified foreign keys. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| for _, constraintDiff := range tdA.ModifiedConstraints { | ||
| processFKDependency(constraintDiff.New) | ||
| } |
| // topologicallySortModifiedTables sorts modified tables based on constraint dependencies. | ||
| // Tables with added UNIQUE/PK constraints that are referenced by other tables' added OR | ||
| // modified FKs will come before those tables. |
Greptile SummaryThis PR updates modified-table dependency ordering for foreign keys that target newly added keys. The main changes are:
Confidence Score: 3/5This is close, but the ordering fix still misses a valid composite foreign key case.
Important Files Changed
Reviews (1): Last reviewed commit: "fix: order modified foreign keys after a..." | Re-trigger Greptile |
| if constraintMatchesFKReference(constraint, fkConstraint) { | ||
| // Add edge: tableB (with new UNIQUE/PK) -> tableA (with new FK) | ||
| adjList[keyB] = append(adjList[keyB], keyA) | ||
| inDegree[keyA]++ | ||
| break | ||
| return | ||
| } |
There was a problem hiding this comment.
This still only adds the dependency edge when the referenced column order exactly matches the new UNIQUE/PK order. PostgreSQL allows a composite FK such as REFERENCES parent (b, a) to use UNIQUE (a, b), and the existing FK recreation planner already treats this as an unordered column set. When a modified FK references the newly added key in the opposite order, constraintMatchesFKReference returns false, so the dependent table can still be ordered before the referenced table and the migration can fail before the unique constraint exists.
| if constraintMatchesFKReference(constraint, fkConstraint) { | |
| // Add edge: tableB (with new UNIQUE/PK) -> tableA (with new FK) | |
| adjList[keyB] = append(adjList[keyB], keyA) | |
| inDegree[keyA]++ | |
| break | |
| return | |
| } | |
| if fkReferencesAnyConstraint(fkConstraint, []*ir.Constraint{constraint}) { | |
| adjList[keyB] = append(adjList[keyB], keyA) | |
| inDegree[keyA]++ | |
| return | |
| } |
When a migration adds a new
UNIQUE/PRIMARY KEYconstraint and also modifies an existing foreign key to reference it, the foreign key can be recreated before the referenced constraint exists.This change updates modified-table dependency ordering so modified foreign keys are applied after newly added referenced
UNIQUE/PRIMARY KEYconstraints.