Skip to content

Commit 670c834

Browse files
fix(precompute): validate planner spatial filters
1 parent f08cbc5 commit 670c834

1 file changed

Lines changed: 27 additions & 11 deletions

File tree

asap-query-engine/src/precompute_engine/ingest_source.rs

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -84,14 +84,18 @@ fn compile_spatial_filter(config: &AggregationConfig) -> Result<Vec<Matcher>, St
8484
}
8585

8686
let filter = config.spatial_filter.trim();
87-
if !filter.starts_with('{') || !filter.ends_with('}') {
88-
return Err(format!(
89-
"aggregation_id {} has invalid spatialFilter {:?}: expected a PromQL label selector body",
90-
config.aggregation_id, config.spatial_filter
91-
));
92-
}
93-
94-
let selector = format!("{}{}", config.metric, filter);
87+
let selector_body = if filter.starts_with('{') || filter.ends_with('}') {
88+
if !filter.starts_with('{') || !filter.ends_with('}') {
89+
return Err(format!(
90+
"aggregation_id {} has invalid spatialFilter {:?}: unmatched selector braces",
91+
config.aggregation_id, config.spatial_filter
92+
));
93+
}
94+
filter.to_string()
95+
} else {
96+
format!("{{{filter}}}")
97+
};
98+
let selector = format!("{}{}", config.metric, selector_body);
9599
let Expr::VectorSelector(vector_selector) = parse(&selector).map_err(|error| {
96100
format!(
97101
"aggregation_id {} has invalid spatialFilter {:?}: {error}",
@@ -105,7 +109,14 @@ fn compile_spatial_filter(config: &AggregationConfig) -> Result<Vec<Matcher>, St
105109
));
106110
};
107111

108-
let matchers = vector_selector.matchers.matchers;
112+
let matchers = vector_selector.matchers;
113+
if !matchers.or_matchers.is_empty() {
114+
return Err(format!(
115+
"aggregation_id {} spatialFilter must not use selector-level or",
116+
config.aggregation_id
117+
));
118+
}
119+
let matchers = matchers.matchers;
109120
if matchers.iter().any(|matcher| matcher.name == "__name__") {
110121
return Err(format!(
111122
"aggregation_id {} spatialFilter must not match __name__; use metric instead",
@@ -348,9 +359,9 @@ mod tests {
348359
}
349360

350361
#[tokio::test]
351-
async fn equality_spatial_filter_routes_only_equal_label_values() {
362+
async fn planner_style_spatial_filter_routes_only_equal_label_values() {
352363
let samples = routed_samples(
353-
r#"{job="api"}"#,
364+
r#"job="api""#,
354365
vec![
355366
sample("cpu_usage{job=\"api\"}", 1_000, 1.0),
356367
sample("cpu_usage{job=\"worker\"}", 2_000, 2.0),
@@ -501,5 +512,10 @@ mod tests {
501512
r#"{__name__="other_metric"}"#,
502513
)]);
503514
assert!(metric_matcher.is_err());
515+
516+
let selector_or = RoutingConfigSet::from_aggregation_configs(vec![aggregation_config(
517+
r#"{job="api" or job="worker"}"#,
518+
)]);
519+
assert!(selector_or.is_err());
504520
}
505521
}

0 commit comments

Comments
 (0)