diff --git a/enginetest/queries/foreign_key_queries.go b/enginetest/queries/foreign_key_queries.go index 0ffc225013..c2ddef5dfd 100644 --- a/enginetest/queries/foreign_key_queries.go +++ b/enginetest/queries/foreign_key_queries.go @@ -2581,6 +2581,41 @@ var ForeignKeyTests = []ScriptTest{ }, }, }, + { + // https://github.com/dolthub/dolt/issues/7857 + Name: "partial foreign key update", + SetUpScript: []string{ + "create table parent1 (i int primary key);", + "create table child1 (" + + "i int primary key, " + + "j int, " + + "k int, " + + "index(j), " + + "index(k), " + + "foreign key (j) references parent1 (i)," + + "foreign key (k) references parent1 (i));", + "insert into parent1 values (1);", + "insert into child1 values (100, 1, 1);", + "set foreign_key_checks = 0;", + "insert into child1 values (101, 2, 2);", + "set foreign_key_checks = 1;", + }, + Assertions: []ScriptTestAssertion{ + { + Query: "update child1 set j = 1 where i = 101;", + Expected: []sql.Row{ + {types.OkResult{RowsAffected: 1, Info: plan.UpdateInfo{Matched: 1, Updated: 1}}}, + }, + }, + { + Query: "select * from child1", + Expected: []sql.Row{ + {100, 1, 1}, + {101, 1, 2}, + }, + }, + }, + }, } var CreateForeignKeyTests = []ScriptTest{ diff --git a/sql/plan/foreign_key_editor.go b/sql/plan/foreign_key_editor.go index 63109467ec..fe86ed47b0 100644 --- a/sql/plan/foreign_key_editor.go +++ b/sql/plan/foreign_key_editor.go @@ -81,6 +81,17 @@ func (fkEditor *ForeignKeyEditor) IsInitialized(editors map[*ForeignKeyEditor]st // Update handles both the standard UPDATE statement and propagated referential actions from a parent table's ON UPDATE. func (fkEditor *ForeignKeyEditor) Update(ctx *sql.Context, old sql.Row, new sql.Row, depth int) error { for _, reference := range fkEditor.References { + // Only check the reference for the columns that are updated + hasChange := false + for _, idx := range reference.RowMapper.IndexPositions { + if old[idx] != new[idx] { + hasChange = true + break + } + } + if !hasChange { + continue + } if err := reference.CheckReference(ctx, new); err != nil { return err }