Skip to content

fix: don't double count column join keys in SortMergeJoinExec buffered batch reservation - #27346

Open
Kristofferjoha wants to merge 2 commits into
apache:mainfrom
Kristofferjoha:27322-fix-join-key-double
Open

Kristofferjoha wants to merge 2 commits into
apache:mainfrom
Kristofferjoha:27322-fix-join-key-double

Conversation

@Kristofferjoha

@Kristofferjoha Kristofferjoha commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

Which issue does this PR close?

Rationale for this change

BufferedBatch::try_new reserves batch.get_array_memory_size() plus the size of each evaluated join key array. For a column key, the key array is the batch's own column, so that column is counted twice. Joins on wide string keys reserve about twice what they hold, and spill or fail under a memory limit earlier than they should.

What changes are included in this PR?

  • BufferedBatch::try_new only charges key buffers the batch doesn't already hold, using RecordBatchMemoryCounter.
  • When a spilled batch is read back, the join keys are re-evaluated against it so the pre-spill key buffers are released.

With the repro from the issue both queries now report 19.5 MB (was 38.8 MB and 19.7 MB).

What is the testing strategy for this PR?

Added column_join_key_not_double_counted, which checks that peak_mem_used is the same for an int key and a string key over the same data.

Updated the expected peak_mem_used in explain_analyze.slt (432 B -> 288 B) and the size formula in three existing spill tests.

The re-evaluation on restore is not covered by a test.

Are there any user-facing changes?

No.

@vinycalves vinycalves left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Two logic questions; no code suggestions.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Does the new test cover a computed join key and the spill/read-back path, where the key array is actually unshared? When a batch spills, does the reservation still avoid double-counting buffers shared with the key arrays?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks, added a test which covers a computed key and the spill/read-back path. On spill the batch is dropped, so only the key arrays stay in memory and they’re counted once.

@github-actions github-actions Bot added sqllogictest SQL Logic Tests (.slt) physical-plan Changes to the physical-plan crate labels Nov 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

physical-plan Changes to the physical-plan crate sqllogictest SQL Logic Tests (.slt)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SortMergeJoinExec double counts join key columns in the buffered batch reservation

2 participants