Skip to content

feat(promql): scalar operand for BinaryOp — vector-op-scalar lowering (#35) - #77

Merged
zzylol merged 1 commit into
mainfrom
feat/binaryop-scalar-operand
Jul 2, 2026
Merged

zzylol merged 1 commit into
mainfrom
feat/binaryop-scalar-operand

Conversation

@zzylol

@zzylol zzylol commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Closes #35 — the single biggest real-world lowering blocker.

What

<vector> op <scalar> — threshold alerts (v > 10*1024*1024), unit conversions (rate(m[5m]) * 100) — didn't lower: BinaryOp required both operands to be vectors and the front end rejected bare number literals.

How

  • New Scalar(f64) leaf in the L2 relational tree and the L3 canonical IR.
  • A number literal — and a constant-folded scalar expression (10*1024*102410485760, 24 * 360086400) — lowers to Scalar. A BinaryOp operand folds to a scalar when it contains no vector selector, otherwise walks as a vector.
  • BinaryOp output schema now follows the vector side (a scalar contributes no labels).
  • num_expr gained constant-folding of scalar arithmetic (also makes topk(2+1, …) work).

Impact

awesome-prometheus-alerts corpus: lowered 13 → 863 / 949 (rejected 86, unparseable 0). The dominant <vector> <cmp> <scalar> shape now lowers.

Flipped scalar_literal_operand_is_rejected__GAP + scalar_threshold_comparisons_are_rejected__GAP into passing conformance/corpus tests; raised the corpus coverage ratchet 12 → 800. Vector-vector BinaryOp and every other path unchanged. Full suite green (29 binaries), clippy clean.

🤖 Generated with Claude Code

…#35)

`<vector> op <scalar>` — threshold alerts (`v > 10*1024*1024`), unit
conversions (`rate(m[5m]) * 100`) — did not lower: BinaryOp required both
operands to be vectors and the front end rejected bare number literals.
This was the single biggest real-world blocker (~822/949 of the alerts
corpus).

Adds a `Scalar(f64)` leaf to the L2 relational tree and the L3 canonical IR.
A number literal (and a constant-folded scalar expression like
`10*1024*1024` / `24 * 3600`) lowers to `Scalar`; a `BinaryOp` operand folds
to a scalar when it has no vector selector, else walks as a vector. The
BinaryOp output schema follows the vector side (a scalar contributes no
labels); `num_expr` now constant-folds arithmetic (also lets `topk(2+1, …)`
work).

Impact: awesome-prometheus-alerts corpus coverage jumps from 13 to 863/949
lowered. Flipped `scalar_literal_operand_is_rejected__GAP` and
`scalar_threshold_comparisons_are_rejected__GAP` into passing tests; raised
the corpus ratchet 12 -> 800. Vector-vector BinaryOp and all other paths
unchanged. Full workspace suite green; clippy --all-targets clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@zzylol
zzylol merged commit a1f1f21 into main Jul 2, 2026
1 check passed
@zzylol
zzylol deleted the feat/binaryop-scalar-operand branch July 2, 2026 22:39
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.

QueryExpr::BinaryOp has no scalar/literal operand — vector-op-scalar PromQL rejected

1 participant