Skip to content

refactor(planner): extract the Stage 3 plan-selection crate - #585

Draft
zzylol wants to merge 2 commits into
stack/572-b3-physical-optimizerfrom
stack/572-b4-plan-selection
Draft

zzylol wants to merge 2 commits into
stack/572-b3-physical-optimizerfrom
stack/572-b4-plan-selection

Conversation

@zzylol

@zzylol zzylol commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

Rebased on main d4869a7 (DF 54).

Why

#572 puts each #509 stage in its own crate so that Cargo enforces the one-way stage flow. This PR is step B4: Stage 3 (plan selection, the only stage that uses the cost model) moves out of asap-aware-mapping into a new crate, asap-plan-selection. As #572 decided, three modules with no callers are deleted instead of moved. Behavior is otherwise unchanged.

What

Before this PR

frontends ──► asap-aware-mapping (Stage 3 + facade) ──┬──► asap-physical-optimizer (Stage 2) ──► asap-types
                                                      └──► asap-logical-optimizer (Stage 1) ──► asap-types
asap-aware-mapping/src/
  plan_selection/{mod, candidate_selection}  cost_model analytical_cost physical_plan_cost_model
  physical_operator_statistics physical_handoff_cost recurrence empirical_cost empirical_resources
  query_physical_lowering storage_io  pane_sharing erp empirical_comparison  pass/  test_support

After this PR

asap-planner ──► asap-aware-mapping (facade: pass/) ──► asap-plan-selection (Stage 3)
asap-plan-selection ──┬──► asap-physical-optimizer (Stage 2) ──► asap-types
                      └──► asap-logical-optimizer  (Stage 1) ──► asap-types
no path from asap-plan-selection to asap-aware-mapping, asap-planner or asap-physical-operators

plan-selection/src/
  lib.rs                 select_plan, select_exhaustive, PlanningModels   (was plan_selection/mod.rs)
  candidate_selection.rs legacy cost-ranked selection (deleted under #580)
  cost/                  cost_model analytical_cost physical_plan_cost_model physical_operator_statistics
                         physical_handoff_cost recurrence empirical_cost empirical_resources
                         query_physical_lowering storage_io
asap-aware-mapping/src/
  lib.rs  pass/{mod, stage_pipeline}

cargo tree -p asap-plan-selection --depth 1 -e normal,dev:

asap-plan-selection
├── asap-logical-optimizer
├── asap-physical-optimizer
├── asap-types
├── serde
├── serde_json
└── thiserror
[dev-dependencies]
└── asap-frontend-promql

How

  • git mv for 16 files (table below). plan_selection/mod.rs becomes the crate root, so PlanningModels (Q37), select_plan and select_exhaustive are at asap_plan_selection::…. The crate root also keeps the re-exports asap-aware-mapping's root had for the moved items: CostModel, DefaultCostModel, the recurrence types and the candidate_selection types.
  • Placement. Everything priced by Stage 3 goes under cost/, including query_physical_lowering and storage_io (Reorganize crates and modules by #509 stages and the #511 unified IR #572 update: only cost code calls them) and empirical_resources (used by empirical_cost). There is no accuracy/ module: its two planned members, erp and empirical_comparison, are deleted, and moving the AccuracyModel trait there (Q22) is a behavior change, not part of this move.
  • No compatibility re-exports. A script, followed by cargo check, rewrote imports across the workspace: crate::cost_model → crate::cost::cost_model inside the crate, and asap_aware_mapping::{cost_model, …, plan_selection} → asap_plan_selection::… in asap-aware-mapping/pass, asap-physical-operators, devtools, integration-tests, planner, frontend-promql tests and the docs. pass no longer re-exports PlanningModels; asap-planner re-exports it from asap_plan_selection.
  • Manifests. asap-aware-mapping drops serde, serde_json and its dev-dependency. devtools, integration-tests, frontend-promql (dev) and asap-physical-operators (dev) now depend on asap-plan-selection instead of asap-aware-mapping, which they no longer import. frontend-sql drops an unused asap-aware-mapping dev-dependency.
  • Paths. include_str! paths in empirical_cost.rs gain one ../ for the deeper location.
  • Manifest guards. A new test, tests/stage3_dependencies.rs, fails if the manifest names asap-aware-mapping, asap-planner or asap-physical-operators. The Stage 1 guard also rejects asap-plan-selection.
  • Docs. Paths that cite moved modules are updated. offline-sketch-evidence.md and the ERP proposal now say that their consumers were deleted. The historical table in planner-vocabulary-migration.md is unchanged.

Deleted modules (no callers)

At the base of this PR, git grep -n -w for each module name and its public items (PaneReuseCandidate, SharedPaneGroup, select_shared_panes, ErpArtifact, ErpSelection, recommend_offline, OfflineComparisonRequest), outside the modules themselves, finds only the pub mod lines and documentation:

crates/asap-aware-mapping/src/lib.rs:41:pub mod empirical_comparison;
crates/asap-aware-mapping/src/lib.rs:44:pub mod erp;
crates/asap-aware-mapping/src/lib.rs:45:pub mod pane_sharing;
docs/design_docs/proposals/error-resource-profile.md:4,13   (ERP module link and status)
docs/develop_docs/offline-sketch-evidence.md:105            (`empirical_comparison::recommend_offline`)
Module Lines Tests deleted
pane_sharing.rs 113 2: shares_compatible_windows, excludes_invalid_and_nonbeneficial_quotes
erp.rs 859 10: selects_cheapest_applicable_accurate_configuration, distribution_mismatch_fails_closed, multi_fit_selects_only_confident_well_fitting_family, multi_fit_rejects_ambiguous_or_poor_observations, multi_fit_jointly_ranks_all_plausible_families, exact_empirical_fingerprint_precedes_fits_and_requires_identity, deserializes_sketch_bench_wire_format, nearest_shape_prefers_cardinality_and_skew_then_cost, nearest_shape_rejects_distribution_family_and_small_benchmarks, pane_window_composes_atomic_operation_costs
empirical_comparison.rs 915 9: accuracy_requirement_changes_selected_configuration_and_cost, preparation_and_exact_resource_dimensions_keep_their_meaning, optional_exact_dimensions_cannot_hide_invalid_measurements, sketch_comparison_requires_unknown_preparation_phase, missing_cost_or_failed_error_acceptance_selects_exact, applicability_is_checked_before_recommendation, resource_objective_and_unknown_memory_are_explicit, formal_minimums_cannot_be_relaxed_by_observed_accuracy, comparison_requires_disjoint_phases_and_one_exact_generation
empirical_cost::snapshot_prepare_cpu (pub(crate)) 16 1: unmeasured_preparation_for_other_families_stays_unknown. Its only production caller was empirical_comparison (empirical_comparison.rs:414); without it the function is dead code and fails -D warnings.

Moved files

From asap-aware-mapping/ To plan-selection/
src/plan_selection/mod.rs src/lib.rs
src/plan_selection/candidate_selection.rs src/candidate_selection.rs
src/{cost_model, analytical_cost, physical_plan_cost_model, physical_operator_statistics, physical_handoff_cost, recurrence, empirical_cost, empirical_resources, query_physical_lowering, storage_io}.rs src/cost/*.rs
src/test_support.rs src/test_support.rs
tests/{physical_handoff_cost, storage_io}.rs, tests/data/offline-evidence-synthetic.json tests/…

New: Cargo.toml, src/cost/mod.rs, tests/stage3_dependencies.rs.

Volume

62 files changed, +340 / −2,208. 16 files moved with git mv, 3 new, 3 modules (1,887 lines) deleted. About 170 changed lines name the new paths.

Gate (at the tip)

  • cargo fmt --all --check: passes.
  • cargo clippy --workspace --all-targets --all-features -- -D warnings: passes.
  • cargo test --workspace: 1,508 passed, 12 ignored. That is B3's 1,529, less the 22 deleted tests listed above, plus the new manifest guard. Compared with refactor: extract the Stage 1 logical-optimizer crate (#572 B2) #583 (1,528): −22 + 2 guards.
  • python3 -m unittest discover -s tools/dag-viewer -p test_render.py: OK, 6 skipped.
  • stage_pipeline --example planner-layering-1 regenerates tools/dag-viewer/examples/planner-layering-example1.json byte for byte.

Part of #572 (B4) and #509. Follows #584. Related: #580 (deletes candidate_selection). Next: B4b (facade into asap-planner).

🤖 Generated with Claude Code

zzylol and others added 2 commits October 10, 2026 13:41
Move asap-aware-mapping's Stage 3 modules into the new asap-plan-selection
crate: the cost model and its inputs under cost/, plan_selection/mod.rs as
the crate root (select_plan, PlanningModels) and candidate_selection, with
their tests and the test_support copy. Delete pane_sharing, erp and
empirical_comparison, which have no callers (#572), and the
snapshot_prepare_cpu helper only empirical_comparison used. A manifest
guard rejects the facade and executor. Imports are rewritten without
compatibility re-exports (#572, B4).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nd Operator<NodeId> payloads

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W7qG9aFyPij5uWsyAJCxDW
@zzylol
zzylol force-pushed the stack/572-b4-plan-selection branch from 4db77b5 to 9ba90c2 Compare October 10, 2026 14:32
@zzylol
zzylol force-pushed the stack/572-b3-physical-optimizer branch from 20db54d to 9c43271 Compare October 10, 2026 14:32
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