Problem
PromQL's without(labels) aggregate modifier groups by every label except the listed ones. Resolving that requires knowing a metric's full label set so the complement can be computed. The current Binder (UsageDerivedCatalog) only knows the labels a query happens to reference — it has no registry of a metric's actual label set — so the schema it builds is always "open" (Schema::closed = false) and cannot enumerate a complement. without(...) is therefore rejected outright rather than silently grouping by the wrong (incomplete) label set.
by(labels) doesn't have this problem since it only needs the labels it explicitly names.
Reproduction
crates/lower/src/promql.rs, resolve_group:
fn resolve_group(agg: &AggregateExpr) -> Result<Vec<ColumnRef>> {
match &agg.modifier {
None => Ok(vec![]),
Some(LabelModifier::Include(ls)) => { ... }
Some(LabelModifier::Exclude(_)) => Err(LoweringError::UnsupportedFeature(
"`without(...)` grouping requires a registry-backed catalog of the \
metric's label set (the usage-derived schema can't enumerate the \
complement)"
.into(),
)),
}
}
Any query using without, e.g. sum without (instance) (rate(http_requests_total[5m])), fails to lower with LoweringError::UnsupportedFeature. There is currently no test exercising a successful without(...) lowering — only the rejection path is reachable.
Problem
PromQL's
without(labels)aggregate modifier groups by every label except the listed ones. Resolving that requires knowing a metric's full label set so the complement can be computed. The currentBinder(UsageDerivedCatalog) only knows the labels a query happens to reference — it has no registry of a metric's actual label set — so the schema it builds is always "open" (Schema::closed = false) and cannot enumerate a complement.without(...)is therefore rejected outright rather than silently grouping by the wrong (incomplete) label set.by(labels)doesn't have this problem since it only needs the labels it explicitly names.Reproduction
crates/lower/src/promql.rs,resolve_group:Any query using
without, e.g.sum without (instance) (rate(http_requests_total[5m])), fails to lower withLoweringError::UnsupportedFeature. There is currently no test exercising a successfulwithout(...)lowering — only the rejection path is reachable.