Skip to content

Comments

[SPARK-28470][SQL] Cast to decimal throws ArithmeticException on overflow#25253

Closed
mgaido91 wants to merge 3 commits intoapache:masterfrom
mgaido91:SPARK-28470
Closed

[SPARK-28470][SQL] Cast to decimal throws ArithmeticException on overflow#25253
mgaido91 wants to merge 3 commits intoapache:masterfrom
mgaido91:SPARK-28470

Conversation

@mgaido91
Copy link
Contributor

What changes were proposed in this pull request?

The flag spark.sql.decimalOperations.nullOnOverflow is not honored by the Cast operator. This means that a casting which causes an overflow currently returns null.

The PR makes Cast respecting that flag, ie. when it is turned to false and a decimal overflow occurs, an exception id thrown.

How was this patch tested?

Added UT

@SparkQA
Copy link

SparkQA commented Jul 25, 2019

Test build #108155 has finished for PR 25253 at commit 2d85089.

  • This patch passes all tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

if (value.changePrecision(decimalType.precision, decimalType.scale)) value else null
if (value.changePrecision(decimalType.precision, decimalType.scale)) {
value
} else {
Copy link
Member

Choose a reason for hiding this comment

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

not a biggie but:

if (value.changePrecision(decimalType.precision, decimalType.scale)) {
  value
} else if (nullOnOverflow) {
  null
} else {
  throw new ArithmeticException(s"${value.toDebugString} cannot be represented as " +
    s"Decimal(${decimalType.precision}, ${decimalType.scale}).")
}

Copy link
Member

Choose a reason for hiding this comment

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

I like the way in this PR. It is more clear about what to do on overflow.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree with @gengliangwang but I am fine changing it. Please @HyukjinKwon let me know if you think we should change it, I'll do it. Thanks.

Copy link
Member

Choose a reason for hiding this comment

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

ah, that's fine. no big deal.

null
} else {
throw new ArithmeticException(s"${value.toDebugString} cannot be represented as " +
s"Decimal(${decimalType.precision}, ${decimalType.scale}).")
Copy link
Member

Choose a reason for hiding this comment

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

Nit: should we just use ${decimalType.catalogString} here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

this is consistent with other similar error messages. We should change it in all cases, then. WDYT?

Copy link
Member

Choose a reason for hiding this comment

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

This is trivial. Maybe we can have another PR to fix it.

@mgaido91
Copy link
Contributor Author

mgaido91 commented Aug 3, 2019

cc @cloud-fan @JoshRosen @maropu

Copy link
Member

@maropu maropu left a comment

Choose a reason for hiding this comment

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

LGTM except for minor comments.

code"""
|$d.changePrecision(${decimalType.precision}, ${decimalType.scale});
|$d.changePrecision(
| ${decimalType.precision}, ${decimalType.scale});
Copy link
Member

Choose a reason for hiding this comment

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

nit: write this in a single line? |$d.changePrecision(${decimalType.precision}, ${decimalType.scale});

} else {
s"""
|throw new ArithmeticException($d.toDebugString() + " cannot be represented as " +
| "Decimal(${decimalType.precision}, ${decimalType.scale})");
Copy link
Member

Choose a reason for hiding this comment

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

super nit: you forgot to add a period in the end? better to have the same message between the codegen/interpreter modes: https://github.com/apache/spark/pull/25253/files#diff-258b71121d8d168e4d53cb5b6dc53ffeR518

}
code"""
|if ($d.changePrecision(${decimalType.precision}, ${decimalType.scale})) {
|if ($d.changePrecision(
Copy link
Member

Choose a reason for hiding this comment

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

ditto: can you write it in a single line?

withSQLConf(SQLConf.DECIMAL_OPERATIONS_NULL_ON_OVERFLOW.key -> "true") {
checkEvaluation(Cast(Literal("134.12"), DecimalType(3, 2)), null)
checkEvaluation(
Cast(Literal(java.sql.Timestamp.valueOf("2019-07-25 22:04:36")), DecimalType(3, 2)), null)
Copy link
Member

Choose a reason for hiding this comment

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

java.sql.Timestamp->Timestamp?

checkExceptionInExpression[ArithmeticException](
Cast(Literal("134.12"), DecimalType(3, 2)), "cannot be represented")
checkExceptionInExpression[ArithmeticException](
Cast(Literal(java.sql.Timestamp.valueOf("2019-07-25 22:04:36")), DecimalType(3, 2)),
Copy link
Member

Choose a reason for hiding this comment

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

ditto

@maropu
Copy link
Member

maropu commented Aug 3, 2019

cc: @dongjoon-hyun

@SparkQA
Copy link

SparkQA commented Aug 4, 2019

Test build #108611 has finished for PR 25253 at commit 2b3aa89.

  • This patch fails Spark unit tests.
  • This patch merges cleanly.
  • This patch adds no public classes.


/**
* Create new `Decimal` with precision and scale given in `decimalType` (if any),
* returning null if it overflows or creating a new `value` and returning it if successful.
Copy link
Member

Choose a reason for hiding this comment

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

Change this comment too?

@mgaido91 mgaido91 changed the title [SPARK-28470][SQL] Cast to decimal throws ArithemticException on overflow [SPARK-28470][SQL] Cast to decimal throws ArithmeticException on overflow Aug 4, 2019
@SparkQA
Copy link

SparkQA commented Aug 4, 2019

Test build #108621 has finished for PR 25253 at commit 23b8ee1.

  • This patch passes all tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

@maropu
Copy link
Member

maropu commented Aug 6, 2019

Anyone can check this for sign-off before merging?

Copy link
Contributor

@cloud-fan cloud-fan left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Member

@gengliangwang gengliangwang left a comment

Choose a reason for hiding this comment

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

LGTM

@maropu
Copy link
Member

maropu commented Aug 7, 2019

Thanks! Merged to master.

@maropu maropu closed this Aug 7, 2019
@HyukjinKwon
Copy link
Member

late LGTM too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants