Skip to content

Commit

Permalink
types/data: the bit operation didn't parse correctly (pingcap#11895)
Browse files Browse the repository at this point in the history
  • Loading branch information
gaoxingliang authored and root committed Sep 26, 2019
1 parent 92d583c commit 5bd621e
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 8 deletions.
6 changes: 3 additions & 3 deletions executor/insert_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -581,14 +581,14 @@ func (s *testSuite3) TestBit(c *C) {
tk.MustExec(`create table t1 (a bit(3))`)
_, err := tk.Exec("insert into t1 values(-1)")
c.Assert(types.ErrDataTooLong.Equal(err), IsTrue)
c.Assert(err.Error(), Matches, ".*Data too long for column 't1' at.*")
c.Assert(err.Error(), Matches, ".*Data too long for column 'a' at.*")
_, err = tk.Exec("insert into t1 values(9)")
c.Assert(err.Error(), Matches, ".*Data too long for column 't1' at.*")
c.Assert(err.Error(), Matches, ".*Data too long for column 'a' at.*")

tk.MustExec(`create table t64 (a bit(64))`)
tk.MustExec("insert into t64 values(-1)")
tk.MustExec("insert into t64 values(18446744073709551615)") // 2^64 - 1
_, err = tk.Exec("insert into t64 values(18446744073709551616)") // z^64
c.Assert(err.Error(), Matches, ".* Out of range value for column 'a' at.*")
c.Assert(err.Error(), Matches, ".*Out of range value for column 'a' at.*")

}
4 changes: 2 additions & 2 deletions types/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,8 @@ func ConvertUintToInt(val uint64, upperBound int64, tp byte) (int64, error) {
}

// ConvertIntToUint converts an int value to an uint value.
func ConvertIntToUint(sc *stmtctx.StatementContext, val int64, upperBound uint64, tp byte, unsignedFlag bool) (uint64, error) {
if sc.ShouldClipToZero() && val < 0 && !unsignedFlag {
func ConvertIntToUint(sc *stmtctx.StatementContext, val int64, upperBound uint64, tp byte) (uint64, error) {
if sc.ShouldClipToZero() && val < 0 {
return 0, overflow(val, tp)
}

Expand Down
11 changes: 8 additions & 3 deletions types/datum.go
Original file line number Diff line number Diff line change
Expand Up @@ -877,7 +877,7 @@ func (d *Datum) convertToUint(sc *stmtctx.StatementContext, target *FieldType) (
)
switch d.k {
case KindInt64:
val, err = ConvertIntToUint(sc, d.GetInt64(), upperBound, tp, mysql.HasUnsignedFlag(target.Flag))
val, err = ConvertIntToUint(sc, d.GetInt64(), upperBound, tp)
case KindUint64:
val, err = ConvertUintToUint(d.GetUint64(), upperBound, tp)
case KindFloat32, KindFloat64:
Expand All @@ -899,7 +899,7 @@ func (d *Datum) convertToUint(sc *stmtctx.StatementContext, target *FieldType) (
if err == nil {
err = err1
}
val, err1 = ConvertIntToUint(sc, ival, upperBound, tp, mysql.HasUnsignedFlag(target.Flag))
val, err1 = ConvertIntToUint(sc, ival, upperBound, tp)
if err == nil {
err = err1
}
Expand All @@ -908,7 +908,7 @@ func (d *Datum) convertToUint(sc *stmtctx.StatementContext, target *FieldType) (
err = dec.Round(dec, 0, ModeHalfEven)
ival, err1 := dec.ToInt()
if err1 == nil {
val, err = ConvertIntToUint(sc, ival, upperBound, tp, mysql.HasUnsignedFlag(target.Flag))
val, err = ConvertIntToUint(sc, ival, upperBound, tp)
}
case KindMysqlDecimal:
val, err = ConvertDecimalToUint(sc, d.GetMysqlDecimal(), upperBound, tp)
Expand Down Expand Up @@ -1215,6 +1215,11 @@ func (d *Datum) convertToMysqlBit(sc *stmtctx.StatementContext, target *FieldTyp
switch d.k {
case KindString, KindBytes:
uintValue, err = BinaryLiteral(d.b).ToInt(sc)
case KindInt64:
// if input kind is int64 (signed), when trans to bit, we need to treat it as unsigned
d.k = KindUint64
uintDatum, err1 := d.convertToUint(sc, target)
uintValue, err = uintDatum.GetUint64(), err1
default:
uintDatum, err1 := d.convertToUint(sc, target)
uintValue, err = uintDatum.GetUint64(), err1
Expand Down

0 comments on commit 5bd621e

Please sign in to comment.