Context
ASAPPlanner#408 found that instant PromQL aggregates lower directly over Scan, so the planner and materializer receive no temporal horizon. The backend currently calls asap_frontend_promql::lower_promql(query, accuracy) through control_plane/src/query_parser/mod.rs::parse_query_expr_canonical; that function has no workload or source-cadence context.
The backend already has BackendLocalPhysicalInputs::source_sample_interval_ms: Option<u64>, but it is separate physical metadata and the HTTP planning path currently supplies None. It never reaches PromQL lowering.
Required changes
- Add
DataWorkload.data_ingestion_interval: Evidence<DurationMs> in ASAPPlanner and require it for plan-ready PromQL workload lowering. Missing or zero values must fail loudly.
- Replace the backend's direct, context-free
lower_promql call with workload-aware lowering that receives the validated QueryWorkload entry and its DataWorkload.
- Update the compile path to lower all
workload.entries() (both batch and repeating entries), rather than parsing each query independently.
- Require the interval at the HTTP/configuration boundary and construct the
DataWorkload from it before planning. Do not silently choose a default.
- Temporarily map
source_sample_interval_ms into DataWorkload.data_ingestion_interval during migration, then remove the duplicate backend-only field so there is one source of truth.
- Update tools, compatibility paths, and fixtures to supply an explicit interval (existing ASAPQuery examples use 1 s).
Expected behavior
For an instant aggregate such as sum(data), a workload with a 1 s ingestion interval lowers its input as:
Aggregate { … }
└── TimeRange { range: 1 s }
└── Scan(data)
An absent interval is a planning/lowering error. Explicit range selectors and range functions retain their query-specified range and do not receive an additional inferred range.
Dependency
This backend migration depends on, and should be coordinated with, ASAPPlanner#408.
Context
ASAPPlanner#408 found that instant PromQL aggregates lower directly over
Scan, so the planner and materializer receive no temporal horizon. The backend currently callsasap_frontend_promql::lower_promql(query, accuracy)throughcontrol_plane/src/query_parser/mod.rs::parse_query_expr_canonical; that function has no workload or source-cadence context.The backend already has
BackendLocalPhysicalInputs::source_sample_interval_ms: Option<u64>, but it is separate physical metadata and the HTTP planning path currently suppliesNone. It never reaches PromQL lowering.Required changes
DataWorkload.data_ingestion_interval: Evidence<DurationMs>in ASAPPlanner and require it for plan-ready PromQL workload lowering. Missing or zero values must fail loudly.lower_promqlcall with workload-aware lowering that receives the validatedQueryWorkloadentry and itsDataWorkload.workload.entries()(both batch and repeating entries), rather than parsing each query independently.DataWorkloadfrom it before planning. Do not silently choose a default.source_sample_interval_msintoDataWorkload.data_ingestion_intervalduring migration, then remove the duplicate backend-only field so there is one source of truth.Expected behavior
For an instant aggregate such as
sum(data), a workload with a 1 s ingestion interval lowers its input as:An absent interval is a planning/lowering error. Explicit range selectors and range functions retain their query-specified range and do not receive an additional inferred range.
Dependency
This backend migration depends on, and should be coordinated with, ASAPPlanner#408.