storage: clear the oneshot-source decode arena per row#37135
Merged
frankmcsherry merged 1 commit intoJun 18, 2026
Conversation
`render_decode_chunk` created a single `RowArena` in the operator body and reused it across every chunk and row without ever clearing it, so the MFP-evaluation temporaries for the entire source accumulated for the lifetime of the COPY — an unbounded arena. Scope the arena to each decoded chunk and clear it per row, so it holds at most one row's temporaries and is freed when the chunk is done. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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
render_decode_chunk(the oneshot/COPY decode operator) created oneRowArenain the operator body and reused it across every chunk and every row without ever clearing it. The arena owns whatever is pushed into it for its lifetime, so the MFP-evaluation temporaries for the entire source accumulated until the COPY finished — an unbounded arena proportional to the data volume.This scopes the arena to each decoded chunk and clears it per row, so it holds at most one row's worth of temporaries and is released when the chunk is processed.
Why
Found while auditing
RowArenalifetimes (companion to the arena work in #37114 / #37134). This was the only arena in the audit that was both operator-lived and never cleared — i.e. a genuine unbounded accumulation rather than a bounded high-water. It brings the operator in line with the "arena per batch, cleared per row" idiom the other operators use.Tests
No behavior change (the MFP output is identical; only the arena's lifetime changes). Covered by the existing oneshot-source / COPY FROM tests.