[fix](fe) Preserve coalesce nullability after conditional rewrite#62094
[fix](fe) Preserve coalesce nullability after conditional rewrite#62094starocean999 wants to merge 2 commits intoapache:masterfrom
Conversation
|
Thank you for your contribution to Apache Doris. Please clearly describe your PR:
|
|
run buildall |
|
/review |
There was a problem hiding this comment.
I found 1 issue that should be addressed before merge.
Critical checkpoint conclusions:
- Goal and correctness: Partially met. The PR fixes the nullability loss in
SimplifyConditionalFunction, but the same regression remains reachable through another rewrite path (FoldConstantRuleOnFE.visitNvl). - Scope: The code change is small and focused.
- Concurrency: Not applicable; this change is in FE expression rewriting only.
- Lifecycle/static init: No issue found.
- Config changes: None.
- Compatibility: No FE/BE protocol or storage compatibility issue found.
- Parallel code paths: Not fully covered.
ifnull/nvlis simplified both here and in FE constant folding, and only one path was updated. - Special conditional checks: The new
NonNullable(...)guard is reasonable for this rule. - Test coverage: Improved for the simplifier path and regression SQL, but still missing coverage for the FE constant-folding path.
- Observability: No additional observability needed.
- Transaction/persistence/data write/FE-BE variable passing: Not applicable.
- Performance: No material issue found.
- Other issues: The remaining
FoldConstantRuleOnFE.visitNvlgap can still produce incorrect nullable metadata after type coercion.
Because of that missed parallel path, I do not consider the fix complete yet.
| Nvl nvl = ctx.expr; | ||
| if (nvl.child(0) instanceof NullLiteral) { | ||
| return TypeCoercionUtils.ensureSameResultType(nvl, nvl.child(1), ctx.rewriteContext); | ||
| return keepConditionalNullability( |
There was a problem hiding this comment.
This fixes the SimplifyConditionalFunction path, but ifnull/nvl can still lose non-nullability through FoldConstantRuleOnFE.visitNvl(). That method still rewrites nvl(nonNullableExpr, nullLiteral) / nvl(nullLiteral, nonNullableExpr) via TypeCoercionUtils.ensureSameResultType(...) and, for cases like datetime(0) -> datetime(6), it returns a nullable Cast. Since FE constant folding is invoked directly in other planner flows (FoldConstantRuleOnFE.evaluate(...), InsertIntoValuesAnalyzer, etc.), the regression is still reachable even after this change. Please apply the same nullability preservation there and add a fold-constant test for that path.
TPC-H: Total hot run time: 28900 ms |
TPC-DS: Total hot run time: 178724 ms |
|
run buildall |
TPC-H: Total hot run time: 28738 ms |
TPC-DS: Total hot run time: 178539 ms |
FE UT Coverage ReportIncrement line coverage |
Problem Summary:
This PR fixes an incorrect nullability regression in Nereids when simplifying conditional functions such as
coalesceandnvl.Root cause:
SimplifyConditionalFunctionrewrites expressions likecoalesce(non_nullable_expr, ...)to the first guaranteed non-null child.ensureSameResultTypemay wrap that child with aCast.coalesceresult is guaranteed to be non-null.coalesce, and downstream plan output metadata became inconsistent.Fix:
SimplifyConditionalFunctioninstead of relying on a later nullable-adjustment pass.coalesceornvl, if the original expression is non-nullable but the rewritten expression becomes nullable because of type coercion, wrap the rewritten result withNonNullable(...).None
Check List (For Author)
Test
Behavior changed:
Does this need documentation?
Check List (For Reviewer who merge this PR)