You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
PromQL offset / @ time-shift modifiers have no IR representation #40
PromQL's offset modifier (metric offset 1h) and @ modifier (metric @ 1609746000) shift the evaluation/lookback time of a vector selector. Unlike without(...) (#39), which is blocked on missing catalog metadata, this is blocked on a missing IR node: there is no time-shift concept anywhere in relational::QueryExpr or canonical QueryExpr to carry the shift amount, so both modifiers are rejected unconditionally rather than partially/incorrectly lowered.
These are common in real dashboards and alerts (week-over-week comparisons, anomaly detection baselines), so this is a meaningful coverage gap distinct from the scalar-operand and without gaps.
Reproduction
crates/lower/src/promql.rs, vs_parts:
fn vs_parts(vs:&VectorSelector) -> Result<(String,Vec<L2Expr>)>{// `offset` / `@` shift the evaluation/lookback time. The intent algebra has// no representation for either, so silently lowering them (as if absent)// would change the query's meaning. Reject rather than mislower.if vs.offset.is_some() || vs.at.is_some(){returnErr(LoweringError::UnsupportedFeature("`offset` / `@` time-shift modifiers have no intent-algebra representation".into(),));}
...
Any query with offset or @ on a vector/matrix selector — e.g. rate(http_requests_total[5m] offset 1h) or http_requests_total @ 1609746000 — fails to lower with LoweringError::UnsupportedFeature. No test exercises a successful lowering of either modifier.
Reopening: this was closed as completed, but the fix never landed on main.
The implementation commit fff0a2e (feat(promql): lower offset / @ time-shift modifiers to a TimeShift node (#40)) exists only on the unmerged branch feat/40-offset-at-modifiers:
$ git merge-base --is-ancestor fff0a2e main; echo $?
1 # not an ancestor
$ git branch -a --contains fff0a2e
feat/40-offset-at-modifiers
remotes/origin/feat/40-offset-at-modifiers
Unlike the other closed feature issues (#84, #89, …), whose branches show as unmerged only because they were squash-merged, there is no equivalent squashed commit for this one on main, and grep -rn TimeShift crates/ir/src/ returns nothing.
crates/frontend-promql/src/promql.rs:1414 on main still rejects unconditionally:
http_requests_total offset 5m
→ unsupported feature: `offset` / `@` time-shift modifiers have no intent-algebra representation
Corpus impact (measured on main)
65 rejections in the Prometheus testdata corpus, and it is the only failure mode in the official-docs corpus — all 4 failing docs queries are offset/@:
That makes it the highest-impact real-world PromQL gap remaining. Either feat/40-offset-at-modifiers needs to be rebased and merged, or this issue should be reclosed as not planned with the branch's rationale recorded.
Correction to the corpus figures above: the docs corpus has 5 failures, not 4. Four are offset/@; the fifth is {__name__=~"job:.*"}, which is rejected deliberately per #67.
offset / @is supported on main. This issue was correctly closed, and my reopen was based on a stale local ref. Apologies for the noise.
What happened: my local main was 2 commits behind origin/main, and the branch I was measuring from (test/asapquery-sql-corpus) is based on that older main. So git merge-base --is-ancestor fff0a2e main was answering about a main that predated the merge. PR #106 merged feat/40-offset-at-modifiers into main on 2026-07-06 (merge commit 7f907a98ba), and origin/main does contain the work:
Verified by running the corpus against a clean origin/main worktree (9fdd3d7):
corpus
on stale branch
on origin/main
docs
44 lowered, 5 rejected
48 lowered, 1 rejected
testdata
1441 lowered, 147 rejected
1502 lowered, 86 rejected
The 65 offset/@ rejections are gone. The single remaining docs rejection is {__name__=~"job:.*"}, which is the deliberate #67 behaviour.
Both of my earlier comments on this issue should be disregarded. I've corrected the corpus figures in #108, #109 and #112, which were all measured against the same stale tree — the parser gaps in #108 are unaffected (still exactly 235 parse failures), but the denominators changed.
Activity
feat(promql): lower offset / @ time-shift modifiers to a TimeShift no…
zzylol commentedon Jul 9, 2026
Reopening: this was closed as completed, but the fix never landed on
main.The implementation commit
fff0a2e(feat(promql): lower offset / @ time-shift modifiers to a TimeShift node (#40)) exists only on the unmerged branchfeat/40-offset-at-modifiers:Unlike the other closed feature issues (#84, #89, …), whose branches show as unmerged only because they were squash-merged, there is no equivalent squashed commit for this one on
main, andgrep -rn TimeShift crates/ir/src/returns nothing.crates/frontend-promql/src/promql.rs:1414onmainstill rejects unconditionally:Corpus impact (measured on
main)65 rejections in the Prometheus testdata corpus, and it is the only failure mode in the official-docs corpus — all 4 failing docs queries are
offset/@:That makes it the highest-impact real-world PromQL gap remaining. Either
feat/40-offset-at-modifiersneeds to be rebased and merged, or this issue should be reclosed asnot plannedwith the branch's rationale recorded.zzylol commentedon Jul 9, 2026
Correction to the corpus figures above: the docs corpus has 5 failures, not 4. Four are
offset/@; the fifth is{__name__=~"job:.*"}, which is rejected deliberately per #67.Verified output:
The substance is unchanged:
offset/@is 4 of the 5 docs-corpus failures and the only unintentional one, plus 65 rejections in the testdata corpus.zzylol commentedon Jul 9, 2026
Retraction — I was wrong, re-closing.
offset/@is supported onmain. This issue was correctly closed, and my reopen was based on a stale local ref. Apologies for the noise.What happened: my local
mainwas 2 commits behindorigin/main, and the branch I was measuring from (test/asapquery-sql-corpus) is based on that oldermain. Sogit merge-base --is-ancestor fff0a2e mainwas answering about amainthat predated the merge. PR #106 mergedfeat/40-offset-at-modifiersintomainon 2026-07-06 (merge commit7f907a98ba), andorigin/maindoes contain the work:Verified by running the corpus against a clean
origin/mainworktree (9fdd3d7):origin/mainThe 65
offset/@rejections are gone. The single remaining docs rejection is{__name__=~"job:.*"}, which is the deliberate #67 behaviour.Both of my earlier comments on this issue should be disregarded. I've corrected the corpus figures in #108, #109 and #112, which were all measured against the same stale tree — the parser gaps in #108 are unaffected (still exactly 235 parse failures), but the denominators changed.
fix(test): cover QueryExpr::TimeShift in the netflow corpus visitor (#…
test(promql): re-baseline the corpus coverage tripwire (#112) (#114)