-
Notifications
You must be signed in to change notification settings - Fork 3
topk grouping_labels mismatch breaks capability-matching fallback for ad-hoc topk queries #720
Description
Problem
find_compatible_aggregation (asap-common/dependencies/rs/asap_types/src/capability_matching.rs:298) filters candidate configs with:
labels_compatible(&c.grouping_labels, &requirements.grouping_labels)
labels_compatible is strict equality (config_labels == req_labels).
For any topk query, requirements.grouping_labels is always the metric's full label set (get_spatial_aggregation_output_labels deliberately always returns all labels for topk, since topk/bottomk output keeps every original label regardless of any by/without clause -- see #714). Meanwhile a stored CountMinSketchWithHeap config's grouping_labels is the engine's partition key, which today is always empty (pre-#714 fix) and, after #714's fix, will be the by/without labels for a bucketed topk (e.g. ["job"]) or still empty for a bare topk(k, x).
Neither of those config values is ever equal to "all labels" (unless the metric happens to have zero labels), so this equality check appears to reject every CountMinSketchWithHeap candidate for any real topk query with a non-empty label set.
Why it hasn't been noticed
This function is only reached via the capability-matching fallback path in asap-query-engine/src/engines/simple_engine/promql.rs (build_query_execution_context_from_parsed, ~line 1224): "try pre-configured query_configs first, fall back to capability matching." Every query driven through promql-compliance's differential runner is pre-registered in query_configs by the planner, so the fallback is never exercised there, and the bug has stayed latent. It would only bite an ad-hoc PromQL topk query against the live query engine that wasn't pre-planned (e.g. an interactive/exploratory query hitting the HTTP query API directly).
Suggested fix direction
labels_compatible's strict-equality contract is fine for reducers (sum/count/avg/min/max), where grouping_labels really is the same concept on both sides. For Statistic::Topk specifically, the comparison needs to either:
- compare
requirements.topk_by_labels(added in topk by (label) over a temporal function collapses all groups into one result #714 ) againstc.grouping_labelsinstead ofrequirements.grouping_labels, treatingNone/empty as "single global heap"; or - special-case topk the same way
topk_weighting_compatible/count_heap_weighting_compatiblealready do (bypass the genericlabels_compatiblecheck and apply topk-specific label-compatibility logic).
Found while implementing the fix for #714; out of scope there since it's a different code path with no current test coverage.