From c55a8407c7f37a403a87309a9ca80f5cabff292a Mon Sep 17 00:00:00 2001 From: nange Date: Sat, 6 Jul 2019 08:16:04 +0800 Subject: [PATCH 1/5] executor: fix autoid doesn't handle float, double type and tiny cleanup --- executor/insert_common.go | 24 +++-- executor/insert_test.go | 180 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 197 insertions(+), 7 deletions(-) diff --git a/executor/insert_common.go b/executor/insert_common.go index 61ad191c3b7f7..3f0606586bdfb 100644 --- a/executor/insert_common.go +++ b/executor/insert_common.go @@ -488,12 +488,7 @@ func (e *InsertValues) adjustAutoIncrementDatum(d types.Datum, hasValue bool, c d.SetNull() } if !d.IsNull() { - sc := e.ctx.GetSessionVars().StmtCtx - datum, err1 := d.ConvertTo(sc, &c.FieldType) - if e.filterErr(err1) != nil { - return types.Datum{}, err1 - } - recordID = datum.GetInt64() + recordID = getAutoRecordID(d, &c.FieldType) } // Use the value if it's not null and not 0. if recordID != 0 { @@ -503,7 +498,6 @@ func (e *InsertValues) adjustAutoIncrementDatum(d types.Datum, hasValue bool, c } e.ctx.GetSessionVars().StmtCtx.InsertID = uint64(recordID) retryInfo.AddAutoIncrementID(recordID) - d.SetAutoID(recordID, c.Flag) return d, nil } @@ -531,6 +525,22 @@ func (e *InsertValues) adjustAutoIncrementDatum(d types.Datum, hasValue bool, c return casted, nil } +func getAutoRecordID(d types.Datum, target *types.FieldType) int64 { + var recordID int64 + + switch target.Tp { + case mysql.TypeFloat, mysql.TypeDouble: + f := d.GetFloat64() + recordID = int64(f) + case mysql.TypeTiny, mysql.TypeShort, mysql.TypeInt24, mysql.TypeLong, mysql.TypeLonglong: + recordID = d.GetInt64() + default: + panic("should never happen") + } + + return recordID +} + func (e *InsertValues) handleWarning(err error) { sc := e.ctx.GetSessionVars().StmtCtx sc.AppendWarning(err) diff --git a/executor/insert_test.go b/executor/insert_test.go index 8c3510b044126..a5bbfc7e8c687 100644 --- a/executor/insert_test.go +++ b/executor/insert_test.go @@ -286,3 +286,183 @@ func (s *testSuite3) TestAllowInvalidDates(c *C) { runWithMode("STRICT_TRANS_TABLES,ALLOW_INVALID_DATES") runWithMode("ALLOW_INVALID_DATES") } + +func (s *testSuite3) TestInsertWithAutoidSchema(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec(`use test`) + tk.MustExec(`create table t1(id int primary key auto_increment, n int);`) + tk.MustExec(`create table t2(id int unsigned primary key auto_increment, n int);`) + tk.MustExec(`create table t3(id tinyint primary key auto_increment, n int);`) + tk.MustExec(`create table t4(id int primary key, n float auto_increment, key I_n(n));`) + tk.MustExec(`create table t5(id int primary key, n float unsigned auto_increment, key I_n(n));`) + tk.MustExec(`create table t6(id int primary key, n double auto_increment, key I_n(n));`) + tk.MustExec(`create table t7(id int primary key, n double unsigned auto_increment, key I_n(n));`) + + tests := []struct { + insert string + query string + result [][]interface{} + }{ + { + `insert into t1(id, n) values(1, 1)`, + `select * from t1 where id = 1`, + testkit.Rows(`1 1`), + }, + { + `insert into t1(n) values(2)`, + `select * from t1 where id = 2`, + testkit.Rows(`2 2`), + }, + { + `insert into t1(n) values(3)`, + `select * from t1 where id = 3`, + testkit.Rows(`3 3`), + }, + { + `insert into t1(id, n) values(-1, 4)`, + `select * from t1 where id = -1`, + testkit.Rows(`-1 4`), + }, + { + `insert into t1(n) values(5)`, + `select * from t1 where id = 4`, + testkit.Rows(`4 5`), + }, + { + `insert into t2(id, n) values(1, 1)`, + `select * from t2 where id = 1`, + testkit.Rows(`1 1`), + }, + { + `insert into t2(n) values(2)`, + `select * from t2 where id = 2`, + testkit.Rows(`2 2`), + }, + { + `insert into t2(n) values(3)`, + `select * from t2 where id = 3`, + testkit.Rows(`3 3`), + }, + { + `insert into t3(id, n) values(1, 1)`, + `select * from t3 where id = 1`, + testkit.Rows(`1 1`), + }, + { + `insert into t3(n) values(2)`, + `select * from t3 where id = 2`, + testkit.Rows(`2 2`), + }, + { + `insert into t3(n) values(3)`, + `select * from t3 where id = 3`, + testkit.Rows(`3 3`), + }, + { + `insert into t3(id, n) values(-1, 4)`, + `select * from t3 where id = -1`, + testkit.Rows(`-1 4`), + }, + { + `insert into t3(n) values(5)`, + `select * from t3 where id = 4`, + testkit.Rows(`4 5`), + }, + { + `insert into t4(id, n) values(1, 1)`, + `select * from t4 where id = 1`, + testkit.Rows(`1 1`), + }, + { + `insert into t4(id) values(2)`, + `select * from t4 where id = 2`, + testkit.Rows(`2 2`), + }, + { + `insert into t4(id, n) values(3, -1)`, + `select * from t4 where id = 3`, + testkit.Rows(`3 -1`), + }, + { + `insert into t4(id) values(4)`, + `select * from t4 where id = 4`, + testkit.Rows(`4 3`), + }, + { + `insert into t4(id, n) values(5, 5.5)`, + `select * from t4 where id = 5`, + testkit.Rows(`5 5.5`), + }, + { + `insert into t4(id) values(6)`, + `select * from t4 where id = 6`, + testkit.Rows(`6 6`), + }, + { + `insert into t5(id, n) values(1, 1)`, + `select * from t5 where id = 1`, + testkit.Rows(`1 1`), + }, + { + `insert into t5(id) values(2)`, + `select * from t5 where id = 2`, + testkit.Rows(`2 2`), + }, + { + `insert into t5(id) values(3)`, + `select * from t5 where id = 3`, + testkit.Rows(`3 3`), + }, + { + `insert into t6(id, n) values(1, 1)`, + `select * from t6 where id = 1`, + testkit.Rows(`1 1`), + }, + { + `insert into t6(id) values(2)`, + `select * from t6 where id = 2`, + testkit.Rows(`2 2`), + }, + { + `insert into t6(id, n) values(3, -1)`, + `select * from t6 where id = 3`, + testkit.Rows(`3 -1`), + }, + { + `insert into t6(id) values(4)`, + `select * from t6 where id = 4`, + testkit.Rows(`4 3`), + }, + { + `insert into t6(id, n) values(5, 5.5)`, + `select * from t6 where id = 5`, + testkit.Rows(`5 5.5`), + }, + { + `insert into t6(id) values(6)`, + `select * from t6 where id = 6`, + testkit.Rows(`6 6`), + }, + { + `insert into t7(id, n) values(1, 1)`, + `select * from t7 where id = 1`, + testkit.Rows(`1 1`), + }, + { + `insert into t7(id) values(2)`, + `select * from t7 where id = 2`, + testkit.Rows(`2 2`), + }, + { + `insert into t7(id) values(3)`, + `select * from t7 where id = 3`, + testkit.Rows(`3 3`), + }, + } + + for _, tt := range tests { + tk.MustExec(tt.insert) + tk.MustQuery(tt.query).Check(tt.result) + } + +} From eac17b8c28e621de850835e9cf70b20e2267f477 Mon Sep 17 00:00:00 2001 From: nange Date: Sat, 6 Jul 2019 08:16:04 +0800 Subject: [PATCH 2/5] executor: fix autoid doesn't handle float, double type and tiny cleanup --- executor/insert_common.go | 24 +++-- executor/insert_test.go | 180 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 197 insertions(+), 7 deletions(-) diff --git a/executor/insert_common.go b/executor/insert_common.go index 861630ea03c11..0f88bc49647e7 100644 --- a/executor/insert_common.go +++ b/executor/insert_common.go @@ -488,12 +488,7 @@ func (e *InsertValues) adjustAutoIncrementDatum(ctx context.Context, d types.Dat d.SetNull() } if !d.IsNull() { - sc := e.ctx.GetSessionVars().StmtCtx - datum, err1 := d.ConvertTo(sc, &c.FieldType) - if e.filterErr(err1) != nil { - return types.Datum{}, err1 - } - recordID = datum.GetInt64() + recordID = getAutoRecordID(d, &c.FieldType) } // Use the value if it's not null and not 0. if recordID != 0 { @@ -503,7 +498,6 @@ func (e *InsertValues) adjustAutoIncrementDatum(ctx context.Context, d types.Dat } e.ctx.GetSessionVars().StmtCtx.InsertID = uint64(recordID) retryInfo.AddAutoIncrementID(recordID) - d.SetAutoID(recordID, c.Flag) return d, nil } @@ -531,6 +525,22 @@ func (e *InsertValues) adjustAutoIncrementDatum(ctx context.Context, d types.Dat return casted, nil } +func getAutoRecordID(d types.Datum, target *types.FieldType) int64 { + var recordID int64 + + switch target.Tp { + case mysql.TypeFloat, mysql.TypeDouble: + f := d.GetFloat64() + recordID = int64(f) + case mysql.TypeTiny, mysql.TypeShort, mysql.TypeInt24, mysql.TypeLong, mysql.TypeLonglong: + recordID = d.GetInt64() + default: + panic("should never happen") + } + + return recordID +} + func (e *InsertValues) handleWarning(err error) { sc := e.ctx.GetSessionVars().StmtCtx sc.AppendWarning(err) diff --git a/executor/insert_test.go b/executor/insert_test.go index 8c3510b044126..a5bbfc7e8c687 100644 --- a/executor/insert_test.go +++ b/executor/insert_test.go @@ -286,3 +286,183 @@ func (s *testSuite3) TestAllowInvalidDates(c *C) { runWithMode("STRICT_TRANS_TABLES,ALLOW_INVALID_DATES") runWithMode("ALLOW_INVALID_DATES") } + +func (s *testSuite3) TestInsertWithAutoidSchema(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec(`use test`) + tk.MustExec(`create table t1(id int primary key auto_increment, n int);`) + tk.MustExec(`create table t2(id int unsigned primary key auto_increment, n int);`) + tk.MustExec(`create table t3(id tinyint primary key auto_increment, n int);`) + tk.MustExec(`create table t4(id int primary key, n float auto_increment, key I_n(n));`) + tk.MustExec(`create table t5(id int primary key, n float unsigned auto_increment, key I_n(n));`) + tk.MustExec(`create table t6(id int primary key, n double auto_increment, key I_n(n));`) + tk.MustExec(`create table t7(id int primary key, n double unsigned auto_increment, key I_n(n));`) + + tests := []struct { + insert string + query string + result [][]interface{} + }{ + { + `insert into t1(id, n) values(1, 1)`, + `select * from t1 where id = 1`, + testkit.Rows(`1 1`), + }, + { + `insert into t1(n) values(2)`, + `select * from t1 where id = 2`, + testkit.Rows(`2 2`), + }, + { + `insert into t1(n) values(3)`, + `select * from t1 where id = 3`, + testkit.Rows(`3 3`), + }, + { + `insert into t1(id, n) values(-1, 4)`, + `select * from t1 where id = -1`, + testkit.Rows(`-1 4`), + }, + { + `insert into t1(n) values(5)`, + `select * from t1 where id = 4`, + testkit.Rows(`4 5`), + }, + { + `insert into t2(id, n) values(1, 1)`, + `select * from t2 where id = 1`, + testkit.Rows(`1 1`), + }, + { + `insert into t2(n) values(2)`, + `select * from t2 where id = 2`, + testkit.Rows(`2 2`), + }, + { + `insert into t2(n) values(3)`, + `select * from t2 where id = 3`, + testkit.Rows(`3 3`), + }, + { + `insert into t3(id, n) values(1, 1)`, + `select * from t3 where id = 1`, + testkit.Rows(`1 1`), + }, + { + `insert into t3(n) values(2)`, + `select * from t3 where id = 2`, + testkit.Rows(`2 2`), + }, + { + `insert into t3(n) values(3)`, + `select * from t3 where id = 3`, + testkit.Rows(`3 3`), + }, + { + `insert into t3(id, n) values(-1, 4)`, + `select * from t3 where id = -1`, + testkit.Rows(`-1 4`), + }, + { + `insert into t3(n) values(5)`, + `select * from t3 where id = 4`, + testkit.Rows(`4 5`), + }, + { + `insert into t4(id, n) values(1, 1)`, + `select * from t4 where id = 1`, + testkit.Rows(`1 1`), + }, + { + `insert into t4(id) values(2)`, + `select * from t4 where id = 2`, + testkit.Rows(`2 2`), + }, + { + `insert into t4(id, n) values(3, -1)`, + `select * from t4 where id = 3`, + testkit.Rows(`3 -1`), + }, + { + `insert into t4(id) values(4)`, + `select * from t4 where id = 4`, + testkit.Rows(`4 3`), + }, + { + `insert into t4(id, n) values(5, 5.5)`, + `select * from t4 where id = 5`, + testkit.Rows(`5 5.5`), + }, + { + `insert into t4(id) values(6)`, + `select * from t4 where id = 6`, + testkit.Rows(`6 6`), + }, + { + `insert into t5(id, n) values(1, 1)`, + `select * from t5 where id = 1`, + testkit.Rows(`1 1`), + }, + { + `insert into t5(id) values(2)`, + `select * from t5 where id = 2`, + testkit.Rows(`2 2`), + }, + { + `insert into t5(id) values(3)`, + `select * from t5 where id = 3`, + testkit.Rows(`3 3`), + }, + { + `insert into t6(id, n) values(1, 1)`, + `select * from t6 where id = 1`, + testkit.Rows(`1 1`), + }, + { + `insert into t6(id) values(2)`, + `select * from t6 where id = 2`, + testkit.Rows(`2 2`), + }, + { + `insert into t6(id, n) values(3, -1)`, + `select * from t6 where id = 3`, + testkit.Rows(`3 -1`), + }, + { + `insert into t6(id) values(4)`, + `select * from t6 where id = 4`, + testkit.Rows(`4 3`), + }, + { + `insert into t6(id, n) values(5, 5.5)`, + `select * from t6 where id = 5`, + testkit.Rows(`5 5.5`), + }, + { + `insert into t6(id) values(6)`, + `select * from t6 where id = 6`, + testkit.Rows(`6 6`), + }, + { + `insert into t7(id, n) values(1, 1)`, + `select * from t7 where id = 1`, + testkit.Rows(`1 1`), + }, + { + `insert into t7(id) values(2)`, + `select * from t7 where id = 2`, + testkit.Rows(`2 2`), + }, + { + `insert into t7(id) values(3)`, + `select * from t7 where id = 3`, + testkit.Rows(`3 3`), + }, + } + + for _, tt := range tests { + tk.MustExec(tt.insert) + tk.MustQuery(tt.query).Check(tt.result) + } + +} From 1088431d1bef0ff13a40ddbc2cfbab89a139019c Mon Sep 17 00:00:00 2001 From: nange Date: Thu, 11 Jul 2019 12:35:05 +0800 Subject: [PATCH 3/5] executor: handle update case of autoid bug(#11109), and add more test --- executor/insert_common.go | 11 +++-- executor/insert_test.go | 45 +++++++++++++++++++ executor/update_test.go | 95 +++++++++++++++++++++++++++++++++++++++ executor/write.go | 6 ++- 4 files changed, 152 insertions(+), 5 deletions(-) diff --git a/executor/insert_common.go b/executor/insert_common.go index 0f88bc49647e7..83f26a111aef7 100644 --- a/executor/insert_common.go +++ b/executor/insert_common.go @@ -488,7 +488,10 @@ func (e *InsertValues) adjustAutoIncrementDatum(ctx context.Context, d types.Dat d.SetNull() } if !d.IsNull() { - recordID = getAutoRecordID(d, &c.FieldType) + recordID, err = getAutoRecordID(d, &c.FieldType) + if err != nil { + return types.Datum{}, err + } } // Use the value if it's not null and not 0. if recordID != 0 { @@ -525,7 +528,7 @@ func (e *InsertValues) adjustAutoIncrementDatum(ctx context.Context, d types.Dat return casted, nil } -func getAutoRecordID(d types.Datum, target *types.FieldType) int64 { +func getAutoRecordID(d types.Datum, target *types.FieldType) (int64, error) { var recordID int64 switch target.Tp { @@ -535,10 +538,10 @@ func getAutoRecordID(d types.Datum, target *types.FieldType) int64 { case mysql.TypeTiny, mysql.TypeShort, mysql.TypeInt24, mysql.TypeLong, mysql.TypeLonglong: recordID = d.GetInt64() default: - panic("should never happen") + return 0, errors.Errorf("unexpected field type [%v]", target.Tp) } - return recordID + return recordID, nil } func (e *InsertValues) handleWarning(err error) { diff --git a/executor/insert_test.go b/executor/insert_test.go index a5bbfc7e8c687..dd1e4285d9ea6 100644 --- a/executor/insert_test.go +++ b/executor/insert_test.go @@ -328,6 +328,31 @@ func (s *testSuite3) TestInsertWithAutoidSchema(c *C) { `select * from t1 where id = 4`, testkit.Rows(`4 5`), }, + { + `insert into t1(id, n) values('5', 6)`, + `select * from t1 where id = 5`, + testkit.Rows(`5 6`), + }, + { + `insert into t1(n) values(7)`, + `select * from t1 where id = 6`, + testkit.Rows(`6 7`), + }, + { + `insert into t1(id, n) values(7.4, 8)`, + `select * from t1 where id = 7`, + testkit.Rows(`7 8`), + }, + { + `insert into t1(id, n) values(7.5, 9)`, + `select * from t1 where id = 8`, + testkit.Rows(`8 9`), + }, + { + `insert into t1(n) values(9)`, + `select * from t1 where id = 8`, + testkit.Rows(`8 9`), + }, { `insert into t2(id, n) values(1, 1)`, `select * from t2 where id = 1`, @@ -398,6 +423,16 @@ func (s *testSuite3) TestInsertWithAutoidSchema(c *C) { `select * from t4 where id = 6`, testkit.Rows(`6 6`), }, + { + `insert into t4(id, n) values(7, '7.7')`, + `select * from t4 where id = 7`, + testkit.Rows(`7 7.7`), + }, + { + `insert into t4(id) values(8)`, + `select * from t4 where id = 8`, + testkit.Rows(`8 8`), + }, { `insert into t5(id, n) values(1, 1)`, `select * from t5 where id = 1`, @@ -443,6 +478,16 @@ func (s *testSuite3) TestInsertWithAutoidSchema(c *C) { `select * from t6 where id = 6`, testkit.Rows(`6 6`), }, + { + `insert into t6(id, n) values(7, '7.7')`, + `select * from t4 where id = 7`, + testkit.Rows(`7 7.7`), + }, + { + `insert into t6(id) values(8)`, + `select * from t4 where id = 8`, + testkit.Rows(`8 8`), + }, { `insert into t7(id, n) values(1, 1)`, `select * from t7 where id = 1`, diff --git a/executor/update_test.go b/executor/update_test.go index e91a95dbba96c..49b89e3050894 100644 --- a/executor/update_test.go +++ b/executor/update_test.go @@ -87,3 +87,98 @@ func (s *testUpdateSuite) TestUpdateGenColInTxn(c *C) { tk.MustQuery(`select * from t;`).Check(testkit.Rows( `1 2`)) } + +func (s *testUpdateSuite) TestUpdateWithAutoidSchema(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec(`use test`) + tk.MustExec(`create table t1(id int primary key auto_increment, n int);`) + tk.MustExec(`create table t2(id int primary key, n float auto_increment, key I_n(n));`) + tk.MustExec(`create table t3(id int primary key, n double auto_increment, key I_n(n));`) + + tests := []struct { + exec string + query string + result [][]interface{} + }{ + { + `insert into t1 set n = 1`, + `select * from t1 where id = 1`, + testkit.Rows(`1 1`), + }, + { + `update t1 set id = id+1`, + `select * from t1 where id = 2`, + testkit.Rows(`2 1`), + }, + { + `insert into t1 set n = 2`, + `select * from t1 where id = 3`, + testkit.Rows(`3 2`), + }, + { + `update t1 set id = id + '1.1' where id = 3`, + `select * from t1 where id = 4`, + testkit.Rows(`4 2`), + }, + { + `insert into t1 set n = 3`, + `select * from t1 where id = 5`, + testkit.Rows(`5 3`), + }, + { + `insert into t2 set id = 1`, + `select * from t2 where id = 1`, + testkit.Rows(`1 1`), + }, + { + `update t2 set n = n+1`, + `select * from t2 where id = 1`, + testkit.Rows(`1 2`), + }, + { + `insert into t2 set id = 2`, + `select * from t2 where id = 2`, + testkit.Rows(`2 3`), + }, + { + `update t2 set n = n + '2.2'`, + `select * from t2 where id = 2`, + testkit.Rows(`2 5.2`), + }, + { + `insert into t2 set id = 3`, + `select * from t2 where id = 3`, + testkit.Rows(`3 6`), + }, + { + `insert into t3 set id = 1`, + `select * from t3 where id = 1`, + testkit.Rows(`1 1`), + }, + { + `update t3 set n = n+1`, + `select * from t3 where id = 1`, + testkit.Rows(`1 2`), + }, + { + `insert into t3 set id = 2`, + `select * from t3 where id = 2`, + testkit.Rows(`2 3`), + }, + { + `update t3 set n = n + '3.3'`, + `select * from t3 where id = 2`, + testkit.Rows(`2 6.3`), + }, + { + `insert into t3 set id = 3`, + `select * from t3 where id = 3`, + testkit.Rows(`3 7`), + }, + } + + for _, tt := range tests { + tk.MustExec(tt.exec) + tk.MustQuery(tt.query).Check(tt.result) + } +} diff --git a/executor/write.go b/executor/write.go index c5304d321a967..07f405d85f0bf 100644 --- a/executor/write.go +++ b/executor/write.go @@ -87,7 +87,11 @@ func updateRecord(ctx sessionctx.Context, h int64, oldData, newData []types.Datu modified[i] = true // Rebase auto increment id if the field is changed. if mysql.HasAutoIncrementFlag(col.Flag) { - if err = t.RebaseAutoID(ctx, newData[i].GetInt64(), true); err != nil { + recordID, err := getAutoRecordID(newData[i], &col.FieldType) + if err != nil { + return false, false, 0, err + } + if err = t.RebaseAutoID(ctx, recordID, true); err != nil { return false, false, 0, err } } From 9905a650dfc4d81b9af0c1979df4f3c84353f083 Mon Sep 17 00:00:00 2001 From: nange Date: Thu, 11 Jul 2019 16:19:47 +0800 Subject: [PATCH 4/5] executor: fix gofmt --- executor/insert_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/executor/insert_test.go b/executor/insert_test.go index 458500961869f..a534a1960387b 100644 --- a/executor/insert_test.go +++ b/executor/insert_test.go @@ -509,7 +509,7 @@ func (s *testSuite3) TestInsertWithAutoidSchema(c *C) { tk.MustExec(tt.insert) tk.MustQuery(tt.query).Check(tt.result) } - + } func (s *testSuite3) TestPartitionInsertOnDuplicate(c *C) { From d7aec0a762e57f3cf43d5b53b6754c4784baeb7c Mon Sep 17 00:00:00 2001 From: nange Date: Fri, 19 Jul 2019 22:42:54 +0800 Subject: [PATCH 5/5] executor: fix autoid value of insert type and add more test --- executor/insert_common.go | 11 ++++++++--- executor/insert_test.go | 32 ++++++++++++++++++++++++++------ executor/update_test.go | 30 ++++++++++++++++++++++++++++++ executor/write.go | 2 +- 4 files changed, 65 insertions(+), 10 deletions(-) diff --git a/executor/insert_common.go b/executor/insert_common.go index 83f26a111aef7..f2ef0ed89a68c 100644 --- a/executor/insert_common.go +++ b/executor/insert_common.go @@ -15,6 +15,7 @@ package executor import ( "context" + "math" "github.com/pingcap/errors" "github.com/pingcap/parser/ast" @@ -488,7 +489,7 @@ func (e *InsertValues) adjustAutoIncrementDatum(ctx context.Context, d types.Dat d.SetNull() } if !d.IsNull() { - recordID, err = getAutoRecordID(d, &c.FieldType) + recordID, err = getAutoRecordID(d, &c.FieldType, true) if err != nil { return types.Datum{}, err } @@ -528,13 +529,17 @@ func (e *InsertValues) adjustAutoIncrementDatum(ctx context.Context, d types.Dat return casted, nil } -func getAutoRecordID(d types.Datum, target *types.FieldType) (int64, error) { +func getAutoRecordID(d types.Datum, target *types.FieldType, isInsert bool) (int64, error) { var recordID int64 switch target.Tp { case mysql.TypeFloat, mysql.TypeDouble: f := d.GetFloat64() - recordID = int64(f) + if isInsert { + recordID = int64(math.Round(f)) + } else { + recordID = int64(f) + } case mysql.TypeTiny, mysql.TypeShort, mysql.TypeInt24, mysql.TypeLong, mysql.TypeLonglong: recordID = d.GetInt64() default: diff --git a/executor/insert_test.go b/executor/insert_test.go index a534a1960387b..c5d63e86d919c 100644 --- a/executor/insert_test.go +++ b/executor/insert_test.go @@ -350,8 +350,8 @@ func (s *testSuite3) TestInsertWithAutoidSchema(c *C) { }, { `insert into t1(n) values(9)`, - `select * from t1 where id = 8`, - testkit.Rows(`8 9`), + `select * from t1 where id = 9`, + testkit.Rows(`9 9`), }, { `insert into t2(id, n) values(1, 1)`, @@ -421,7 +421,7 @@ func (s *testSuite3) TestInsertWithAutoidSchema(c *C) { { `insert into t4(id) values(6)`, `select * from t4 where id = 6`, - testkit.Rows(`6 6`), + testkit.Rows(`6 7`), }, { `insert into t4(id, n) values(7, '7.7')`, @@ -431,7 +431,17 @@ func (s *testSuite3) TestInsertWithAutoidSchema(c *C) { { `insert into t4(id) values(8)`, `select * from t4 where id = 8`, - testkit.Rows(`8 8`), + testkit.Rows(`8 9`), + }, + { + `insert into t4(id, n) values(9, 10.4)`, + `select * from t4 where id = 9`, + testkit.Rows(`9 10.4`), + }, + { + `insert into t4(id) values(10)`, + `select * from t4 where id = 10`, + testkit.Rows(`10 11`), }, { `insert into t5(id, n) values(1, 1)`, @@ -476,7 +486,7 @@ func (s *testSuite3) TestInsertWithAutoidSchema(c *C) { { `insert into t6(id) values(6)`, `select * from t6 where id = 6`, - testkit.Rows(`6 6`), + testkit.Rows(`6 7`), }, { `insert into t6(id, n) values(7, '7.7')`, @@ -486,7 +496,17 @@ func (s *testSuite3) TestInsertWithAutoidSchema(c *C) { { `insert into t6(id) values(8)`, `select * from t4 where id = 8`, - testkit.Rows(`8 8`), + testkit.Rows(`8 9`), + }, + { + `insert into t6(id, n) values(9, 10.4)`, + `select * from t6 where id = 9`, + testkit.Rows(`9 10.4`), + }, + { + `insert into t6(id) values(10)`, + `select * from t6 where id = 10`, + testkit.Rows(`10 11`), }, { `insert into t7(id, n) values(1, 1)`, diff --git a/executor/update_test.go b/executor/update_test.go index 49b89e3050894..410ba65fc4246 100644 --- a/executor/update_test.go +++ b/executor/update_test.go @@ -125,6 +125,16 @@ func (s *testUpdateSuite) TestUpdateWithAutoidSchema(c *C) { `select * from t1 where id = 5`, testkit.Rows(`5 3`), }, + { + `update t1 set id = id + '0.5' where id = 5`, + `select * from t1 where id = 6`, + testkit.Rows(`6 3`), + }, + { + `insert into t1 set n = 4`, + `select * from t1 where id = 7`, + testkit.Rows(`7 4`), + }, { `insert into t2 set id = 1`, `select * from t2 where id = 1`, @@ -150,6 +160,16 @@ func (s *testUpdateSuite) TestUpdateWithAutoidSchema(c *C) { `select * from t2 where id = 3`, testkit.Rows(`3 6`), }, + { + `update t2 set n = n + '0.5' where id = 3`, + `select * from t2 where id = 3`, + testkit.Rows(`3 6.5`), + }, + { + `insert into t2 set id = 4`, + `select * from t2 where id = 4`, + testkit.Rows(`4 7`), + }, { `insert into t3 set id = 1`, `select * from t3 where id = 1`, @@ -175,6 +195,16 @@ func (s *testUpdateSuite) TestUpdateWithAutoidSchema(c *C) { `select * from t3 where id = 3`, testkit.Rows(`3 7`), }, + { + `update t3 set n = n + '0.5' where id = 3`, + `select * from t3 where id = 3`, + testkit.Rows(`3 7.5`), + }, + { + `insert into t3 set id = 4`, + `select * from t3 where id = 4`, + testkit.Rows(`4 8`), + }, } for _, tt := range tests { diff --git a/executor/write.go b/executor/write.go index 07f405d85f0bf..62574621b19de 100644 --- a/executor/write.go +++ b/executor/write.go @@ -87,7 +87,7 @@ func updateRecord(ctx sessionctx.Context, h int64, oldData, newData []types.Datu modified[i] = true // Rebase auto increment id if the field is changed. if mysql.HasAutoIncrementFlag(col.Flag) { - recordID, err := getAutoRecordID(newData[i], &col.FieldType) + recordID, err := getAutoRecordID(newData[i], &col.FieldType, false) if err != nil { return false, false, 0, err }