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]

Reply via email to