From 028aab22c3db6e9fc7c37873b846238499c62557 Mon Sep 17 00:00:00 2001 From: Akanksha Akkihal Date: Mon, 1 Jun 2026 14:11:12 +0000 Subject: [PATCH] fix spatial sql minmax config generation --- asap-planner-rs/src/planner/sql.rs | 19 +++++++++++++- asap-planner-rs/tests/sql_integration.rs | 33 ++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/asap-planner-rs/src/planner/sql.rs b/asap-planner-rs/src/planner/sql.rs index 1c0c7c0..40c0bce 100644 --- a/asap-planner-rs/src/planner/sql.rs +++ b/asap-planner-rs/src/planner/sql.rs @@ -114,7 +114,7 @@ impl SQLSingleQueryProcessor { all_metadata.difference(&spatial_output) }; - let configs = build_agg_configs_for_statistics( + let mut configs = build_agg_configs_for_statistics( &statistics, treatment_type, &spatial_output, @@ -135,6 +135,23 @@ impl SQLSingleQueryProcessor { ) .map_err(ControllerError::SqlParse)?; + // 1s spatial MIN/MAX: single MinMax per GROUP BY key (not MultipleMinMax subpopulations). + if matches!(query_type, QueryType::Spatial) { + match agg_info.get_name().to_uppercase().as_str() { + "MIN" | "MAX" => { + let sub_type = agg_info.get_name().to_lowercase(); + for cfg in &mut configs { + cfg.aggregation_type = AggregationType::MinMax; + cfg.aggregation_sub_type = sub_type.clone(); + cfg.grouping_labels = spatial_output.clone(); + cfg.aggregated_labels = KeyByLabelNames::empty(); + cfg.rollup_labels = KeyByLabelNames::empty(); + } + } + _ => {} + } + } + let t_lookback = match query_type { QueryType::Spatial => self.data_ingestion_interval, _ => sql_query.query_data[0].time_info.get_duration() as u64, diff --git a/asap-planner-rs/tests/sql_integration.rs b/asap-planner-rs/tests/sql_integration.rs index 242bef8..fe1460e 100644 --- a/asap-planner-rs/tests/sql_integration.rs +++ b/asap-planner-rs/tests/sql_integration.rs @@ -476,6 +476,39 @@ fn spatial_count_distinct_hll() { ); } +/// 1s spatial MAX(pkt_len) GROUP BY dstip → MinMax (max), grouping [dstip], empty rollup. +#[test] +fn spatial_max_pkt_len() { + let q = "SELECT dstip, MAX(pkt_len) AS max_pkt_len FROM netflow_table WHERE time BETWEEN DATEADD(s, -11, NOW()) AND DATEADD(s, -10, NOW()) GROUP BY dstip"; + let out = SQLController::from_yaml(&netflow_one_query_config(q, 1), sql_opts_1s_ingest()) + .unwrap() + .generate() + .unwrap(); + + assert_eq!(out.streaming_aggregation_count(), 1); + assert_eq!(out.inference_query_count(), 1); + assert!(out.has_aggregation_type("MinMax")); + assert!(out.has_aggregation_type_and_sub_type("MinMax", "max")); + assert!(!out.has_aggregation_type("MultipleMinMax")); + assert!(out.all_tumbling_window_sizes_eq(1)); + assert_eq!( + out.aggregation_value_column("MinMax"), + Some("pkt_len".to_string()) + ); + assert_eq!( + out.aggregation_labels("MinMax", "grouping"), + vec!["dstip".to_string()] + ); + assert_eq!( + out.aggregation_labels("MinMax", "rollup"), + Vec::::new() + ); + assert_eq!( + out.aggregation_labels("MinMax", "aggregated"), + Vec::::new() + ); +} + // ── T-value variants for SUM (range = 300 s fixed) ─────────────────────────── // // These three tests use the same query and differ only in repetition_delay (T).