Repository navigation
refactor: define every stage's interfaces from #1207 and delete the ones they replace (#1207 PR 0) - #1226
Conversation
4772efb to
f57ae08
Compare
|
Per-file test deletions in #1226 (origin/main → PR head).
Restored in the 2026-11-06 revision through the test-only |
f57ae08 to
2966355
Compare
341c98b to
3a75e1e
Compare
|
Key code interfaces, continued (moved here from the PR body, which GitHub limits to 65,536 characters). Links point at the head.
|
| File | Tests | Restored by |
|---|---|---|
types/tests/summary_coverage.rs (file deleted) |
32: coverage derived on node trees (lifting, merges, time windows, rollups, definition ids) | PR 2's types/tests/memo_summary_coverage.rs (8) over memo groups; the rest as later PRs need them |
integration-tests/tests/summary_coverage_e2e.rs (file deleted) |
8: query string → planned state → coverage() |
no replacement planned: it read node-tree coverage of front-end trees |
types/tests/summary_merge_structure.rs |
idempotent_families_merge_overlapping_states (node merge check) |
PR 2's states_with_overlapping_selections_do_not_merge |
types/tests/tumbling_window_chain.rs |
a_rollup_of_the_newest_tumbling_windows_covers_their_window; the coverage asserts of 5 more |
PR 2's a_tumbling_window_chain_covers_its_whole_window |
types/tests/tumbling_window_chain.rs |
a_merge_of_the_newest_tumbling_windows_covers_their_window (read the build through the node-tree merged_window_build) |
PR 4, with the merged-windows guarantee over groups |
devtools/src/bin/asap_planner.rs |
memo_node_table_stores_a_shared_node_once (with MemoNodes::add) |
PR 9 |
accuracy/src/estimators/mod.rs, mod shared_size_tests |
4: size_for_all_readers |
no replacement: deleted with the function |
The coverage asserts in integration-tests/tests/sketch_rollup.rs (2 tests) and logical-asap-optimization's per_computation_candidates_tests.rs (1 test) are removed; the tests stay.
Kept by building the DAG directly (decided 2026-11-06). Tests that hand-built operator roots and ran them now export them with the test-only physical_asap_dag_at_query_time(_with_node_ids) instead of the deleted roots-based export. Restored: executor time_series_window, node_ids, current_series_heap, planspace_series_identity_heap, 3 of deployment_computation's tests; integration filtered_aggregates, kll_tumbling_window_execution, per_series_exact_execution, sql_cardinality, sql_frequency, exact_composition, and parts of sketch_rollup, stage1_logical_asap_optimization, operator_design_examples, operator_sharing, promql_numeric_regressions, sql_to_post_asap, promql_to_post_asap; types physical_export; frontend count_planning, pearson_corr. types/tests/physical_export.rs::untimed_plan_is_rejected (the +1 above, deleted after the comment was posted) is deleted: the builder always assigns query time, and an untimed export is no longer possible. Restored sketch tests fail at the executor's todo!() until PR 6, because the builder leaves parameters: None. Tests whose DAG came from the planner (runtime_install's planning tests, sql_per_group_topk, sql_table_scans, per_sample_updater, the planner-built deployment_computation tests, and others) stay deleted; PR 6 restores them.
Moved from the PR body (2026-11-08, body size limit)
2026-11-07 round, 10 more:
| File | Tests | Restored by |
|---|---|---|
types/tests/tumbling_window_chain.rs |
6: merged_tumbling_windows_cover_the_whole_window, each_tumbling_window_is_one_shifted_minute, expansion_merges_the_tumbling_windows, a_merge_of_the_newest_tumbling_windows_reads_one_chain_and_fewer_than_all_tumbling_windows, newest_tumbling_windows_serializes_only_when_set, expansion_keeps_a_rollup_of_the_tumbling_windows (window count, newest windows, expansion) |
PR 1 (TimeRange over a chain), PR 6 (executor by window index) |
types/src/ir/properties/summary_coverage.rs |
3: large_reverse_ordered_tumbling_window_union_is_one_exact_interval, interval_fast_path_matches_general_union_for_permutations, sorted_union_preserves_gaps_boundaries_and_original_group_order (relative_time union) |
PR 2 (timestamp-column intervals) |
planner/tests/runtime_install.rs |
tumbling_windows_of_an_hour_share_one_definition_with_distinct_times (expanded windows' relative_time) and its now-unused helpers plan_json, plan_json_for |
PR 6 |
633460c to
22caa51
Compare
…nes they replace (#1207 PR 0)
…iming, lifetime }
Deletes Schedule and the σ-only InvalidPhysicalProperties variants; the only
invalid combination left is (IngestionTime, OneEvaluation). satisfies_physical
checks timing x lifetime only; delivers_on is the per-context alignment check
(w | I and w | φ). A OneEvaluation result runs in one evaluation context, so
x_{κ,v} covers it as for ℓ = None.
…physical drops memo InvalidLogicalProperties gains SketchBuildWithoutParameters and renames FloorNotInParameterList to ParametersNotInList, returned by LogicalProperties::new. LogicalRequirement::new no longer checks list membership (a floor is any value of the family's parameter type, e.g. heap_size >= k), so it returns Self. satisfies_physical takes only the producer and consumer.
Context::QueryEvaluation(QueryId) becomes Context::Evaluation(EvaluationSchedule):
queries with the same (interval, phase) are evaluated together and share
their OneEvaluation results. evaluation_schedule returns that schedule.
QueryId stays for z_{q,v}. A non-periodic query has no context yet.
InvalidLogicalProperties -> LogicalPropertiesError, InvalidPhysicalProperties -> PhysicalPropertiesError, LogicalRequirement -> LogicalRequirements (parameter_floor -> parameter_floor_for_required_accuracy), satisfies_logical / satisfies_physical -> producer_satisfies_logical_requirements / producer_satisfies_physical_requirements, Medium -> StorageMedium, Context / ContextId -> ExecutionContext / ExecutionContextId (x_in_context / y_in_context -> x_in_execution_context / y_in_execution_context). PhysicalCandidate and PhysicalCandidateKey fields -> logical_candidate_id, physical_properties; edge fields -> producer_candidate_id, consumer_candidate_id; PhysicalASAPMemoCandidates fields -> logical_candidates, physical_candidates.
Deletes EvaluationSchedule and ExecutionContext::evaluation_schedule. An
evaluation context is Evaluation { recurrence, range_evaluation }: queries
with equal ones share it and its OneEvaluation results, one-off queries
included. ExecutionContext, ExecutionContextId and RefreshWindowId move to
asap_types::stages so PhysicalCandidate::delivers_on can take the context.
Contexts are deduplicated by equality (QueryRecurrence holds an f64).
PhysicalASAPDAGValidationError::InvalidPhysicalProperties becomes
PhysicalProperties { node, reason }. In the files this unit edits, "kept"
describing a materialized result or retained data becomes "materialized"
or "retained" (cost, materialized views, realizer, installable plan,
deployment capabilities; locals kept/raw_kept_rows -> retained/
raw_retained_rows), and "reader" becomes "query" where it is a query
(execution demand, ScheduleGroup::queries, cost usage, labels, tests) or
"consumer" where it is a consuming candidate.
find_or_add_group returns the node rules' SchemaDerivationError and add_candidate a CandidateError (the node rules, or an output that differs from the group's). Bodies stay todo!() until PR 2.
…mo (#1207 PR 0) Memo::groups is private, read through groups(); groups are added only through find_or_add_group and queries through add_query (todo!() until PR 2). memo_of_queries returns Result and its body is todo!() until PR 2, which builds Stage 0 on find_or_add_group; Stage 0's node-level CSE (cse.rs), its test_support export and the dead share_identical helper are deleted.
…OperatorInput; coverage only in the memo (#1207 PR 0) MemoGroup { expression, group_properties: GroupProperties, parents, queries, candidates } replaces logical_node and child_groups; GroupProperties { schema, result_kind, summary_coverage, shareable_when_equal } is derived once by derive_group_properties, which applies the existing rules to the expression over MemoGroupAsInputs. The rules (output_schema, output_kind, validate_inputs, is_shareable_when_equal, summary builds, window chains, scalar subqueries, top-k, populations) are generic over OperatorInput, implemented for Rc<OperatorNode> and MemoGroupAsInput; only how they read an input changed. BuiltOrInput carries the builds a rule makes while deriving (one build over a chain's window, the build a rollup or a selection stands for). SummaryCoverage { definition: SummaryStateDefinition { input_group, unlifted_operators }, selection } is derived only from memo groups (derive_from_inputs) and stored in GroupProperties; node-tree coverage, NodeToSummaryCoverageCache, derive_cached and OperatorNode::coverage are deleted, so node trees have no merge check. Memo::logical_node_trees is deleted: Pass 1 target discovery (PR 3), devtools group labels (PR 9) and the export's view coverage (PR 6) are todo!(). find_or_add_group and add_candidate derive the properties, then todo!() until PR 2.
…elpers (#1207 PR 0) One state's θ is no longer sized for several consumers: θ comes from parameter_list per candidate. size_for_all_readers had no non-test caller; min_recorded, kll::shared_k and univmon::shared_heap served only it.
…perators; delete merged_window_build_node (#1207 PR 0) - BuiltOrInput / BuiltInput renamed InputOrTemporaryBuild / TemporaryBuild: a build a rule constructs only while it derives, never stored in the memo. - SummaryStateDefinition::unlifted_operators is Vec<Operator<Option<MemoGroupId>>>: None marks an operator's main input, Some(g) another input group it reads (a scalar subquery's). States whose definitions read subqueries compare and merge; CoverageError::SubqueryInDefinition deleted. - merged_window_build_node deleted with its test; the accuracy guarantee of a read of merged tumbling windows is todo!() until PR 4 rewrites it over groups.
…, TimeBound, Pass 2 pruned list, Stage 2 entry (#1207 PR 0) - Delete WindowLayout, LogicalProperties::window_layout and its two error variants, SummaryMerge::newest_tumbling_windows and SummaryTumblingWindowChain::tumbling_window_count, with the count-based chain builds and expansion; behaviour that read the count is todo!() for PR 1, 2, 6, 7 or 9. - SelectionBox { columns } only, and TimeBound { At, FromEvaluationTime }; lifting TimeRange/TimeShift is todo!() for PR 2. - PrunedLogicalCandidate, PruneCause, RootPruneReason and LogicalASAPMemoCandidates::pruned. - error_propagation(consumer, metric) -> Option<ErrorPropagation>; Memo::set_input_requirements. - PhysicalCandidateKey deleted (PrunedCandidate<PhysicalCandidate>), PrunedCandidate::group and PhysicalASAPMemoCandidates::query_roots dropped; new(logical, physical, edges, pruned). - Stage 2 entry takes &DeploymentCapabilities (moved into asap-types) and cannot fail; PruneReason follows the doc's Stage 2 table. - DataArrival::{Ingesting, Mixed} gain max_out_of_order_ms. - GroupProperties::summary_coverage -> aggregate_coverage.
…l; ScalarValue::Timestamp (#1207 PR 0) Replace TimeBound by IntervalConstraintLimit { FixedValue(ScalarValue), EvaluationTimePlusMs(i64) }: Constraint::Interval holds Bound<IntervalConstraintLimit> on every column, so the timestamp column and value columns share one interval type. Doc comments carry the examples (m[5m], offset 1h, @ T, SQL ts >= literal, price > 10). ScalarValue::Timestamp(ms since the epoch) is the fixed value of an @ T or a SQL timestamp literal.
…s; delete ParametersOfAnotherFamily (#1207 PR 0) A range m[r] evaluated at t reads (t - r, t]: IntervalConstraintLimit and Constraint::Interval examples, the chain window doc and the primitive-schema table now use Excluded lower and Included upper ends. A parameter list holds only its own family's parameters, so ParametersNotInList also rejects another family's parameters.
…acy, the plan is one PhysicalASAPDAG (#1207 PR 0) - Terminology: ops' `family` is `summary_type`; FieldDataType::Sketch(SketchAlgorithm) (SketchKind, GroupingStrategy, HydraKind and the ops' `grouping` deleted); FamilyCapability is SummaryTypeCapability; parameter_list(algorithm). - θ is structure only: SketchParams derives equality; KLL failure_probability, UnivMon distinct_failure_probability and HLL/KMV relative_error deleted. - ValueSign and GroupProperties::column_sign; SourceFacts::column_signs replaces values_non_negative. - LogicalRequirements { required_accuracy: Option<RequiredAccuracy> }; RootPruneReason::BelowRequiredAccuracy; Memo::add_query takes the target and n_q; AggIntent measures carry no accuracy and front ends take none. - asap-accuracy: AccuracyEvidence::measured_guarantee, theoretical_guarantee (was local_guarantee), producer_satisfies_logical_requirements(memo, producer, consumer, input_index, evidence); the AccuracyModel trait and evidence provider, Pass 1's accuracy pruning and AccuracyCheckInputs deleted. - Physical: ExecutionContext::Evaluation { grid: EvaluationGrid }, IngestionPipeline(RefreshWindow); RefreshWindowId deleted; producer_satisfies_physical_requirements(producer, consumer_timing); PruneReason::CountMinWeightsNotProvenNonNegative. - Plan: PlanOutput { plan: PhysicalASAPDAG }; PhysicalASAPDAGNode:: selected_physical_candidate; select_plan returns (PhysicalASAPDAG, Selection); Selection { accepted_accuracy_per_query, pruned_candidates, milp_* }; RealizedPlan, PhysicalWorkloadPlan, DagOfSelectedCandidates, SelectedEdge, SelectedNodeId, AssignmentRealizer, ScanWindow and the scan/view window functions, SearchReport, SearchStatus, InexactObjective, ObjectiveDiffersFromPlanCost, SelectedPlanFailedCheck and PlanCost::cost_unit deleted. - Plan file wire version 14 (summary_type, Sketch(algorithm), no grouping). - Cost names: NodeCostSource, cost_source, PlanRanking::Cost; Serialize on PruneReason, PhysicalProperties, OriginOfCandidateForMemoGroup and RootPruneReason.
…e trait, MemoQuery, evaluation grids of groups (#1207 PR 0) 2026-11-09 decisions: - theoretical_guarantee and AccuracyEvidence::measured_guarantee take the failure probability and return the error bound that holds at it (None when θ cannot fail that rarely); bodies stay todo!() for PR 4. - AccuracyEvidence is a trait; NoMeasuredGuarantees has no measurement. PlanningModels::evidence and Pass 2 take &dyn AccuracyEvidence. - The memo holds its queries in one Vec<MemoQuery> { root, accuracy_target, values_per_evaluation }; add_query(query). - SupportedSummary::family is summary_type. - satisfies is deleted with metric_meets, scope_meets, native_target and AccuracyScope::covers, which only it used; target_limit is the comparison limit with the tolerance. - PhysicalCandidate::delivers_on(&PhysicalASAPMemoCandidates, context). - GroupProperties::depends_on_evaluation_time (derived in PR 2) and LogicalASAPMemoCandidates::evaluation_grid_of_group (filled in PR 4).
… the tests that use it (#1207 PR 0) pass1/composition.rs composed one whole-workload candidate DAG from one per-computation candidate per target, for tests only; planning adds every way to compute to the memo instead. It and the 74 tests and fixture helpers that compose through it are deleted (no interim code for PR 3).
…racy argument (#1207 PR 0)
2ed6ec0 to
61541f7
Compare
…requirement setters by what they hold (#1207 PR 0) - asap_types::stages: logical/ (memo/, group, candidate, requirements, edge, memo_candidates) and physical/ (execution_context, candidate, edge, memo_candidates); pruning.rs holds every stage's removed candidates. Public asap_types::stages paths are unchanged. - parameter_list moves to asap_types::ir::schema (sketch_parameter_lists.rs). - Error propagation moves to asap-accuracy (error_propagation.rs) as the free function error_propagation. - MemoQuery::values_per_evaluation -> number_of_values_per_query_evaluation; Memo::set_input_requirements -> set_candidate_input_requirements. - Pass 1: its entry moves into pass1.rs; per_computation_candidates.rs -> computation_targets.rs. Pass 2: its entry moves into pass2.rs.
…1207 PR 0) asap-types: - summary_type/: parameters.rs, parameter_lists.rs, statistic.rs and capability.rs (were ir/schema/sketch.rs, sketch_parameter_lists.rs and summary_type_capability.rs). - accuracy/: target.rs and guarantee.rs (were ir/properties/accuracy.rs and guarantee.rs). - plan/: physical_asap_dag.rs and materialized_view.rs (were ir/physical_export.rs and ir/materialized_view.rs). - stages/physical/properties.rs (was physical/properties.rs; the physical module is deleted). - ir/operator/arguments.rs (was operator_properties.rs); ir/schema/series_identity.rs (was schema_support.rs). - workload/mod.rs split into query.rs, data.rs and planning.rs; mod.rs re-exports them. asap-accuracy: - guarantee/ (was estimators/): each summary type's theoretical guarantee. - evidence.rs: AccuracyEvidence, NoMeasuredGuarantees (was model.rs). - requirements.rs: producer_satisfies_logical_requirements (was model.rs), target_limit and meets (were lib.rs). - The old evidence.rs (PropagationStats) is renamed propagation_stats.rs so the new evidence.rs does not collide with it. - lib.rs holds module declarations and re-exports only; the modules that glob-imported its imports now import what they use. asap-cost: - model.rs: the cost models and the deployment's cost inputs (were lib.rs). - resources/mod.rs: ResourceUsage (was lib.rs) with the resource dimensions (was resources.rs). - node/: usage.rs (one node's usage and cost: node_usage, NodeCost, ProducerOutput, node_map; was usage.rs and lib.rs), analytical.rs, state_bytes.rs and operator_statistics.rs. - plan/: cost.rs (plan_cost, PlanCost, QueryLatency), retention.rs (the tumbling windows a plan retains; was usage.rs), execution_demand.rs and ranking.rs. - lib.rs holds module declarations and re-exports only. Users of asap_cost::analytical, ::state_bytes and ::execution_demand use their new paths. Every user's path is updated, docs included; no alias for an old path is kept.
Summary
Sketch(SketchKind, GroupingStrategy)with θ recording the error it was sized for, accuracy was a θ floor and a pluggableAccuracyModelchecked after Stage 3, and Stage 3 decoded a selected-candidate DAG that Stage 2 realized into aRealizedPlan.todo!()bodies where the behavior lands in a later PR, and deletes the interfaces they replace (420 files, +6,122 / −79,960 lines), so no later PR needs an adapter between an old and a new interface.quantile_over_time(0.99, latency[1m]) / quantile_over_time(0.5, latency[1m])within relative 0.03, the readout's input now carriesRequiredAccuracy { metric: Relative, max_error, failure_probability }instead of a θ floor, θ is structure only (Kll { k }), and Stage 3 returns(PhysicalASAPDAG, Selection);PlanOutputholds onlyplan. Test status at the head: 1,078 passed / 217 failed / 9 ignored, every failure at atodo!()except one stale fixture.Review guide
main. First code PR of the Tracking: implement the optimization formulation (memo candidates, properties, edges y_{u,c,i}, MILP) as named code per stage #1207 stack, after the concepts doc docs(concepts): memo groups, properties, requirements, per-stage interfaces and rules #1224; refactor: one crate per stage (#1207 PR 0b) #1229 (PR 0b, one crate per stage) builds on it. Head7030d68de.types/src/ir/schema/mod.rsandtypes/src/summary_type/{parameters.rs, parameter_lists.rs, statistic.rs, capability.rs}: summary types and θ.types/src/stages/logical/{memo/mod.rs, group.rs, candidate.rs, requirements.rs, edge.rs, memo_candidates.rs},types/src/stages/pruning.rsandtypes/src/stages/physical/{execution_context.rs, candidate.rs, edge.rs, memo_candidates.rs, properties.rs}: the memo, requirements, contexts, by scope (memo → group → candidate → candidate input → edge → stage output).accuracy/src/{evidence.rs, requirements.rs, error_propagation.rs, guarantee/mod.rs}:AccuracyEvidence,producer_satisfies_logical_requirements,target_limit,error_propagation,theoretical_guarantee.logical-asap-optimization/src/{stage0.rs, pass1.rs, pass2.rs},plan-selection/src/{select.rs, report.rs}.planner/src/{pass.rs, run.rs, installable.rs}.family→summary_type,FamilyCapability→SummaryTypeCapability,NodePriceSource→NodeCostSource,PlanRanking::Price→Cost,family_name→summary_type_name);SerializeonPruneReason,PhysicalProperties,OriginOfCandidateForMemoGroup,RootPruneReason; docs (asap-primitive-schema§1 and §6, architecture, library-API, mapping-contracts, extension, input-output, accuracy docs) using the new names; the checked-in version-10 fixture's DAG migrated; workload fixtures and the viewer readcolumn_signs.lower_sql_dialectin main's new ClickHouse tests (frontend-sql/tests/clickbench/clickbench.rs,sql_lowering.rs) and writesAggIntent::Countas a unit variant there. The argument is gone because this PR moves the accuracy target from the operator (AggIntent::Count { accuracy }) to the query (MemoQuery::accuracy_target).git diff -M 61541f748 7030d68deshows them as renames where a file moved whole.todo!()names the PR that fills it; the public signatures below (the later PRs fill them without changing them); the deletion table (each deleted item's replacement).SelectionVariables::t: Vec<Option<Variable>>(only on strongly connected components);AccuracyVariables::{error_bound, error_bound_of_input}per metric (Behavior: before → after
The design need: one model from the concepts doc that every stage PR fills in behind fixed interfaces. Example workload: p99 / p50 of
latency(declared non-negative), relative error 0.03, every 10 s.Sketch(SketchKind { Kll, Kll { k, failure_probability } }, GroupingStrategy); Hydra a grouping axis; op fieldfamilySketch(Kll); Hydra an algorithm (HydraKll,HydraCms,HydraCountSketch); op fieldsummary_type; θKll { k }on the candidateQuantile { col, q, accuracy }Quantile { col, q }; the target enters the memo with the query (MemoQuery::accuracy_target) withAccuracyModel::satisfiesbefore and after Stage 3LogicalRequirements { required_accuracy: Option<RequiredAccuracy> }on a readout's input; α^log compares the producer's measured-or-theoretical guarantee at δ_r (PR 4); nothing checked after Stage 3Selection { selected_dag, cost, search_report, .. }realized by Stage 2 into aRealizedPlan;PlanOutput::plansper queryselect_plan(..) -> (PhysicalASAPDAG, Selection); each node names its physical candidate;PlanOutput { plan }values_non_negative: true"column_signs": {"value": "non_negative"}summary_type, a sketch state is{"Sketch": "Kll"}, nogrouping;selected_physical_candidatenot writtentodo!()until PR 2Interfaces
Permalinks at the PR head
7030d68de; diff againstmain(82165ae2b). The interface list as of the earlier head7e83db97d(decisions of 2026-11-06 and 2026-11-07, with its deletion tables) is kept in this comment; the 2026-11-07 detail in the interfaces comment.types/src/ir/schema/mod.rs·types/src/summary_type/(parameters.rs,parameter_lists.rs,statistic.rs,capability.rs)/// A column's type: a plain value or a summary type (family + algorithm). Stays. pub enum FieldDataType { /// An ordinary readable value. Plain(DataType), /// Exact, mergeable accumulator state. ExactAggregate(ExactKind, ExactParams), - /// Sketch state: algorithm and θ bundled, plus per-group or shared (Hydra) grouping. - Sketch(SketchKind, GroupingStrategy), + /// Sketch state of one algorithm, the `Hydra*` algorithms included; θ is not part of the type. + Sketch(SketchAlgorithm), /// A summary sample (the rows a sampling summary keeps). SummarySample(SamplingKind, SamplingParams), /// Wavelet summary state. Wavelet(WaveletKind, WaveletParams), /// Statistical-model summary state. StatModel(StatModelKind, StatModelParams), } /// θ: the structure's sizes, from `parameter_list(algorithm)`; no sized-for error fields, /// so equality (now derived) compares every field. Stays. pub enum SketchParams { /// UnivMon. UnivMon { heap_size: u32, sketch_rows: u32, sketch_cols: u32, layers: u8, - distinct_failure_probability: Option<f64>, }, /// KLL. Kll { k: u32, - failure_probability: Option<f64>, }, /// Count-Min. Cms { width: u32, depth: u32, }, /// HyperLogLog. Hll { precision: u8, - relative_error: Option<f64>, }, /// DDSketch. DDSketch { alpha: f64, }, /// Count-Min with a top-k heap. CmsWithHeap { width: u32, depth: u32, heap_size: u32, }, /// KMV. Kmv { k: u32, - relative_error: Option<f64>, }, /// Count Sketch. CountSketch { width: u32, depth: u32, }, /// Count Sketch with a top-k heap. CountSketchWithHeap { width: u32, depth: u32, heap_size: u32, }, + /// The sizes of a Hydra structure, for the `Hydra*` algorithms. + Hydra(HydraParams), } -/// An algorithm and its θ, validated as a pair. -pub struct SketchKind { - algorithm: SketchAlgorithm, - params: SketchParams, -} -/// The Hydra variants of the shared grouping. -pub enum HydraKind { - HydraKll, - HydraCms, - HydraCountSketch, -} -/// One sketch per group, or one shared structure for all groups. -pub enum GroupingStrategy { - PerSubpopulationInstance, - SharedMultiSubpopulation { - kind: HydraKind, - params: HydraParams, - }, -} -/// What one family can do. Renamed below. -pub struct FamilyCapability { +/// What one summary type can do: its row of the capability table. +pub struct SummaryTypeCapability { /// How the inputs of a merge must relate; `None` without a sound merge. pub merge_inputs: Option<MergeInputRule>, /// Each statistic one state answers, with the error of that readout from a merged state. pub(crate) readouts: &'static [(StatisticKind, MergedError)], } -impl FamilyCapability { +impl SummaryTypeCapability { /// Each statistic one state answers, with its merged-state error. pub fn readouts(&self) -> &'static [(StatisticKind, MergedError)]; /// Whether a rollup may merge different groups' states (not a Hydra's: its groups share one state). - pub fn merges_groups(family: &FieldDataType) -> bool; + pub fn merges_groups(summary_type: &FieldDataType) -> bool; + /// Whether `summary_type` is a Hydra algorithm; read by `merges_groups` and the executor's kernel check. + pub fn shares_one_state_across_groups(summary_type: &FieldDataType) -> bool; /// Whether one state answers `statistic`. pub fn answers(&self, statistic: &SketchStatistic) -> bool; /// The error of `statistic` from a merged state; `None` without a sound merge. pub fn merged_error(&self, statistic: &SketchStatistic) -> Option<MergedError>; - pub fn of_per_instance_sketch(algorithm: &SketchAlgorithm) -> Self; /// The row of `summary_type`; types not listed fail closed. - pub fn of(family: &FieldDataType) -> Self; + pub fn of(summary_type: &FieldDataType) -> Self; } /// One summary type a deployment's executor can build, with its readouts. pub struct SupportedSummary { - pub family: SketchAlgorithm, + /// The summary type the executor can build (JSON field `summary_type`). + pub summary_type: SketchAlgorithm, /// The statistics it answers from one state. pub readouts: Vec<StatisticKind>, }of_per_instance_sketch:of(&Sketch(a))covers it once Hydra is an algorithm. Modulefamily_capabilityis nowasap_types::summary_type(capability.rs).types/src/ir/operator/asap.rs·agg_intent.rs/// The ASAP summary operators. Stays; three variants change. pub enum ASAPOp<C = Rc<OperatorNode>> { /// Build one summary state per group (or one shared Hydra structure). SummaryAgg { child: C, - family: FieldDataType, + summary_type: FieldDataType, input: SummaryUpdate, reduction: Reduction, - grouping: GroupingStrategy, #[serde(default)] filter: Option<crate::ir::scalar::Predicate<C>>, }, /// Read a statistic from a state (unchanged). SummaryEstimate { .. }, /// Finalize an exact accumulator (unchanged). FinalizeExactAccumulator { .. }, /// Maintain a population (unchanged). MaintainPopulation { .. }, /// Evaluate a population (unchanged). EvaluatePopulation { .. }, /// Merge states (unchanged). SummaryMerge { .. }, /// A chain of tumbling windows of states; no window count (the width only). SummaryTumblingWindowChain { child: C, - family: FieldDataType, + summary_type: FieldDataType, input: SummaryUpdate, reduction: Reduction, - grouping: GroupingStrategy, #[serde(default)] filter: Option<crate::ir::scalar::Predicate<C>>, #[serde(alias = "pane_width_ms")] tumbling_window_width_ms: u64, - #[serde(alias = "pane_count")] - tumbling_window_count: u32, }, /// Subtract states (unchanged). SummarySubtract { .. }, /// Delete from a state (unchanged). SummaryDelete { .. }, /// Join two states on a key. SummaryJoin { outer: C, inner: C, key: ColumnId, - family: FieldDataType, + summary_type: FieldDataType, }, /// An extension operator (unchanged). Extension { .. }, } /// What an aggregate computes. Stays; measures carry no accuracy (the query's target does, N1). pub enum AggIntent<C = ColumnId> { - Count { - accuracy: AccuracyTarget, - }, + Count, Sum { col: Option<C> }, Min { col: Option<C> }, Max { col: Option<C> }, Avg { col: Option<C> }, StdDev { col: Option<C>, population: bool }, Variance { col: Option<C>, population: bool }, PearsonCorr { left: C, right: C }, Quantile { col: Option<C>, #[serde(with = "crate::serde_f64")] q: f64, - accuracy: AccuracyTarget, }, TopK { k: usize, - accuracy: AccuracyTarget, }, Cardinality { cols: Vec<C>, - accuracy: AccuracyTarget, }, FrequencyL2 { col: Option<C>, - accuracy: AccuracyTarget, }, FrequencyEntropy { col: Option<C>, - accuracy: AccuracyTarget, }, Rate, IRate, Increase, Changes, Delta, IDelta, Deriv, Resets, PredictLinear { seconds: f64 }, DoubleExpSmoothing { smoothing: f64, trend: f64 }, HistogramCount, HistogramSum, HistogramAvg, HistogramStdDev, HistogramStdVar, HistogramFraction { lower: f64, upper: f64 }, HistogramQuantile { q: f64, le: C }, Math(MathFunc), Absent { labels: BTreeMap<String, String> }, AbsentOverTime, PresentOverTime, TimeFn(TimeFunc), Group, CountValues { label: String }, LastOverTime, FirstOverTime, MadOverTime, TsOfMinOverTime, TsOfMaxOverTime, TsOfFirstOverTime, TsOfLastOverTime, Extension { ext_kind: String, payload: serde_json::Value }, }types/src/stages/logical/(memo/mod.rs,group.rs,candidate.rs,requirements.rs,edge.rs,memo_candidates.rs) ·types/src/stages/pruning.rs·types/src/accuracy/types/src/stages/physical/(execution_context.rs,candidate.rs,edge.rs,memo_candidates.rs,properties.rs) ·types/src/plan/physical_asap_dag.rs·types/src/workload/Materializationis replaced byPhysicalProperties { timing, lifetime }withLifetime. The window functions: aScanis an ordinary node, its retention itsretention_ms(executor/src/sources/window.rs) until PR 6 (P10).evidence.rs·requirements.rs·error_propagation.rs·guarantee/mod.rs·lib.rsAlso deleted:
metric_meets,scope_meets,native_target,AccuracyScope::covers(onlysatisfiesused them).Stages:
stage0.rs·pass1.rs·pass2.rs·plan-selection/src/select.rs·report.rsFacade and tools:
planner/src/pass.rs·run.rs·installable.rs·cost/src·frontend-sql/src/lib.rs·frontend-metricsql/src/lib.rs/// Planning logic and models, split by stage. Stays. pub struct PlanningModels<'a> { - pub accuracy: &'a dyn AccuracyModel, - pub evidence: &'a dyn AccuracyEvidenceProvider, + /// The deployment's measured accuracy, read by Pass 2; none by default. + pub evidence: &'a dyn AccuracyEvidence, /// The deployment's cost inputs. pub cost_inputs: &'a CostInputs, /// What the deployment's executor can run and keep. pub deployment_capabilities: &'a DeploymentCapabilities, /// Do not enforce accuracy: the facade gives every query no target before Pass 2. pub ignore_accuracy_guarantees: bool, } impl<'a> PlanningModels<'a> { - pub fn new( - accuracy: &'a dyn AccuracyModel, - evidence: &'a dyn AccuracyEvidenceProvider, - ) -> Self; + /// This evidence with the default settings. + pub fn new(evidence: &'a dyn AccuracyEvidence) -> Self; - pub fn accuracy_check_inputs(&self) -> AccuracyCheckInputs<'a>; - pub fn with_accuracy(mut self, accuracy: &'a dyn AccuracyModel) -> Self; - pub fn with_evidence(mut self, evidence: &'a dyn AccuracyEvidenceProvider) -> Self; + /// Replaces the evidence. + pub fn with_evidence(mut self, evidence: &'a dyn AccuracyEvidence) -> Self; } -pub struct QueryPlan { - pub entry_index: usize, - pub root: Rc<OperatorNode>, -} /// The selected plan: one `PhysicalASAPDAG`, the only plan structure. Stays. pub struct PlanOutput { - pub plans: Vec<QueryPlan>, - pub scalar_roots: Vec<(usize, asap_types::ir::ScalarExpr)>, - pub scalar_plans: Vec<QueryPlan>, - pub selection: Option<Selection>, - pub tumbling_window_retention_ms: BTreeMap<PhysicalASAPNodeId, u64>, + pub plan: PhysicalASAPDAG, } impl PlanOutput { - pub fn new(plans: Vec<QueryPlan>) -> Self; + pub fn new(plan: PhysicalASAPDAG) -> Self; } /// Why a pass failed. Stays. pub enum OptimizeError { Input(#[from] OptimizationInputError), PerComputationCandidates(#[from] PerComputationCandidateError), Selection(#[from] SelectionError), /// The pass returned something the contract forbids: a pass defect. ContractViolation { pass: &'static str, detail: String }, + /// The pass returned an invalid DAG: a pass defect (P12). + InvalidPlan { + pass: &'static str, + error: PhysicalASAPDAGValidationError, + }, } /// Every stage's output for one workload. Stays. pub struct PlanningRun { - pub per_computation_candidates: Option<PerComputationLogicalMemoCandidates>, + /// Pass 1's memo. + pub pass1_memo: Option<Memo>, pub logical_asap_candidates: Option<LogicalASAPMemoCandidates>, pub physical_asap_candidates: Option<PhysicalASAPMemoCandidates>, - pub selection: Result<Selection, SelectionError>, - pub selected_physical_plan: Option<RealizedPlan>, - pub selected_plan: Option<Vec<QueryRoot>>, + /// Stage 3's plan and its report. + pub selection: Result<(PhysicalASAPDAG, Selection), SelectionError>, pub report: PlanningReport, } /// The installable plan of `plan` with the report of its cost (P13). pub fn installable_plan_of( - roots: &[QueryRoot], - selection: Option<&Selection>, - tumbling_window_retention_ms: &BTreeMap<PhysicalASAPNodeId, u64>, + plan: &PhysicalASAPDAG, + cost: Option<&PlanCost>, entries: &[QueryWorkloadEntry], ) -> Result<(InstallablePlan, Option<SelectedPlanReport>), InstallablePlanError>; /// The selected plan's cost, for reporting. Stays. pub struct SelectedPlanReport { pub cost_per_second: Option<f64>, pub predicted_usage: PredictedUsage, - pub search_report: SearchReport, - pub queries_accepted_without_guarantee: Vec<usize>, } /// Which costs one node's CPU came from (M8). -pub enum NodePriceSource { +pub enum NodeCostSource { Analytical, Measured, } /// How a cost model orders valid plans (M8). pub enum PlanRanking { - Price, + Cost, Latency, Memory, } /// The plan's cost. pub fn plan_cost( dag: &PhysicalASAPDAG, nodes: &NodeMap<'_>, - kept_chains: &HashSet<PhysicalASAPNodeId>, recurrence: &[QueryRecurrence], range_evaluations: &[Option<RangeEvaluation>], data: &DataWorkload, settings: &CostInputs, formula_scale: f64, ) -> Result<(PlanCost, CalibrationFit), (PhysicalASAPNodeId, AnalyticalCostError)>; /// SQL front end: no accuracy argument (measures carry none). pub async fn lower_sql( query: &str, catalog: &SqlCatalog, - accuracy: AccuracyTarget, ) -> Result<Rc<OperatorNode>, SqlError>; pub async fn lower_sql_dialect( query: &str, catalog: &SqlCatalog, dialect: SqlDialect, - accuracy: AccuracyTarget, ) -> Result<Rc<OperatorNode>, SqlError>; /// MetricsQL front end: no accuracy argument. pub fn lower_metricsql_query( query: &str, - accuracy: AccuracyTarget, sample_interval: Duration, ) -> Result<asap_types::ir::QueryRoot, MetricsqlError>;Also:
NodeCost::cost_source(wasprice_source);summary_type_name(wasfamily_name);PlanCost::cost_unitandCOST_UNITdeleted;InstallablePlanError::TumblingWindowRetentionOfUnknownChaindeleted;INSTALLABLE_PLAN_WIRE_VERSION14 (was 13). Tools: theasap_plannerdocument has noL1/P1candidate lists (they were the realized plan);stage3_plan_selectionholdsplanand the newSelectionfields;sketch_coverageloses--max-error; the fuzz planner's plan read and the peak-memory warning aretodo!()(PR 9, PR 6).File layout and renames (2026-11-10 review)
Pure moves and renames: no logic change, no alias for an old path. Public
asap_types::stages::Xpaths are unchanged; every user of a moved module path is updated, docs included.pub struct MemoQuery { - pub values_per_evaluation: Option<u64>, + pub number_of_values_per_query_evaluation: Option<u64>, } impl Memo { - pub fn set_input_requirements(&mut self, id: CandidateForMemoGroupId, input_requirements: Vec<LogicalRequirements>); + pub fn set_candidate_input_requirements(&mut self, id: CandidateForMemoGroupId, input_requirements: Vec<LogicalRequirements>); } -impl LogicalRequirements { - pub fn error_propagation(consumer: &Operator<MemoGroupId>, metric: AccuracyMetric) -> Option<ErrorPropagation>; -} -pub struct asap_types::stages::ErrorPropagation { .. } +// asap-accuracy, error_propagation.rs +pub fn asap_accuracy::error_propagation(consumer: &Operator<MemoGroupId>, metric: AccuracyMetric) -> Option<ErrorPropagation>; +pub struct asap_accuracy::ErrorPropagation { .. } -pub fn asap_types::stages::parameter_list(algorithm: SketchAlgorithm) -> &'static [SketchParams]; +pub fn asap_types::summary_type::parameter_list(algorithm: SketchAlgorithm) -> &'static [SketchParams];types/src/stages/candidates.rs(Memo,MemoQuery) andmemo.rs(root_groups,queries_rooted_at)types/src/stages/logical/memo/mod.rstypes/src/stages/memo.rs(MemoGroupId,MemoGroup,GroupProperties,ValueSign,MemoGroupAsInput) andcandidates.rs(derive_group_properties)types/src/stages/logical/group.rstypes/src/stages/candidates.rs(CandidateForMemoGroupId,CandidateForMemoGroup,CandidateExpression,OriginOfCandidateForMemoGroup,CandidateError,LogicalProperties(Error))types/src/stages/logical/candidate.rstypes/src/stages/candidates.rs(LogicalRequirements,RequiredAccuracy)types/src/stages/logical/requirements.rstypes/src/stages/logical_memo_candidates.rs(LogicalEdge)types/src/stages/logical/edge.rstypes/src/stages/logical_memo_candidates.rs(LogicalASAPMemoCandidates)types/src/stages/logical/memo_candidates.rstypes/src/stages/logical_memo_candidates.rs(PrunedLogicalCandidate,PruneCause,RootPruneReason)types/src/stages/pruning.rstypes/src/stages/physical/memo_candidates.rs(PhysicalCandidate(Id),producer_satisfies_physical_requirements;PhysicalEdge(Id))types/src/stages/physical/candidate.rs;edge.rstypes/src/physical/properties.rs(moduleasap_types::physicaldeleted)types/src/stages/physical/properties.rs(asap_types::stages::{PhysicalProperties, Lifetime, StorageMedium, PhysicalPropertiesError})types/src/stages/candidates.rs(parameter_list)types/src/summary_type/parameter_lists.rstypes/src/ir/schema/sketch.rstypes/src/summary_type/parameters.rs(θ types,EXACT_ACCUMULATOR_STATE_BYTES,KLL_MAX_K) andstatistic.rs(SketchStatistic,SummaryUpdate,SummaryInputExpr,WeightDomain,NonNegativeWeightProof,EntityIdentity);SketchAlgorithmre-exported insummary_type/mod.rsasap_types::ir::schema::X→asap_types::summary_type::X)types/src/ir/schema/summary_type_capability.rstypes/src/summary_type/capability.rstypes/src/ir/schema/schema_support.rstypes/src/ir/schema/series_identity.rstypes/src/ir/operator/operator_properties.rstypes/src/ir/operator/arguments.rstypes/src/ir/properties/{accuracy,guarantee}.rstypes/src/accuracy/{target,guarantee}.rs(asap_types::accuracy::X)types/src/ir/physical_export.rs,ir/materialized_view.rstypes/src/plan/physical_asap_dag.rs,plan/materialized_view.rstypes/src/workload/mod.rsworkload/query.rs,data.rs,planning.rs;mod.rsre-exports (paths unchanged)types/src/stages/candidates.rs(LogicalRequirements::error_propagation,ErrorPropagation)accuracy/src/error_propagation.rs(free fn)accuracy/src/estimators/accuracy/src/guarantee/accuracy/src/model.rsevidence.rs(AccuracyEvidence,NoMeasuredGuarantees) andrequirements.rs(producer_satisfies_logical_requirements)accuracy/src/lib.rs(target_limit,meets)accuracy/src/requirements.rs;lib.rsre-exports onlyaccuracy/src/evidence.rs(PropagationStats)accuracy/src/propagation_stats.rsevidence.rsdoes not collidecost/src/lib.rs(cost models,CostInputs,CalibrationFit, cost-source consts)cost/src/model.rscost/src/lib.rs(ResourceUsage),resources.rscost/src/resources/mod.rscost/src/usage.rs(node_usage,NodeUsage,ProducerOutput,node_map,summary_type_name) andlib.rs(NodeCost)cost/src/node/usage.rscost/src/{analytical,state_bytes,operator_statistics}.rscost/src/node/(asap_cost::node::analytical,::node::state_bytes)cost/src/usage.rs(plan_cost) andlib.rs(PlanCost,QueryLatency)cost/src/plan/cost.rscost/src/usage.rs(tumbling-window retention,query_reach,maintained_window_ms)cost/src/plan/retention.rscost/src/{execution_demand,ranking}.rscost/src/plan/(asap_cost::plan::execution_demand)logical-asap-optimization/src/pass1/logical_memo_candidates.rs(pass1_memo,Pass1Error)pass1.rslogical-asap-optimization/src/pass1/per_computation_candidates(_tests).rspass1/computation_targets(_tests).rslogical-asap-optimization/src/pass2/logical_memo_candidates.rs(generate_logical_asap_memo_candidatesand its two steps)pass2.rsRemoved items and their replacements
SketchKind,GroupingStrategy,HydraKind, ops'grouping,SummaryGroupingMismatchFieldDataType::Sketch(SketchAlgorithm)with theHydra*algorithmsFamilyCapability,of_per_instance_sketch,family_capability.rsSummaryTypeCapability::of(summary_type/capability.rs)PartialEq,with_failure_probability(×3), KMV/HLL sized εLogicalRequirements::new,RootPruneReason::BelowAccuracyFloorRequirement(earlier PR 0 rounds)required_accuracy: Option<RequiredAccuracy>,BelowRequiredAccuracyasap_types::stages::producer_satisfies_logical_requirements(producer, requirement)(earlier round)asap_accuracy::producer_satisfies_logical_requirements(memo, producer, consumer, input, evidence)AccuracyModel,BuiltinAccuracyModel,IgnoreAccuracyGuarantees,AccuracyEvidenceProvider,NoAccuracyEvidence,OperandDomain,AccuracyCheckInputs,PlanningModels::{accuracy, accuracy_check_inputs, with_accuracy}AccuracyEvidence(Pass 2); ignore mode = no targets before Pass 2local_guaranteetheoretical_guaranteepub struct AccuracyEvidence {}(earlier round)trait AccuracyEvidence+NoMeasuredGuaranteesMemo::{query_roots, query_accuracy_targets, query_values_per_evaluation}Memo::queries: Vec<MemoQuery>satisfies,metric_meets,scope_meets,native_target,AccuracyScope::coverstarget_limit; the metric and scope rules: no replacement (α^log compares one metric at δ_r, PR 4)SupportedSummary::familySupportedSummary::summary_typewithout_summaries_no_query_can_use,output_can_meet_target,sizing_target,accuracy_budget,DEFAULT_DELTA,PerComputationCandidateError::InvalidAccuracy)AggIntentmeasures'accuracy; front ends' accuracy parameterMemoQuery::accuracy_target)SourceFacts::values_non_negativeSourceFacts::column_signs(P7)ExecutionContext::Evaluation { recurrence, range_evaluation },RefreshWindowId(earlier rounds)Evaluation { grid: EvaluationGrid },IngestionPipeline(RefreshWindow)RealizedPlan,PhysicalWorkloadPlan,DagOfSelectedCandidates,SelectedEdge,SelectedNodeId,AssignmentRealizer,Stage2AssignmentRealizer,PhysicalCandidateError,SelectionError::Realization,ErrorSelectingPlan::RealizerRejectedPhysicalASAPDAG;selected_physical_candidateSearchReport,SearchStatus,InexactObjective,relative_gap,ObjectiveDiffersFromPlanCost,SelectedPlanFailedCheck,Selection::{selected_dag, nodes_with_proven_non_negative_weights, cost, search_report},PlanCost::cost_unit,COST_UNIT,AcceptedAccuracy::{target_metric, accepted_regardless_of_guarantee, guarantee_check_rejection},RejectionCause::CountMinWeightsNotProvenNonNegativeSelection::{milp_*};plan_cost(&plan); (K) has every bound;PruneReason::CountMinWeightsNotProvenNonNegativewith_confirmed_weights(_at),confirmed_weights,WeightDomain::confirmedcolumn_sign, PR 4–5)PlanOutput::{plans, scalar_roots, scalar_plans, selection, tumbling_window_retention_ms},QueryPlan,PlanningRun::{selected_plan, selected_physical_plan},PlanningReport::search_report,InstallablePlanError::TumblingWindowRetentionOfUnknownChainPlanOutput { plan },PlanningRun::selection; retention is on the nodesScanWindow,union,scan_window(s),view_window(s),time_range_window,offset_below(types);materialized_tumbling_window_chains,trailing_window,widest_window_read_ms,node_usage'sscan_window,plan_cost's chain set (cost)retention_ms(asap-costa query-timeScan's read and retention aretodo!()(PR 7);set_retention,raw_data_retentionandrefresh_windowsaretodo!()(PR 6)NodePriceSource,price_source,PlanRanking::Price,family_nameNodeCostSource,cost_source,PlanRanking::Cost,summary_type_namepass1/composition.rs(compose_logical_candidateand its helpers),test_support::{cms_summary, weighted, estimate_over},planning::{explicit_local_candidates, explicit_summary_candidate}, the PromQL tests'logical_candidates/logical_plan/local_computation_candidates, the executor tests'computation_candidates(P11)ShownLogicalCandidate,logical_candidates(),physical_candidates(),candidate_labels,physical_labeland its helpers,usage_json,sketch_coverage --max-errorplanUsage, end to end (the bodies are
todo!()until the PRs named, so this is the call flow, not a run):Algorithm changes
None: the bodies of the new interfaces are
todo!(). One behavior is removed: Pass 1 no longer prunes summaries no query could use for accuracy (without_summaries_no_query_can_use); Pass 2's dead-candidate elimination (PR 4) replaces it. The executor's window derivation is unchanged code in a new place (P10).Decisions and open questions
Needs reviewer decision: None.
Decided (all approved; nothing pending):
MemoQuery::values_per_evaluation→number_of_values_per_query_evaluation; R2Memo::set_input_requirements→set_candidate_input_requirements; R3Memo/MemoQuerylive in the memo module. L1types/src/stages/is organized by scope, logical vs physical first, then memo → group → candidate → candidate input → edge → stage output, withpruning.rsfor every stage's removed candidates. L2parameter_listbeside the θ types. L3 error propagation inasap-accuracyas the free functionerror_propagation. L4HowToComputeAggregateMeasureleavesasap-typesonce only Pass 1 uses it. L5 Pass 1's entry in its root module,computation_targets.rsfor choosing targets. L6 Pass 2's entry in its root module. E1–E3asap-types,asap-accuracyandasap-costorganized by scope the same way (summary types, accuracy, plan, workload split; guarantee/evidence/requirements; model, resources, node, plan). Pure moves and renames; the move table is under Interfaces.ComputationTargetandFusedComputation, still intypes/src/stages/per_computation_logical_memo_candidates.rs, holdHowToComputeAggregateMeasure, and devtools and the SQL front end's tests read it, so the file stays until PR 3 empties it.error_propagation(consumer, metric); PR 4 adds the memo argument.add_aggregate_candidatesyet, so all of Pass 1's target code iscomputation_targets.rs; PR 3 addscandidates.rs. The#[cfg(any(test, feature = "test-support"))]that sat on the oldmod logical_memo_candidatesis gone with the file (the crate root re-exported its items unconditionally, socargo test -p asap-logical-asap-optimizationwithout that feature did not build before; it does now).asap_types::physical::ExecutionTimingwas a re-export ofir::properties::ExecutionTiming; its users now nameir::properties::ExecutionTiming.accuracy/src/evidence.rsheldPropagationStats(deleted in PR 4), so it is renamedpropagation_stats.rsand the newevidence.rsholdsAccuracyEvidence. The modules that glob-importedlib.rs's imports (composition.rs,budget.rs,guarantee/mod.rs,propagation_stats.rs) now import what they use.summary_type_namestays withnode_usageincost/src/node/usage.rs, its only reader.cost_sourceispub(crate)there becauseplan_costreads it too;derive_group_propertiesispub(super)ingroup.rsbecause the memo calls it;MAX_RANGE_EVALUATION_STEPSandvalidate_ratearepub(super)inworkload/because the query and data files share them.TimestampMsandDurationMsare inworkload/query.rs, their main user;workload/data.rsimportsDurationMs.mod tests) in the scope file of what they test;workload/mod.rs's tests are split overquery.rs,data.rsandplanning.rs.FieldDataTypevariant, algorithm = one structure (SketchAlgorithm, Hydra included), summary type = both (oneFieldDataTypevalue), θ = sizes. Accuracy is a requirement on a readout's input, not a θ floor: one rule for every algorithm; θ records no error. The accuracy source is decided up front (measured guarantee, else the formula), so nothing is checked after Stage 3:AccuracyModel, the post-solve check and the "accept regardless" mode go. One plan structure: Stage 3 builds thePhysicalASAPDAGdirectly; the selected-candidate DAG, the realizer and the plan wrappers go. N1: measures carry no accuracy. M8: cost names. R4:Serializeon the prune and property types. R10: the label tooling deleted.AccuracyEvidenceis a trait with one method, its bound at δ;NoMeasuredGuaranteesis the default.AccuracyGuaranteewhosefailure_probabilityis the δ asked for. Rejected: a new type.producer_satisfies_logical_requirementsinasap-accuracy(it needs the guarantee;asap-typescannot depend onasap-accuracy).Vec<MemoQuery>, replacingquery_rootsand the two parallel vectors. (P17):MemoQuery::accuracy_target: Option<AccuracyTarget>;Nonecarriesignore_accuracy_guaranteesand "no target reaches it". Rejected: a non-optionalAccuracyTarget.memo_of_queries(roots, accuracy_targets, data): Stage 0 computesseries_read,values_per_resultkept for it) and reads the declared signs fromdata.Memostores the declared signs (Memo::new(declared_column_signs), private field; PR 2), because rules add groups too (a rollup's finest commonScan).column_signs; the workload JSON in other repositories changes in one PR.SummaryTypeCapability::shares_one_state_across_groups, one Hydra list read bymerges_groupsand the executor's kernel check (it was duplicated); the doc's Hydra capability (subpopulation readout) comes when Hydra is in scope.PhysicalASAPDAG::query_roots()(test support) and integration-tests'plan_cost_per_second: tests that inspectedselected_planorSelection::costread the plan instead.ScanWindowexecutor-private until PR 6.pass1/composition.rsdeleted in this PR, with its fixtures and the 74 tests that use them. Rejected: keeping it behindtest-supportuntil PR 3 (no interim code).OptimizeError::InvalidPlan { pass, error }: the pass contract validates the returned DAG and that its roots and scalar roots answer every entry.installable_plan_of(plan, cost: Option<&PlanCost>, entries);SelectedPlanReport { cost_per_second, predicted_usage }(the report is the plan's cost, not the selection's).summary_type(alsoSupportedSummary, JSONsummary_type; the viewer reads it). (P15):WeightDomaindeleted in PR 5, Count-Min readscolumn_sign. (P16):satisfiesdeleted.delivers_on(&self, candidates: &PhysicalASAPMemoCandidates, context)so aMaterialized(v)context can read v;GroupProperties::depends_on_evaluation_timeandLogicalASAPMemoCandidates::evaluation_grid_of_group. Example: X =sum_over_time(m[5m])read every 60 s and every 120 s has grid 60 s @ 0, so a stored X delivers on 60 s and 120 s grids, not on 30 s.family_of_operator/summary_type_of_operatorandsketch_algorithm_of(PR 1 adds them; withSketch(SketchAlgorithm)the latter is a match);floor_for_cap,strongest,weakest,dominates,combine(PR 1/PR 4);ExportedNodeAssignment,physical_asap_dag_with_assignments(PR 6);AccuracyCheckInputs::query_roots(the struct is deleted).Verification
cargo test -p <crate> --all-features --no-fail-fastat the head;cargo clippy --workspace --all-targets --all-features -- -D warningsandcargo clippy --workspace -- -D warningsclean (no new#[allow];derive_group_propertiescarries#[allow(unreachable_code)]until PR 2 derivescolumn_sign);cargo fmt --checkclean;crate_graphpasses (no stage crate depends on another). Every failure except the stale fixture panics at atodo!(); the notes name it and the PR that fills it in. Newly failing vsmain: not measured by test name; main has none of thesetodo!()s, so the failures below are expected until their PRs.retention_msisassertion failed: output.status.success(): 2retention_ms(PR 6): 3; stale fixturematerialized_views_equal_the_stored_outputs_main_listed(old wire format; PR 9 re-baselines it): 1By test name against earlier heads of this PR:
61541f748(before the 2026-11-10 file layout),asap-types,asap-accuracy,asap-costandasap-logical-asap-optimization(featuretest-support): 269 passed / 27 failed / 0 ignored on both heads; the same tests by name (only module paths and the workload doctests' file changed);cargo check --workspace --testswith no warnings,cargo clippy --workspace --all-targets -- -D warningsandcargo fmt --checkclean;cargo docwith-D warningsreports the same pre-existing link errors as before. The other crates' tests were not rerun for this move (they only change import paths and compile).be6ea1d6a(before P11): the only differences are the 74 tests deleted withpass1/composition.rs(70 failed, 3 passed, 1 ignored there); no other test changed result.7708f3668: no test that passed fails now. Differences: 8 deleted tests and the addedtarget_limit_admits_only_floating_point_noise(passes). Passed 1088 → 1081, failed 287 → 287.New tests:
accuracytests::target_limit_admits_only_floating_point_noise: the limit admits only floating-point noise above the target.contract_rejects_a_scalar_root_keyed_beyond_the_entries: the pass contract rejects a scalar root keyed beyond the entries.Deleted tests (with why):
accuracy/src/guarantee/mod.rs(wasestimators/mod.rs)enlarging_meets_the_failure_probability_at_no_larger_error,a_distinct_count_univmon_grows_its_heap,local_guarantee_needs_a_statistic_the_family_answerslocal_guaranteedeletedaccuracy/src/guarantee/kll.rssizing_meets_a_failure_probability_below_one_percent,sizing_below_one_percent_names_a_distinct_contract,an_invalid_failure_probability_gives_no_guaranteefailure_probabilitydeleted; PR 4 evaluates the guarantee at δ_raccuracy/src/guarantee/cardinality.rskmv_sized_for_a_failure_probability_meets_it,kmv_k_follows_the_failure_probabilitytypes/src/ir/schema/sketch.rs(nowtypes/src/summary_type/)sketch_kind_keeps_a_valid_algorithm_and_params_pair,sketch_kind_rejects_params_from_another_algorithm,grouping_strategy_default_is_per_subpopulation_instanceSketchKind,GroupingStrategydeletedtypes/tests/physical_export.rsa_scan_window_is_the_union_of_its_readers_windows,a_view_window_is_the_union_of_the_windows_below_it,a_scan_read_under_an_at_anchor_has_an_unbounded_windowlogical-asap-optimization/src/pass1/per_computation_candidates.rs(nowpass1/computation_targets.rs)count_min_estimate_over_raw_data_samples_is_gated_on_the_metriclocal_guaranteewithout θ; replaced bycolumn_sign(PR 4)planner/src/pass.rscontract_rejects_a_scalar_reference_without_its_plan,contract_checks_scalar_plan_order_entry_and_countscalar_plansdeleteddevtools/src/candidate_labels.rsconnected_labels_describe_selected_states,connected_labels_name_actual_shared_state,connected_labels_name_exact_resultsfrontend-promql/tests/promql_lowering.rs,frontend-sql/tests/sql_lowering.rsaccuracy_target_flows_into_quantile_intent,median_threads_the_accuracy_targetintegration-tests/tests/promql_numeric_regressions.rslogical_candidates_fails_on_a_candidate_that_does_not_composeShownLogicalCandidatedeletedintegration-tests/tests/joint_search_equivalence.rscustom_accuracy_policy_is_respectedAccuracyModeldeletedaccuracy/src/lib.rssatisfies_is_fail_closed_on_unknowns_and_exact,satisfies_requires_the_targets_metric,a_target_without_delta_ignores_the_failure_probability,per_value_guarantees_meet_whole_result_targets_over_g_values,a_record_share_target_is_met_over_one_over_share_groups,scope_matters_only_with_a_failure_probability,a_target_without_a_metric_accepts_any_metricsatisfiesdeletedtypes/src/ir/properties/accuracy.rs(nowtypes/src/accuracy/target.rs)a_wider_scope_covers_a_narrower_oneAccuracyScope::coversdeletedRenamed, with the accuracy assertion dropped:
count_maps_to_count(wascount_maps_to_count_and_inherits_accuracy),distinct_over_time_lowers_to_cardinality_over_nested_windows,asap_input_is_rejected(its invalid-accuracy half deleted withInvalidAccuracy). Tests that readPlanOutput::plans,selected_planorSelection::costnow readplan.query_roots()andplan_cost_per_second(P9). The estimator tests that calledsatisfies(CMS, Count Sketch, HLL, KLL, UnivMon, composition) check the evaluated error and δ againsttarget_limitthrough a test-onlymeets, with their metric asserted beside it.P11: 74 tests deleted, all composing whole-workload candidates through
pass1/composition.rs(names in this comment):frontend-metricsql/tests/external_corpus.rs1,frontend-promql/tests/count_planning.rs4,.../observability/metrics_observability.rs2,.../observability/promql_corpus.rs1,frontend-promql/tests/univmon_candidates.rs1,integration-tests/tests/exact_composition.rs1,per_computation_candidates_sql.rs4,promql_numeric_regressions.rs7,sketch_rollup.rs3,sql_to_post_asap.rs7,stage1_logical_asap_optimization.rs13,pass1/per_computation_candidates.rs19,pass1/per_computation_candidates_tests.rs10,pass1/realization.rs1. Files left without a test are deleted with their registrations:frontend-promql/tests/univmon_candidates.rs,frontend-promql/tests/observability/metrics_observability.rs(test target),integration-tests/tests/{exact_composition, promql_numeric_regressions, sketch_rollup, stage1_logical_asap_optimization}.rs.End-to-end evidence: not applicable (planning panics at Stage 0 until PR 2; no snapshot or plan comparison applies).
Self-review (over-abstraction, duplication, dead code):
PhysicalASAPDAG::validate'sScalarRootPosition(the contract counts the roots, then validates); the Hydra list was inmerges_groupsand the executor's kernel check (oneshares_one_state_across_groups, P8);of_per_instance_sketchduplicatedof; the satisfaction tolerance formula lives once, intarget_limit.InvalidAccuracyand its mapping;computation_candidates_for_intent's never-failingResult;sources_read; the weight-proof application; the chain-window helpers;payloads_by_id,offset_below;TumblingWindowRetentionOfUnknownChain;OperandDomain;DEFAULT_DELTA; the label helpers (for_queries,query_names,duration_name,build_label,state_label,dag_readers) andusage_json;parse_max_error;metric_meets,scope_meets,native_target,AccuracyScope::covers, the staticNO_ACCURACY_EVIDENCE; test helperswindow_over,exported_with_scan,series_scan,approximate,error_and_delta,delta_and_error; the emptymod stream_norms {}(Pass 1 tests) and two emptymod tests {}(devtoolsplanning_stages_text.rs,candidate_labels.rs).plan_cost's andeach_node_usage's chain set,each_node_usage'sroot_scan_lookback_ms,node_usage'sscan_window, devtools'lower_promql_with_sample_interval's accuracy, test helpers'accuracy.PerComputationCandidates::{roots, aggregate}behindtest-support.target_limithas no production caller until PR 4 (α^log) and PR 8 ((K));root_groupsnone until PR 5–6;AccuracyGuarantee::over_scopenone (PR 4/8 state a whole-result δ);NoMeasuredGuaranteesis the doc's default evidence;series_read,values_per_resultwait for Stage 0'sdepends_on_evaluation_timeis a second unreachabletodo!()inderive_group_properties(PR 2);RejectionCause,RejectionandErrorSelectingPlan::NoValidCandidateare never constructed (PR 6 decides); the#[allow(dead_code)]markers from earlier rounds (θ-based estimators and sizing,milp/model.rs,valid_matrix,GroupStates::Keyed) stay until PRs 4–8; the front-end test helperlower_promql(query, accuracy)still takes a target (it fills the workload entry, not the measures).AccuracyGuarantee(P18).Follow-ups
todo!()names its PR: Stage 0 and group properties (PR 2, feat(stage0, types): memo hash-consing, group properties (column_sign, depends_on_evaluation_time, aggregate_coverage), @ end()/@ start() above their subtree (#1207 PR 2) #1230), Pass 1 over the memo (PR 3, refactor(stage1-pass1): per-computation candidates over memo groups (#1207 PR 3) #1232), α^log andtheoretical_guarantee(PR 4, refactor(stage1-pass2): rollup from the finest common group, readout requirements, dead-candidate elimination, chain groups (#1207 PR 4) #1234), Stage 2 and the Count-Min rule (PR 5, refactor(stage2): physical expansion (decision-tree levels 3–4), physical edges, pruned alternatives; Count-Min weights via column_sign (#1207 PR 5) #1235), Stage 3, θ in the executor and retention (PR 6, refactor(stage3): baseline selection MILP and its PhysicalASAPDAG; executor θ, native chains and a time-indexed store (#1207 PR 6) #1236), contexts and scan reads (PR 7, refactor(stage3): select over execution contexts: x_{κ,v}, y_{κ,u,c,i}, h_v and constraint (R) (#1207 PR 7) #1237), (K) (PR 8, refactor(stage3): constraint (K) per execution and metric; sign-conditioned accuracy rules (#1207 PR 8) #1238), tools and the stale fixture (PR 9, refactor: tools and snapshots over the #1207 memo, edges and contexts (#1207 PR 9) #1239).