Skip to content

Commit

Permalink
Merge pull request #213 from pingcap/siddontang/bit-boundary-check
Browse files Browse the repository at this point in the history
support boundary check for bit type
  • Loading branch information
qiuyesuifeng committed Sep 21, 2015
2 parents 2a67b61 + d5457cb commit 5c1320f
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 1 deletion.
11 changes: 11 additions & 0 deletions tidb_test.go
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -823,6 +823,17 @@ func (s *testSessionSuite) TestShow(c *C) {
match(c, rows[0], "c", "INT", "YES", "", nil, "") match(c, rows[0], "c", "INT", "YES", "", nil, "")
} }


func (s *testSessionSuite) TestBit(c *C) {
store := newStore(c, s.dbName)
se := newSession(c, store, s.dbName)

mustExecSQL(c, se, "drop table if exists t")
mustExecSQL(c, se, "create table t (c1 bit(2))")
mustExecSQL(c, se, "insert into t values (0), (1), (2), (3)")
_, err := exec(c, se, "insert into t values (4)")
c.Assert(err, NotNil)
}

func newSession(c *C, store kv.Storage, dbName string) Session { func newSession(c *C, store kv.Storage, dbName string) Session {
se, err := CreateSession(store) se, err := CreateSession(store)
c.Assert(err, IsNil) c.Assert(err, IsNil)
Expand Down
21 changes: 20 additions & 1 deletion util/types/convert.go
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -370,7 +370,26 @@ func Convert(val interface{}, target *FieldType) (v interface{}, err error) { //
} }
return convertToInt(val, target) return convertToInt(val, target)
case mysql.TypeBit: case mysql.TypeBit:
return convertToUint(val, target) x, err := convertToUint(val, target)
if err != nil {
return x, errors.Trace(err)
}

// check bit boundary, if bit has n width, the boundary is
// in [0, (1 << n) - 1]
width := target.Flen
if width == 0 {
width = mysql.MinBitWidth
} else if width == mysql.UnspecifiedBitWidth {
width = mysql.MaxBitWidth
}

maxValue := uint64(1)<<uint64(width) - 1

if x > maxValue {
return maxValue, overflow(val, tp)
}
return x, nil
case mysql.TypeDecimal, mysql.TypeNewDecimal: case mysql.TypeDecimal, mysql.TypeNewDecimal:
x, err := ToDecimal(val) x, err := ToDecimal(val)
if err != nil { if err != nil {
Expand Down
13 changes: 13 additions & 0 deletions util/types/convert_test.go
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ func (s *testTypeConvertSuite) TestConvertType(c *C) {


// For TypeBit // For TypeBit
ft = NewFieldType(mysql.TypeBit) ft = NewFieldType(mysql.TypeBit)
ft.Flen = 8
v, err = Convert("100", ft) v, err = Convert("100", ft)
c.Assert(err, IsNil) c.Assert(err, IsNil)
c.Assert(v, Equals, uint64(100)) c.Assert(v, Equals, uint64(100))
Expand All @@ -181,6 +182,18 @@ func (s *testTypeConvertSuite) TestConvertType(c *C) {
c.Assert(err, IsNil) c.Assert(err, IsNil)
c.Assert(v, Equals, uint64(100)) c.Assert(v, Equals, uint64(100))


ft.Flen = 1
v, err = Convert(1, ft)
c.Assert(err, IsNil)
c.Assert(v, Equals, uint64(1))

_, err = Convert(2, ft)
c.Assert(err, NotNil)

ft.Flen = 0
_, err = Convert(2, ft)
c.Assert(err, NotNil)

// For TypeNewDecimal // For TypeNewDecimal
ft = NewFieldType(mysql.TypeNewDecimal) ft = NewFieldType(mysql.TypeNewDecimal)
ft.Decimal = 5 ft.Decimal = 5
Expand Down

0 comments on commit 5c1320f

Please sign in to comment.