Skip to content

Commit

Permalink
executor: fix autoid doesn't handle float, double type and tin… (ping…
Browse files Browse the repository at this point in the history
  • Loading branch information
nange authored and lzmhhh123 committed Jul 23, 2019
1 parent d8560a9 commit dbaedb4
Show file tree
Hide file tree
Showing 4 changed files with 416 additions and 8 deletions.
31 changes: 25 additions & 6 deletions executor/insert_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
package executor

import (
"context"
"fmt"
"math"

"github.com/pingcap/errors"
"github.com/pingcap/parser/ast"
Expand Down Expand Up @@ -470,12 +472,10 @@ 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, err = getAutoRecordID(d, &c.FieldType, true)
if err != nil {
return types.Datum{}, err
}
recordID = datum.GetInt64()
}
// Use the value if it's not null and not 0.
if recordID != 0 {
Expand All @@ -485,7 +485,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
}

Expand Down Expand Up @@ -513,6 +512,26 @@ func (e *InsertValues) adjustAutoIncrementDatum(d types.Datum, hasValue bool, c
return casted, nil
}

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()
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:
return 0, errors.Errorf("unexpected field type [%v]", target.Tp)
}

return recordID, nil
}

func (e *InsertValues) handleWarning(err error, logInfo string) {
sc := e.ctx.GetSessionVars().StmtCtx
sc.AppendWarning(err)
Expand Down
260 changes: 260 additions & 0 deletions executor/insert_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,3 +211,263 @@ func (s *testSuite) TestAllowInvalidDates(c *C) {
runWithMode("STRICT_TRANS_TABLES,ALLOW_INVALID_DATES")
runWithMode("ALLOW_INVALID_DATES")
}

func (s *testSuite) 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 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 = 9`,
testkit.Rows(`9 9`),
},
{
`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 7`),
},
{
`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 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)`,
`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 7`),
},
{
`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 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)`,
`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)
}

}

func (s *testSuite3) TestPartitionInsertOnDuplicate(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec(`use test`)
tk.MustExec(`create table t1 (a int,b int,primary key(a,b)) partition by range(a) (partition p0 values less than (100),partition p1 values less than (1000))`)
tk.MustExec(`insert into t1 set a=1, b=1`)
tk.MustExec(`insert into t1 set a=1,b=1 on duplicate key update a=1,b=1`)
tk.MustQuery(`select * from t1`).Check(testkit.Rows("1 1"))

tk.MustExec(`create table t2 (a int,b int,primary key(a,b)) partition by hash(a) partitions 4`)
tk.MustExec(`insert into t2 set a=1,b=1;`)
tk.MustExec(`insert into t2 set a=1,b=1 on duplicate key update a=1,b=1`)
tk.MustQuery(`select * from t2`).Check(testkit.Rows("1 1"))

}
Loading

0 comments on commit dbaedb4

Please sign in to comment.