Skip to content

Commit a33ea22

Browse files
test(query-engine): SQL quantile roll-up over several windows (#871)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 05ae0be commit a33ea22

1 file changed

Lines changed: 100 additions & 0 deletions

File tree

‎asap-query-engine/src/tests/rollup_tests.rs‎

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,106 @@ mod tests {
342342
assert_eq!(vector.values[0].value, hll(0..2_000).estimate());
343343
}
344344

345+
/// A SQL quantile served by rolling up a DDSketch grouped by
346+
/// (endpoint, service), over a lookback of several tumbling windows: the
347+
/// shape `--planner saved` writes for sketch-bench's p99 CUBE.
348+
#[test]
349+
fn sql_quantile_by_subset_over_several_windows_equals_the_merged_sketch() {
350+
const WINDOW_MS: u64 = 60_000;
351+
const WINDOWS: u64 = 5;
352+
// A multiple of the window, as the e2e client floors eval times.
353+
const ALIGNED_QUERY_TIME_S: f64 = 960.0;
354+
let sql = "SELECT service, QUANTILE(0.9, value) FROM events WHERE time BETWEEN \
355+
DATEADD(s, -300, NOW()) AND NOW() GROUP BY service";
356+
let streaming_config = Arc::new(StreamingConfig {
357+
aggregation_configs: HashMap::from([(
358+
1,
359+
AggregationConfig {
360+
aggregation_id: 1,
361+
aggregation_type: AggregationType::DDSketch,
362+
aggregation_sub_type: String::new(),
363+
parameters: HashMap::new(),
364+
grouping_labels: KeyByLabelNames::new(vec![
365+
"endpoint".to_string(),
366+
"service".to_string(),
367+
]),
368+
aggregated_labels: KeyByLabelNames::empty(),
369+
rollup_labels: KeyByLabelNames::empty(),
370+
original_yaml: String::new(),
371+
window_size_ms: WINDOW_MS,
372+
slide_interval_ms: WINDOW_MS,
373+
window_type: WindowType::Tumbling,
374+
spatial_filter: String::new(),
375+
spatial_filter_normalized: String::new(),
376+
metric: "events".to_string(),
377+
num_aggregates_to_retain: None,
378+
read_count_threshold: None,
379+
table_name: Some("events".to_string()),
380+
value_column: Some("value".to_string()),
381+
},
382+
)]),
383+
});
384+
let store = Arc::new(SimpleMapStore::new(
385+
streaming_config.clone(),
386+
CleanupPolicy::NoCleanup,
387+
));
388+
let query_time_ms = (ALIGNED_QUERY_TIME_S * 1_000.0) as u64;
389+
let mut all = Vec::new();
390+
for (g, labels) in [["/x", "a"], ["/y", "a"]].iter().enumerate() {
391+
for w in 0..WINDOWS {
392+
let values: Vec<f64> = (1..=100)
393+
.map(|i| f64::from(i + 100 * (w as u32 * 2 + g as u32)))
394+
.collect();
395+
all.extend(values.iter().copied());
396+
let end = query_time_ms - w * WINDOW_MS;
397+
store
398+
.insert_precomputed_output(
399+
PrecomputedOutput::new(
400+
end - WINDOW_MS,
401+
end,
402+
key(labels).map(|labels| KeyByLabelValues { labels }),
403+
1,
404+
),
405+
Box::new(dd(values)),
406+
)
407+
.unwrap();
408+
}
409+
}
410+
let inference_config = InferenceConfig {
411+
schema: SchemaConfig::SQL(create_test_schema(
412+
"events",
413+
"time",
414+
"value",
415+
vec!["endpoint", "service"],
416+
)),
417+
query_configs: vec![QueryConfig::new(sql.to_string())
418+
.add_aggregation(AggregationReference::new(1, None))],
419+
cleanup_policy: CleanupPolicy::NoCleanup,
420+
};
421+
let engine = SimpleEngine::new(
422+
store,
423+
inference_config,
424+
streaming_config,
425+
1_000,
426+
QueryLanguage::sql,
427+
);
428+
429+
let (_, result) = engine
430+
.handle_query_sql(sql.to_string(), ALIGNED_QUERY_TIME_S)
431+
.expect("the SQL roll-up should be served locally");
432+
let QueryResult::Vector(vector) = result else {
433+
panic!("expected an instant vector");
434+
};
435+
let expected = dd(all).get_quantile(0.9);
436+
assert_eq!(vector.values.len(), 1);
437+
assert_eq!(vector.values[0].labels.labels, vec!["a".to_string()]);
438+
assert!(
439+
(vector.values[0].value - expected).abs() <= expected * 1e-9,
440+
"rolled-up p90 {} should equal the whole-data sketch's {expected}",
441+
vector.values[0].value
442+
);
443+
}
444+
345445
/// A range query rolls up at every step, and a subgroup that only
346446
/// appears partway through contributes from then on.
347447
#[test]

0 commit comments

Comments
 (0)