@@ -606,16 +606,27 @@ impl SimpleEngine {
606606 }
607607 } ;
608608
609- // Top-k (CountMinSketchWithHeap) is defined only for flat temporal queries:
610- // one window, one GROUP BY key, COUNT/SUM ... ORDER BY <agg alias> DESC LIMIT k.
611- // Nested patterns attach ORDER BY / LIMIT to the outer SELECT; `query_data` from
612- // parse is the outer layer, while the temporal aggregate lives in `inner_data`
613- // for OneTemporalOneSpatial. Running detect_sql_topk on the outer layer would
614- // mis-classify spatial rollups as top-k.
609+ // Top-k (CountMinSketchWithHeap) applies to flat single-layer queries:
610+ // COUNT/SUM ... GROUP BY <key> ORDER BY <agg alias> DESC LIMIT k.
611+ // Nested patterns attach ORDER BY / LIMIT to the outer SELECT; `query_data`
612+ // from parse is the outer layer, while the temporal aggregate lives in
613+ // `inner_data` for OneTemporalOneSpatial. Running detect_sql_topk on the
614+ // outer layer would mis-classify spatial rollups as top-k.
615+ //
616+ // Single-interval windows (duration == scrape interval) classify as
617+ // `OnlySpatial` in the pattern matcher even though they are flat temporal
618+ // reads, so both `OnlyTemporal` and `OnlySpatial` must run detection.
615619 let topk = match query_pattern_type {
616- QueryPatternType :: OnlyTemporal => detect_sql_topk ( & query_data) ,
617- QueryPatternType :: OnlySpatial | QueryPatternType :: OneTemporalOneSpatial => None ,
620+ QueryPatternType :: OnlyTemporal | QueryPatternType :: OnlySpatial => {
621+ detect_sql_topk ( & query_data)
622+ }
623+ QueryPatternType :: OneTemporalOneSpatial => None ,
618624 } ;
625+ if topk. is_some_and ( |t| t. weighting == TopkWeighting :: Sum ) {
626+ warn ! (
627+ "SUM top-k assumes non-negative values; results are undefined for columns with negative entries"
628+ ) ;
629+ }
619630 let statistic_to_compute = if topk. is_some ( ) {
620631 Statistic :: Topk
621632 } else {
@@ -980,7 +991,7 @@ mod detect_topk_tests {
980991 let qd = parse ( & sql) . expect ( "nested query should parse" ) ;
981992 assert ! (
982993 detect_sql_topk( & qd) . is_some( ) ,
983- "outer SELECT alone matches the top-k shape (this is why OnlyTemporal is gated)" ,
994+ "outer SELECT alone matches the top-k shape (this is why OneTemporalOneSpatial is gated)" ,
984995 ) ;
985996 }
986997}
0 commit comments