Uh oh!
There was an error while loading. Please reload this page.
[SPARK-24957][SQL] Average with decimal followed by aggregation returns wrong result - #21910
Closed
mgaido91 wants to merge 2 commits into
Closed
[SPARK-24957][SQL] Average with decimal followed by aggregation returns wrong result#21910mgaido91 wants to merge 2 commits into
mgaido91 wants to merge 2 commits into
Conversation
holdensmagicalunicorn
commented
Jul 29, 2018
@mgaido91, thanks! I am a bot who has found some folks who might be able to help with the review:@rxin, @marmbrus and @gatorsmile |
SparkQA
commented
Jul 29, 2018
Test build #93747 has finished for PR 21910 at commit
|
| Cast(Cast(sum, dt) / Cast(count, DecimalType.bounded(DecimalType.MAX_PRECISION, 0)), | ||
| case _: DecimalType => | ||
| Cast( | ||
| DecimalPrecision.decimalAndDecimal.lift(sum / Cast(count, DecimalType.LongDecimal)).get, |
Contributor
There was a problem hiding this comment.
nit: can we just call apply instead of lift(...).get?
cloud-fan
commented
Jul 30, 2018
Contributor
good catch! LGTM |
SparkQA
commented
Jul 30, 2018
Test build #93779 has finished for PR 21910 at commit
|
cloud-fan
commented
Jul 30, 2018
Contributor
thanks, merging to master/2.3! |
1 similar comment
cloud-fan
commented
Jul 30, 2018
Contributor
thanks, merging to master/2.3! |
asfgit pushed a commit
that referenced
this pull request
Jul 30, 2018
…ns wrong result ## What changes were proposed in this pull request? When we do an average, the result is computed dividing the sum of the values by their count. In the case the result is a DecimalType, the way we are casting/managing the precision and scale is not really optimized and it is not coherent with what we do normally. In particular, a problem can happen when the `Divide` operand returns a result which contains a precision and scale different by the ones which are expected as output of the `Divide` operand. In the case reported in the JIRA, for instance, the result of the `Divide` operand is a `Decimal(38, 36)`, while the output data type for `Divide` is 38, 22. This is not an issue when the `Divide` is followed by a `CheckOverflow` or a `Cast` to the right data type, as these operations return a decimal with the defined precision and scale. Despite in the `Average` operator we do have a `Cast`, this may be bypassed if the result of `Divide` is the same type which it is casted to, hence the issue reported in the JIRA may arise. The PR proposes to use the normal rules/handling of the arithmetic operators with Decimal data type, so we both reuse the existing code (having a single logic for operations between decimals) and we fix this problem as the result is always guarded by `CheckOverflow`. ## How was this patch tested? added UT Author: Marco Gaido <marcogaido91@gmail.com> Closes#21910 from mgaido91/SPARK-24957. (cherry picked from commit 85505fc) Signed-off-by: Wenchen Fan <wenchen@databricks.com>
robert3005 pushed a commit
to palantir/spark
that referenced
this pull request
Jul 31, 2018
…ns wrong result ## What changes were proposed in this pull request? When we do an average, the result is computed dividing the sum of the values by their count. In the case the result is a DecimalType, the way we are casting/managing the precision and scale is not really optimized and it is not coherent with what we do normally. In particular, a problem can happen when the `Divide` operand returns a result which contains a precision and scale different by the ones which are expected as output of the `Divide` operand. In the case reported in the JIRA, for instance, the result of the `Divide` operand is a `Decimal(38, 36)`, while the output data type for `Divide` is 38, 22. This is not an issue when the `Divide` is followed by a `CheckOverflow` or a `Cast` to the right data type, as these operations return a decimal with the defined precision and scale. Despite in the `Average` operator we do have a `Cast`, this may be bypassed if the result of `Divide` is the same type which it is casted to, hence the issue reported in the JIRA may arise. The PR proposes to use the normal rules/handling of the arithmetic operators with Decimal data type, so we both reuse the existing code (having a single logic for operations between decimals) and we fix this problem as the result is always guarded by `CheckOverflow`. ## How was this patch tested? added UT Author: Marco Gaido <marcogaido91@gmail.com> Closesapache#21910 from mgaido91/SPARK-24957.
cloud-fan
commented
Aug 1, 2018
Contributor
@mgaido91 do you mind open a PR for 2.2? I think this fixes a serious bug which is very hard to detect. Maybe that's the reason no one report it for such a long time. |
mgaido91
commented
Aug 1, 2018
ContributorAuthor
@cloud-fan sure, will do (anyway the cherry-pick to 2.2 was clean for me) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changes were proposed in this pull request?
When we do an average, the result is computed dividing the sum of the values by their count. In the case the result is a DecimalType, the way we are casting/managing the precision and scale is not really optimized and it is not coherent with what we do normally.
In particular, a problem can happen when the
Divideoperand returns a result which contains a precision and scale different by the ones which are expected as output of theDivideoperand. In the case reported in the JIRA, for instance, the result of theDivideoperand is aDecimal(38, 36), while the output data type forDivideis 38, 22. This is not an issue when theDivideis followed by aCheckOverflowor aCastto the right data type, as these operations return a decimal with the defined precision and scale. Despite in theAverageoperator we do have aCast, this may be bypassed if the result ofDivideis the same type which it is casted to, hence the issue reported in the JIRA may arise.The PR proposes to use the normal rules/handling of the arithmetic operators with Decimal data type, so we both reuse the existing code (having a single logic for operations between decimals) and we fix this problem as the result is always guarded by
CheckOverflow.How was this patch tested?
added UT