Bug
A Sliding-window range query whose first requested output step is earlier
than the aggregation's window_size_ms gets a phantom sample at that step,
duplicating the value of the first legitimate step (current_time == window_size_ms) instead of correctly having no sample there.
Root cause
execute_range_query_pipeline (asap-query-engine/src/engines/simple_engine/mod.rs):
each step's window_start is computed as current_time.saturating_sub(lookback_ms)
(lookback_ms == window_size_ms for WindowType::Sliding). For current_time < window_size_ms this saturates to 0 — the same window_start that the
legitimately-computed step current_time == window_size_ms also resolves to
(via ordinary, non-saturating subtraction). single_window does a bare
bucket_map.get(&window_start) with no check that current_time actually had
window_size_ms worth of history behind it, so both steps collide on the one
store entry built for current_time == window_size_ms.
Repro
Minimal case: window_size_ms=2000, slide_interval_ms=1000 (2 panes/window),
one key with panes at t=1000 (value 10.0) and t=2000 (value 5.0). The only
genuine full window is [0, 2000) → merged value 15.0, correctly surfaced at
t=2000. Querying from t=1000 with sum_over_time(http_requests[1s]) should
show no sample at t=1000 (a window ending at 1000 would need history back
to t=-1000, which doesn't exist) — but the engine currently reports 15.0
there too, identical to t=2000.
Pinned as an #[ignore]d regression test on #630:
asap-query-engine/src/tests/sliding_window_keyed_oracle_tests.rs:302
(sliding_window_range_query_start_before_window_size_ms_returns_wrong_value).
Run with cargo test --package asap-query-engine sliding_window_range_query_start_before_window_size_ms_returns_wrong_value -- --ignored
once a fix is attempted; un-ignore once it passes.
Bug
A Sliding-window range query whose first requested output step is earlier
than the aggregation's
window_size_msgets a phantom sample at that step,duplicating the value of the first legitimate step (
current_time == window_size_ms) instead of correctly having no sample there.Root cause
execute_range_query_pipeline(asap-query-engine/src/engines/simple_engine/mod.rs):each step's window_start is computed as
current_time.saturating_sub(lookback_ms)(
lookback_ms == window_size_msforWindowType::Sliding). Forcurrent_time < window_size_msthis saturates to 0 — the same window_start that thelegitimately-computed step
current_time == window_size_msalso resolves to(via ordinary, non-saturating subtraction).
single_windowdoes a barebucket_map.get(&window_start)with no check thatcurrent_timeactually hadwindow_size_msworth of history behind it, so both steps collide on the onestore entry built for
current_time == window_size_ms.Repro
Minimal case:
window_size_ms=2000,slide_interval_ms=1000(2 panes/window),one key with panes at t=1000 (value 10.0) and t=2000 (value 5.0). The only
genuine full window is
[0, 2000)→ merged value 15.0, correctly surfaced att=2000. Querying from t=1000 with
sum_over_time(http_requests[1s])shouldshow no sample at t=1000 (a window ending at 1000 would need history back
to t=-1000, which doesn't exist) — but the engine currently reports 15.0
there too, identical to t=2000.
Pinned as an
#[ignore]d regression test on #630:asap-query-engine/src/tests/sliding_window_keyed_oracle_tests.rs:302(
sliding_window_range_query_start_before_window_size_ms_returns_wrong_value).Run with
cargo test --package asap-query-engine sliding_window_range_query_start_before_window_size_ms_returns_wrong_value -- --ignoredonce a fix is attempted; un-ignore once it passes.