diff --git a/executor/insert_test.go b/executor/insert_test.go index d0cf9d00608dc..2b66f80bf31cf 100644 --- a/executor/insert_test.go +++ b/executor/insert_test.go @@ -97,6 +97,18 @@ func (s *testSuite) TestInsertOnDuplicateKey(c *C) { tk.MustQuery(`select * from t;`).Check(testkit.Rows(`1 2 3`)) } +func (s *testSuite) TestUpdateDuplicateKey(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + + tk.MustExec(`drop table if exists t;`) + tk.MustExec(`create table c(i int,j int,k int,primary key(i,j,k));`) + tk.MustExec(`insert into c values(1,2,3);`) + tk.MustExec(`insert into c values(1,2,4);`) + _, err := tk.Exec(`update c set i=1,j=2,k=4 where i=1 and j=2 and k=3;`) + c.Assert(err.Error(), Equals, "[kv:1062]Duplicate entry '1-2-4' for key 'PRIMARY'") +} + func (s *testSuite) TestInsertWrongValueForField(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") diff --git a/executor/write_test.go b/executor/write_test.go index c7476e9a8b3ae..902bd5fd2121b 100644 --- a/executor/write_test.go +++ b/executor/write_test.go @@ -1000,7 +1000,7 @@ func (s *testSuite) TestUpdate(c *C) { _, err = tk.Exec("update ignore t set a = 1 where a = 2;") c.Assert(err, IsNil) r = tk.MustQuery("SHOW WARNINGS;") - r.Check(testkit.Rows("Warning 1062 key already exist")) + r.Check(testkit.Rows("Warning 1062 Duplicate entry '1' for key 'I_uniq'")) tk.MustQuery("select * from t").Check(testkit.Rows("1", "2")) tk.MustExec("drop table if exists t") diff --git a/table/tables/tables.go b/table/tables/tables.go index 37bd31a5ce788..4cfc7a85303a1 100644 --- a/table/tables/tables.go +++ b/table/tables/tables.go @@ -748,6 +748,16 @@ func (t *tableCommon) removeRowIndex(sc *stmtctx.StatementContext, rm kv.Retriev // buildIndexForRow implements table.Table BuildIndexForRow interface. func (t *tableCommon) buildIndexForRow(ctx sessionctx.Context, rm kv.RetrieverMutator, h int64, vals []types.Datum, idx table.Index) error { if _, err := idx.Create(ctx, rm, vals, h); err != nil { + if kv.ErrKeyExists.Equal(err) { + // Make error message consistent with MySQL. + entryKey, err1 := t.genIndexKeyStr(vals) + if err1 != nil { + // if genIndexKeyStr failed, return the original error. + return errors.Trace(err) + } + + return kv.ErrKeyExists.FastGen("Duplicate entry '%s' for key '%s'", entryKey, idx.Meta().Name) + } return errors.Trace(err) } return nil