-
-
Notifications
You must be signed in to change notification settings - Fork 210
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
fix /
and div
operations on value of decimal type column
#1622
Conversation
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.
Looks good! Just one comment about a very small possible simplification.
Nice comments in several places. The arithmetic code is quite tricky in some places and those good comments really help a lot to explain the intent of the code. 🙌
sql/expression/div.go
Outdated
@@ -717,9 +742,11 @@ func intDiv(ctx *sql.Context, lval, rval interface{}) (interface{}, error) { | |||
|
|||
// intDiv operation gets the integer part of the divided value | |||
divRes := l.DivRound(r, 2) |
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.
Could we pass in 0
here as the precision and avoid the call to divRes.Truncate(0)
on line 748? Seems like that might be a little more direct, since we don't ever need those decimal digits.
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.
Ah DivRound rounds the result value with defined precision, but int division only takes int part without rounding the result, which is why I have it do this weird steps 😅
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 just made it more clear and added comment for this behavior.
// this operation is only done on the left value as the scale/fraction part of the leftmost value | ||
// is used to calculate the scale of the final result. If the value is GetField of decimal type column | ||
// the decimal value evaluated does not always match the scale of column type definition |
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.
Fantastic comment! ✨
The cases fixed are:
DECIMAL(25,10)
and the value stored is4990
. This value is evaluated with 0 scale, whereas this should be evaluated as value with scale of 10.IntPart()
function of decimal package returns 0 as undefined value for out of range values. This causes it hard to differentiate between cases where the final result is valid value of 0 and the final result is out of range value.