Repository navigation
Conversation
…ns for levels 4-5 (#1207 PR 5) PhysicalASAPMemoCandidates::new builds the admissible-edge indexes into each (consumer, input) and out of each producer. PruneReason gains NoIngestionPipeline, QueryTimeResultsNotRetained and AcrossEvaluationsWithoutWindowLayout; TooFewQueryReaders (a consumer-count policy, deleted with constraint (J)) is deleted.
… edges, pruned_candidates (#1207 PR 5) generate_physical_asap_memo_candidates expands each logical candidate into every valid (timing, lifetime), in memory only (#1217), pruning ingestion time without an ingestion pipeline, query-time raw scans without retained raw data, across-evaluations results without a window layout or (at query time) without retained query-time results, and per-entity aggregates the executor cannot run. Each logical edge becomes one physical edge per pair of alternatives with alpha^log copied and alpha^phys from producer_satisfies_physical_requirements. Alternatives with an input no buildable producer supplies, or that no query output reads, are pruned over the admissible edges. Stage 2 cannot fail: its error type, the facade's SelectionError::PhysicalASAPCandidates and the unused workload-entries argument are deleted. Tests build Pass 2's output through the Memo APIs.
…s, one pruned-candidate builder, terminology; tests for a scalar root, an unbuildable input and a root read at ingestion time (#1207 PR 5)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
#1207's Order, row "5. Stage 2": physical expansion (decision-tree levels 4–5), physical edges,$y_{u,c,i}$ on the admissible physical edges this PR builds.
pruned_candidates(concepts doc §2 "Physical requirements", "Invalid combinations", "Decision tree"; §3 "Stage 2: physical alternatives"; #1200, #1201). Stage 3 (PR 6) allocatesWhat
Expansion, levels 4 and 5 ($p^{\mathrm{phys}} = (\tau, \ell)$ : the product of
stage2-physical-optimization/src/catalog/configurations.rs). Each logical candidate gets onePhysicalCandidateper validExecutionTiming{QueryTime, IngestionTime} andLifetime{None, OneEvaluation(Memory), AcrossEvaluations(Memory)}.PhysicalProperties::newrejects (IngestionTime, OneEvaluation), so it is neither offered nor pruned. Stage 2 creates no logical candidates.Prune rules (each reads only the value it removes and the values above it), each alternative recorded in
pruned_candidateswith itsPruneReason:PruneReasonAggregate(every (τ, ℓ))PerEntityAggregateNotExecutableDataArrival::AtRestorUnknown)NoIngestionPipeline(new)Scanand raw data is not retainedRawDataNotRetainedAcrossEvaluationsWithoutWindowLayout(new)QueryTimeResultsNotRetained(new)InputHasNoBuildableProducerReachesNoQueryOutputA materialized result is in memory only: the executor does not store
Diskresults yet (Executor: store Disk-medium materialized views and one-evaluation results on disk #1217). This is a stated rule, not a pruned alternative.Physical edges. Each logical edge$(u, c, i)$ becomes one $u$ and $c$ , grouped by (consumer, input). $\alpha^{\log}$ is copied from the logical edge. $\alpha^{\mathrm{phys}}$ is $\mathcal E$ of §1). $P^{\mathrm{adm}}_{c,i}$ ): $\alpha^{\mathrm{phys}}$ : Stage 3 checks it with
PhysicalEdgeper pair of emitted alternatives ofproducer_satisfies_physical_requirements(timing and lifetime only). Every edge is listed, admissible or not (PhysicalASAPMemoCandidates::newindexes the admissible ones (admissible_edges_into(c, i),admissible_edges_out_of(u). Alignment with an execution context is not part ofPhysicalCandidate::delivers_on(PR 1).Stage 2 cannot fail. It returns
PhysicalASAPMemoCandidates, not aResult, and no longer takes the workload entries (alignment is Stage 3's).Deleted
ErrorGeneratingPhysicalASAPMemoCandidates(Pruning(String))asap_planner::SelectionError::PhysicalASAPCandidates(String)entries: &[QueryWorkloadEntry]argument ofgenerate_physical_asap_memo_candidatesdelivers_on.PruneReason::TooFewQueryReadersMinimumQueryReaders), deleted with constraint (J) on 2026-11-06; the cost model decides.thiserrordependency ofasap-stage2-physical-optimizationtodo!("#1207 PR 5 …")inPhysicalASAPMemoCandidates::{new, admissible_edges_into, admissible_edges_out_of}andgenerate_physical_asap_memo_candidatesOld Stage 2 rules not ported (deleted in PR 0; see spec questions): per-query ingestion eligibility (
NotRepeated,NotPredictable,WindowNotFixed,WindowOffEpochGrid,RangeEvaluatedWholeWindow,TumblingWindowsOff{Phase,Interval}are nowdelivers_onper context),Filtered,CounterNeedsTimeOrder, readouts forced to query time, andOneEvaluationonly for summaries or nodes reached by two or more queries.New abstractions not in #1207 or the doc (pending approval)
PruneReason::{NoIngestionPipeline, QueryTimeResultsNotRetained, AcrossEvaluationsWithoutWindowLayout}types/src/stages/pruning.rspruned_candidates; the doc defines noPruneReasonlist.generate_physical_asap_memo_candidates(logical, data, query_time_results_retained, raw_data_retained) -> PhysicalASAPMemoCandidates(PR 0: alsoentries, returnedResult<_, ErrorGenerating…>)stage2-physical-optimization/src/catalog/mod.rsPhysicalASAPMemoCandidates::newsetspruned_candidatesempty; Stage 2 assigns the pub fieldtypes/src/stages/physical/memo_candidates.rsnew(PR 0) has no pruned-list argument.Deployment { has_ingestion_pipeline, query_time_results_retained, raw_data_retained },enumerate_candidate_configurations(named in the doc),executor_can_run,pruned,logical_edges_into_input,prune_reasons,read_by_query_outputstage2-physical-optimizationcatalog/tests.rs(example,example_with_root,candidate,group,generate,stage2,offered,pruned,id_of)Memomethods.Spec questions (conservative choice taken)
ReachesNoQueryOutput(an unmaterialized ingestion-time result is read only at ingestion time, and only windowed results are materialized across evaluations). Main forced readouts and population operators to query time.rate/increase) over data not known to arrive in time order (Mixed) and an ingestion-time filtered build. Neither is a doc rule, so neither is ported. Should they become level-4 prune rules (two morePruneReasons)?ReachesNoQueryOutputtreats each query as a query-time consumer that is not materialized: a query may read its root group's alternatives with τ = QueryTime or (IngestionTime, AcrossEvaluations). The doc does not state how a query reads its output.How
generate_physical_asap_memo_candidates:enumerate_candidate_configurations(the doc's name) tries every (τ, ℓ) inTIMINGS×LIFETIMESorder throughPhysicalProperties::new. It offers the valid ones and records each pruned one with its reason.PhysicalEdgewith both $\alpha$s. Edges use provisional IDs.prune_reasons: buildable is the least fixed point of "every input has an admissible edge from a buildable producer" (a cycle without a buildable way out is not). Reached is the closure from each query root group's buildable alternatives that a query-time consumer may read, over admissible edges into buildable producers.PhysicalCandidateId); edges with a pruned end are dropped and the rest renumbered.PhysicalASAPMemoCandidates::newbuilds the admissible-edge indexes.Key code interfaces added / modified
types/src/stages/physical/memo_candidates.rstypes/src/stages/pruning.rsstage2-physical-optimization/src/catalog/mod.rsplanner/src/run.rsUsage (the running example's query A, from
catalog/tests.rs; end-to-end planning stops at Stage 3, PR 6):Major algorithm changes
Stage 2 expansion and pruning. Problem: main expanded operator nodes into materialization modes, filtered by per-query eligibility, with consumer-count constraints and timing-only producer sets per input, and no edge objects. PR 0 deleted all of it. Before (main): modes per node kind; per-query eligibility; interned producer sets per input; pruning with consumer-count constraints. After: the product of timing × lifetime per logical candidate less the prune rules above; explicit edges with both$\alpha$ ; buildable/reached fixed points over admissible edges. Correctness: the invalid combination cannot be built (
PhysicalProperties::new); pruning removes only alternatives no feasible selection can use: a candidate without a buildable producer for some input violates (A) when selected, and one no query output reaches violates (F). Tests below. Complexity: alternatives ≤ 5 per logical candidate; edges ≤ 25 per logical edge before pruning; both fixed points are linear in edges per round (rounds ≤ DAG depth). Limits: spec questions 1–5.Before / After
todo!().Representation, rules, enumeration
PhysicalASAPMemoCandidatesis now filled.PhysicalCandidate::physical_properties(PhysicalProperties { timing, lifetime })PhysicalASAPMemoCandidates::physical_candidatesPhysicalEdge,PhysicalASAPMemoCandidates::edges()PhysicalEdge::satisfies_logical_requirement(fromLogicalEdge)producer_satisfies_physical_requirements(producer, consumer)→PhysicalEdge::satisfies_physical_requirementadmissible_edges_into(c, i)PhysicalCandidate::delivers_on(memo, context)(Stage 3)PrunedCandidate<PhysicalCandidateKey>withPruneReasonConcepts not in the formulation: the pruned list and its reasons (diagnostics, #1205).
Verification
cargo test -p asap-stage2-physical-optimization: 12 passed. Every test checks that each emitted candidate has an admissible edge into each input and that edges are grouped by (consumer, input) over emitted candidates (generate). Coverage: expansion per level over the running example (every_logical_candidate_expands_into_its_valid_timings_and_lifetimes); the invalid combination andDisknever appear (the_invalid_combination_and_disk_are_never_alternatives); level 4 (ingestion_time_needs_an_ingestion_pipeline,without_raw_data_only_ingestion_time_builds_read_the_scan, which also coversInputHasNoBuildableProducer); level 5 (query_time_across_evaluations_needs_retained_query_time_results); executor support (a_per_entity_aggregate_without_a_kernel_is_pruned_whole); edges with bothphysical_edges_carry_both_compatibilities,an_unsatisfied_logical_requirement_is_not_admissible); alignment on emitted candidates (alignment_is_checked_per_context_with_delivers_on); pruning (a_consumer_without_a_producer_for_one_input_cannot_be_built,a_scalar_root_reaches_the_groups_it_reads,a_root_group_read_at_ingestion_time_keeps_its_ingestion_time_alternative).cargo fmt --check;cargo clippy -p asap-types -p asap-stage2-physical-optimization -p asap-planner -p asap-devtools --all-targets --all-features -- -D warnings: clean.crate_graph: 6 passed.enumerate_candidate_configurations, stale "operator node" text inplanner-layering.md, "kept" wording, one builder for pruned candidates, and three tests (scalar root, an input group without candidates, a root group read at ingestion time). Not taken: visiting groups in topological order for the buildable fixed point (rounds are bounded by DAG depth),HashMaps replaced by nestedVecs, adebug_assert!on logical-edge input indexes.Test status
cargo test -p <crate> --all-features --no-fail-fast, per crate, passed / failed / ignored. PR 4 is #1234 at 72a4037; PR 5 is this PR (all crates at 36f4208; Stage 2 re-run at d11f12e, which changes only Stage 2 and docs).select_plan; were PR 5)asap_plannersubprocesses; were PR 5); 12 at PR 9 (10 labels as before, 2 now atstage2_pruned_candidates_json, #1205)select_plan, were PR 5; 19 as before); 1 as before (materialized_views)select_plan)