-
Notifications
You must be signed in to change notification settings - Fork 5.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ddl, util/types: make converter correctly convert string to hex or bit. #3115
Changes from 4 commits
38d63e7
0edfd46
72d3847
9d24322
4d8d851
76e3319
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 binary string for bit type into uint64. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. s/binary string/string There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry I don‘t understand what you mean. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. substitute "binary string" with "string" usually written as "s/binary string/string" for short. |
||
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)<<uint64(width))-1 { | ||
return 0, errors.Errorf("bit %s is too long for width %d", s, width) | ||
} | ||
|
||
return n, nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1044,7 +1044,17 @@ func (d *Datum) convertToMysqlYear(sc *variable.StatementContext, target *FieldT | |
} | ||
|
||
func (d *Datum) convertToMysqlBit(sc *variable.StatementContext, target *FieldType) (Datum, error) { | ||
x, err := d.convertToUint(sc, target) | ||
var ( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any unit test covers this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Newly added tests are fundamentally related to changes within this function. Parser will pass a string type |
||
x Datum | ||
err error | ||
) | ||
if d.Kind() == KindString { | ||
var n uint64 | ||
n, err = ParseStringToBitValue(d.GetString(), target.Flen) | ||
x = NewUintDatum(n) | ||
} else { | ||
x, err = d.convertToUint(sc, target) | ||
} | ||
if err != nil { | ||
return x, errors.Trace(err) | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add test for
insert into t_issue_2858_bit value('\x01')
select a + 0 from t;
In MySQL, we get: 7876657
It seems we will get 2 in TiDB with this commmit?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Never mind it, I've test this case which is ok.