gengliangwang opened a new pull request, #57143:
URL: https://github.com/apache/spark/pull/57143

   ### What changes were proposed in this pull request?
   
   `Ceil` and `Floor` (ANSI mode, `DOUBLE -> LONG`) check for overflow before 
casting the rounded
   double to long. That check is currently implemented twice, in a private 
`CeilFloor` helper object in
   `mathExpressions.scala`:
   
   - `CeilFloor.doubleToLong` for the interpreted path, and
   - `CeilFloor.doubleToLongCode`, which re-emits the bound check as ~9 lines 
of Java into every
     `Ceil`/`Floor` codegen stage.
   
   This PR replaces both with a single shared `MathUtils.doubleToLong(value, 
context)` utility that the
   interpreted and generated code both call, and deletes the `CeilFloor` 
object. The generated code
   collapses from the inline block:
   
   ```java
   double roundedValue = java.lang.Math.ceil(input);
   if (!java.lang.Double.isNaN(roundedValue) &&
       (roundedValue < (double) java.lang.Long.MIN_VALUE ||
        roundedValue >= (double) java.lang.Long.MAX_VALUE)) {
     throw QueryExecutionErrors.arithmeticOverflowError("long overflow", "", 
errCtx);
   }
   result = (long) roundedValue;
   ```
   
   to a single call:
   
   ```java
   result = org.apache.spark.sql.catalyst.util.MathUtils.doubleToLong(
     java.lang.Math.ceil(input), errCtx);
   ```
   
   `MathUtils` is the natural home: it already hosts the other 
arithmetic-overflow helpers
   (`addExact`, `negateExact`, `withOverflow`) and follows the same "shared by 
the eval and codegen
   paths so the two never diverge" convention already used for `pmod`. Placing 
`doubleToLong` there also
   means one fewer copy of the bound check emitted per stage (part of the 
broader effort to shrink
   whole-stage-codegen output, SPARK-56908).
   
   ### Why are the changes needed?
   
   The overflow check is type-independent bookkeeping that does not need to be 
re-emitted into each
   generated stage. Consolidating it into `MathUtils`:
   - removes the duplicated logic (the `CeilFloor.doubleToLong` eval copy and 
the
     `doubleToLongCode` string builder collapse into one method), so the two 
paths cannot drift, and
   - shrinks the generated code for every ANSI `CEIL`/`FLOOR` over a `DOUBLE` 
from the multi-line
     bound check to a single call.
   
   ### Does this PR introduce _any_ user-facing change?
   
   No. The check, the error (`ARITHMETIC_OVERFLOW`), and the query context are 
identical; `defineCodeGen`
   applies the same null-safety wrapper the previous `nullSafeCodeGen` did. 
This is a pure
   code-organization change.
   
   ### How was this patch tested?
   
   Existing tests, run with whole-stage codegen both on and off:
   - `MathExpressionsSuite` (`ceil` and `floor`, including the ANSI overflow 
cases and
     `checkConsistencyBetweenInterpretedAndCodegenAllowingException` for 
`DoubleType`), and
   - regenerated `postgreSQL/float8.sql.out` (unchanged, confirming the 
behavior is preserved).
   
   ### Was this patch authored or co-authored using generative AI tooling?
   
   Generated-by: Claude Code (Opus 4.8)
   


-- 
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]

Reply via email to