Baymine opened a new pull request, #66505:
URL: https://github.com/apache/doris/pull/66505
## Proposed changes
Issue Number: no issue
Problem Summary:
Add a new rewrite to `SimplifyConditionalFunction` that collapses
`if(cond, x, x)` to `x` when the two branches are structurally identical and
dropping the condition cannot change observable behavior. The rewrite is
registered as an additional `matchesType(If.class)` rule alongside the
existing
Coalesce/Nvl/NullIf rules and fires only when all of the following soundness
guards hold:
1. `then` and `else` are structurally equal (`then.equals(else)`).
2. The condition is deterministic (`!condition.containsNondeterministic()`),
so
dropping its evaluation cannot remove an observable side effect such as
`rand()`/`now()`/unique functions.
3. Neither the condition NOR the surviving branch contains a function that
stays
observable even when deterministic and error-free, i.e. a
`NoneMovableFunction` (contractually must-not-prune, e.g. `assert_true`)
or
`sleep()` (a deterministic function whose whole point is the blocking side
effect, which BE also refuses to fold). The branch is guarded too because
BE
evaluates the then/else argument columns unconditionally before selecting
between them, so `if(cond, sleep(1), sleep(1))` already runs `sleep()`
twice
per block; collapsing to a single `sleep(1)` would halve that side effect.
4. Every subtree of the condition that may throw is also evaluated
unconditionally by the surviving branch, so removing the condition cannot
suppress a runtime error the original expression would have raised. This
is
checked by `collectThrowingSubtrees` (maximal potentially-throwing
subtrees of
the condition, using a conservative `cannotThrowAtNode`
over-approximation)
plus `occursUnconditionally` (target reachable from the branch root
without
crossing a lazy/guarded boundary such as `If`/`CaseWhen`/`Coalesce`/`Nvl`/
`NullIf`/`CompoundPredicate`/`Lambda`).
Nullability is preserved automatically: `If.nullable()` is
`then.nullable() || else.nullable()`, which equals `then.nullable()` when the
branches are identical, so the result type is stabilized via
`TypeCoercionUtils.ensureSameResultType`.
## Release note
None
## Check List (For Author)
- Test: Unit Test
- Added `SimplifyConditionalFunctionTest#testIf` covering 10 cases: basic
rewrite, non-deterministic condition, distinct branches, throwing
subtree
only in condition, the Case3 shape where the throwing subtree also
occurs
unconditionally in the branch, a throwing subtree hidden under a
guarded
inner `if`, and the `sleep()`/`assert_true` guards in both the
condition
and the branches. Ran
`run-fe-ut.sh --run
org.apache.doris.nereids.rules.expression.rules.SimplifyConditionalFunctionTest`
=> Tests run: 4, Failures: 0, Errors: 0, Skipped: 0 (testIf included).
FE `build.sh --fe` succeeded with 0 Checkstyle violations.
- Behavior changed: No
- Does this need documentation: No
--
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]