Skip to content

Commit

Permalink
expression: remove unnecessary convertIntToUint. fix error in err msg…
Browse files Browse the repository at this point in the history
…(should be bigint but not double) (#11640) (#11707)
  • Loading branch information
sre-bot authored Aug 13, 2019
1 parent 66daa9f commit ae8d2f2
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 24 deletions.
29 changes: 9 additions & 20 deletions expression/builtin_cast.go
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,9 @@ func (b *builtinCastIntAsIntSig) Clone() builtinFunc {

func (b *builtinCastIntAsIntSig) evalInt(row chunk.Row) (res int64, isNull bool, err error) {
res, isNull, err = b.args[0].EvalInt(b.ctx, row)
if isNull || err != nil {
return
}
if b.inUnion && mysql.HasUnsignedFlag(b.tp.Flag) && res < 0 {
res = 0
}
Expand All @@ -463,10 +466,8 @@ func (b *builtinCastIntAsRealSig) evalReal(row chunk.Row) (res float64, isNull b
} else if b.inUnion && val < 0 {
res = 0
} else {
var uVal uint64
sc := b.ctx.GetSessionVars().StmtCtx
uVal, err = types.ConvertIntToUint(sc, val, types.IntergerUnsignedUpperBound(mysql.TypeLonglong), mysql.TypeLonglong)
res = float64(uVal)
// recall that, int to float is different from uint to float
res = float64(uint64(val))
}
return res, false, err
}
Expand All @@ -491,13 +492,7 @@ func (b *builtinCastIntAsDecimalSig) evalDecimal(row chunk.Row) (res *types.MyDe
} else if b.inUnion && val < 0 {
res = &types.MyDecimal{}
} else {
var uVal uint64
sc := b.ctx.GetSessionVars().StmtCtx
uVal, err = types.ConvertIntToUint(sc, val, types.IntergerUnsignedUpperBound(mysql.TypeLonglong), mysql.TypeLonglong)
if err != nil {
return res, false, err
}
res = types.NewDecFromUint(uVal)
res = types.NewDecFromUint(uint64(val))
}
res, err = types.ProduceDecWithSpecifiedTp(res, b.tp, b.ctx.GetSessionVars().StmtCtx)
return res, isNull, err
Expand All @@ -521,13 +516,7 @@ func (b *builtinCastIntAsStringSig) evalString(row chunk.Row) (res string, isNul
if !mysql.HasUnsignedFlag(b.args[0].GetType().Flag) {
res = strconv.FormatInt(val, 10)
} else {
var uVal uint64
sc := b.ctx.GetSessionVars().StmtCtx
uVal, err = types.ConvertIntToUint(sc, val, types.IntergerUnsignedUpperBound(mysql.TypeLonglong), mysql.TypeLonglong)
if err != nil {
return res, false, err
}
res = strconv.FormatUint(uVal, 10)
res = strconv.FormatUint(uint64(val), 10)
}
res, err = types.ProduceStrWithSpecifiedTp(res, b.tp, b.ctx.GetSessionVars().StmtCtx, false)
if err != nil {
Expand Down Expand Up @@ -748,13 +737,13 @@ func (b *builtinCastRealAsIntSig) evalInt(row chunk.Row) (res int64, isNull bool
return res, isNull, err
}
if !mysql.HasUnsignedFlag(b.tp.Flag) {
res, err = types.ConvertFloatToInt(val, types.IntergerSignedLowerBound(mysql.TypeLonglong), types.IntergerSignedUpperBound(mysql.TypeLonglong), mysql.TypeDouble)
res, err = types.ConvertFloatToInt(val, types.IntergerSignedLowerBound(mysql.TypeLonglong), types.IntergerSignedUpperBound(mysql.TypeLonglong), mysql.TypeLonglong)
} else if b.inUnion && val < 0 {
res = 0
} else {
var uintVal uint64
sc := b.ctx.GetSessionVars().StmtCtx
uintVal, err = types.ConvertFloatToUint(sc, val, types.IntergerUnsignedUpperBound(mysql.TypeLonglong), mysql.TypeDouble)
uintVal, err = types.ConvertFloatToUint(sc, val, types.IntergerUnsignedUpperBound(mysql.TypeLonglong), mysql.TypeLonglong)
res = int64(uintVal)
}
return res, isNull, err
Expand Down
25 changes: 25 additions & 0 deletions expression/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2193,6 +2193,31 @@ func (s *testIntegrationSuite) TestBuiltin(c *C) {
msg := strings.Split(err.Error(), " ")
last := msg[len(msg)-1]
c.Assert(last, Equals, "bigint")
tk.MustExec(`drop table tb5;`)

// test builtinCastIntAsDecimalSig
tk.MustExec(`create table tb5(a bigint(64) unsigned, b decimal(64, 10));`)
tk.MustExec(`insert into tb5 (a, b) values (9223372036854775808, 9223372036854775808);`)
tk.MustExec(`insert into tb5 (select * from tb5 where a = b);`)
result = tk.MustQuery(`select * from tb5;`)
result.Check(testkit.Rows("9223372036854775808 9223372036854775808.0000000000", "9223372036854775808 9223372036854775808.0000000000"))
tk.MustExec(`drop table tb5;`)

// test builtinCastIntAsRealSig
tk.MustExec(`create table tb5(a bigint(64) unsigned, b double(64, 10));`)
tk.MustExec(`insert into tb5 (a, b) values (13835058000000000000, 13835058000000000000);`)
tk.MustExec(`insert into tb5 (select * from tb5 where a = b);`)
result = tk.MustQuery(`select * from tb5;`)
result.Check(testkit.Rows("13835058000000000000 13835058000000000000", "13835058000000000000 13835058000000000000"))
tk.MustExec(`drop table tb5;`)

// test builtinCastIntAsStringSig
tk.MustExec(`create table tb5(a bigint(64) unsigned,b varchar(50));`)
tk.MustExec(`insert into tb5(a, b) values (9223372036854775808, '9223372036854775808');`)
tk.MustExec(`insert into tb5(select * from tb5 where a = b);`)
result = tk.MustQuery(`select * from tb5;`)
result.Check(testkit.Rows("9223372036854775808 9223372036854775808", "9223372036854775808 9223372036854775808"))
tk.MustExec(`drop table tb5;`)

// Test corner cases of cast string as datetime
result = tk.MustQuery(`select cast("170102034" as datetime);`)
Expand Down
1 change: 1 addition & 0 deletions types/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ func IntergerSignedLowerBound(intType byte) int64 {
}

// ConvertFloatToInt converts a float64 value to a int value.
// `tp` is used in err msg, if there is overflow, this func will report err according to `tp`
func ConvertFloatToInt(fval float64, lowerBound, upperBound int64, tp byte) (int64, error) {
val := RoundFloat(fval)
if val < float64(lowerBound) {
Expand Down
5 changes: 1 addition & 4 deletions types/etc.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,7 @@ func IsTemporalWithDate(tp byte) bool {
// IsBinaryStr returns a boolean indicating
// whether the field type is a binary string type.
func IsBinaryStr(ft *FieldType) bool {
if ft.Collate == charset.CollationBin && IsString(ft.Tp) {
return true
}
return false
return ft.Collate == charset.CollationBin && IsString(ft.Tp)
}

// IsNonBinaryStr returns a boolean indicating
Expand Down

0 comments on commit ae8d2f2

Please sign in to comment.