feat(promql): native-histogram accessor functions (#43) - #78
Merged
Merged
Conversation
`histogram_count`/`histogram_sum`/`histogram_avg`/`histogram_stddev`/
`histogram_stdvar`/`histogram_fraction` parsed but were rejected. They now
lower to per-series intents — the largest un-implemented function family
(~282 corpus rejections, dominated by histogram_fraction).
Each `histogram_<accessor>(v)` extracts one float per series from a native
histogram, so it lowers to a per-series `Aggregate{[accessor]}` directly over
the (instant) argument vector — mirroring `histogram_quantile`, which was
already handled and (unlike these) also covers the classic `le`-bucket form.
`histogram_fraction(lower, upper, v)` carries its bounds in the intent.
- L3 `AggIntent`: + HistogramCount/Sum/Avg/StdDev/StdVar/Fraction{lower,upper};
requires()=TimeSeries, is_per_series()=true, float output columns.
- L2 `AggFunc`: mirror variants; converter maps each.
- Front end: `walk_histogram_accessor` + dispatch.
+ conformance tests (per-series intents, fraction bounds). Full workspace
suite green; clippy --all-targets clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Collapse the two `Expr::Call` histogram arms into one
`starts_with("histogram_")` guard routing to a `walk_histogram` dispatcher
(histogram_quantile → Quantile; accessors → Histogram* intents). Same
behavior; one arm.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…s native)
Per review feedback: keep two lowerings of histogram_quantile instead of
collapsing both to a generic Quantile.
- Classic `le`-bucket form (recognised by a `by (le)` grouping, e.g.
`histogram_quantile(φ, sum by (le) (rate(x_bucket[5m])))`) → a new
`HistogramQuantile{q}` intent: exact cumulative-bucket interpolation, not a
sketch-able quantile (no accuracy target).
- Native-histogram form (any other argument) → the generic `Quantile` intent
(sketch-able), unchanged.
We can't see sample types at lowering, so the classic form is detected by its
distinctive `by (le)` grouping (`groups_by_le`).
L3 AggIntent + L2 AggFunc + converter mapping added. Updated the three tests
that asserted the classic form → Quantile, added
`histogram_quantile_classic_bucket_vs_native`, and refreshed the module
doc-table. Full workspace suite green; clippy --all-targets clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The bucket-vs-sketch discriminator recognised only a `by (le)` grouping, so a
genuinely bucketed query without an explicit `sum by (le)` fell to the
sketch-able generic `Quantile` — wrong for pre-aggregated bucket counts.
`is_classic_bucket_arg` now recurses the argument and treats it as the classic
cumulative-bucket form when it finds any of: a `by (le)` grouping, a selector
on a `_bucket` metric (bare name or `__name__`), or an `le` label matcher.
Native histograms and raw samples (no le/bucket signal) still lower to the
sketch-able `Quantile{q, accuracy}`.
Verified: `rate(x_bucket[5m])` and `rate(x{le="0.5"}[5m])` → HistogramQuantile;
native/raw metrics → Quantile. Updated the two `_bucket`-without-`sum-by-le`
tests + strengthened the classic-vs-native test. Full suite green; clippy clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #43 — the largest un-implemented function family (~282 corpus rejections).
What
histogram_count/histogram_sum/histogram_avg/histogram_stddev/histogram_stdvar/histogram_fractionparsed but were rejected. They now lower to per-series intents. (histogram_quantilewas already handled and — unlike these — also covers the classicle-bucket form, so it's unchanged.)How
Each
histogram_<accessor>(v)extracts one float per series from a native histogram, so it lowers to a per-seriesAggregate{[accessor]}directly over the (instant) argument vector — the same shape ashistogram_quantile.histogram_fraction(lower, upper, v)reads its bounds from args 0/1 and the vector from arg 2, carrying the bounds in the intent.AggIntent: +HistogramCount/Sum/Avg/StdDev/StdVar/Fraction{lower,upper};requires()=TimeSeries,is_per_series()=true, float output columns.AggFunc: mirror variants; converter maps each.walk_histogram_accessor+ dispatch (mirrorswalk_histogram_quantile).Verified
histogram_count(rate(http_req[5m]))→Aggregate{HistogramCount} over Aggregate{Rate} over TimeRange;histogram_fraction(0, 0.2, v)carries{lower:0, upper:0.2};sum by (job)(histogram_count(v))preserves the label. + conformance tests. Full suite green (29 binaries), clippy clean.Note: this models intent (extract count/sum/… from a native histogram); actual native-histogram execution is an L4/runtime concern, deliberately not encoded at L3.
🤖 Generated with Claude Code