Shahzeb-DataEngineer opened a new pull request, #26653: URL: https://github.com/apache/datafusion/pull/26653
## Which issue does this PR close? - Closes #26651 ## Rationale for this change Writing a signed integer type's minimum value with a postfix cast kills the query: ```sql SELECT -2147483648::INT; -- Error: Optimizer rule 'simplify_expressions' failed -- caused by Failed to cast field 'lit' from Int64 to Int32 -- caused by Arrow error: Cast error: Can't cast value 2147483648 to type Int32 ``` The planner builds `-(CAST(2147483648 AS Int32))`: the cast binds to the unsigned positive magnitude and the negation stays outside. The positive magnitude of a signed type's minimum is not representable in that type, so constant folding of the inner cast fails. The same happens for BIGINT, SMALLINT and TINYINT minima, in SELECT, VALUES, WHERE and INSERT, and `skip_failed_rules` does not rescue it. Equivalent spellings (`CAST(-2147483648 AS INT)`, bare `-9223372036854775808`, string casts) all work. ## What changes are included in this PR? - `datafusion/sql/src/expr/unary_op.rs`: in `parse_sql_unary_op`, when unary minus is applied to a `CAST` / `::` cast whose operand is a number literal, fold the sign into the literal first (the same treatment the planner already gives a bare negative literal) and then apply the cast to the negated literal, so the cast sees the representable negative value. - `datafusion/sql/src/expr/mod.rs`: split the planned-operand half of `sql_cast_to_expr` into `sql_cast_planned_expr_to_expr` so the unary-minus path shares the exact cast semantics (including the timestamp-seconds special case). The format check keeps its original position ahead of operand planning in `sql_cast_to_expr`. Only `CAST` and postfix `::` casts of number literals take the new path; `TRY_CAST` / `SAFE_CAST` and non-literal operands are planned exactly as before. ## What is the testing strategy for this PR? - New sqllogictest cases at the end of `datafusion/sqllogictest/test_files/cast.slt`: the minimum value with a postfix cast for all four signed widths (TINYINT, SMALLINT, INT, BIGINT), the CAST spelling, ordinary negative literals and a negative decimal literal with postfix casts (unaffected), a WHERE filter and INSERT .. VALUES using the BIGINT minimum, and one-past-the-minimum still erroring. - Ran the `cast` sqllogictests and the `datafusion-sql` test suite; all pass. `cargo fmt --all` and clippy on the touched crates are clean. ## Are there any user-facing changes? Yes: minimum-value integer literals written with a postfix cast (e.g. `-2147483648::INT`) now return the minimum value instead of failing the query. No other behavior changes. This PR was prepared with AI assistance; all changes and tests were reviewed and verified by me. -- 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]
