jiangxt2 opened a new pull request, #58028: URL: https://github.com/apache/spark/pull/58028
### What changes were proposed in this pull request? When casting a large Double or Float value to Timestamp, the seconds value is multiplied by MICROS_PER_SECOND and then converted to a Long. If the product falls outside the Long range, the JVM saturates the conversion to Long.MAX_VALUE or Long.MIN_VALUE, so an out-of-range input silently produces an extreme but valid-looking timestamp instead of NULL. This PR fixes the silent overflow clamping for Double and Float to Timestamp casts in non-ANSI mode. The fix checks the microsecond product against the Long bounds before the conversion, in both the interpreted and codegen paths. The negative bound keeps Long.MinValue inclusive, and the positive bound treats the rounded 2^63 boundary as overflow because Long.MaxValue is not exactly representable as a Double. Out-of-range values now return NULL in non-ANSI mode. ANSI mode keeps throwing CAST_OVERFLOW; the ANSI helper is also aligned to reject the exact 2^63 boundary, which previously slipped through the existing bounds check and was silently clamped to Long.MAX_VALUE. NaN and Infinity keep their existing behavior: NULL in non-ANSI mode and the datetime invalid-input exception in ANSI mode. Decimal to Timestamp conversion is unchanged. ### Why are the changes needed? The silent clamping is a correctness bug: `CAST(1e20 AS TIMESTAMP)` currently returns `+294247-01-10 04:00:54.775807` (the clamped Long.MAX_VALUE) instead of NULL, hiding the fact that the input is out of range. See [SPARK-58235](https://issues.apache.org/jira/browse/SPARK-58235). ### Does this PR introduce _any_ user-facing change? Yes. Under non-ANSI mode, casting an overflowing Double or Float to Timestamp now returns NULL instead of a wrong timestamp produced by numeric overflow. The SQL migration guide is updated accordingly. ANSI mode behavior is unchanged except that the exact 2^63 boundary now throws CAST_OVERFLOW as the documented contract requires, instead of silently clamping to Long.MAX_VALUE. ### How was this patch tested? Added tests to CastWithAnsiOffSuite and CastWithAnsiOnSuite covering positive and negative overflow, the Long bounds (including the exact -2^63 boundary and the rounded 2^63 boundary), NaN, Infinity, Double, Float and normal values. Verified results: CastWithAnsiOffSuite 138 tests passed, CastWithAnsiOnSuite 136 tests passed, SQLQueryTestSuite cast.sql 6 tests passed, full catalyst/test 10,559 ScalaTest tests and 10,938 JUnit tests passed with 5 ignored, and git diff --check passed. The Spark PR pre-check reported 0 failures and 1 warning (a mechanical golden-file notice; no golden update is needed since no finite overflow input changes existing test output). The full sql/test module could not be completed locally: the Python planner worker and the Ivy dependency resolution are blocked in the current environment, which is unrelated to this change. ### Was this patch authored or co-authored using generative AI tooling? Generated-by: Codex and Claude AI -- 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]
