morrySnow opened a new pull request, #67733:
URL: https://github.com/apache/doris/pull/67733
## Problem
Arithmetic simplification can move a `CAST` or `TRY_CAST` from around an
arithmetic expression to each operand. That changes where type conversion
happens. With large exact integers converted to `DOUBLE`, the rewritten
expression loses precision before subtraction and returns the wrong value.
For example, subtracting `9223372036854775800` from `9223372036854775807` in
`BIGINT` produces the exact value `7`. Converting that result to `DOUBLE` must
still produce `7`, but converting both operands first rounds them to the same
floating-point value and produces `0`.
## Root cause
The arithmetic flattener recognized a cast containing addition, subtraction,
multiplication, or division and recursively propagated the cast target type to
every operand. This rewrite assumes that conversion distributes over
arithmetic, which is not generally true. Besides floating-point rounding, the
transformation can alter overflow, conversion-error, and `TRY_CAST` null
behavior.
## Reproduction
```sql
CREATE TABLE t (
id INT NOT NULL,
k BIGINT NOT NULL
)
DUPLICATE KEY(id)
DISTRIBUTED BY HASH(id) BUCKETS 1
PROPERTIES ("replication_num" = "1");
INSERT INTO t VALUES
(1, 9223372036854775807),
(2, 9223372036854775806);
SELECT id,
k - 9223372036854775800 AS exact_delta,
TRY_CAST(k - 9223372036854775800 AS DOUBLE) + CAST(0 AS DOUBLE) AS
try_expr,
CAST(k - 9223372036854775800 AS DOUBLE) + CAST(0 AS DOUBLE) AS
cast_expr
FROM t
ORDER BY id;
```
Before this change, `exact_delta` is `7`/`6`, while both converted
expressions incorrectly return `0`/`0`.
## Fix
Treat explicit cast expressions as semantic boundaries and atomic operands
during arithmetic flattening. The simplifier can continue optimizing arithmetic
below and above a cast, but it no longer distributes the conversion into the
cast's operands.
This deliberately chooses correctness over the optimization enabled by
cross-cast flattening; no target-type whitelist is used because conversion
distribution is not safe across all values and operation types.
## Tests
- Added expression-rule coverage for both `CAST` and `TRY_CAST` around a
large-integer subtraction.
- Ran `SimplifyArithmeticRuleTest`: 5 tests passed.
- Deployed the FE to a local sandbox. The reproduction now returns `7`/`6`
for both converted expressions, and the physical expression keeps the `BIGINT`
subtraction inside the cast.
--
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]