Problem
PromQL unary negation (-expr) flips the sign of every sample — -rate(http_errors_total[5m]), -some_metric, and negation nested inside a larger expression (http_requests_total - -http_errors_total, sum(-node_cpu_seconds_total)) are all rejected. Root cause: the L2 PromQL path has no negate/scalar node to express "multiply this vector by -1", so Expr::Unary is rejected outright rather than silently computing the wrong (unnegated) result.
This is the same underlying gap as #35 (no scalar operand in the relational-level binary-op shape) — negation is effectively x * -1, which needs a scalar operand to express.
Reproduction
crates/lower/tests/promql_conformance.rs, test unary_negation_is_rejected__GAP:
#[test]
fn unary_negation_is_rejected__GAP() {
let _ = rejected("-rate(http_errors_total[5m])");
let _ = rejected("-some_metric");
let _ = rejected("-metric_a or -metric_b");
let _ = rejected("http_requests_total - -http_errors_total");
let _ = rejected("sum(-node_cpu_seconds_total)");
}
All five currently assert rejection. Lowering them to a correctly-negated result is the acceptance criterion.
Problem
PromQL unary negation (
-expr) flips the sign of every sample —-rate(http_errors_total[5m]),-some_metric, and negation nested inside a larger expression (http_requests_total - -http_errors_total,sum(-node_cpu_seconds_total)) are all rejected. Root cause: the L2 PromQL path has no negate/scalar node to express "multiply this vector by -1", soExpr::Unaryis rejected outright rather than silently computing the wrong (unnegated) result.This is the same underlying gap as #35 (no scalar operand in the relational-level binary-op shape) — negation is effectively
x * -1, which needs a scalar operand to express.Reproduction
crates/lower/tests/promql_conformance.rs, testunary_negation_is_rejected__GAP:All five currently assert rejection. Lowering them to a correctly-negated result is the acceptance criterion.