From 5c707ecf733c5f366e62a70b88e3724affc36f44 Mon Sep 17 00:00:00 2001 From: Zejun Li Date: Tue, 25 Apr 2017 22:41:14 +0800 Subject: [PATCH] ddl, util/types: make converter correctly convert string to hex or bit. (#3115) --- ddl/ddl_api.go | 7 +++++++ ddl/ddl_db_test.go | 18 ++++++++++++++++++ util/types/bit.go | 31 +++++++++++++++++++++++++++++++ util/types/bit_test.go | 4 ++++ util/types/convert_test.go | 5 +++-- util/types/datum.go | 12 +++++++++++- 6 files changed, 74 insertions(+), 3 deletions(-) diff --git a/ddl/ddl_api.go b/ddl/ddl_api.go index 21cc9bc47056a..35a196993afaa 100644 --- a/ddl/ddl_api.go +++ b/ddl/ddl_api.go @@ -19,6 +19,7 @@ package ddl import ( "fmt" + "strconv" "strings" "time" @@ -353,9 +354,15 @@ func getDefaultValue(ctx context.Context, c *ast.ColumnOption, tp byte, fsp int) if err != nil { return nil, errors.Trace(err) } + if v.IsNull() { return nil, nil } + + if v.Kind() == types.KindMysqlHex { + return strconv.FormatInt(v.GetMysqlHex().Value, 10), nil + } + return v.ToString() } diff --git a/ddl/ddl_db_test.go b/ddl/ddl_db_test.go index 4ff59884c0bd3..2d7c068e5cd65 100644 --- a/ddl/ddl_db_test.go +++ b/ddl/ddl_db_test.go @@ -1093,3 +1093,21 @@ out: expected := fmt.Sprintf("%d %d", updateCnt, 3) s.tk.MustQuery("select c2, c3 from tnn where c1 = 99").Check(testkit.Rows(expected)) } + +func (s *testDBSuite) TestIssue2858And2717(c *C) { + defer testleak.AfterTest(c)() + s.tk = testkit.NewTestKit(c, s.store) + s.tk.MustExec("use " + s.schemaName) + + s.tk.MustExec("create table t_issue_2858_bit (a bit(64) default b'0')") + s.tk.MustExec("insert into t_issue_2858_bit value ()") + s.tk.MustExec(`insert into t_issue_2858_bit values (100), ('10'), ('\0')`) + s.tk.MustQuery("select a+0 from t_issue_2858_bit").Check([][]interface{}{{0}, {100}, {0x3130}, {0}}) + s.tk.MustExec(`alter table t_issue_2858_bit alter column a set default '\0'`) + + s.tk.MustExec("create table t_issue_2858_hex (a int default 0x123)") + s.tk.MustExec("insert into t_issue_2858_hex value ()") + s.tk.MustExec("insert into t_issue_2858_hex values (123), (0x321)") + s.tk.MustQuery("select a from t_issue_2858_hex").Check([][]interface{}{{0x123}, {123}, {0x321}}) + s.tk.MustExec(`alter table t_issue_2858_hex alter column a set default 0x321`) +} diff --git a/util/types/bit.go b/util/types/bit.go index 8fbcd80e10b9f..9247c921c7ddd 100644 --- a/util/types/bit.go +++ b/util/types/bit.go @@ -19,6 +19,7 @@ import ( "strings" "github.com/juju/errors" + "github.com/pingcap/tidb/util/hack" ) // Bit is for mysql bit type. @@ -104,3 +105,33 @@ func ParseBit(s string, width int) (Bit, error) { return Bit{Value: n, Width: width}, nil } + +// ParseStringToBitValue parses the string for bit type into uint64. +func ParseStringToBitValue(s string, width int) (uint64, error) { + if len(s) == 0 { + return 0, errors.Errorf("invalid empty string for parsing bit value") + } + + b := hack.Slice(s) + if width == UnspecifiedBitWidth { + width = len(b) * 8 + } + if width == 0 { + width = MinBitWidth + } + if width < MinBitWidth || width > MaxBitWidth { + return 0, errors.Errorf("invalid display width for bit type, must in [1, 64], but %d", width) + } + + var n uint64 + l := len(b) + for i := range b { + n += uint64(b[l-i-1]) << uint(i*8) + } + + if n > (uint64(1)<