mgaido91 commented on a change in pull request #25461: [SPARK-28741][SQL]Throw
exceptions when casting to integers causes overflow
URL: https://github.com/apache/spark/pull/25461#discussion_r315176325
##########
File path:
sql/catalyst/src/main/scala/org/apache/spark/sql/types/numerics.scala
##########
@@ -107,4 +109,85 @@ object LongExactNumeric extends LongIsIntegral with
Ordering.LongOrdering {
override def times(x: Long, y: Long): Long = Math.multiplyExact(x, y)
override def negate(x: Long): Long = Math.negateExact(x)
+
+ override def toInt(x: Long): Int =
+ if (x == x.toInt) {
+ x.toInt
+ } else {
+ throw new ArithmeticException(s"Casting $x to Int causes overflow.")
+ }
+}
+
+object FloatExactNumeric extends FloatIsFractional with Ordering.FloatOrdering
{
+ private def exceptionMessage(x: Float, dataType: String): String =
+ s"Casting $x to $dataType causes overflow."
+
+ private val intUpperBound = Int.MaxValue + 1L
+ private val intLowerBound = Int.MinValue - 1L
+
+ override def toInt(x: Float): Int = {
+ if (x < intUpperBound && x > intLowerBound) {
+ x.toInt
+ } else {
+ throw new ArithmeticException(exceptionMessage(x, "Int"))
+ }
+ }
+
+ override def toLong(x: Float): Long = {
+ if (x <= Long.MaxValue && x >= Long.MinValue) {
+ x.toLong
+ } else {
+ throw new ArithmeticException(exceptionMessage(x, "Long"))
+ }
+ }
+}
+
+object DoubleExactNumeric extends DoubleIsFractional with
Ordering.DoubleOrdering {
+ private def exceptionMessage(x: Double, dataType: String): String =
+ s"Casting $x to $dataType causes overflow."
+
+ private val intUpperBound = Int.MaxValue + 1L
+ private val intLowerBound = Int.MinValue - 1L
+
+ override def toInt(x: Double): Int = {
+ if (x < intUpperBound && x > intLowerBound) {
+ x.toInt
+ } else {
+ throw new ArithmeticException(exceptionMessage(x, "Int"))
+ }
+ }
+
+ override def toLong(x: Double): Long = {
+ if (x <= Long.MaxValue && x >= Long.MinValue) {
+ x.toLong
+ } else {
+ throw new ArithmeticException(exceptionMessage(x, "Long"))
+ }
+ }
+}
+
+object DecimalExactNumeric extends DecimalIsConflicted {
+ private def exceptionMessage(x: Decimal, dataType: String): String =
+ s"Casting $x to $dataType causes overflow."
+
+ private val intUpperBound = Decimal(Int.MaxValue + 1L)
+ private val intLowerBound = Decimal(Int.MinValue - 1L)
+ private val longUpperBound = Decimal(Long.MaxValue) + Decimal(1L)
+ private val longLowerBound = Decimal(Long.MinValue) - Decimal(1L)
+
+ override def toInt(x: Decimal): Int = {
+ if (x < intUpperBound && x > intLowerBound) {
+ x.toInt
+ } else {
+ throw new ArithmeticException(exceptionMessage(x, "Int"))
+ }
+ }
+
+ override def toLong(x: Decimal): Long = {
+ if (x < longUpperBound && x > longLowerBound) {
+ x.toLong
Review comment:
shall we rather add a flag to the `toLong` method in order to control this?
I think it would be more efficient
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
With regards,
Apache Git Services
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]