Skip to content
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

Merged
merged 6 commits into from
Apr 25, 2017

Conversation

bobotu
Copy link
Contributor

@bobotu bobotu commented Apr 21, 2017

This PR fix #2858 and #2717. Furthermore fix the error that
unable to set default value as a hex value just like what happend in #2858.
I also noticed that TiDB have some differences when compared to MySQL.

create table t1 (a bit(64));
insert t1 value ('10');
select a+0 from t1;

In MySQL we can get:
+-------+
| a+0 |
+-------+
| 12592 |
+-------+

But in TiDB we will get:
+-------+
| a+0 |
+-------+
| 10 |
+-------+

As a result of fix #2717, TiDB now behave same as MySQL.

This PR fix pingcap#2858 and pingcap#2717. Furthermore fix the error that
unable to set default value as a hex value just like what happend in pingcap#2858.
I also noticed that TiDB have some differences when compared to MySQL.

create table t1 (a bit(64));
insert t1 value ('10');
select a+0 from t1;

In MySQL we can get:
+-------+
| a+0   |
+-------+
| 12592 |
+-------+

But in TiDB we will get:
+-------+
| a+0   |
+-------+
| 10    |
+-------+

As a result of fix pingcap#2717, TiDB now behave same as MySQL.
@bobotu bobotu changed the title util/types: fix wrong string representation of hex and bit. ddl, util/types: make converter correctly convert string to hex or bit. Apr 22, 2017
@ngaut
Copy link
Member

ngaut commented Apr 22, 2017

Well done.

@zhexuany
Copy link
Contributor

@bobotu Please rebase your PR and do run goword to ensure there is no comments or spelling error.

ddl/ddl_api.go Outdated
if v.IsNull() {
return nil, nil
} else if v.Kind() == types.KindMysqlHex {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You do not need the else.

@@ -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 (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any unit test covers this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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 Datum to this function when user input '\0' or '100', and getDefaultValue will pass a string presentation of bit to it in the end. As mentioned in commit message, MySQL treat string as binary string when convert it to bit, but TiDB treat it as number literal. This difference cause #2858 and #2717. So new tests cover the string type case and existing tests cover others cases.

@coocood
Copy link
Member

coocood commented Apr 24, 2017

LGTM
Great job!

@coocood coocood added the status/LGT1 Indicates that a PR has LGTM 1. label Apr 24, 2017

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')`)
Copy link
Contributor

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?

Copy link
Contributor

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.


b := hack.Slice(s)
if width == UnspecifiedBitWidth {
width = (len(b) + 7) & ^7
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementation of this func seems to be parse hex string to uint64?
If so, it seems width = len(b)*8?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right. I'll fix it later.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, would it be better to rename the function to ParseHex?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or ParseStringToBitValue

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ParseStringToBitValue would be better. I'll refactor the code.

@@ -106,15 +106,15 @@ func ParseBit(s string, width int) (Bit, error) {
return Bit{Value: n, Width: width}, nil
}

// ParseBitValue parses the binary string for bit type into uint64.
func ParseBitValue(s string, width int) (uint64, error) {
// ParseStringToBitValue parses the binary string for bit type into uint64.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/binary string/string

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I don‘t understand what you mean.

Copy link
Contributor

Choose a reason for hiding this comment

The 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.

@bobotu
Copy link
Contributor Author

bobotu commented Apr 25, 2017

PTAL @shenli

@shenli
Copy link
Member

shenli commented Apr 25, 2017

LGTM
@bobotu Thanks! Good Job!

@shenli shenli merged commit 5c707ec into pingcap:master Apr 25, 2017
@bobotu bobotu deleted the iss2858 branch August 10, 2020 07:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status/LGT1 Indicates that a PR has LGTM 1.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Failed to create table t (a bit(1) default b'0') Failed to insert t1 values('\0');
7 participants