Skip to content

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

Open
milindsrivastava1997 wants to merge 1 commit into
refactor/stage-boundariesfrom
1096-stage0-metricsql-negation
Open

milindsrivastava1997 wants to merge 1 commit into
refactor/stage-boundariesfrom
1096-stage0-metricsql-negation

Conversation

@milindsrivastava1997

Copy link
Copy Markdown
Collaborator

Part of #1096 (Stage 0). Merges into the integration branch refactor/stage-boundaries.

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. Same 7 asap-integration-tests failures as the untouched base; none touch this change:
    filtered_aggregates::{hand_filtered_kll_compiles_and_executes, kll_quantile_of_all_null_group_is_null},
    per_computation_candidates_sql::a_filter_or_group_key_over_an_estimate_has_no_guarantee,
    promql_to_post_asap::{planner_heap_topk_reference_execution_matches_ground_truth, planner_only_e2e_temporal_topk_preserves_query_update_and_evaluation_contract},
    sql_to_post_asap::{sql_filter_keeps_read_predicate_and_summary_population_selection, sql_relational_parents_retain_summary_bound_aggregate}.
    corpus_snapshots and sketch_plan_snapshots fail on the base too; this branch produces the same output (only solver timings/bounds differ). Commits skip the pre-commit cargo test hook for this reason (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>
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.

1 participant