yujun777 opened a new pull request, #70521: URL: https://github.com/apache/doris/pull/70521
### Background Nereids propagates logical empty relations through joins, projections and set operations. Incremental materialized-view refreshes also use anti joins to repair the NULL-extended rows of outer joins, so an empty delta can leave a repair branch with no possible output. ### What problem does this PR solve? Issue Number: None Related PR: None PR Type: Performance Problem Summary: An empty left input of a LEFT ANTI JOIN, or an empty right input of a RIGHT ANTI JOIN, still retains the join and its snapshot subtree. Add these two cases to the existing empty-relation rule so that subsequent projections and unions can collapse as well. Most of the diff tests the join-side matrix, semantic boundaries and incremental refresh results. ### Details - **Change map:** 2 production lines extend the join predicate; 243 test lines cover rule boundaries and SQL/IVM results; 205 added/deleted generated-output lines record the new cases and simplified existing IVM plan. - **Why it was slow:** The empty-relation join predicate omitted ordinary anti joins, leaving their opposite input in the physical plan even when the output-producing side was statically empty. - **Optimization:** Recognize LEFT ANTI with an empty left child and RIGHT ANTI with an empty right child inside the existing mark-join and side-effect guards. Reuse the current empty-relation construction and union folding. - **Results:** In the existing `test_ivm_explain_refresh` all-streams golden plan, LEFT ANTI nodes change from 2 to 0, OLAP scan nodes from 5 to 2, and union nodes from 2 to 0 after regeneration. Ordinary empty-output anti joins and nested unions now produce an empty physical relation without scans. These are plan-size measurements; refresh latency, CPU and physical bytes read were not benchmarked. - **Applicability and cost:** Applies only to explicit empty relations, including IVM repair branches, in cloud and shared-nothing planning. Row-count estimates, NULL-aware anti joins, non-empty output sides, mark joins, scalar cardinality checks and non-movable expressions keep their existing behavior. No configuration or protocol changes; the two constant-time type checks add no data-size-dependent work. ### Testing - Local `EliminateEmptyRelationTest`: 17 tests passed. The two output-side cases fail on the original rule and pass after the change; checks include output ExprIds/types/nullability, the opposite empty side, both sides empty, nested project/union propagation, mark joins, nested scalar assertions and non-movable expressions. - Local ASAN `./build.sh --be --fe`: passed, with Checkstyle enabled. - Local shared-nothing regression suites `eliminate_empty_anti_join`, `test_ivm_empty_anti_join`, and `test_ivm_explain_refresh`: golden generation and subsequent comparison both passed for all 3 suites. The IVM result test checks 8 stages against the full query with materialized-view rewrite disabled, including insert/delete/update, key changes, NULL keys and both-table changes. ### Release note The optimizer removes ordinary anti joins whose output side is statically empty, including empty outer-join repair branches during incremental materialized-view refreshes. ### Check List (For Author) - Behavior changed: No - Does this need documentation: No - Pre-submission status: Ready -- 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]
