Skip to content

refactor(planner): plan one shared unified workload DAG - #542

Draft
zzylol wants to merge 5 commits into
stack/528-06-nativefrom
stack/528-07-planner
Draft

zzylol wants to merge 5 commits into
stack/528-06-nativefrom
stack/528-07-planner

Conversation

@zzylol

@zzylol zzylol commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

Rebased on main d4869a7 (DF 54). The conflict resolution carries DF 54 into the moved SQL lowering: TypeCoercion runs after the temporal-subtraction check (DF 54's coercion otherwise rejects CASE ... ELSE d - d with a different error first); a cast to Decimal128(_, 0) (DF 54's coercion of a UInt64-vs-Int64 comparison such as approx_distinct(x) >= 1000) lowers to its input; main's identity-projection skip for SQL top-k populations is ported to the unified IR; the bgp_jan2024 tally is now Lowered 106, InvalidRepresentation 54, Plan 40, UnsupportedFeature 0.

Rebuilt on the revised stack (2026-10-03): cutover only

This PR was based on the old stack/528-legacy-physical-base chain. It is now rebuilt on #541' (Phase A in #528) as three commits. Its scope is cutover only: today's planner (MajorPass and the existing Pass 1 strategies) emits the unified OperatorNode DAG. It adds no new #509 stage logic.

  1. Plan one shared unified workload DAG. This is the old commit, ported to the revised IR with one root per batch query. It also promotes the runtime's unified planner to physical_planner, and readout becomes evaluation.
  2. Declare whole-source coverage on planned summary states. Every planned SummaryAgg declares CoverageRegion { time_ms: None, population: {} } over the Source of its single scan. The declaration is trusted (Check declared summary coverage population against subtree filters #570). Rebuilding a state over a re-placed input, or changing its Hydra grouping, keeps its coverage.
  3. Export a planned workload as one physical ASAP DAG. PlanOutput::execution_timed_dag() times every query root with one shared TimingMemo and exports a single PhysicalASAPDAG with one root per query. Shared states appear once.

Left out of the old version:

Tests: the old PR deleted the unified_* duplicate tests and some legacy tests. Each removed test was checked by name against the base: all but two are replaced by equivalent #539/#540 tests. subquery_time_shift_is_retained was ported to the unified IR, and planning_subquery_bridge_reuses_canonical_promql_subquery is covered by ...rejects_a_relation_without_vector_conversion.

Validation, independently re-run: clippy with -D warnings is clean, and cargo test --workspace gives 1,717 passed, 0 failed, 2 ignored. The two ignored tests have stated reasons: splitting a multi-measure aggregate, and Avg having no summary realization.


Revised Phase A stack (see #528): #567 → #560 → #537 → #539 → #540 → #541 → #542 → #543. The pre-rebuild description is in the PR history.

🤖 Generated with Claude Code

@zzylol
zzylol force-pushed the stack/528-06-native branch from 75903b5 to b22fa53 Compare October 2, 2026 18:32
@zzylol
zzylol force-pushed the stack/528-07-planner branch 2 times, most recently from 2a3bcd0 to a03efc2 Compare October 2, 2026 19:40
@zzylol
zzylol force-pushed the stack/528-06-native branch from b22fa53 to d82bcde Compare October 2, 2026 19:40
@zzylol
zzylol force-pushed the stack/528-07-planner branch from a03efc2 to 2c708f3 Compare October 2, 2026 21:14
@zzylol
zzylol force-pushed the stack/528-06-native branch 2 times, most recently from 337a0ff to a94bd59 Compare October 2, 2026 21:22
@zzylol
zzylol force-pushed the stack/528-07-planner branch from 2c708f3 to 03166e7 Compare October 2, 2026 21:22
@zzylol
zzylol force-pushed the stack/528-06-native branch from a94bd59 to d84830e Compare October 2, 2026 21:25
@zzylol
zzylol force-pushed the stack/528-07-planner branch 2 times, most recently from 4b84314 to d9da0f9 Compare October 2, 2026 21:56
@zzylol
zzylol force-pushed the stack/528-06-native branch from d84830e to b631137 Compare October 2, 2026 21:56
@zzylol
zzylol force-pushed the stack/528-07-planner branch from d9da0f9 to ec9f8cb Compare October 3, 2026 02:31
@zzylol
zzylol force-pushed the stack/528-06-native branch 2 times, most recently from 075d8e2 to d9dc49c Compare October 3, 2026 02:39
@zzylol
zzylol force-pushed the stack/528-07-planner branch from ec9f8cb to 95eef55 Compare October 3, 2026 02:39
@zzylol
zzylol force-pushed the stack/528-06-native branch from d9dc49c to 04f9db2 Compare October 3, 2026 19:55
@zzylol
zzylol marked this pull request as draft October 3, 2026 20:02
@zzylol
zzylol force-pushed the stack/528-06-native branch from 04f9db2 to 0ebce24 Compare October 3, 2026 20:17
zzylol added a commit that referenced this pull request Oct 3, 2026
Cut today's planner over to the unified OperatorNode IR. Frontends return
OperatorNode / QueryRoot, ParsedWorkload keeps scalar roots, Pass 1
(ASAPStrategies), the existing identical-sub-DAG sharing, selection, DAG
assembly and lifecycle costing all run on OperatorNode, and PlanOutput exposes
the whole workload DAG. The native compiler from #541 becomes the canonical
physical_planner and consumes the PhysicalASAPDAG export.

Ported from the earlier #542 (95eef55) without new #509 stage logic. Legacy
QueryExpr/SummaryNode modules stay compiled for their own tests but are no
longer re-exported from post_asap; the cleanup PR removes them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@zzylol
zzylol force-pushed the stack/528-07-planner branch from 95eef55 to 74b4884 Compare October 3, 2026 20:31
zzylol added a commit that referenced this pull request Oct 3, 2026
Cut today's planner over to the unified OperatorNode IR. Frontends return
OperatorNode / QueryRoot, ParsedWorkload keeps scalar roots, Pass 1
(ASAPStrategies), the existing identical-sub-DAG sharing, selection, DAG
assembly and lifecycle costing all run on OperatorNode, and PlanOutput exposes
the whole workload DAG. The native compiler from #541 becomes the canonical
physical_planner and consumes the PhysicalASAPDAG export.

Ported from the earlier #542 (95eef55) without new #509 stage logic. Legacy
QueryExpr/SummaryNode modules stay compiled for their own tests but are no
longer re-exported from post_asap; the cleanup PR removes them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@zzylol
zzylol force-pushed the stack/528-07-planner branch from 74b4884 to e629370 Compare October 3, 2026 20:48
@zzylol
zzylol force-pushed the stack/528-06-native branch 2 times, most recently from aaa8467 to 672a187 Compare October 5, 2026 06:21
@zzylol
zzylol force-pushed the stack/528-07-planner branch from e629370 to 0c62c4a Compare October 5, 2026 06:21
@zzylol
zzylol force-pushed the stack/528-07-planner branch from 0c62c4a to e153234 Compare October 6, 2026 17:47
@zzylol
zzylol force-pushed the stack/528-06-native branch from 672a187 to 9cff08d Compare October 6, 2026 17:47
zzylol added a commit that referenced this pull request Oct 6, 2026
Cut today's planner over to the unified OperatorNode IR. Frontends return
OperatorNode / QueryRoot, ParsedWorkload keeps scalar roots, Pass 1
(ASAPStrategies), the existing identical-sub-DAG sharing, selection, DAG
assembly and lifecycle costing all run on OperatorNode, and PlanOutput exposes
the whole workload DAG. The native compiler from #541 becomes the canonical
physical_planner and consumes the PhysicalASAPDAG export.

Ported from the earlier #542 (95eef55) without new #509 stage logic. Legacy
QueryExpr/SummaryNode modules stay compiled for their own tests but are no
longer re-exported from post_asap; the cleanup PR removes them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@zzylol
zzylol force-pushed the stack/528-06-native branch from 9cff08d to adb9c9e Compare October 6, 2026 20:02
@zzylol
zzylol force-pushed the stack/528-07-planner branch 2 times, most recently from 9d9bff2 to dbbf4c7 Compare October 6, 2026 20:17
@zzylol
zzylol force-pushed the stack/528-06-native branch from adb9c9e to 24b9baf Compare October 6, 2026 20:17
@zzylol
zzylol force-pushed the stack/528-06-native branch from 24b9baf to cb1022e Compare October 6, 2026 20:48
@zzylol
zzylol force-pushed the stack/528-07-planner branch from dbbf4c7 to fa46076 Compare October 6, 2026 20:48
zzylol and others added 5 commits October 6, 2026 21:52
Cut today's planner over to the unified OperatorNode IR. Frontends return
OperatorNode / QueryRoot, ParsedWorkload keeps scalar roots, Pass 1
(ASAPStrategies), the existing identical-sub-DAG sharing, selection, DAG
assembly and lifecycle costing all run on OperatorNode, and PlanOutput exposes
the whole workload DAG. The native compiler from #541 becomes the canonical
physical_planner and consumes the PhysicalASAPDAG export.

Ported from the earlier #542 (95eef55) without new #509 stage logic. Legacy
QueryExpr/SummaryNode modules stay compiled for their own tests but are no
longer re-exported from post_asap; the cleanup PR removes them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SummaryAgg nodes require SummaryCoverage. Today's planner has no time or
population evidence, so a SummaryAgg it builds declares the whole of the one
source scanned beneath it (no time bound, empty population). The declaration
is trusted, not derived from the scan (#570). Rebuilding the same state over a
re-placed input or with a different grouping strategy keeps its coverage.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PlanOutput::execution_timed_dag times every plan root with one shared
TimingMemo and compiles them with compile_physical_asap_workload, so a batch
is one DAG with a root per operator query and shared sub-DAGs exported once.
Lifecycle phases come from the deployments of every plan. The per-plan
SummaryMaintenanceLifecyclePlan::execution_timed_dag is the batch of one.
Standalone scalar roots have no physical form yet and are left out.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Follow #537 and #541: the physical DAG carries Operator<NodeId> instead of
the removed wire mirror types. Port the moved physical_planner, the
planner's lifecycle export and the tests that read or hand-build physical
DAGs; hand-built nodes now name their children by id, matching their edges.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Coverage is now checked against the SummaryAgg's subtree, so the planner
can no longer declare an unrestricted population over a filtered scan (for
example a PromQL `{job="worker"}` selector). Build it with
SummaryCoverage::for_summary instead of the removed whole_source_coverage;
time bounds stay unset.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@zzylol
zzylol force-pushed the stack/528-06-native branch from cb1022e to 24d2158 Compare October 6, 2026 22:16
@zzylol
zzylol force-pushed the stack/528-07-planner branch from fa46076 to 67800ba Compare October 6, 2026 22:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant