Skip to content

Instant sum/count/avg by and avg_over_time are not accelerated; instant sum fails to compile #702

Description

@milindsrivastava1997

Environment

  • Tool: control_plane --example inspect_physical_dag (normal BackendLocalPlanningSnapshot::compile path)
  • Snapshots: version 1, derived from docs/examples/asapquery-compatibility-demo-snapshot.json;
    source_sample_interval_ms = 1000, horizon_seconds = 3600, no window_candidates supplied.
    Instant queries use lookback 1s. sum/count/avg queries use implicit_exact; w14 uses
    EpsilonDelta { epsilon: 0.01, delta: 0.01 } because it contains a quantile.

Related: #701 (same snapshot setup).

Workloads and results

Metric data, scraped every 1s.

id query repeats every result
w3 (#701) quantile by (job) (0.9, data) 1s compiles: DDSketch grouped by job, tumbling 1s/1s, pane 1s
w12 sum by (job) (data) 1s compile error
sum(data) 1s compile error (same as w12)
w13 avg_over_time(data[5m]) 30s no state; QueryPlan is a single exact_fallback
w14 avg_over_time(data[5m]) / quantile_over_time(0.5, data[5m]) 30s no state; single exact_fallback
w15 count by (job) (data) 1s no state; single exact_fallback
count(data) 1s no state; single exact_fallback
w16 avg by (job) (data) 1s no state; single exact_fallback
sum by (job) (sum_over_time(data[5m])) 30s compiles: Sum state, read_materializationexact_readoutsum by (job)

1. Instant sum fails to compile

Error: Query { query_id: "compat-query-0", reason: "instantaneous sample selection is not a temporal accumulator readout" }

Both sum by (job) (data) and sum(data) fail. The same instant-selector shape is handled three
different ways: quantile by (job) (φ, data) is materialized, count by (job) (data) falls back to
exact, and sum by (job) (data) is a hard compile error. Expected either a supported plan or exact
routing, consistently across aggregations.

2. avg_over_time gets no summary (w13, w14)

Planner's only candidate for avg_over_time(data[5m]) is a pass-through:

Avg { col: None } has no summary realization and stays a logical pass-through

No avg → sum/count rewrite candidate is proposed, although the backend registers
SemanticEquivalentRewriteStrategy (which contains that rewrite) and sum_over_time/count_over_time
compile to Sum state. w14 also hits the quantile composition rejection described in #701:

composed guarantee (Rank, bound Some(0.013294757464848584), failure probability Some(0.01)) does not satisfy EpsilonDelta { epsilon: 0.01, delta: 0.01 }

3. avg by (job) (data): rewrite proposed but not selected (w16)

Planner searches each sub-expression as a separate group. The root group (the whole
avg by (job) (data)) has two candidates:

root candidate meaning status
pass-through (SketchAlgorithmStrategy: "Avg { col: None } has no summary realization and stays a logical pass-through") run the original expression unchanged (KeepPreAsap) selected
rewrite (SemanticEquivalentRewriteStrategy) sum by (job) (data) / count by (job) (data) unselected

The rewrite's sum and count sub-groups do choose candidates (exact Sum, exact Count, UnivMon), but
those choices are only used if the root takes the rewrite. Because the root takes the pass-through,
the QueryPlan is a single exact_fallback. Every candidate in logical_selection has
estimated_cost: null, so the choice is not explained by reported costs.

4. count by (job) (data): Count or Cardinality intent? (w15)

PromQL count by (job) (v) counts the elements (series) in each group. ASAPPlanner's PromQL frontend
lowers it to the distinct-count intent:

  • crates/frontend-promql/src/promql.rs:48 documents count by (d) (…)Aggregate{[Cardinality], …}
  • build_over_subtree (promql.rs:593-599) emits AggIntent::Cardinality { col: None } for the outer count

Cardinality is technically correct here: Prometheus does not allow duplicate series label sets, so
the number of elements in an instant vector equals its number of distinct series. We should still
decide whether this should lower to AggIntent::Count or AggIntent::Cardinality.

If it stays Cardinality, it is not implemented anyway. Planner's only candidate is a pass-through,
and the query runs as exact fallback:

cardinality (distinct count) has no summary realization and stays a logical pass-through

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions