fix(lower): topk over a bare selector preserves by-labels (#30) - #31
Merged
Conversation
This was referenced Jun 19, 2026
…ng by-labels (#30) `topk(k, <bare instant selector>) by (labels)` — e.g. `topk(3, http_requests_total) by (job)` ("top-3 series per job") — mislowered. The non-heavy-hitter path in `build`'s `Outer::TopK` else-branch defaulted a bare selector argument (`inner.func == None`) to an implicit cross-series `AggFunc::Sum`. That reducing `Sum` collapsed every label (including the `by` partition keys) into a single `sum` column, so `Sort.partition_by = [job]` no longer resolved at L3 — a regression surfaced reviewing the Partition → `Sort.partition_by` reframe (#12, PR #18). It was also semantically wrong: PromQL `topk` ranks the raw instant-vector samples, it does not sum them. A bare selector now ranks over the `filtered_source` directly (label- preserving), so `Sort.partition_by` ranks within each group. A range-vector- function argument (`topk(k, rate(m[5m]))`) still reduces per series first — also label-preserving — so those paths are unchanged, as are the heavy-hitter `count_over_time` and `bottomk` cases. Expected: `topk(3, http_requests_total) by (job)` → `Limit{3} → Sort{value desc, partition_by:[job]} → Scan`. Tests: bare-selector topk by-label (ranks per group, no implicit Sum) and bare-selector topk without `by` (ranks raw samples). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
zzylol
force-pushed
the
fix/topk-bare-selector-partition
branch
from
July 2, 2026 12:36
0def7fa to
0d24439
Compare
This was referenced Jul 2, 2026
Closed
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.
What & why
Fixes #30 — a follow-up to PR #18 (which removed the L3
Partitionnode and routed per-group ranking ontoSort.partition_by).topk(k, <bare instant selector>) by (labels)— e.g.topk(3, http_requests_total) by (job)("top-3 series perjob") — mislowered:The non-heavy-hitter path in
build'sOuter::TopKelse-branch defaulted a bare-selector argument (inner.func == None) to an implicit cross-seriesAggFunc::Sum. That reducingSumcollapsed every label (including thebypartition keys), soSort.partition_by = [job]no longer resolved at L3. It was also semantically wrong — PromQLtopkranks the raw instant-vector samples, it does not sum them.How
A bare selector now ranks over the
filtered_sourcedirectly (label-preserving), soSort.partition_byranks within each group:A range-vector-function argument (
topk(k, rate(m[5m])),topk by (host) (k, avg_over_time(...))) still reduces per series first — also label-preserving — so those paths are unchanged, as are the heavy-hittercount_over_timeandbottomkcases.Tests
topk_over_bare_selector_by_label_ranks_per_group—Sort.partition_by = [job]over a bareScan, no implicitSum.topk_over_bare_selector_ranks_raw_samples— noby→ global ranking over raw samples.cargo clippy --all-targetsclean.Closes #30. Follow-up to #18.
🤖 Generated with Claude Code