Skip to content

Commit

Permalink
insert: fix the auto id retry won't cast the datum to origin type (pi…
Browse files Browse the repository at this point in the history
  • Loading branch information
ti-srebot authored Nov 25, 2021
1 parent 421d819 commit 75f81d2
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 3 deletions.
15 changes: 12 additions & 3 deletions executor/insert_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -756,7 +756,10 @@ func (e *InsertValues) adjustAutoIncrementDatum(ctx context.Context, d types.Dat
if retryInfo.Retrying {
id, ok := retryInfo.GetCurrAutoIncrementID()
if ok {
d.SetAutoID(id, c.Flag)
err := setDatumAutoIDAndCast(e.ctx, &d, id, c)
if err != nil {
return types.Datum{}, err
}
return d, nil
}
}
Expand Down Expand Up @@ -829,7 +832,10 @@ func (e *InsertValues) adjustAutoRandomDatum(ctx context.Context, d types.Datum,
if retryInfo.Retrying {
autoRandomID, ok := retryInfo.GetCurrAutoRandomID()
if ok {
d.SetAutoID(autoRandomID, c.Flag)
err := setDatumAutoIDAndCast(e.ctx, &d, autoRandomID, c)
if err != nil {
return types.Datum{}, err
}
return d, nil
}
}
Expand All @@ -855,7 +861,10 @@ func (e *InsertValues) adjustAutoRandomDatum(ctx context.Context, d types.Datum,
return types.Datum{}, err
}
e.ctx.GetSessionVars().StmtCtx.InsertID = uint64(recordID)
d.SetAutoID(recordID, c.Flag)
err = setDatumAutoIDAndCast(e.ctx, &d, recordID, c)
if err != nil {
return types.Datum{}, err
}
retryInfo.AddAutoRandomID(recordID)
return d, nil
}
Expand Down
30 changes: 30 additions & 0 deletions executor/insert_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1326,3 +1326,33 @@ func (s *testSuite9) TestIssue26762(c *C) {
_, err = tk.Exec("insert into t1 values('2020-02-31');")
c.Assert(err.Error(), Equals, `[table:1366]Incorrect date value: '2020-02-31' for column 'c1' at row 1`)
}

// TestInsertIssue29892 test the double type with auto_increment problem, just leverage the serial test suite.
func (s *testAutoRandomSuite) TestInsertIssue29892(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec(`use test`)

tk.MustExec("set global tidb_txn_mode='optimistic';")
tk.MustExec("set global tidb_disable_txn_auto_retry=false;")
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(a double auto_increment key, b int)")
tk.MustExec("insert into t values (146576794, 1)")

tk1 := testkit.NewTestKit(c, s.store)
tk1.MustExec(`use test`)
tk1.MustExec("begin")
tk1.MustExec("insert into t(b) select 1")

tk2 := testkit.NewTestKit(c, s.store)
tk2.MustExec(`use test`)
tk2.MustExec("begin")
tk2.MustExec("insert into t values (146576795, 1)")
tk2.MustExec("insert into t values (146576796, 1)")
tk2.MustExec("commit")

// since the origin auto-id (146576795) is cached in retryInfo, it will be fetched again to do the retry again,
// which will duplicate with what has been inserted in tk1.
_, err := tk1.Exec("commit")
c.Assert(err, NotNil)
c.Assert(strings.Contains(err.Error(), "Write conflict"), Equals, true)
}
1 change: 1 addition & 0 deletions types/datum.go
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@ func (d *Datum) GetRaw() []byte {
}

// SetAutoID set the auto increment ID according to its int flag.
// Don't use it directly, useless wrapped with setDatumAutoIDAndCast.
func (d *Datum) SetAutoID(id int64, flag uint) {
if mysql.HasUnsignedFlag(flag) {
d.SetUint64(uint64(id))
Expand Down

0 comments on commit 75f81d2

Please sign in to comment.