-
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
server: fix type year has too many 0s in prepare/execute #7525
Conversation
server/driver_tidb.go
Outdated
@@ -391,7 +391,7 @@ func convertColumnInfo(fld *ast.ResultField) (ci *ColumnInfo) { | |||
// Consider the decimal point. | |||
ci.ColumnLength++ | |||
} | |||
} else if fld.Column.Tp != mysql.TypeBit && fld.Column.Tp != mysql.TypeTiny { | |||
} else if fld.Column.Tp != mysql.TypeBit && fld.Column.Tp != mysql.TypeTiny && types.IsString(fld.Column.Tp) { |
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.
I think we can only use types.IsString(fld.Column.Tp)
.
Could we test the cases in the comments at line 395 to 399, maybe we need a Navicat.
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.
I will have a try.
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.
In PR's description, you say this fixes too many leading 0 before year
. I am confused why you check column type is string
or not.
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.
Because too many leading zero may also appear when column type is a number type and has ZerofillFlag
.
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.
@zhexuany , according to the comments below, this else branch is only used for the show create table
results when it meets Navicat. I think adding a string type check is suitable here.
You could blame the history of this line, it caused at least 2 issues in the past.
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.
@imtbkcat
The types.IsString
covers the previous conditions, we can remove them.
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.
@coocood
Get it.
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.
"according to the comments below, this else branch is only used for the show create table results when it meets Navicat." I had read this part and understand this change made to make navicat happy. While the problem stil remains open: why do we only check the column type is string or not? The reason I ask is to clarify this. And I think it is worth to be commented.
/run-all-tests |
LGTM |
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.
LGTM
one more issue need to be addressed.
@@ -391,7 +391,7 @@ func convertColumnInfo(fld *ast.ResultField) (ci *ColumnInfo) { | |||
// Consider the decimal point. | |||
ci.ColumnLength++ | |||
} | |||
} else if fld.Column.Tp != mysql.TypeBit && fld.Column.Tp != mysql.TypeTiny { | |||
} else if types.IsString(fld.Column.Tp) { |
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.
My original question still remains open. Why does types.IsString(fld.Column.Tp)
work for year
? I understood this is used for solving the compatibility issue we found in Navicat.
At least, it is worth a comment here.
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.
I think this is already explained in the PR description, we don't need to explain why old code causes some bug, because old code is removed.
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.
Firstly, year
is a number typer, so it will not multiply mysql.MaxBytesOfCharacter
.
Secondly, using types.IsString(fld.Column.Tp)
rather than just fld.Column.Tp != mysql.TypeYear
can fix some other problem cause by this if branch.
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.
@zhexuany , For example,
create table t (k smallint(10) unsigned zerofill);
insert into t value (10);
using jdbc test code above, TiDB and MySQL has different result.
MySQL: 0000000010
TiDB: 0000000000000000000000000000000000000010
This mean number type meet zerofill
will has this problem. So we should use types.IsString(fld.Column.Tp)
.
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.
we don't need to explain why old code causes some bug, because old code is removed.
But we need why the fixes work?. Information still resides at PR not code itself.
When people read this code, they probably have no idea about this change. They have to go through PR which is a form of cost. I believe information has to be togehter with the code. That is why we need comment.
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.
I will add some comment.
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.
Yes. We only need check string type simply because string type has truncation problem. This comment can provide context which can help other people better understand.
What problem does this PR solve?
Fix type year has too many 0s in prepare/execute.
What is changed and how it works?
Add a condition to avoid multiply
mysql.MaxBytesOfCharacter
for number type.Before adding condition, using test code below will receive result
0000000000001999
, but expect1999
. This is becauseci.ColumnLength * mysql.MaxBytesOfCharacter
, the value should be 4 not 16.Check List
Tests
Test code:
Expect:
1999
Code changes
Side effects