englefly opened a new pull request, #69308:
URL: https://github.com/apache/doris/pull/69308

   ### What problem does this PR solve?
   
   Issue Number: DORIS-29796
   
   Related PR: #62828 (source of the pick), #61146 (source of the dependency 
fix), #68211
   
   Problem Summary: backport the CTE empty/cascading pruning fix #62828 to 
branch-4.2, plus the
   `ColumnPruning` CTE protection that #62828 implicitly depends on. Without it 
the three branch-4.2
   RQG cases tracked by DORIS-29796 (6540158413 / DORIS-25384, 6540160970 / 
DORIS-25408,
   6540160107 / DORIS-25409) keep failing.
   
   #### Why #62828 alone is not enough on branch-4.2
   
   `ColumnPruning` on branch-4.2 only protects `LogicalCTEProducer` with 
`skipPruneThis` and has no
   `visitLogicalCTEAnchor`. When the required slots of an anchor do not include 
the producer outputs
   (the normal case, because consumers reference the producer slots directly), 
the producer subtree is
   pruned with an empty required set and `LogicalProject` materializes the 
empty projection as the
   dummy `1 AS 1` projection. The rewrite plan therefore becomes
   
   ```
   LogicalCteAnchor
   |--LogicalProject ( projects=[1 AS 1] )
   |  +--LogicalCteProducer
   +--...
   ```
   
   which (a) breaks the `anchor.left() instanceof LogicalCTEProducer` invariant 
that #62828's
   `normalizeCtePlan`/`refreshCteContext` relies on (`ClassCastException`), and 
(b) is an invalid CTE
   structure: the materialized columns no longer match the slot mapping the 
consumers were built from,
   which is what surfaces as `VSlotRef ... have invalid slot id` in case 
6540160107.
   
   Master has had the protection since #61146 (`visitLogicalCTEAnchor` +
   `skipPruneThisAndFirstLevelChildren`); this PR ports exactly that hunk.
   
   #### Hunk audit of the #62828 pick (source commit `c75eba5488f`)
   
   | Source file | Disposition |
   | --- | --- |
   | `nereids/jobs/executor/Optimizer.java` | Ported verbatim 
(`normalizeCtePlan`, `refreshCteContext`, `containsCte`, 
`generateFilterPushedDownInlinedPlan`, method rename). |
   | `nereids/rules/rewrite/CTEInliner.java` | Ported verbatim 
(`inlineByCurrentConsumerCount`, `InlineResult`, zero-consumer anchor removal, 
recursive anchor trimming). |
   | `nereids/StatementContext.java` | Not applied: branch-4.2 already has 
`clearCteEnvironment()` from the multi-mode CTE inline work (#68211), and its 
variant also clears `consumerIdToLimitRows`. |
   | `nereids/rules/rewrite/ClearContextStatus.java` | Not applied: 4.2 keeps 
the explicit per-map clears, which are a superset of what the picked code 
needs. |
   | `qe/SessionVariable.java` | Not applied: 4.2 keeps 
`@VariableMgr.VarAttr(..., alias = "cbo_cte_inline_mode")`; the source commit 
only dropped the alias. |
   | `.../CTEInlineTest.java` | Ported verbatim, including the new 
`refreshCteConsumersAfterNormalizeEliminatesEmptyBranch`. |
   | `regression-test/suites/query_p0/cte/test_cbo_cte_inline_prune.groovy` | 
Ported verbatim, path adapted to the 4.2 layout (`suites/nereids_p0/cte/`; 
`suites/query_p0/cte` does not exist on 4.2). |
   | `regression-test/data/query_p0/...` baselines | Paths adapted to the 4.2 
layout (`data/nereids_p0/repeat/`, `data/nereids_rules_p0/unique_function/`); 
content unchanged. |
   
   The dependency fix is a separate commit, ported from `5de1ed88d4b` (#61146) 
and limited to the
   `ColumnPruning` hunk (12 added lines): CTE anchors and producers are no 
longer column pruned and
   keep their first level children's full output requirement.
   
   No BE changes.
   
   ### Release note
   
   None
   
   ### Check List (For Author)
   
   - Test
       - [x] FE unit test: `./run-fe-ut.sh --run 
org.apache.doris.nereids.rules.rewrite.CTEInlineTest`
         → `Tests run: 2, Failures: 0, Errors: 0` (includes the new
         `refreshCteConsumersAfterNormalizeEliminatesEmptyBranch`).
       - [x] FE build: `./build.sh --fe` → `BUILD SUCCESS` on this branch 
(checkstyle included).
       - [x] Original RQG cases replayed against a local 4.2 cluster (FE+BE 
built from this branch,
         BE alive), using the full DDL/INSERT/session settings from the 
DORIS-29796 attachment
         `repro-cte-empty-42.sql` (database renamed to a hyphen-free name so 
branch-4.2's parser
         accepts it; no other change):
         | case | expected | branch-4.2 before | this branch |
         | --- | --- | --- | --- |
         | 6540158413 | 0 rows | `size of sources must be greater than 0` | 0 
rows, no error |
         | 6540160970 | 0 rows | `size of sources must be greater than 0` | 0 
rows, no error |
         | 6540160107 | 0 rows | `VSlotRef col_int_undef_signed have invalid 
slot id: 15` | 0 rows, no error |
         With only the #62828 commit replayed, cases 6540158413/6540160970 
return 0 rows and
         6540160107 still fails (`ClassCastException: LogicalProject cannot be 
cast to
         LogicalCTEProducer`), which is why the `ColumnPruning` commit is part 
of this PR.
       - [x] Candidate 6540166225 from the DORIS-29796 evidence could not be 
replayed: the evidence
         attachment only carries its error text, not its SQL, so there is no 
input to verify locally.
       - [x] Regression (local 4.2 cluster, JDBC `127.0.0.1:29731`):
           - `-d nereids_p0/cte` → 9 suites, failed 0 (includes the new 
`test_cbo_cte_inline_prune`)
           - `-s test_repeat_output_slot` → pass (baseline updated by the pick)
           - `-s agg_with_unique_function` → pass (baseline updated by the pick)
           - `-d nereids_rules_p0/cte` → 3 suites, failed 0
           - `-d nereids_rules_p0/cte_limit_pushdown` → 1 suite, failed 0
           - `-d nereids_rules_p0/column_pruning` → 9 suites, failed 0
   - Introspective analysis
       - [x] `normalizeCtePlan` iterates to a fixpoint instead of comparing 
`Plan.equals()`, because
         `LogicalCTEAnchor`/`LogicalSubQueryAlias` ignore children in 
`equals()`.
       - [x] Zero-consumer anchors are removed before memoization; anchors with 
an empty producer or
         consumers below `inline_cte_referenced_threshold` are inlined.
       - [x] CTE environment (`cteIdToProducer`, `cteIdToConsumers`, rewritten 
caches) is refreshed
         from the normalized plan so memo construction does not see stale CTE 
state.
   


-- 
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