Summary
limitk(k, v) and limit_ratio(r, v) parse but are rejected (UnsupportedAggregateOp). Split out of #49, which landed the two aggregation operators group and count_values.
Unlike group/count_values, these are series-sampling selection operators: they return a deterministic-but-unordered subset of the input series unchanged, not a reduction.
limitk(k, v) — up to k series per group. Which series is unspecified (deterministic across evals), so it is not topk (no value ranking).
limit_ratio(r, v) — a deterministic ~r fraction of series; r ∈ [-1, 1], negative selects the complement.
Corpus impact
33 rejections (limit_ratio 19, limitk 14) — see promql_corpus_testdata.txt.
Why deferred
Honest lowering needs a sampling-selection node in the IR, which neither the aggregate-intent model nor the Sort → Limit (topk) pair captures:
- Modeling
limitk as Sort{value} → Limit{k} would rank by value and change which series pass through — a silent divergence (the same anti-pattern that made group→sum wrong). The corpus exercises exactly this: count(limitk(2, http_requests) and http_requests) asserts on the identity of the surviving series.
limit_ratio selects a fraction of a runtime-unknown series count — not expressible as a static Limit{n}; it needs a ratio-sampling node (with the negative-ratio complement rule).
- Many uses carry a dynamic k / ratio (
limitk(scalar(foo), …), limit_ratio(time() % 17/17, …)) that the constant-parameter path can't express.
Design questions: a Sample { by, kind: TopKUnordered(k) | Ratio(r) } selection node; per-group partitioning without an ordering; deterministic-selection semantics; dynamic k/ratio.
Pin
limitk_and_limit_ratio_are_rejected__GAP in crates/frontend-promql/tests/promql_conformance.rs (§S).
Summary
limitk(k, v)andlimit_ratio(r, v)parse but are rejected (UnsupportedAggregateOp). Split out of #49, which landed the two aggregation operatorsgroupandcount_values.Unlike
group/count_values, these are series-sampling selection operators: they return a deterministic-but-unordered subset of the input series unchanged, not a reduction.limitk(k, v)— up tokseries per group. Which series is unspecified (deterministic across evals), so it is nottopk(no value ranking).limit_ratio(r, v)— a deterministic ~rfraction of series;r ∈ [-1, 1], negative selects the complement.Corpus impact
33 rejections (
limit_ratio19,limitk14) — seepromql_corpus_testdata.txt.Why deferred
Honest lowering needs a sampling-selection node in the IR, which neither the aggregate-intent model nor the
Sort → Limit(topk) pair captures:limitkasSort{value} → Limit{k}would rank by value and change which series pass through — a silent divergence (the same anti-pattern that madegroup→sumwrong). The corpus exercises exactly this:count(limitk(2, http_requests) and http_requests)asserts on the identity of the surviving series.limit_ratioselects a fraction of a runtime-unknown series count — not expressible as a staticLimit{n}; it needs a ratio-sampling node (with the negative-ratio complement rule).limitk(scalar(foo), …),limit_ratio(time() % 17/17, …)) that the constant-parameter path can't express.Design questions: a
Sample { by, kind: TopKUnordered(k) | Ratio(r) }selection node; per-group partitioning without an ordering; deterministic-selection semantics; dynamic k/ratio.Pin
limitk_and_limit_ratio_are_rejected__GAPincrates/frontend-promql/tests/promql_conformance.rs(§S).