gengliangwang commented on code in PR #55934:
URL: https://github.com/apache/spark/pull/55934#discussion_r3288515948
##########
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/Cast.scala:
##########
@@ -2017,23 +2025,36 @@ case class Cast(
from: DataType,
to: DataType): CastFunction = {
assert(ansiEnabled)
- val (min, max) = lowerAndUpperBound(integralType)
- val mathClass = classOf[Math].getName
- val fromDt = ctx.addReferenceObj("from", from, from.getClass.getName)
- val toDt = ctx.addReferenceObj("to", to, to.getClass.getName)
- // When casting floating values to integral types, Spark uses the method
`Numeric.toInt`
- // Or `Numeric.toLong` directly. For positive floating values, it is
equivalent to `Math.floor`;
- // for negative floating values, it is equivalent to `Math.ceil`.
- // So, we can use the condition `Math.floor(x) <= upperBound &&
Math.ceil(x) >= lowerBound`
- // to check if the floating value x is in the range of an integral type
after rounding.
- (c, evPrim, _) =>
- code"""
- if ($mathClass.floor($c) <= $max && $mathClass.ceil($c) >= $min) {
- $evPrim = ($integralType) $c;
- } else {
- throw QueryExecutionErrors.castingCauseOverflowError($c, $fromDt,
$toDt);
- }
- """
+ if (integralType == "int" || integralType == "long") {
+ // Float/Double -> Int/Long: call
FloatExactNumeric/DoubleExactNumeric.toInt/toLong
+ // directly. Each already does the floor/ceil bounds check and throws
+ // castingCauseOverflowError -- same as the inline body.
+ val numericObj = (from match {
+ case FloatType => FloatExactNumeric
+ case DoubleType => DoubleExactNumeric
+ }).getClass.getCanonicalName.stripSuffix("$")
+ val method = s"to${integralType.capitalize}"
+ (c, evPrim, _) => code"$evPrim = $numericObj.$method($c);"
+ } else {
+ // Byte/short narrowing remains inline; refactored in a follow-up PR.
Review Comment:
```suggestion
```
--
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.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]