From 2c68cc08c315d5873e73114b6034f28279c9c937 Mon Sep 17 00:00:00 2001 From: ti-srebot <66930949+ti-srebot@users.noreply.github.com> Date: Fri, 17 Jun 2022 17:16:35 +0800 Subject: [PATCH] executor: replace should not change other rows when auto ID is out of range (#30301) (#32324) close pingcap/tidb#29483 --- executor/insert_common.go | 5 +++++ executor/insert_test.go | 15 +++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/executor/insert_common.go b/executor/insert_common.go index e16253a7756bc..9c7adbb3c4d1a 100644 --- a/executor/insert_common.go +++ b/executor/insert_common.go @@ -682,6 +682,11 @@ func setDatumAutoIDAndCast(ctx sessionctx.Context, d *types.Datum, id int64, col d.SetAutoID(id, col.Flag) var err error *d, err = table.CastValue(ctx, *d, col.ToInfo(), false, false) + if err == nil && d.GetInt64() < id { + // Auto ID is out of range, the truncated ID is possible to duplicate with an existing ID. + // To prevent updating unrelated rows in the REPLACE statement, it is better to throw an error. + return autoid.ErrAutoincReadFailed + } return err } diff --git a/executor/insert_test.go b/executor/insert_test.go index 0d6788dad075a..72735d160440d 100644 --- a/executor/insert_test.go +++ b/executor/insert_test.go @@ -1825,3 +1825,18 @@ func (s *testAutoRandomSuite) TestInsertIssue29892(c *C) { c.Assert(err, NotNil) c.Assert(strings.Contains(err.Error(), "Duplicate entry"), Equals, true) } + +// https://github.com/pingcap/tidb/issues/29483. +func (s *testSuite13) TestReplaceAllocatingAutoID(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("drop database if exists replace_auto_id;") + tk.MustExec("create database replace_auto_id;") + tk.MustExec(`use replace_auto_id;`) + + tk.MustExec("SET sql_mode='NO_ENGINE_SUBSTITUTION';") + tk.MustExec("DROP TABLE IF EXISTS t1;") + tk.MustExec("CREATE TABLE t1 (a tinyint not null auto_increment primary key, b char(20));") + tk.MustExec("INSERT INTO t1 VALUES (127,'maxvalue');") + // Note that this error is different from MySQL's duplicated primary key error. + tk.MustGetErrCode("REPLACE INTO t1 VALUES (0,'newmaxvalue');", errno.ErrAutoincReadFailed) +}