Skip to content

refactor(types): properties and requirements from #1207; chains as time-indexed state (#1207 PR 1) - #1227

Draft
zzylol wants to merge 1 commit into
refactor/1207-crates-per-stagefrom
refactor/1207-properties
Draft

zzylol wants to merge 1 commit into
refactor/1207-crates-per-stagefrom
refactor/1207-properties

Conversation

@zzylol

@zzylol zzylol commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

Merge unit. This is PR 1 of #1207's merge unit (PRs 0–9). It is stacked on PR 0b (#1229, refactor/1207-crates-per-stage, head 058ea4234), which is stacked on PR 0 (#1226, head 2ed6ec0b8). The PRs merge into main together, after PR 9. This PR fills in the section 2 functions that PR 0 left as todo!(): the logical properties and the predefined θ lists, the physical properties, α^phys and delivers_on over the execution contexts, and chains as time-indexed state. Planning still panics at the first todo!() of a later stage (see "Test status").

Why

Every later stage reads the property checks of the concepts doc, section 2:

  • Pass 1 (PR 3) adds one candidate per listed θ (parameter_list), checked by LogicalProperties::new.
  • Pass 2 (PR 4) adds chain groups (rule 1) whose merges must land in the original state group, and gives readouts their required accuracy (producer_satisfies_logical_requirements, in asap-accuracy, PR 4).
  • Stage 2 (PR 5) builds physical alternatives (PhysicalProperties::new) and edges with α^phys (producer_satisfies_physical_requirements).
  • Stage 3 (PRs 6–7) checks per execution context whether a producer can be read there (delivers_on).

PR 0 defined these signatures with todo!() bodies. On 2026-11-08 PR 0 changed them: θ is structure only (no sized-for fields, derived equality), a summary type is FieldDataType::Sketch(SketchAlgorithm) (no grouping strategy), the accuracy a readout needs is RequiredAccuracy instead of a parameter floor, and execution contexts are evaluation grids. This PR implements the checks against that design.

What

  • Logical properties. LogicalProperties::new(expression, parameters) reads the summary type of a build (summary_type_of_operator) and, for FieldDataType::Sketch(algorithm), requires θ from parameter_list(algorithm). It rejects a sketch build, a chain included, without θ (SketchBuildWithoutParameters), θ on an operator that builds no sketch (ParametersOnExactOperator), and θ not in the list (ParametersNotInList, which also covers another algorithm's θ).

  • Predefined θ lists (structures only). parameter_list(algorithm):

    Algorithm Entries List
    KLL 7 k = 26, 52, 132, 269, 547, 1404, 2863 (no δ variants: KLL's δ is not a parameter)
    DDSketch 7 alpha = 0.1 … 0.001
    HLL 4 precision 13, 15, 17, 18
    KMV 4 k = 1118, 4323, 26 656, 106 263 (ε down to 0.01)
    Count-Min 28 widths 28, 55, 136, 272, 544, 1360, 2719, each with depths 5, 7, 10, 12 (δ = e^−d ≤ 1e-2, 1e-3, 1e-4, 1e-5)
    Count Sketch 28 widths 300 … 3 000 000, each with depths 47, 81, 117, 155 (its median-of-rows δ = P(Binomial(d, 1/3) ≥ (d+1)/2) ≤ 1e-2, 1e-3, 1e-4, 1e-5; approved 2026-11-09)
    CMS / Count Sketch with heap 280 each each width × depth with heap sizes 10, 20, 50, …, 10 000
    UnivMon 40 7 L2 shapes, 4 distinct-count shapes, the 28 combinations, and the baseline (no distinct_failure_probability)
    Hydra and other algorithms 0 no error model yet (Planner: error models and parameter lists for Hydra (and other unsized families), so Pass 1 can offer them #1228), so no build of them is a valid candidate

    The widths, ks, precisions and heap sizes are today's sizing over ε = 0.1 … 0.001 (smallest first); a test in asap-accuracy keeps them equal to it. That sizing is test-only.

  • No parameter floors. This PR adds no floor_for_cap, strongest, weakest, dominates or combine: a readout's input carries a RequiredAccuracy, checked against the producer's guarantee (PR 4). The previous version of this PR had them; they are deleted.

  • Physical properties. PhysicalProperties::new rejects the one invalid combination, (IngestionTime, OneEvaluation). producer_satisfies_physical_requirements(producer, consumer_timing) is the timing × lifetime table.

  • delivers_on(&self, candidates: &PhysicalASAPMemoCandidates, context) over execution contexts (2026-11-08, PR 7 J3 and K3; the stored-result rows 2026-11-09):

    Producer Evaluation { grid } IngestionPipeline(RefreshWindow) Materialized(v)
    ℓ = None true true true
    ℓ = OneEvaluation true false false
    chain of width w, ℓ = AcrossEvaluations w divides period_ms and phase_ms w divides width_ms and phase_ms todo!() (PR 7: v's own schedule)
    any other group, ℓ = AcrossEvaluations, group not depends_on_evaluation_time true true true
    any other group, ℓ = AcrossEvaluations, time-dependent, grid g = evaluation_grid_of_group[group] g's period divides period_ms and phase_ms ≡ g's phase (mod g's period) the same with width_ms todo!() (PR 7)
    the same without a known grid (None) false false todo!() (PR 7)

    Example (doc, 2026-11-09): X = sum_over_time(m[5m]) read every 60 s and every 120 s has grid 60 s @ 0; a stored X delivers on 60 s @ 0, 120 s @ 0 and 120 s @ 60 s, not on 30 s @ 0 or 60 s @ 15 s.

  • Chains as time-indexed state.

    • One schema for every SummaryTumblingWindowChain: (window_end, keys…, state). window_end at column 0 is the time index, a computed column; the build's own time column is dropped; the unique key is (window_end, keys).
    • TimeRange and TimeShift accept a time-indexed state and keep its schema; over any other state they are rejected, and a TimeRange over a chain must be a range (Instant is a validation error).
    • A SummaryMerge over a time-indexed state reads exactly one TimeRange over a chain; its schema is the chain's build over that range, so it can join the original state group.
    • PR 0's two todo!()s are filled in: FinalizeExactAccumulator and a rollup over merged windows derive as over the chain's build over that range. selected_from and summary_build see through the TimeRange/TimeShift over a chain.
  • Evaluation grid. QueryRecurrence::evaluation_grid_ms(range_evaluation) (moved from QueryWorkloadEntry) is None for a FixedInterval without a phase. Pass 2's chain widths and Stage 3's evaluation grids come from it.

  • Accuracy crate. The sizing functions are #[cfg(test)]; sizing::default_size_params, test_support::default_size_params and test_support::cms_width are deleted (no caller). propagation.rs reads merged windows through summary_build (PR 0's merged_chain is gone).

Decisions

Item Decision Status
θ is structure only lists without sized-for fields; derived equality approved 2026-11-08
Count-Min depths 5, 7, 10, 12 per width (δ grid 1e-2 … 1e-5) approved 2026-11-08
Count Sketch depths (P1) 47, 81, 117, 155 per width (same δ grid, median-of-rows model) approved 2026-11-09
UnivMon list 40 entries: 7 L2, 4 distinct-count, 28 combined, baseline approved 2026-11-08
No floors no floor_for_cap/strongest/weakest/dominates/combine; RequiredAccuracy instead approved 2026-11-08
Summary type FieldDataType::Sketch(SketchAlgorithm); summary_type_of_operator (was family_of_operator); sketch_algorithm_of deleted approved 2026-11-08
producer_satisfies_physical_requirements(producer, consumer_timing) consumer's timing only approved 2026-11-08 (PR 7 J3)
OneEvaluation in delivers_on only in Evaluation contexts approved 2026-11-08 (PR 7 J3 b)
delivers_on for IngestionPipeline(RefreshWindow) / Materialized(v) implemented; Materialized(v) stays todo!() for PR 7 approved 2026-11-08 (PR 7 K3)
delivers_on(&PhysicalASAPMemoCandidates, context) (P2) the signature is PR 0's; this PR reads the memo through it approved 2026-11-09
GroupProperties::depends_on_evaluation_time, LogicalASAPMemoCandidates::evaluation_grid_of_group (P3) types in PR 0 (derived in PR 2, filled in PR 4); delivers_on reads them here approved 2026-11-09
One chain schema; instant TimeRange over a chain rejected as above approved 2026-11-08
SummaryMerge over a time-indexed state reads exactly one TimeRange approved 2026-11-08
selected_from/summary_build see through TimeRange/TimeShift no merged-chain helper approved 2026-11-08
evaluation_grid_ms None for FixedInterval without a phase; the QueryWorkloadEntry wrapper deleted approved 2026-11-07 / 2026-11-08
A sketch build without θ; θ outside the list rejected approved 2026-11-06
Test-only sizing in asap-accuracy kept here; PR 4 deletes it with a per-entry guarantee test approved 2026-11-08

Pending approval

None: P1–P3 were approved on 2026-11-09 (see "Decisions").

Deleted

Deleted Replaced by
this PR's earlier strongest, weakest, dominates, combine and their tests (strongest_and_weakest_combine_one_family_per_parameter, a_listed_univmon_dominates_an_l2_and_a_distinct_floor, hydra_dominance_compares_every_size_of_one_kind) none: no floors (2026-11-08)
this PR's earlier producer_satisfies_logical_requirements(properties, requirement) (θ dominance) and its test, LogicalRequirements::new and logical_requirement_new_accepts_any_floor asap_accuracy::producer_satisfies_logical_requirements(memo, producer, consumer, input_index, evidence) (PR 0 interface, PR 4 body); LogicalRequirements { required_accuracy }
a_configuration_satisfying_a_listed_floor_is_no_less_accurate (accuracy) none: it tested floor dominance
this PR's earlier family_of_operator and sketch_algorithm_of summary_type_of_operator; FieldDataType::Sketch(algorithm) holds the algorithm
KLL, HLL and KMV list entries' sized-for fields; UnivMon's distinct_failure_probability none: θ is structure only (PR 0 deleted the fields)
delivers_on's reading of QueryRecurrence/RangeEvaluation from the context the context's EvaluationGrid / RefreshWindow
pub fn merged_chain (PR 0's, tumbling_window_chain.rs) summary_build / selected_from through the window selection
QueryWorkloadEntry::evaluation_grid_ms QueryRecurrence::evaluation_grid_ms(range_evaluation)
sizing::default_size_params, test_support::default_size_params, test_support::cms_width none (no caller; the lists replace sizing)
PR 0's new_rejects_one_evaluation_at_ingestion, new_accepts_each_valid_pair new_over_every_timing_and_lifetime

How

  • Lists. const arrays built by two const fns: with_depths(widths, depths, shape) crosses 7 widths with the 4 depths (CMS_DEPTHS or COUNT_SKETCH_DEPTHS) (as Cms or CountSketch), with_heap_sizes(shapes) crosses those 28 with the 10 heap sizes; univmon_parameters() builds the 40 UnivMon shapes. The match in parameter_list lists every SketchAlgorithm (no _), so a new sketchlib algorithm fails to compile until it gets a list.

  • delivers_on matches ℓ; for AcrossEvaluations it reads the candidate's operator from candidates.logical_candidates.memo. A chain needs its tumbling_window_width_ms w to divide the context's (period, phase): the grid's, or the refresh window's (width, phase), so w divides every time phase + k·period. Any other result delivers everywhere when its group's depends_on_evaluation_time is false; else every context time must lie on evaluation_grid_of_group[group]: its period divides the context's and the phases agree modulo it.

  • Chain schema. chain_schema derives the build's schema, removes its time column if it has one, inserts a computed window_end (the input time column's type) at 0 as the time index, and sets the unique key to (window_end, plain columns). A merge over a window selection derives summary_agg_schema(chain input, summary type, reduction).

  • producer_satisfies_physical_requirements:

    producer consumer QueryTime consumer IngestionTime
    QT, None / OneEvaluation / AcrossEvaluations ✓ ✗
    IT, None ✗ ✓
    IT, AcrossEvaluations ✓ ✓

Key code interfaces

Bodies are elided as ;.

crates/types/src/stages/candidates.rs

impl Memo {
    /// The candidate `id` (pulled forward from PR 2; `delivers_on` reads a chain's width through it).
    pub fn candidate(&self, id: CandidateForMemoGroupId) -> &CandidateForMemoGroup; // body filled in
}

/// p^log = θ_v; the summary type and a chain's width are operator arguments. // unchanged type
pub struct LogicalProperties {
    /// θ_v from the algorithm's list; None for an exact operator. // unchanged
    parameters: Option<SketchParams>,
}

impl LogicalProperties {
    /// Rejects θ missing on a sketch build (a chain included), present on an operator that
    /// builds no sketch, or not in parameter_list(algorithm).
    pub fn new(expression: &CandidateExpression, parameters: Option<SketchParams>)
        -> Result<Self, LogicalPropertiesError>; // body filled in
}

/// The algorithm's predefined θ list, structures only, smallest first; empty for an algorithm
/// without an error model.
pub fn parameter_list(algorithm: SketchAlgorithm) -> &'static [SketchParams]; // body filled in

crates/types/src/ir/operator/asap.rs, tumbling_window_chain.rs

/// The summary type a build operator (SummaryAgg or SummaryTumblingWindowChain) builds; None otherwise.
pub fn summary_type_of_operator<I>(operator: &Operator<I>) -> Option<&FieldDataType>; // new

/// The build a state carries: a build, the chain under the TimeRange/TimeShifts that select its
/// windows, or the first input's build under SummaryMerges. // was: no TimeRange/TimeShift case
pub fn summary_build<I: OperatorInput>(state: &I) -> Option<ASAPOp<I>>;

/// The states a node keeps whole: a Filter by plain columns, or a TimeRange/TimeShift over a
/// time-indexed state. // was: Filter only
pub fn selected_from<I: OperatorInput>(node: &I) -> Option<I>;

/// The chain a SummaryMerge kept its groups over. // removed (replaced by summary_build)
pub fn merged_chain<I: OperatorInput>(state: &I) -> Option<I>;

crates/types/src/workload/mod.rs

impl QueryRecurrence {
    /// The epoch-anchored grid every evaluation falls on; None when the times are not known,
    /// including FixedInterval without a phase.
    pub fn evaluation_grid_ms(&self, range_evaluation: Option<RangeEvaluation>) -> Option<u64>; // moved from QueryWorkloadEntry
}

impl QueryWorkloadEntry {
    pub fn evaluation_grid_ms(&self) -> Option<u64>; // removed
}

crates/types/src/stages/physical/memo_candidates.rs, crates/types/src/physical/properties.rs

impl PhysicalCandidate {
    /// Whether a consumer running in `context` can read this producer: None everywhere,
    /// OneEvaluation only in Evaluation contexts, an AcrossEvaluations chain when its width
    /// divides the context's period and phase, any other stored result on its group's grid.
    pub fn delivers_on(&self, candidates: &PhysicalASAPMemoCandidates, context: &ExecutionContext) -> bool; // body filled in (signature PR 0's, 2026-11-09)
}

/// α^phys: the timing × lifetime table only.
pub fn producer_satisfies_physical_requirements(
    producer: &PhysicalCandidate,
    consumer_timing: ExecutionTiming,
) -> bool; // body filled in

impl PhysicalProperties {
    /// (τ, ℓ), unless (IngestionTime, OneEvaluation).
    pub fn new(timing: ExecutionTiming, lifetime: Lifetime) -> Result<Self, PhysicalPropertiesError>; // body filled in
}

crates/accuracy/src/sizing.rs, crates/accuracy/src/test_support.rs

pub(crate) fn default_size_params(kind: SketchAlgorithm, intent: &AggIntent, eps: f64, delta: f64) -> SketchParams; // removed
pub fn default_size_params(kind: SketchAlgorithm, intent: &AggIntent, eps: f64, delta: f64) -> SketchParams; // removed
pub fn cms_width(eps: f64) -> u32; // removed

Usage

No workload reaches these functions end to end yet: Stage 0 (PR 2), Pass 1 (PR 3), Pass 2 (PR 4) and Stage 2 (PR 5) are still todo!(). The flow below is the one those PRs run for the doc's section 5 example (Q_A = quantile_over_time(0.99, latency[1m]) every 10 s at phase 0, declared with FixedIntervalAt), using the calls this PR implements; the unit tests named in "Verification" check each step at the linked commit.

// Pass 1 (PR 3): one KLL build per listed θ for G3 = SummaryAgg[KLL](TimeRange(1m, G1)).
let kll_list = parameter_list(SketchAlgorithm::Kll); // [k=26, 52, 132, 269, 547, 1404, 2863]
// Pass 2 rule 1 (PR 4): Gw = SummaryTumblingWindowChain[KLL, w = 10 s](G1), output (window_end, state).
let chain_expression = CandidateExpression { operator: Operator::ASAP(ASAPOp::SummaryTumblingWindowChain {
    child: g1, summary_type: FieldDataType::Sketch(SketchAlgorithm::Kll),
    input: SummaryUpdate::column(ColumnRef::SampleValue), reduction: Reduction::PerEntity,
    filter: None, tumbling_window_width_ms: 10_000 }) };
// The chain's θ must be listed: k = 547 is; k = 270 is ParametersNotInList.
let k_547 = LogicalProperties::new(&chain_expression, Some(kll_list[4].clone()))?;
// G3's second candidate SummaryMerge(TimeRange(1m, Gw)) has G3's schema, so it joins G3.

// Stage 2 (PR 5): Gw at ingestion time, materialized across evaluations.
let chain = PhysicalCandidate { logical_candidate_id: gw_candidate,
    physical_properties: PhysicalProperties::new(ExecutionTiming::IngestionTime,
        Lifetime::AcrossEvaluations(StorageMedium::Memory))? };
// α^phys for G3's merge, which runs at query time: an ingestion-time chain materialized across
// evaluations serves query-time consumers.
assert!(producer_satisfies_physical_requirements(&chain, ExecutionTiming::QueryTime));

// Stage 3 (PRs 6–7): contexts are evaluation grids. κ10 = Q_A's grid; κ30 = Q_C's (every 30 s).
let kappa_10 = ExecutionContext::Evaluation { grid: EvaluationGrid { period_ms: 10_000, phase_ms: 0 } };
let kappa_30 = ExecutionContext::Evaluation { grid: EvaluationGrid { period_ms: 30_000, phase_ms: 0 } };
assert!(chain.delivers_on(&candidates, &kappa_10)); // 10 s divides 10 s and 0
assert!(chain.delivers_on(&candidates, &kappa_30)); // 10 s divides 30 s and 0
// A query every 10 s at phase 5 s reads no 10 s chain (Pass 2 offers it w = 5 s instead).
assert!(!chain.delivers_on(&candidates, &ExecutionContext::Evaluation {
    grid: EvaluationGrid { period_ms: 10_000, phase_ms: 5_000 } }));

The planner's text output does not change in this PR: planning still stops at Stage 0's todo!().

Major algorithm changes

None in planning results: no stage that would reach these checks runs yet. Schema derivation changes for chains (time-indexed output, merges over a TimeRange over a chain), replacing the count-based chain PR 0 deleted.

Before this PR

Every section 2 function was todo!() (PR 0), as were finalizing and rolling up merged windows. A chain had the plain build's schema (no time index) and TimeRange/TimeShift rejected state.

After this PR

The section 2 checks run, each covered by a table test. θ comes from a fixed list of structures per algorithm. delivers_on answers for every execution context except Materialized(v) with ℓ = AcrossEvaluations (PR 7). A chain is a time-indexed state; a merge over a TimeRange (and TimeShifts) over a chain has the schema of the build over that range.

Verification

Tests added or changed:

  • stages::candidates::tests: logical_properties_new_over_every_operator_and_parameters (5 operators: KLL build, Sketch(HydraCms) build, exact Sum, KLL chain, readout × 5 θ: none, KLL 269, CMS, Hydra CMS, unlisted KLL 270); summary_type_of_operator_reads_the_builds_summary_type; parameter_list_holds_its_algorithm_without_repeats (one type per list, empty exactly for algorithms without an error model, Count-Min depths 5, 7, 10, 12, Count Sketch 47, 81, 117, 155, sizes 28 / 280 / 40).
  • stages::physical::memo_candidates::tests: delivers_on_by_lifetime_without_windows (None in every context; OneEvaluation only in Evaluation); delivers_on_a_chain_when_its_width_divides_the_context_times (grids 10 s @ 0, @ 5 s, @ 2 s, 7 s @ 0; refresh windows 5 s @ 0, 10 s @ 5 s, 10 s @ 2.5 s; widths 5 s and 10 s): delivers_on_a_stored_result_on_its_group_grid (new 2026-11-09: X = the scan's last 5 minutes, grid 60 s @ 0, against 60 s @ 0, 120 s @ 0, 120 s @ 60 s, 30 s @ 0, 60 s @ 15 s, refresh 60 s @ 0, and no grid); both fixtures build the memo with find_or_add_group, so they panic at PR 2's todo!() here; producer_satisfies_physical_requirements_over_every_valid_timing_and_lifetime.
  • physical::properties::tests::new_over_every_timing_and_lifetime.
  • types/tests/tumbling_window_chain.rs: a_chain_is_a_state_with_a_time_index, an_instant_time_range_over_a_chain_is_rejected, time_range_and_time_shift_select_a_chains_windows, merged_windows_are_the_build_over_the_selected_range, a_merge_over_a_chain_reads_one_time_range.
  • workload::tests::range_evaluation_is_optional_carried_and_validated: FixedInterval without a phase has no grid; FixedIntervalAt keeps its grids.
  • asap-accuracy: parameter_list_is_the_sizing_over_the_error_grid: every list is today's sizing over the ε grid at δ = 0.01, in order; Count-Min with depths 5, 7, 10, 12, Count Sketch with 47, 81, 117, 155; heap variants with every heap size; UnivMon has 28 more (the combined shapes).

Checks at the head: cargo fmt --all -- --check and cargo clippy --workspace --all-targets --all-features -- -D warnings: clean; crate_graph: 6 passed.

Test status

cargo test -p <crate> --all-features --no-fail-fast at the head (8030d3f). Every failure panics at a later PR's todo!() (or is the stale fixture, PR 9).

Compared by test name with the previous head 3c2825903 (2026-11-09, second round): only the 36 tests PR 0 now deletes with pass1/composition.rs (P11) are gone (35 failed, 1 passed there); no test changed result. crate_graph: 6 passed. Earlier comparison: Compared by test name with PR 0b at 0e0f75a7d: no test that passed fails. The differences are this PR's tests: 12 new tests pass; PR 0's two PhysicalProperties::new tests (which failed at its todo!()) are replaced by new_over_every_timing_and_lifetime; delivers_on_a_chain_when_its_width_divides_the_context_times and the new delivers_on_a_stored_result_on_its_group_grid fail at PR 2's todo!() (their memo fixture), and pass once PR 2 lands. Compared with the previous head 1ca33f19c: only PR 0's 2026-11-09 test changes (8 deleted, target_limit_admits_only_floating_point_noise added) and the new delivers_on_a_stored_result_on_its_group_grid. crate_graph: 6 passed.

Crate Passed Failed Ignored Fails at
asap-types 164 2 0 each output column's sign, per operator, from the input groups' and the sources' declared signs (PR 2): 2
asap-accuracy 60 0 0 —
asap-cost 31 1 0 check θ, which the exported node carries (PR 6): 1
asap-frontend-common 49 0 0 —
asap-sql-function-catalog 10 0 0 —
metricsql_common 3 0 0 —
asap-frontend-promql 217 0 0 —
asap-frontend-metricsql 15 0 0 —
asap-frontend-sql 173 0 0 —
asap-executor 210 63 1 check θ, which the exported node carries (PR 6): 32; the Hydra grid's sizes are θ, which the exported node carries (PR 6): 13; each materialized node's retention_ms is its h_v, which Stage 3 sets (PR 6): 8; the weighted-frequency θ, which the exported node carries (PR 6): 7; check the weighted-frequency θ, which the exported node carries (PR 6): 2; Stage 0 over Memo::find_or_add_group, each query with its target and n_q (PR 2): 1
asap-planner 8 18 1 Stage 0 over Memo::find_or_add_group, each query with its target and n_q (PR 2): 18
asap-devtools 37 56 3 Stage 0 over Memo::find_or_add_group, each query with its target and n_q (PR 2): 54; OTHER: assertion failed: output.status.success(): 2
asap-integration-tests 83 51 4 Stage 0 over Memo::find_or_add_group, each query with its target and n_q (PR 2): 47; each materialized node's retention_ms is its h_v, which Stage 3 sets (PR 6): 3; OTHER: called Result::unwrap() on an Err value: Error("invalid type: sequence, expected string or map", line: 0, column: 0): 1
asap-stage3-plan-selection 3 0 0 —
asap-stage0-memo 0 0 0 —
asap-stage2-physical-optimization 0 0 0 —
asap-stage1-pass2-reuse-candidates 0 0 0 —
asap-stage1-pass1-per-computation-candidates 11 0 0 —
Total 1074 191 9

Self-review (2026-11-09)

  • Over-abstraction. None added: delivers_on reads the two new fields directly; no helper type for "a context's times" (the (period, phase) pair is local).
  • Duplication. One with_depths takes the depth array instead of a second function for Count Sketch. The chain and stored-result branches share the context-times match.
  • Dead code. None new; SKETCH_DEPTHS replaced by CMS_DEPTHS and COUNT_SKETCH_DEPTHS. The accuracy list test still compares the lists with test-only sizing (PR 4 replaces it).
  • For PR 4. delivers_on does not shift the context's times by a TimeShift on the reading path: evaluation_grid_of_group is the grid of the times the group itself is evaluated at, so Pass 2 must fold the queries' shifts into it when it fills it.

Self-review (2026-11-08)

  • Over-abstraction. None added. The two const fns exist because the lists are const (no allocation, &'static slices); they replace hand-written 28- and 280-entry arrays.
  • Duplicated code or interfaces. Removed: this PR's own strongest/weakest/dominates/combine (now deleted), sketch_algorithm_of (the algorithm is in the summary type), family_of_operator (renamed), the sizing wrappers in sizing.rs and test_support.rs. The lists duplicate today's sizing as constants by design; one test keeps them equal (PR 4 replaces that test with a per-entry guarantee test).
  • Dead code or interfaces. The sizing helpers only the list test reads are #[cfg(test)] (kll_k, kmv_k, count_sketch_depth, UnivMon's distinct_heap and its constants). QueryRecurrence::evaluation_grid_ms has no caller in this PR; it is the doc's interface for Pass 2's chain widths and Stage 3's grids (PRs 4, 7).
  • Found and flagged: Count Sketch's listed depths (P1).

History. 2026-11-09 (second): plain rebase onto PR 0b 058ea4234 (PR 0 2ed6ec0b8, P11: Pass 1's whole-workload composition and its 74 tests deleted), no conflict; previous head kept as backup/1207-properties-3c2825903; fmt and clippy -D warnings clean. 2026-11-09: rebased onto PR 0b 0e0f75a7d (PR 0 be6ea1d6a, the 2026-11-09 interfaces) and applied P1–P3 in the same single commit. Previous head kept as backup/1207-properties-1ca33f19c. 2026-11-08 (second round): squashed the previous four commits (9c2cfa05e … cf93b3707) into one and rebased onto PR 0b b768e8dd1 (PR 0 7708f3668, the 2026-11-08 interfaces), adapting to them as listed above. Previous head kept as backup/1207-properties-cf93b3707.

@zzylol zzylol added optimizer Workload optimization and plan selection refactor labels Nov 6, 2026
@zzylol
zzylol force-pushed the refactor/1207-properties branch 4 times, most recently from 5ef1ef3 to d9d64df Compare November 6, 2026 15:37
@zzylol
zzylol force-pushed the refactor/1207-properties branch from d9d64df to 2a62109 Compare November 6, 2026 15:47
@zzylol
zzylol force-pushed the refactor/1207-properties branch from 2a62109 to b87b7c0 Compare November 6, 2026 16:30
@zzylol
zzylol changed the base branch from refactor/1207-interfaces to refactor/1207-crates-per-stage November 6, 2026 16:30
@zzylol
zzylol force-pushed the refactor/1207-properties branch 3 times, most recently from 460e9c7 to ba60db8 Compare November 6, 2026 17:12
@zzylol
zzylol force-pushed the refactor/1207-crates-per-stage branch from 4d55373 to ae4843e Compare November 6, 2026 18:56
@zzylol
zzylol force-pushed the refactor/1207-properties branch from ba60db8 to 60a16ee Compare November 6, 2026 18:56
@zzylol
zzylol force-pushed the refactor/1207-crates-per-stage branch from ae4843e to 8d020b0 Compare November 6, 2026 19:10
@zzylol
zzylol force-pushed the refactor/1207-properties branch from 60a16ee to 107a77b Compare November 6, 2026 19:12
@zzylol
zzylol force-pushed the refactor/1207-crates-per-stage branch from 8d020b0 to d1feaad Compare November 6, 2026 21:29
@zzylol
zzylol force-pushed the refactor/1207-properties branch from 107a77b to c7a0bc9 Compare November 6, 2026 21:31
@zzylol
zzylol force-pushed the refactor/1207-crates-per-stage branch from d1feaad to 9a3bb19 Compare November 6, 2026 21:38
@zzylol
zzylol force-pushed the refactor/1207-properties branch from c7a0bc9 to 9e5ce62 Compare November 6, 2026 21:38
@zzylol
zzylol force-pushed the refactor/1207-crates-per-stage branch from 9a3bb19 to 345b5df Compare November 6, 2026 21:57
@zzylol
zzylol force-pushed the refactor/1207-properties branch from 9e5ce62 to 96d3457 Compare November 6, 2026 22:11
@zzylol
zzylol force-pushed the refactor/1207-crates-per-stage branch from cbd0359 to 4445d45 Compare November 6, 2026 22:46
@zzylol
zzylol force-pushed the refactor/1207-properties branch from 96d3457 to b250852 Compare November 6, 2026 22:46
@zzylol
zzylol force-pushed the refactor/1207-crates-per-stage branch from 4445d45 to 84cf80d Compare November 7, 2026 17:47
@zzylol
zzylol force-pushed the refactor/1207-properties branch from b250852 to 7ceb7c3 Compare November 7, 2026 18:04
@zzylol zzylol changed the title refactor(types): properties and requirements from #1207 (#1207 PR 1) refactor(types): properties and requirements from #1207; chains as time-indexed state (#1207 PR 1) Nov 7, 2026
@zzylol
zzylol force-pushed the refactor/1207-crates-per-stage branch from 84cf80d to 69fed95 Compare November 7, 2026 20:51
@zzylol
zzylol force-pushed the refactor/1207-properties branch from 7ceb7c3 to 12a4b96 Compare November 7, 2026 20:55
@zzylol
zzylol force-pushed the refactor/1207-crates-per-stage branch from 69fed95 to dfd6a5b Compare November 8, 2026 15:06
@zzylol
zzylol force-pushed the refactor/1207-properties branch from 12a4b96 to cf93b37 Compare November 8, 2026 15:10
@zzylol
zzylol force-pushed the refactor/1207-crates-per-stage branch from dfd6a5b to b768e8d Compare November 8, 2026 21:29
@zzylol
zzylol force-pushed the refactor/1207-properties branch from cf93b37 to 1ca33f1 Compare November 8, 2026 21:42
@zzylol
zzylol force-pushed the refactor/1207-crates-per-stage branch from b768e8d to 0e0f75a Compare November 9, 2026 03:33
@zzylol
zzylol force-pushed the refactor/1207-properties branch from 1ca33f1 to 3c28259 Compare November 9, 2026 03:45
@zzylol
zzylol force-pushed the refactor/1207-crates-per-stage branch from 0e0f75a to 058ea42 Compare November 9, 2026 04:31
- LogicalProperties::new(expression, parameters): a sketch build (a chain
  included) needs θ from parameter_list(algorithm) of its
  FieldDataType::Sketch(algorithm); an exact operator has none.
- parameter_list(algorithm): structures only. Count-Min lists each width
  with depths 5, 7, 10 and 12, Count Sketch with 47, 81, 117 and 155 (its
  median-of-rows δ levels 1e-2 … 1e-5); heap variants each of those
  with the 1-2-5 heap sizes; UnivMon 40 entries; KLL, DDSketch, HLL, KMV
  one entry per ε level. A test keeps the lists equal to today's sizing,
  which is test-only.
- PhysicalProperties::new rejects (IngestionTime, OneEvaluation);
  producer_satisfies_physical_requirements(producer, consumer_timing).
- PhysicalCandidate::delivers_on(candidates, context): None in every
  context, OneEvaluation only in Evaluation contexts, a chain with
  AcrossEvaluations when its width divides the grid's period and phase
  (or the refresh window's width and phase), any other AcrossEvaluations
  result everywhere when its group does not depend on the evaluation
  time, else when its group's evaluation grid holds the context's times;
  Materialized(v) contexts stay todo!() for PR 7.
- Chains: one schema (window_end at column 0, keys, state), TimeRange and
  TimeShift over a chain select windows (an instant TimeRange is
  rejected), a SummaryMerge over them finalizes and rolls up as the
  chain's build over that range (the two PR 0 todos).
- summary_type_of_operator; QueryRecurrence::evaluation_grid_ms is None
  for a fixed interval without a phase.
@zzylol
zzylol force-pushed the refactor/1207-properties branch from 3c28259 to 8030d3f Compare November 9, 2026 04:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

optimizer Workload optimization and plan selection refactor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant