[fix](fe) Fix DPHyp join reorder producing wrong results for aliases on nullable side of outer join - #65682
[fix](fe) Fix DPHyp join reorder producing wrong results for aliases on nullable side of outer join#65682starocean999 wants to merge 13 commits into
Conversation
|
Thank you for your contribution to Apache Doris. Please clearly describe your PR:
|
|
/review |
There was a problem hiding this comment.
Automated review result: REQUEST_CHANGES
The simple one-leaf LEFT OUTER JOIN case is addressed, but I found three blocking planner-correctness gaps:
- Nullable aliases are placed at their referenced-node bitmap rather than their original Project boundary, which changes nested outer-join null results and can move non-movable/volatile evaluation across inner joins.
- Dependent nullable aliases sharing a bitmap are flattened into sibling expressions even though the later alias ExprId is absent from the LogicalProject child.
- Multi-node aliases are emitted after their raw inputs have already been pruned from contributing DP groups.
The concrete plan trees and fix directions are in the inline comments.
Checkpoint conclusions:
- Goal and scope: the patch is focused and its new ordered regression results are internally consistent for the narrow leaf case, but the generalized placement structure does not preserve Project boundary, dependency layers, or pending-input liveness, so it does not safely accomplish the full goal.
- Join semantics, special conditions, and parallel paths: simple LEFT/RIGHT/FULL nullable-side propagation is directionally symmetric; nested joins and multi-node subsets fail as noted. ASOF checks are unreachable because this builder rejects ASOF joins.
JoinOrderJobuses the v2 implementation; the legacy receiver is not a parallel runtime path, but it demonstrates the missing dependency/liveness handling. - Tests and results: all four added queries exercise the same single-leaf LEFT JOIN shape. Nested outer, multi-node, dependent-alias, non-movable/volatile, RIGHT, and FULL cases are not covered; the first four are tied to concrete failures above.
- Concurrency, lifecycle, configuration, compatibility, persistence, transaction/data-write behavior, FE-BE transport, and observability: not applicable to this per-query FE planner change; no new shared runtime state, config, protocol, or persisted data is introduced.
- Performance: no separate substantiated performance regression was found.
- Validation: static review only, as required by the review runner; no build or test command was run.
- User focus: no additional user-provided focus was supplied.
Review completion: the full four-file change and related planner paths were reviewed through two convergence rounds; every candidate was resolved and all final reviewers returned NO_NEW_VALUABLE_FINDINGS against this exact comment set.
|
/review |
There was a problem hiding this comment.
Automated review result: REQUEST_CHANGES
The follow-up fixes the simple leaf nullable-alias case, but three distinct planner-correctness gaps remain:
- A retained alias can activate an upper join edge at its smaller input bitmap before the full source Project subtree emits the alias, producing a join predicate whose slot is absent from both children.
- Chained replacement bypasses the normal volatile-expression merge guard and can evaluate a volatile producer more than once, changing values.
- The same transitive expansion bypasses the normal expression-limit fallback, so DPHyp graph construction can reject a valid layered plan near the configured limit.
The earlier Project-boundary, dependent-alias, and pending-input threads remain the authoritative locations for their unresolved constant/interleaved variants; duplicate inline comments were suppressed.
Checkpoint conclusions:
- Goal and scope: the four-file patch is focused and the basic unmatched LEFT OUTER case is fixed, but the edge-availability, volatile, and expression-limit failures mean the generalized goal is not yet accomplished.
- Join semantics, special conditions, and parallel paths: LEFT/RIGHT/FULL nullable propagation is symmetric; ASOF is rejected before these checks, and mark/leading/hinted joins remain opaque.
JoinOrderJobuses hypergraphv2, so no active parallel receiver change is missing. Inner association and partial DP alternatives expose the failures above. - Tests and results: the checked-in aggregates are arithmetically consistent and use ordered queries. However, the deterministic chained case merges before DPHyp and the multi-node case never consumes
ab.sv, so neither exercises its claimed mechanism. Parent alias predicates, non-mergeable volatile chains, actual multi-node liveness, RIGHT/FULL, matched nullable rows, and the expression-limit fallback are not proved. - Concurrency and lifecycle: not applicable; the added maps are per-query optimizer state used synchronously, with no threads, locks, static initialization, or resource ownership changes.
- Configuration and compatibility: no config definition, persisted format, EditLog, FE-BE field, RPC symbol, rolling-upgrade, or storage contract changes are introduced.
- Transactions, data writes, crash recovery, and observability: not applicable to this logical FE planner change; no production write path or distributed operation is modified, and no new logs or metrics are needed.
- Error handling and performance: invalid alias availability can fail rewrite validation, and expression-limit exceptions escape the normal merge fallback. Alias-map scans and wider intermediate projections add overhead, but no separate performance-only blocker was substantiated.
- Other core invariants: data visibility, versions, delete bitmaps, BE memory/nullable-column handling, and security are outside this planner-only change.
- Validation: static review only, as required by the review runner; no build or test command was run.
- User focus: no additional user-provided focus was supplied.
Review completion: the complete four-file patch, related planner control flow, tests, existing threads, and all candidate points were reviewed through three allowed convergence rounds. Every candidate was accepted, dismissed with code evidence, or deduplicated, and the final normal and risk-focused reviewers returned NO_NEW_VALUABLE_FINDINGS against this exact comment set.
|
/review |
There was a problem hiding this comment.
Automated review result: REQUEST_CHANGES
The latest revision addresses the previously reported boundary, dependency, volatility, expression-limit, pending-input, and alias-consumer mechanisms, but it introduces one distinct planner-correctness failure: each rebuilt source Project layer contains only aliases, so applying it as a new LogicalProject discards pass-through outputs such as the nullable child's join key. The parent join can then reference a slot absent from its child and fail rewrite validation. The concrete plan tree and fix direction are in the new inline comment; the six existing threads remain the authoritative locations for their own mechanisms and were not duplicated.
Critical checkpoint conclusions:
- Goal and proof: the goal is to preserve nullable-side Project semantics during DPHyp reorder. The new layered representation is directionally appropriate, but alias-only layers drop required outputs, so the goal is not yet accomplished. The added row-result suite does not prove a valid reconstructed plan.
- Scope and clarity: the change is focused on HyperGraph/PlanReceiver plus one regression suite and generated output. The remaining issue is in the central reconstruction step, not unrelated code.
- Join semantics, conditions, and parallel paths: LEFT/RIGHT/FULL nullable propagation matches the null-extended side; inherited context through INNER/CROSS/SEMI/ANTI is intentional, and ASOF/mark/leading/hinted joins are excluded. The legacy receiver preserves pass-through and projected outputs together and confirms the missing v2 invariant.
- Tests and results: all checked-in expected aggregates are arithmetically consistent and ordered. Several advertised branches remain unproved (including the unused multi-node alias and deterministic/unmatched volatile case), but those coverage obligations are already present in the existing threads and were deduplicated.
- Concurrency and lifecycle: not applicable; this is synchronous per-query optimizer state with no locks, shared threads, unusual ownership, static initialization, or teardown changes.
- Configuration and compatibility: no configuration definition, persisted format, EditLog, RPC/FE-BE field, function symbol, rolling-upgrade, or storage-format change is introduced.
- Transactions, data writes, recovery, and observability: not applicable to this logical FE planner change; no production write path or distributed operation changes, and no new logging/metrics requirement was identified.
- Error handling and performance: the missing child slot is a hard planner-validation failure. Repeated alias-map scans are bounded by the existing DPHyp enumeration limit; no separate performance blocker was substantiated.
- Other core invariants: data visibility, versions, delete bitmaps, BE memory/nullable-column handling, and security are outside this planner-only patch.
- Validation: static inspection only, as the review runner explicitly forbids builds and test execution.
- User focus: no additional user-provided review focus was supplied.
Review completion: the complete four-file patch, related planner control flow, tests, existing threads, and every candidate were reviewed through two convergence rounds. Both final normal reviewers and the separate risk-focused reviewer returned NO_NEW_VALUABLE_FINDINGS for this exact ledger and comment set.
|
/review |
There was a problem hiding this comment.
Automated review result: COMMENT (no new non-duplicate inline findings)
The current head fixes the alias-only Project-layer pass-through failure at the exact stored boundary, but the full review still reproduced two broader materialization-boundary failures: crossing partial DP groups can prune pending alias inputs, and a missed edge can consume an alias before the post-join layer emits it. I did not add duplicate inline comments because those invariants are already stated by the existing pending-input, consumer-ownership, and source-Project-boundary threads; those threads remain authoritative for the unresolved blockers.
Critical checkpoint conclusions:
- Goal and proof: the patch is focused on preserving nullable-side aliases during DPHyp reorder, and exact-boundary layer ordering/pass-through is improved. The goal is not yet proven complete because legal crossing subsets still violate the previously requested “until emission” and source-stage invariants.
- Join semantics, conditions, and parallel paths: LEFT/RIGHT/FULL nullable-side selection is directionally symmetric; ASOF, mark, leading, and hinted joins are excluded from this builder. Same-key chains, constants, volatile expressions, expression limits, ExprIds, final projection, and the active v2/legacy-reference paths were traced. The remaining crossing/missed-edge routes are covered by existing threads.
- Tests and results: the ordered
.outvalues are arithmetically consistent and the basic unmatched leaf case is effective. The multi-node alias is unused, the “volatile” SQL has no volatile function or match, the nested case has no inner null-extension, and FE tests assert only plan construction; these gaps correspond to existing review requests and were deduplicated. - Concurrency and lifecycle: not applicable; the new structures are synchronous per-query optimizer state with no locks, threads, static initialization, ownership, or teardown changes.
- Configuration, compatibility, persistence, transactions/data writes, FE-BE transport, security, and observability: not applicable; no config, protocol, persisted state, write path, trust boundary, log, or metric is changed.
- Error handling and performance: the unresolved existing paths can build joins/Projects with missing child slots and fail validation. Repeated alias-layer scans are bounded by the existing DPHyp enumeration limit; no separate performance-only blocker was substantiated.
- Validation: static inspection only, as the review runner forbids builds and test execution. Current GitHub CheckStyle is green; no functional test result was independently run here.
- User focus: no additional user-provided review focus was supplied.
Review completion: the complete five-file patch, related planner paths, live threads, and all candidates were reviewed through two convergence rounds. Every candidate was accepted, dismissed with evidence, or deduplicated, and the final normal and risk-focused reviewers returned NO_NEW_VALUABLE_FINDINGS against this exact ledger and comment set.
4293d43 to
3b6d3e7
Compare
|
/review |
There was a problem hiding this comment.
Request changes: two existing P1 discussions still apply to the current head.
-
Pending alias inputs must survive until emission. For a nullable-side
Project(A.v + B.v AS s)over{A,B}, the new helper retains inputs for direct subsets such as{A}, but not for a legal mixed connected subplan{A,C}. Inner/inner reordering can build{A,C}first, pruneA.v, then joinB; the{A,B}layer is emitted over{A,B,C}with its input already missing. This is the same existing "until emission" contract, so I did not post a duplicate inline. -
The source Project boundary still is not encoded. Keying a layer by
{A,B}does not prevent it from first being emitted on a wider{A,B,C}union. A zero-inputuuid()alias originally evaluated overA JOIN Bcan therefore be moved above an unrelatedCjoin, changing evaluation multiplicity; a none-movable assertion can similarly move past filtering. Separate layers fix chained flattening, but not this whole-layer placement problem. This is already covered by the existing boundary thread, so no duplicate inline was added.
Checkpoint conclusions:
- Goal and proof: the direct leaf-keyed COALESCE/IFNULL, consumer-bitmap, expression-limit, chained-layer, and pass-through cases are addressed, but the arbitrary-reordering cases above mean the full correctness goal is not yet met.
- Scope and design: the production changes are localized to DPHyp alias bookkeeping and reconstruction. No new concurrency, lifecycle, configuration, persistence/EditLog, transaction/data-write, FE/BE protocol, or observability concern applies.
- Parallel paths: LEFT/RIGHT/FULL nullable propagation is symmetric in code; ASOF joins are excluded before the added ASOF checks. Tests cover only LEFT OUTER joins.
- Error handling and performance: invariants still fail loudly through preconditions/
CheckAfterRewrite; no distinct error-boundary or substantiated performance issue was found beyond the wrong-stage evaluation above. - Tests: expected
.outarithmetic is deterministic and internally correct, butsvis never consumed, the "volatile" test is deterministic and has no matching row, and the nested case never exercises inner null-extension. The non-null/result-only oracles can also pass if DPHyp falls back to the original group. These gaps support the regression requirements in the existing threads rather than warranting duplicate comments.
There was no additional user-provided review focus. Review was static only, as required by the runner contract; no build or test command was run, and local thirdparty/installed/bin/protoc is unavailable. The current GitHub CheckStyle check is passing.
3b6d3e7 to
ea5cbd7
Compare
|
/review |
There was a problem hiding this comment.
Automated review result: REQUEST_CHANGES
The latest head addresses the same-key dependency layers, expression-limit fallback, direct mixed-input retention, alias pass-through, and ordinary consumer-bitmap cases, but two existing P1 correctness threads still apply:
- The source Project boundary is still not encoded. If DPHyp builds {A,C} before B, a layer sourced at {A,B} is first emitted on {A,B,C}; volatile/non-movable evaluation can therefore move across C's filtering or row multiplication.
- A consumer can still run before its alias is emitted. In the same mixed split, processMissedEdges can attach the {A,B}--C predicate to the join of {A,C} and B, while proposeProject emits the alias only after that join.
I added two distinct P2 inline comments for current-head performance regressions: raw alias inputs remain live through every ancestor after materialization, and bare forwarding aliases are unnecessarily rebound to full source subtrees, eliminating safe selective join orders.
Critical checkpoint conclusions:
- Goal and proof: the patch is focused on preserving nullable-side Project semantics during DPHyp reorder, but the two existing P1 paths above mean the full correctness goal is not achieved.
- Join semantics, special conditions, and parallel paths: LEFT/RIGHT/FULL nullable-context propagation is symmetric in code; ASOF, mark, leading, and hinted joins are excluded before these paths. Mixed inner subplans and the missed-edge fallback expose the remaining failures.
- Tests and results: the ordered .out values are internally consistent, but the mixed alias is unused, the claimed volatile case is deterministic and unmatched, the nested case never observes inner null-extension, and FE tests assert only non-null plan construction even though DPHyp may fall back to the original group. RIGHT/FULL and the two new performance invariants are untested.
- Concurrency and lifecycle: not applicable; the added maps/lists are synchronous per-query optimizer state with no locks, threads, static initialization, ownership, or teardown change.
- Configuration, compatibility, persistence, transactions/data writes, FE-BE transport, and observability: not applicable; no config, protocol, persisted state, write path, or distributed runtime surface changes.
- Error handling and performance: the existing P1 paths can produce a join predicate bound to a missing child slot or change volatile/non-movable evaluation. The two inline P2 findings cover intermediate-width and search-space regressions.
- Validation: static review only, as required by the review runner. GitHub CheckStyle is green, but no targeted FE unit or regression result is available here; thirdparty/installed and protoc are absent.
- User focus: no additional user-provided review focus was supplied.
Review completion: the complete five-file patch, related join-order control flow, live threads, test oracles, and every candidate were reviewed through three convergence rounds. Every candidate was accepted, dismissed with code evidence, or deduplicated, and the final normal and risk-focused reviewers returned NO_NEW_VALUABLE_FINDINGS against this exact payload.
|
/review |
There was a problem hiding this comment.
Automated review result: REQUEST_CHANGES
The patch improves ordinary nullable-side Project reconstruction, but three P1 planner-correctness failures remain:
- The bare-Slot endpoint exception exposes an alias to join enumeration without substituting predicate consumers, so a normalization-stable mixed Project can produce a join predicate whose alias slot is absent from both children.
- A lower stored Project layer carries only final/edge requirements and can drop a raw slot needed by a later join-separated Project layer.
- A Project layer keyed to its source subtree may first be emitted only on a larger reordered supertree, moving volatile or non-movable evaluation across an unrelated join.
The concrete plan trees and fix directions are in the inline comments.
Critical checkpoint conclusions:
- Goal and proof: the current implementation does not fully preserve nullable-side Project semantics for legal DPHyp alternatives, and the added tests do not cover the three failing shapes.
- Scope and clarity: the patch is localized, but the layered materialization model needs explicit alias-availability, inter-layer slot-lifetime, and exact-source-boundary invariants.
- Join semantics and parallel conditions: LEFT/RIGHT/FULL nullable-context propagation and nested inner alternatives were reviewed; ASOF joins are rejected by
isValidJoin, and mark, hinted, and leading joins do not enter this builder. The bare-Slot exception and containing-supertree eligibility remain insufficiently constrained. - Error handling and data correctness: two paths construct expressions whose input slots are absent from child outputs; the third changes volatile/error evaluation stage and cardinality. These are planner-correctness failures rather than recoverable status paths.
- Tests and results: the checked-in ordered results are deterministic and internally consistent, but the multi-node alias is never consumed, the claimed volatile case is deterministic and unmatched, and plan-only non-null assertions do not prove forwarding reorder, inter-layer lifetime, or exact source-stage behavior.
- Concurrency and lifecycle: no threads, locks, shared mutable runtime state, static initialization, resource ownership, or teardown changes are introduced.
- Configuration, compatibility, persistence, transactions, data writes, FE-BE transport, security, and observability: not applicable to this FE-local logical optimizer change; no such boundary is modified.
- Performance: no new standalone performance blocker beyond existing review threads; correctness-preserving materialization constraints must precede the endpoint/search-space optimization.
- Validation: static inspection only, as required by the review runner; no build or test command was run.
- User focus: no additional user-provided review focus was supplied.
Review status: incomplete at the explicit three-round cap. The final round required two material reproducer/context corrections; I independently verified and applied those corrections, but the cap prohibited another convergence pass on the exact final payload. Per the cap exit rule, this review submits the corrected confirmed blockers without claiming full convergence or that no other issue is possible. The live head at submission was 602425d4a4d2ed221783c329c2e5d460c16bed67.
602425d to
3dfb8ce
Compare
|
/review |
There was a problem hiding this comment.
Review outcome: request changes for 3dfb8ceb8a6d0b0651e28a08932fe8b93b2937f1.
The current head still allows a preserved nullable-side Project layer to materialize above its exact source boundary. In the feasible {A,C} + {B} order, a layer sourced at {A,B} first satisfies getProjectedAliasLayers only at {A,B,C}; an outside multiplying/filtering relation can therefore change volatile evaluation count or suppress a non-movable error. This is already captured by the live current-head P1 thread, so I did not post a duplicate inline comment.
Critical checkpoint conclusions:
- Goal and correctness: the direct null-extension bug for simple nullable-side aliases is addressed, but exact source-boundary preservation is not complete because of the reordered plan above.
- Scope and clarity: the change is localized to DPHyp graph metadata, Project reconstruction, and tests, but the new layer/liveness machinery is broader than the original alias-replacement condition.
- Concurrency: not involved; graph construction and receiver enumeration use job-local mutable state.
- Lifecycle/static initialization: not involved; no new long-lived resources, cycles, threads, or cross-TU state.
- Configuration: no configuration item or dynamic-reload behavior is added.
- Compatibility: no FE/BE protocol, persisted format, function symbol, rolling-upgrade, or storage compatibility boundary changes.
- Parallel paths and join types: LEFT, RIGHT, and FULL OUTER nullable propagation matches their null-extending children. ASOF, mark, leading, and hinted joins remain atomic at this builder boundary; semi/anti descendants introduce no separate null-extension. The prior forwarding/missing-input current-head variants were rechecked and no longer reproduce.
- Conditional/error handling: the nullable-context conditions are consistent with reachable join types. The remaining error is the layer-eligibility predicate, which accepts a source key inside a larger newly formed union instead of enforcing its exact materialization barrier.
- Test coverage: the simple unmatched COALESCE/IFNULL/CAST regressions detect upward movement across the outer join, and all ten
.outvalues are arithmetically consistent. Coverage is incomplete for the live P1: no test forces the mixed reordered boundary with a volatile or non-movable expression. The multi-node alias is not consumed, the purported volatile case is deterministic and unmatched, the nested case has no missing inner row, and Java tests only assert that plan construction succeeds. These gaps were already requested in existing threads, so they were not reposted. - Test results: this review runner was explicitly review-only, so I did not build or run tests. The live checks observed for this head include successful CheckStyle/format/license checks, but no completed FE unit or regression result was used as correctness evidence.
- Observability: no runtime path requiring new logs, metrics, or tracing is introduced.
- Persistence/transactions/data writes: not involved; there are no EditLog, failover, transactionality, atomicity, or crash-recovery changes.
- FE/BE variable passing: no new transmitted variable or scattered thrift/protobuf send path.
- Performance: the current global alias-input set retains already-consumed raw columns through later joins until the final Project, matching the already-known P2 thread. No distinct performance finding was added.
- Other issues: after full changed-file and upstream/downstream sweeps, no additional non-duplicate correctness issue was substantiated.
There was no additional user-provided focus. Review convergence is complete for this head: the main-agent scan, two complete-review agents, and the separate risk-focused agent all reviewed the same final ledger/comment set and returned no new valuable findings after deduplication. The review itself is complete; the PR remains blocked on the existing exact-boundary P1.
|
/review |
There was a problem hiding this comment.
Automated review conclusion: request changes
I found one new, non-duplicate P1 correctness issue on head 3fd9ab1cd9226ec9d31a5efb874b1491f72d5c9f: a nullable-side alias mapped to its full source bitmap can still be consumed before materialization when DPHyp splits that bitmap across two children and processMissedEdges attaches the alias predicate. The inline comment contains the concrete plan and fix direction.
Critical checkpoint conclusions:
- Goal and data correctness: the change preserves basic COALESCE/IFNULL/CAST aliases below an ancestor outer join, but the split-hyperedge alternative can build a join predicate with a missing alias ExprId, so the stated correctness goal is not complete.
- Scope and parallel paths: the code is FE/Nereids-local. LEFT/RIGHT/FULL nullable propagation, nested joins, constant/forwarding/complex/chained aliases, mark/leading/hinted/ASOF boundaries, and the volatile/
NoneMovableFunctioncluster boundaries were reviewed. No second distinct issue survived deduplication. - Concurrency and lifecycle: no shared-thread state, lock ordering, static initialization, or special resource lifecycle is introduced.
- Configuration, compatibility, persistence, and writes: no configuration, FE-BE protocol, storage format, rolling-upgrade, EditLog, transaction, or data-write path is changed.
- Tests and results: the regression output arithmetic is internally consistent and covers the basic LEFT nullable-side cases, but no changed test covers a consumed
{A,B}alias plus an independently connectingC, which is needed for the reported failure. The FE tests assert successful planning rather than Project placement or child-output ExprIds. Per the review-runner contract I did not build or run tests locally; the current PR checks show CheckStyle passing, but no FE unit/regression execution was observed in the listed checks. - Performance: raw alias-input retention and forwarding-endpoint reorder loss were reviewed as existing-thread concerns and were not duplicated here. No additional performance finding was substantiated.
- Observability and error handling: no new runtime-observability requirement applies; the accepted issue violates the planner child-output invariant rather than adding a new error boundary.
User focus: no additional focus points were provided.
Review completion: three rounds covered the full changed-file set, including two normal full-review agents and a separate risk-focused agent per round. Every candidate was independently verified and either accepted for the inline comment or suppressed with concrete duplicate/code evidence.
3fd9ab1 to
56c647f
Compare
|
/review |
There was a problem hiding this comment.
Request changes: one additional P1 correctness issue remains in the nullable-side alias-layer reconstruction. A join-separated computed alias can still reference a direct forwarding alias whose producer the builder removed, so DPHyp can construct a LogicalProject with an input ExprId absent from its child and reject a valid query.
Critical checkpoint conclusions:
- Goal and correctness: the change preserves computed aliases below outer-join null extension in the covered cases, but the forwarding-to-computed transition in MAIN-001 leaves the end-to-end fix incomplete.
- Scope and clarity: the production changes and tests are focused on DPHyp v2 nullable-side Project handling; no unrelated source changes were found.
- Concurrency and lifecycle: this is planner-local memo/enumeration state with no new threads, shared static state, lock ordering, or special resource lifecycle.
- Conditions and parallel paths: normal CSG/CMP edges, missed-edge fallback, graph simplification, LEFT/RIGHT/FULL nullable propagation, direct forwarding, computed layers, volatile/NoneMovable barriers, and the old parallel hypergraph implementation were inspected. ASOF joins remain outside this v2 join-cluster path. Other live concerns are already covered by existing inline threads and were not duplicated.
- Configuration, compatibility, persistence, and data writes: no new configuration, FE-BE protocol/storage format, EditLog, transaction, or data-write behavior is introduced.
- Tests and results: FE unit and regression coverage were added, but there is no join-separated forwarding-to-computed regression for MAIN-001. The vacuous volatile, multi-node, and nested-outer cases map directly to existing threads 3594102562, 3592512016, and 3592512010. Per the review-runner contract, no build or test execution was attempted; this checkout is also not worktree-initialized and lacks
thirdparty/installed/bin/protoc. - Performance and observability: no new observability requirement was identified. Over-retention of raw alias inputs remains the known issue in thread 3600123245; no duplicate comment was submitted.
- User focus: no additional user-provided focus was supplied.
Overall: request changes for MAIN-001; all other suspicious points have been either tied to existing review context or dismissed with code evidence.
|
/review |
There was a problem hiding this comment.
Automated code review: changes requested.
I found one new P2 issue in the added coverage: the mixed-subplan test can prune the alias before DPHyp, has no third relation inside the nullable subquery to create the claimed partial-overlap alternative, and accepts original-plan fallback. See the inline comment on NullableAliasTest.java.
Critical checkpoint conclusions:
- Goal and proof: The production changes preserve complex nullable-side aliases as ordered Project layers, keep volatile and non-movable Projects as cluster boundaries, and gate split-source missed edges before
proposeJoin. The main left-outer result cases are covered, but the newly added mixed-subplan test does not prove the required alias-input lifecycle, so the PR is not yet fully demonstrated by its tests. - Scope and clarity: The implementation is focused on
HyperGraph/PlanReceiverplus targeted tests. The layer/endpoint design is necessarily intricate but follows the existing DPHyp flow; no unrelated runtime behavior is changed. - Parallel paths and special conditions: Left, right, and full outer nullable propagation are symmetric; ASOF joins remain opaque; regular and graph-simplified edges require the complete alias endpoint in one child; the new safety check covers the distinct missed-edge split path. Forwarding aliases are substituted consistently, and post-DPHyp
AdjustNullablerepairs nullability beforeCheckAfterRewrite. - Concurrency and lifecycle: This is single-threaded optimizer construction/reconstruction. No shared mutable runtime state, lock ordering, asynchronous lifecycle, or static-initialization concern applies.
- Compatibility, persistence, and data flow: No configuration, storage/serialization format, EditLog, transaction, data-write, FE-BE transport, or rolling-upgrade boundary is changed.
- Error handling and invariants: Existing preconditions plus the final nullable/output checker keep invalid ExprId/output shapes loud. The test's original-group fallback is the verification weakness identified inline, not a new production error-swallowing path.
- Tests and results: The regression result arithmetic is internally consistent and ordered. However, the mixed alias is unused in both the Java and regression cases, the Java checks only require a non-null plan, and the claimed mixed alternative is absent from the nullable subquery. Per the review-run contract I did not build or run tests locally. The visible GitHub checks include passing CheckStyle, but no targeted FE unit/regression result was available in this run.
- Performance and observability: The completed-layer raw-input retention concern is already covered by an existing inline thread and was not duplicated. No other distinct performance issue was substantiated; existing DPHyp tracing is adequate for this planner-only change.
- User focus: No additional user-provided focus was supplied.
All changed files and existing inline threads were reviewed and deduplicated. After the final wording was frozen, three independent review tracks converged with no additional valuable findings. Please address the inline test-validity issue before approval.
8900dd8 to
8c67f48
Compare
|
/review |
|
run buildall |
TPC-DS: Total hot run time: 177676 ms |
ClickBench: Total hot run time: 24.81 s |
FE Regression Coverage ReportIncrement line coverage |
5c4d029 to
cc467bf
Compare
|
/review |
|
run buildall |
|
Codex automated review failed and did not complete. Error: You've hit your usage limit. Visit https://chatgpt.com/codex/settings/usage to purchase more credits or try again at Aug 5th, 2026 4:09 AM. Please inspect the workflow logs and rerun the review after the underlying issue is resolved. |
TPC-H: Total hot run time: 29206 ms |
TPC-DS: Total hot run time: 169634 ms |
ClickBench: Total hot run time: 24.01 s |
FE UT Coverage ReportIncrement line coverage |
FE Regression Coverage ReportIncrement line coverage |
|
/review |
There was a problem hiding this comment.
Review result
Requesting changes for two distinct P1 planner-correctness defects at head cc467bf83a8fcd2d081b58b1c68c1ccab2896f49: a bounded simplifier retry can report success without producing the full bitmap, and a nullable-side forwarding alias can be reconstructed with stale non-nullable metadata.
Critical checkpoints:
- Goal and proof: The patch is intended to preserve nullable-side alias semantics through DPHyp reordering. It does not fully accomplish that goal because the two inline cases remain reachable. The changed tests do not force the low-
dphyper_limitsimplifier/retry path or select a direct forwarding alias on unmatched LEFT/RIGHT/FULL rows while checking output nullability. - Scope and clarity: The nine changed files are focused on HyperGraph alias construction, receiver parity, and their tests. The risks arise at the intended integration boundaries rather than from unrelated changes.
- Concurrency: HyperGraph construction and enumeration are synchronous, query-local operations. No new thread, shared mutable state, lock, or deadlock risk was introduced.
- Lifecycle: Builder layer state is saved/restored recursively and both receivers reset per enumeration retry. No resource ownership, static initialization, or abnormal cleanup lifecycle applies.
- Configuration: No configuration item is added. The existing
dphyper_limitis material to the first defect and needs a regression that reaches its bounded retry path. - Compatibility: No public symbol, persisted/storage format, rolling-upgrade contract, or cross-version protocol changes.
- Parallel paths: Counter versus PlanReceiver, initial enumeration versus GraphSimplifier retry, missed/enforced/conflict edges, and LEFT/RIGHT/FULL nullable-child paths were traced. The two inline failures are distinct from the already-live comments on invalid cross-bitmap Project flattening and RIGHT/FULL complex-alias coverage.
- Conditional and error paths: The new alias-dependency gates return
CONTINUE. That rejection is locally intentional, but enumeration completion is incorrectly treated as feasible success when no full-bitmap group exists. No ignored Status or swallowed exception applies in this FE Java path. - Test coverage: Unit tests mostly prove only that some plan exists and can accept original-group fallback. Regression coverage has deterministic ordered queries, but only LEFT-join execution; it lacks the two targeted oracles above. Existing live threads already cover the other fallback-tolerant, raw-slot, boundary, dependency-order, and RIGHT/FULL gaps, so they are not duplicated here.
- Test results: The ten changed regression query blocks match the ten output blocks and their expected values are internally consistent. Current remote compile, FE UT, CheckStyle, P0, nonConcurrent, and coverage checks passed; this review was static-only as required, so no local build or test was run.
- Observability: Existing planner tracing is sufficient for this local rewrite; no distinct logging or metric gap was found.
- Transactions, persistence, and writes: No transaction, EditLog, data-write, crash-recovery, memory-safety, or storage-visibility path is changed.
- FE/BE propagation: No new variable or protocol field needs propagation between FE and BE.
- Performance: The added edge/alias scans are bounded planner work. No distinct performance defect beyond already-reviewed raw-slot retention concerns was substantiated.
- Other issues: The older mixed-join-type Counter/PlanReceiver asymmetry was rechecked but predates this PR, and no new reachable failure attributable to this patch was established.
- User focus: The supplied focus file contains no additional review focus; the entire PR was reviewed.
- Completion: Two review rounds converged. Both normal reviewers and the separate risk reviewer returned
NO_NEW_VALUABLE_FINDINGSagainst this frozen two-comment set after a full existing-thread deduplication and current-head anchor check.
…on nullable side of outer join fix comment fix comment fix comment fix comment fix bug
cc467bf to
de02a15
Compare
|
/review |
|
run buildall |
Related PR: #61146
Problem Summary:
When enable_dphyp_optimizer=true, DPHyp join reorder can produce wrong results for queries where the nullable side of an outer join contains Alias/Project expressions with functions like COALESCE, IFNULL, or CAST(COALESCE(...)).
Root Cause:
HyperGraph.Builder.addAlias() unconditionally adds all aliases to aliasReplaceMap, including those defined on the nullable side of outer joins. This causes their defining expressions to be "unwrapped" and later reconstructed by PlanReceiver.proposeProject() ABOVE the outer join via finalProjects. The expression then operates on null-extended values, changing semantics — e.g., COALESCE(NULL, 0) = 0 instead of the correct NULL for non-matching outer join rows.
Fix:
Added an isNullableSide context flag that propagates through buildForDPhyper() and addAlias() during graph construction. When processing an outer join:
LEFT OUTER JOIN → right child flagged as nullable
RIGHT OUTER JOIN → left child flagged as nullable
FULL OUTER JOIN → both children flagged as nullable
The flag propagates through nested projects and inner joins
Aliases on the nullable side are not added to aliasReplaceMap, preserving the original Project boundary below the outer join so that expressions execute before null-extension.
None
Check List (For Author)
Test
Behavior changed:
Does this need documentation?
Check List (For Reviewer who merge this PR)