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

[SPARK-41554] fix changing of Decimal scale when scale decreased by m… #39099

Closed
wants to merge 3 commits into from

Conversation

fe2s
Copy link
Contributor

@fe2s fe2s commented Dec 16, 2022

…ore than 18

What changes were proposed in this pull request?

Fix Decimal scaling that is stored as compact long internally when scale decreased by more than 18. For example,

Decimal(1, 38, 19).changePrecision(38, 0)

produces an exception

java.lang.ArrayIndexOutOfBoundsException: 19
    at org.apache.spark.sql.types.Decimal.changePrecision(Decimal.scala:377)
    at org.apache.spark.sql.types.Decimal.changePrecision(Decimal.scala:328)

Another way to reproduce it with SQL query

sql("select cast(cast(cast(cast(id as decimal(38,15)) as decimal(38,30)) as decimal(38,37)) as decimal(38,17)) from range(3)").show

The bug exists for Decimal that is stored using compact long only, it works fine with Decimal that uses scala.math.BigDecimal internally.

Why are the changes needed?

Not able to execute the SQL query mentioned above. Please note, for my use case the SQL query is generated programatically, so I cannot optimize it manually.

Does this PR introduce any user-facing change?

Yes, it will allow scale Decimal properly that is not currently possible due to the exception.

How was this patch tested?

Tests were added. The fix affects the scale decrease only, but I decided to also include tests for scale increase as I didn't find them.

@github-actions github-actions bot added the SQL label Dec 16, 2022
@AmplabJenkins
Copy link

Can one of the admins verify this patch?

@fe2s
Copy link
Contributor Author

fe2s commented Dec 22, 2022

Hi @cloud-fan, @MaxGekk, @gengliangwang, would you be able to review? Thank you!

@@ -374,7 +374,7 @@ final class Decimal extends Ordered[Decimal] with Serializable {
if (scale < _scale) {
// Easier case: we just need to divide our scale down
val diff = _scale - scale
val pow10diff = POW_10(diff)
val pow10diff = POW_10(math.min(diff, MAX_LONG_DIGITS))
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we still use compact long to store the decimal value? Shall we go to the branch // Give up on using Longs; switch to BigDecimal, which we'll modify below?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Compact long can still be used when diff > MAX_LONG_DIGITS. In this case longVal becomes 0, 1 or -1 depending on rounding, so using BigDecimal is not actually needed.

@cloud-fan cloud-fan closed this in 838954e Dec 30, 2022
@cloud-fan
Copy link
Contributor

cloud-fan commented Dec 30, 2022

thanks, merging to master!

@cloud-fan
Copy link
Contributor

@fe2s can you create backport PRs for other branches? Thanks!

@fe2s
Copy link
Contributor Author

fe2s commented Dec 30, 2022

@cloud-fan thank you, which branches should fix also? 3.1, 3.2 and 3.3?

@cloud-fan
Copy link
Contributor

3.2 and 3.3, as they are both active branches.

srowen pushed a commit that referenced this pull request Feb 3, 2023
…ore than 18

This is a backport PR for #39099

Closes #39813 from fe2s/branch-3.3-fix-decimal-scaling.

Authored-by: oleksii.diagiliev <oleksii.diagiliev@workday.com>
Signed-off-by: Sean Owen <srowen@gmail.com>
srowen pushed a commit that referenced this pull request Feb 3, 2023
…ore than 18

This is a backport PR for #39099

Closes #39381 from fe2s/branch-3.2-fix-decimal-scaling.

Authored-by: oleksii.diagiliev <oleksii.diagiliev@workday.com>
Signed-off-by: Sean Owen <srowen@gmail.com>
sunchao pushed a commit to sunchao/spark that referenced this pull request Jun 2, 2023
…ore than 18

This is a backport PR for apache#39099

Closes apache#39381 from fe2s/branch-3.2-fix-decimal-scaling.

Authored-by: oleksii.diagiliev <oleksii.diagiliev@workday.com>
Signed-off-by: Sean Owen <srowen@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
3 participants