Skip to content

Commit

Permalink
executor: fix issue of update with same foreign key value returns err…
Browse files Browse the repository at this point in the history
…or (#44907)

close #44848
  • Loading branch information
crazycs520 committed Jun 25, 2023
1 parent d28fdc7 commit b042ba2
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 1 deletion.
24 changes: 24 additions & 0 deletions executor/foreign_key.go
Expand Up @@ -34,6 +34,7 @@ import (
"github.com/pingcap/tidb/types"
driver "github.com/pingcap/tidb/types/parser_driver"
"github.com/pingcap/tidb/util/codec"
"github.com/pingcap/tidb/util/collate"
"github.com/pingcap/tidb/util/execdetails"
"github.com/pingcap/tidb/util/set"
"github.com/tikv/client-go/v2/txnkv/txnsnapshot"
Expand Down Expand Up @@ -161,6 +162,29 @@ func (fkc *FKCheckExec) insertRowNeedToCheck(sc *stmtctx.StatementContext, row [
}

func (fkc *FKCheckExec) updateRowNeedToCheck(sc *stmtctx.StatementContext, oldRow, newRow []types.Datum) error {
newVals, err := fkc.fetchFKValues(newRow)
if err != nil {
return err
}
oldVals, err := fkc.fetchFKValues(oldRow)
if err != nil {
return err
}
if len(oldVals) == len(newVals) {
isSameValue := true
for i := range oldVals {
cmp, err := oldVals[i].Compare(sc, &newVals[i], collate.GetCollator(oldVals[i].Collation()))
if err != nil || cmp != 0 {
isSameValue = false
break
}
}
if isSameValue {
// If the old fk value and the new fk value are the same, no need to check.
return nil
}
}

if fkc.FK != nil {
return fkc.addRowNeedToCheck(sc, newRow)
} else if fkc.ReferredFK != nil {
Expand Down
2 changes: 1 addition & 1 deletion executor/test/fktest/BUILD.bazel
Expand Up @@ -8,7 +8,7 @@ go_test(
"main_test.go",
],
flaky = True,
shard_count = 38,
shard_count = 39,
deps = [
"//config",
"//executor",
Expand Down
12 changes: 12 additions & 0 deletions executor/test/fktest/foreign_key_test.go
Expand Up @@ -2865,3 +2865,15 @@ func TestForeignKeyAndSessionVariable(t *testing.T) {
tk.MustQuery("select * from t1").Check(testkit.Rows())
tk.MustQuery("select * from t2").Check(testkit.Rows())
}

func TestForeignKeyIssue44848(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("set @@foreign_key_checks=1")
tk.MustExec("use test")
tk.MustExec("create table b ( id int(11) NOT NULL AUTO_INCREMENT, f int(11) NOT NULL, PRIMARY KEY (id));")
tk.MustExec("create table a ( id int(11) NOT NULL AUTO_INCREMENT, b_id int(11) NOT NULL, PRIMARY KEY (id), CONSTRAINT fk_b_id FOREIGN KEY (b_id) REFERENCES b (id) ON DELETE CASCADE);")
tk.MustExec("insert b(id,f) values(1,1);")
tk.MustExec("insert a(id,b_id) values(1,1);")
tk.MustExec("update b set id=1,f=2 where id=1;")
}

0 comments on commit b042ba2

Please sign in to comment.