Skip to content

Fix xrate extended-range iteration and refresh rate-vs-xrate showcase (2.55) - #21

Closed
ColinDKelley wants to merge 0 commit into
invoca-2.55.1-basefrom
invoca-2.55.1/fix-xrate-extended-range
Closed

Fix xrate extended-range iteration and refresh rate-vs-xrate showcase (2.55)#21
ColinDKelley wants to merge 0 commit into
invoca-2.55.1-basefrom
invoca-2.55.1/fix-xrate-extended-range

Conversation

@ColinDKelley

@ColinDKelleyColinDKelley commented Apr 19, 2026

Copy link
Copy Markdown

Branch stack context

This PR is the second layer in the 2.55.1 stack. Review bottom-up:

invoca-2.53.1-base
└─ #27 invoca-2.55.1-base (upstream v2.55.1 merge)
└─ #21 fix-xrate-extended-range ← this PR
└─ #22 add-yrate
└─ #20 align-yrate-to-3x-range-boundary
└─ #26 replace-rate-funcs-keep-orig

Summary

Forward-port of #16 onto invoca-2.55.1-base.

Cherry-picked cleanly from invoca-2.53.1/fix-xrate-extended-range (one commit, auto-merged in both promql/engine.go and promql/promqltest/testdata/functions.test). No code changes from the 2.53.1 version — the 2.53→2.55 upstream delta does not touch the lines involved.

  • Fixes the mintFloats vs mint off-by-one in the extended-range branch of matrixIterSlice that re-appended previous-step samples into the next step's points list (inflated counter-reset corrections for xrate / xincrease / xdelta in range-query mode).
  • Refreshes the three rate() showcase expected values to match upstream's 2.53+ extrapolation behaviour (same three values we updated on 2.53.1).

Test plan

Related

Comment threadpromql/engine.go
// replacing it with later points while not yet (strictly)
// inside the range.
if t > mint || !appendedPointBeforeMint {
if t > mintFloats || !appendedPointBeforeMint {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ColinDKelley Could you help me understand the difference between mintFloats and mint?

mint is the minimum timestamp?

@ColinDKelleyColinDKelleyJul 9, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(from Cursor)

Good question — they're related but not the same thing in this function.

mint is the left edge of the current step's matrix-selector window (a timestamp in ms). For each range-query step it's computed as maxt - selRange (with optional lookback adjustments for anchored/smoothed). It's the parameter passed into matrixIterSlice and represents "start of this evaluation window."

mintFloats starts equal to mint, but after overlap handling it becomes the timestamp of the last float already in the buffer from the previous step:

mintFloats, mintHistograms:=mint, mint// ...iflen(floats) >0&&floats[len(floats)-1].T>mint {
// trim/reuse overlapping points from the prior step ...mintFloats=floats[len(floats)-1].T
}

So mintFloats means "only pull new float samples strictly after what we already have," which avoids duplicating points when stepping through a range query.

The bug this PR fixes is in the extended-range (extRange) branch, which has special logic to keep one sample at or before mint for xrate/xincrease/xdelta extrapolation. That branch was comparing iterator timestamps against mint instead of mintFloats. On step 2+ of a range query, mint advances with the window, but the buffer already contains points with mint < t ≤ mintFloats. Using mint made those look "new" again (t > mint is true), so they got re-appended and inflated counter-reset math.

Using mintFloats matches the non-extended path (if t > mintFloats at line ~3071) and the histogram path (if t > mintHistograms): compare against what's already buffered, not just the window start.

Happy to walk through a concrete step-by-step example in functions.test if that's helpful.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No this was really helpful! Thanks for explaining this out further!

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Credit all goes to Cursor! I'm learning this from its response.

Comment threadpromql/engine.go
// replacing it with later points while not yet (strictly)
// inside the range.
if t > mint || !appendedPointBeforeMint {
if t > mintFloats || !appendedPointBeforeMint {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No this was really helpful! Thanks for explaining this out further!

@ColinDKelley
ColinDKelleyforce-pushed the invoca-2.55.1/fix-xrate-extended-range branch from 5d25fc0 to 2e35102CompareJuly 9, 2026 22:27
@ColinDKelley

Copy link
Copy Markdown
Author

@ttstarck I had Cursor push this bug fix back to 2.55.1 branch (in case we want to release that) and that caused this PR to become a no-op.

Sign up for freeto 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.

2 participants

@ColinDKelley@ttstarck