Skip to content

fix(frontend-metricsql): lower vector negation as PromQL does (#1096) - #1120

Merged
milindsrivastava1997 merged 1 commit into
mainfrom
1096-stage0-metricsql-negation
Nov 2, 2026
Merged

milindsrivastava1997 merged 1 commit into
mainfrom
1096-stage0-metricsql-negation

Conversation

@milindsrivastava1997

@milindsrivastava1997 milindsrivastava1997 commented Oct 30, 2026 •

Copy link
Copy Markdown
Collaborator

Part of #1096 (Stage 0). Merges into main.

Why

MetricsQL and PromQL lowered the same vector negation -x to different IR, and a comment in the MetricsQL frontend claimed they matched. Different IR for the same query means later stages can treat it differently (rules, pricing, accuracy propagation). (The audit called this a cross-language CSE break; a workload has exactly one language, so the defect is the IR divergence itself.)

What

MetricsQL -x now lowers exactly as PromQL's: a PromqlMap whose sample is Negative and which drops the metric name. Stale * -1 test names and comments on the PromQL side are corrected.

How

One arm of MetricsqlLowerer::lower changes from PromqlScalarOp { Mul, -1 } to the PromqlMap PromQL builds. asap-frontend-promql becomes a dev-dependency of asap-frontend-metricsql so the regression test can compare both frontends.

Key code interfaces added / modified

None.

Major algorithm changes

None.

Before this PR

-rate(up[5m]) as MetricsQL → Project { value: Arithmetic { Mul, Column(value), Literal(-1.0) } }; as PromQL → Project { value: Negative { Column(value) } }.

After this PR

Both produce Project { value: Negative { Column(value) }, … promql_drop_metric_name … }; the lowered QueryRoots are equal.

Evidence

The new test failed before the fix with exactly that difference (left: … Arithmetic { op: Mul, … Literal(Float64(-1.0)) }, right: … Negative { … }) and passes after.

Verification

  • Unit tests: frontend-metricsql lowering_semantics::vector_negation_lowers_as_in_promql — MetricsQL and PromQL lower -rate(up[5m]) to equal query roots. All asap-frontend-metricsql, asap-frontend-promql, asap-planner tests pass.
  • End-to-end tests: renamed integration-tests binary_op::q36_unary_negation_is_a_negative_projection and frontend-promql promql_conformance::unary_negation_lowers_as_a_negative_projection (assertions unchanged).
  • Other checks: fmt, clippy -D warnings. Tests ran before rebasing onto main, against the former integration branch refactor/stage-boundaries. That base had 7 asap-integration-tests failures and failing corpus_snapshots/sketch_plan_snapshots, all unrelated to this change; this branch matched it. Not yet re-run on main. Commits skip the pre-commit cargo test hook (fmt/check/clippy ran).

Snapshot changes

None (the corpus is PromQL only).

Architectural decisions

Compare against the PromQL lowering rather than assert a node shape, so the two frontends cannot drift again for this construct.

Limitations and follow-up

docs/develop_docs/physical-compile-coverage.md row 8 still says the frontend emits * -1; that table is a snapshot "at #475" and is left as is.

Human review — do not complete with an agent

  • The MVP boundary is correct.
  • New conceptual layers or public interfaces are necessary.
  • The before/after description matches the intended product behavior.
  • Human reviewer:
  • Decision and rationale:

🤖 Generated with Claude Code

MetricsQL lowered `-x` as `x * -1` (a PromqlScalarOp Mul), while the PromQL
front end lowers it as a PromqlMap whose sample is `Negative` and which drops
the metric name. The two front ends therefore produced different IR for the
same query, and the comment claiming they matched was false.

The regression test lowers `-rate(up[5m])` through both front ends and
asserts equal query roots. Stale `* -1` test names and comments on the
PromQL side are corrected; their assertions already checked `Negative`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@milindsrivastava1997
milindsrivastava1997 force-pushed the 1096-stage0-metricsql-negation branch from 9e31b3f to 0a4c49c Compare November 2, 2026 14:51
@milindsrivastava1997
milindsrivastava1997 changed the base branch from refactor/stage-boundaries to main November 2, 2026 16:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants