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

   ### What changes were proposed in this pull request?
   
   Add Long range validation for the Double/Float-to-Timestamp cast path in 
both interpreted and codegen execution.
   
   When a Double or Float value multiplied by `MICROS_PER_SECOND` (1,000,000) 
exceeds `Long` range, the unchecked cast to `long` silently produces a clamped 
value (`Long.MAX_VALUE` or `Long.MIN_VALUE`). The fix detects this overflow and 
either returns `NULL` (non-ANSI mode) or throws `CAST_OVERFLOW` (ANSI mode).
   
   The interpreted path (`Cast.doubleToTimestamp`) now checks the 
multiplication result against Long range before calling `.toLong`. The codegen 
path (`castToTimestampCode` Double/Float branches) applies the same range check 
before the `(long)` cast.
   
   ### Why are the changes needed?
   
   `CAST(1e20 AS TIMESTAMP)` silently produces `+294247-01-10 04:00:54.775807` 
(clamped to `Long.MAX_VALUE`) instead of `NULL` in non-ANSI mode. This is 
inconsistent with other overflow behavior:
   
   ```sql
   SET spark.sql.ansi.enabled=false;
   SELECT CAST(1e20 AS TIMESTAMP);
   -- Before fix: +294247-01-10 04:00:54.775807  (clamped to Long.MAX_VALUE)
   -- After fix:  NULL
   
   SELECT CAST(-1e20 AS TIMESTAMP);
   -- Before fix: -290308-12-21 19:59:05.224192  (clamped to Long.MIN_VALUE)
   -- After fix:  NULL
   ```
   
   The ANSI mode path (`doubleToTimestampAnsi` → `DoubleExactNumeric.toLong`) 
already correctly throws `CAST_OVERFLOW`. This bug only affects non-ANSI mode.
   
   ### Does this PR introduce _any_ user-facing change?
   
   Yes. Previously, `CAST(large_double AS TIMESTAMP)` silently returned an 
incorrect value caused by numeric overflow. Now:
   - Non-ANSI mode: returns `NULL` (consistent with other overflow casts)
   - ANSI mode: throws `CAST_OVERFLOW` error (unchanged)
   
   ### How was this patch tested?
   
   Added unit tests in `CastWithAnsiOffSuite` and `CastWithAnsiOnSuite`:
   
   Non-ANSI mode (`CastWithAnsiOffSuite`):
   - Positive overflow: `1E20` → null
   - Negative overflow: `-1E20` → null
   - Boundary just under: `9223372036854.0` → passes through
   - Boundary just over: `9223372036855.0` → null
   - Negative boundary: `-9223372036854.0` / `-9223372036855.0`
   - Finite input overflowing to +-Infinity: `Double.MaxValue` / 
`-Double.MaxValue`
   - NaN, Infinity, normal values, zero, Float overflow
   
   ANSI mode (`CastWithAnsiOnSuite`):
   - Positive overflow: throws `CAST_OVERFLOW` with correct error parameters
   - Negative overflow: throws `CAST_OVERFLOW` with correct error parameters
   - Boundary values, normal values, Float overflow
   
   ### 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