fix: clear stale sliding aggregate state for empty RANGE frames - #24185
fix: clear stale sliding aggregate state for empty RANGE frames#24185lyne7-sc wants to merge 1 commit into
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #24185 +/- ##
==========================================
- Coverage 81.06% 81.05% -0.01%
==========================================
Files 1107 1106 -1
Lines 382191 382266 +75
Branches 382191 382266 +75
==========================================
+ Hits 309805 309863 +58
- Misses 54083 54089 +6
- Partials 18303 18314 +11 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
viirya
left a comment
There was a problem hiding this comment.
Verified the fix end-to-end locally — LGTM.
Reproduced the bug on current main with the issue's query: pre-fix output is 40 110 2 10 100 (the k=10 frame's v=100 leaks into k=40's result via SUM/COUNT/MAX), post-fix it's the correct 40 10 1 10 10. So the diagnosis in #24184 is spot on: the empty k=30 frame (k ∈ [20,25], no rows) returned default_value without touching the accumulator, leaving it holding the previous frame's rows while last_range advanced to the empty range — so the next non-empty frame's incremental retract_bound = cur.start - last.start never removed the stale rows.
The fix restores the invariant that the accumulator holds exactly last_range: on an empty frame it retracts the whole prior [last_range.start, last_range.end), using the same filter-mask slicing as the update path. Correct and minimal.
A couple of things I checked that might be useful:
- The plain (non-sliding) sibling doesn't need the same change.
PlainAggregateWindowExpr::get_aggregate_result_inside_rangehas the identicalcur_range.start == cur_range.endearly-return, but it's only ever used foris_ever_expanding()frames (start pinned atUNBOUNDED PRECEDING). Such a frame can only be empty as a leading prefix and stays non-empty once it grows, so the non-empty→empty→non-empty sequence that triggers this bug isn't reachable there. Good that the fix is scoped to sliding only. - No regressions in the sliding-window suite. (The only failures I saw in
window*.sltwere the pre-existingwindow_topk_pushdown.sltones that also fail onmainwithout this patch — they're a missing-test-data/plan-shape thing, unrelated to this change.)
Nice catch and clean fix.
|
@viirya thanks for your review! |
Which issue does this PR close?
Rationale for this change
Sliding aggregate window functions can return incorrect results when a bounded
RANGEframe transitions from non-empty to empty and then back to non-empty.The empty frame does not clear the previous accumulator state, so stale values are included in subsequent results.
What changes are included in this PR?
Are these changes tested?
Yes.
Are there any user-facing changes?
Bug fix only.