-
Notifications
You must be signed in to change notification settings - Fork 5.8k
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
expression: fix cast string like '.1a1' to decimal has no warnings information #26005
base: master
Are you sure you want to change the base?
Changes from all commits
4129fcb
5c2c38c
a8660e6
58dc37e
219c746
141b0e8
e382660
e9f1bcd
e73d76f
7393274
f0ed397
37c511f
66235fc
b9646b3
b20c17b
e4e4165
cc2277d
8f76d73
a65bd7b
05258c7
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 |
---|---|---|
|
@@ -552,13 +552,14 @@ func (s *testColumnTypeChangeSuite) TestColumnTypeChangeFromStringToOthers(c *C) | |
tk.MustExec("insert into t values ('123.45', '123.45', '123.45', '123.45', '123.45', '123.45', '123', '123')") | ||
tk.MustExec("alter table t modify c decimal(7, 4)") | ||
tk.MustExec("alter table t modify vc decimal(7, 4)") | ||
tk.MustExec("alter table t modify bny decimal(7, 4)") | ||
// alter binary 0x3132332E34350000 to decimal(7,4) will get error | ||
tk.MustGetErrCode("alter table t modify bny decimal(7, 4)", mysql.ErrTruncatedWrongValue) | ||
tk.MustExec("alter table t modify vbny decimal(7, 4)") | ||
tk.MustExec("alter table t modify bb decimal(7, 4)") | ||
tk.MustExec("alter table t modify txt decimal(7, 4)") | ||
tk.MustExec("alter table t modify e decimal(7, 4)") | ||
tk.MustExec("alter table t modify s decimal(7, 4)") | ||
tk.MustQuery("select * from t").Check(testkit.Rows("123.4500 123.4500 123.4500 123.4500 123.4500 123.4500 1.0000 1.0000")) | ||
tk.MustQuery("select * from t").Check(testkit.Rows("123.4500 123.4500 123.45\x00\x00 123.4500 123.4500 123.4500 1.0000 1.0000")) | ||
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. ditto, it seems result changes. 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. see the reason above |
||
// double | ||
reset(tk) | ||
tk.MustExec("insert into t values ('123.45', '123.45', '123.45', '123.45', '123.45', '123.45', '123', '123')") | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -836,7 +836,7 @@ func (b *builtinCastRealAsDecimalSig) vecEvalDecimal(input *chunk.Chunk, result | |
if types.ErrOverflow.Equal(err) { | ||
warnErr := types.ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", b.args[0]) | ||
err = b.ctx.GetSessionVars().StmtCtx.HandleOverflow(err, warnErr) | ||
} else if types.ErrTruncated.Equal(err) { | ||
} else if strings.Contains(err.Error(), "Truncated incorrect") { | ||
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. Why do we do string matching for identifying an error? It is quite brittle. 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. Agree, sorry, i can't find more elegant methods to handle this, please do me a favor about this point 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.
|
||
// This behavior is consistent with MySQL. | ||
err = nil | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -244,10 +244,11 @@ func (s *testTypeConvertSuite) TestConvertType(c *C) { | |
c.Assert(terror.ErrorEqual(err, ErrOverflow), IsTrue, Commentf("err %v", err)) | ||
c.Assert(v.(*MyDecimal).String(), Equals, "-9999.9999") | ||
v, err = Convert("1,999.00", ft) | ||
c.Assert(terror.ErrorEqual(err, ErrBadNumber), IsTrue, Commentf("err %v", err)) | ||
c.Assert(terror.ErrorEqual(err, | ||
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. ditto behavior changes |
||
ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", "1,999.00")), IsTrue, Commentf("err %v", err)) | ||
c.Assert(v.(*MyDecimal).String(), Equals, "1.0000") | ||
v, err = Convert("1,999,999.00", ft) | ||
c.Assert(terror.ErrorEqual(err, ErrBadNumber), IsTrue, Commentf("err %v", err)) | ||
c.Assert(terror.ErrorEqual(err, ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", "1,999,999.00")), IsTrue, Commentf("err %v", err)) | ||
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. ditto behavior changes |
||
c.Assert(v.(*MyDecimal).String(), Equals, "1.0000") | ||
v, err = Convert("199.00 ", ft) | ||
c.Assert(err, IsNil) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -414,15 +414,24 @@ func (d *MyDecimal) ToString() (str []byte) { | |
func (d *MyDecimal) FromString(str []byte) error { | ||
// strErr is used to check str is bad number or not | ||
var strErr error | ||
var strBak = str | ||
for i := 0; i < len(str); i++ { | ||
if !isSpace(str[i]) { | ||
str = str[i:] | ||
break | ||
} | ||
} | ||
// trim space in the end | ||
for j := len(str) - 1; j >= 0; j-- { | ||
if !isSpace(str[j]) { | ||
str = str[:j+1] | ||
break | ||
} | ||
} | ||
|
||
if len(str) == 0 { | ||
*d = zeroMyDecimal | ||
return ErrBadNumber | ||
return ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", string(strBak)) | ||
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. ditto behavior changes |
||
} | ||
switch str[0] { | ||
case '-': | ||
|
@@ -443,9 +452,13 @@ func (d *MyDecimal) FromString(str []byte) error { | |
for endIdx < len(str) && isDigit(str[endIdx]) { | ||
endIdx++ | ||
} | ||
|
||
if endIdx < len(str) && str[endIdx] != 'E' && str[endIdx] != 'e' && str[endIdx] != ' ' { | ||
strErr = ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", string(strBak)) | ||
} | ||
digitsFrac = endIdx - strIdx - 1 | ||
} else if strIdx < len(str) && (str[strIdx] != 'e' && str[strIdx] != 'E' && str[strIdx] != ' ') { | ||
strErr = ErrBadNumber | ||
strErr = ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", string(strBak)) | ||
} else { | ||
digitsFrac = 0 | ||
endIdx = strIdx | ||
|
@@ -481,6 +494,11 @@ func (d *MyDecimal) FromString(str []byte) error { | |
innerIdx = 0 | ||
} | ||
} | ||
|
||
if digitsInt != 0 { | ||
strErr = ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", string(strBak)) | ||
} | ||
|
||
if innerIdx != 0 { | ||
wordIdx-- | ||
d.wordBuf[wordIdx] = word | ||
|
@@ -508,8 +526,8 @@ func (d *MyDecimal) FromString(str []byte) error { | |
if endIdx+1 <= len(str) && (str[endIdx] == 'e' || str[endIdx] == 'E') { | ||
exponent, err1 := strToInt(string(str[endIdx+1:])) | ||
if err1 != nil { | ||
err = errors.Cause(err1) | ||
if err != ErrTruncated { | ||
err = err1 | ||
if errors.Cause(err1) != ErrTruncated { | ||
*d = zeroMyDecimal | ||
} | ||
} | ||
|
@@ -535,6 +553,15 @@ func (d *MyDecimal) FromString(str []byte) error { | |
} | ||
} | ||
} | ||
|
||
if err == ErrTruncated { | ||
strErr = ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", string(str)) | ||
} | ||
|
||
if strErr == nil && (endIdx+1 < len(str) && str[endIdx] == ' ') { | ||
strErr = ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", string(str)) | ||
} | ||
|
||
allZero := true | ||
for i := 0; i < wordBufLen; i++ { | ||
if d.wordBuf[i] != 0 { | ||
|
@@ -549,6 +576,7 @@ func (d *MyDecimal) FromString(str []byte) error { | |
if strErr != nil { | ||
return strErr | ||
} | ||
|
||
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. please avoid unnecessary diff. |
||
return err | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -46,7 +46,8 @@ func init() { | |
ast.NewDecimal = func(str string) (interface{}, error) { | ||
dec := new(types.MyDecimal) | ||
err := dec.FromString(hack.Slice(str)) | ||
if err == types.ErrTruncated { | ||
if err == types.ErrTruncated || (err != nil && | ||
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. ditto brittle string matching. |
||
strings.Contains(err.Error(), "Truncated incorrect")) { | ||
err = nil | ||
} | ||
return dec, 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.
We change existing test case here. Does it mean this PR changes TiDB behavior explicitly (more than a warning)?
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, In MySQL, this case will directly return error