Skip to content

Arrow: Fix double-scaled setInitialCapacity for vectorized reads#17057

Open
thswlsqls wants to merge 1 commit into
apache:mainfrom
thswlsqls:fix/arrow-vectorized-reader-setinitialcapacity-double-scale
Open

Arrow: Fix double-scaled setInitialCapacity for vectorized reads#17057
thswlsqls wants to merge 1 commit into
apache:mainfrom
thswlsqls:fix/arrow-vectorized-reader-setinitialcapacity-double-scale

Conversation

@thswlsqls

Copy link
Copy Markdown
Contributor

Fixes the same over-allocation described in #11672.

Summary

  • VectorizedArrowReader.allocateVectorBasedOnTypeName() passed batchSize * typeWidth (or batchSize * AVERAGE_VARIABLE_WIDTH_RECORD_SIZE for BINARY) to Arrow's setInitialCapacity(int).
  • setInitialCapacity(int valueCount) already multiplies by type width internally (verified against arrow-vector 15.0.2, pinned in gradle/libs.versions.toml), so the extra multiplication double-scaled the allocation.
  • Affected: FIXED_LEN_BYTE_ARRAY (fixed(N)/UUID), BINARY, INT96. Large fixed(N) columns can over-allocate per batch, risking OOM (default MAX_ALLOCATION_SIZE is unbounded, so it does not always throw).
  • Fix: pass batchSize alone, matching the sibling branches in the same method and the logical-type paths (UUID, decimal) that already allocate correctly with allocateNew(batchSize).
  • Scope limited to allocateVectorBasedOnTypeName(); the same pattern also exists in allocateVectorForEnumJsonBsonString() (STRING/ENUM/JSON/BSON), left for a follow-up.

Testing done

  • Added TestVectorizedReaderAllocation#fixedLenByteArrayVectorCapacityMatchesBatchSize and #binaryVectorCapacityMatchesBatchSize, writing a single row through a real Parquet file and asserting the vector's getValueCapacity() stays within a small multiple of the batch size.
  • Verified against the pre-fix code that both tests fail as expected: a fixed(1000) column with batchSize=16 measured capacity 16775 (bound 64), and a BINARY column measured 247 (bound 64).
  • ./gradlew :iceberg-arrow:check — 31 tests passed (0 failures), including spotlessCheck and checkstyle.

allocateVectorBasedOnTypeName() passed batchSize * typeWidth to Arrow's
setInitialCapacity(int), which already multiplies by type width internally
(arrow-vector 15.0.2). This double-scaled allocation for FIXED_LEN_BYTE_ARRAY,
BINARY, and INT96 columns. Pass batchSize alone, matching the sibling
branches and logical-type paths in the same method.

Generated-by: Claude Code
@github-actions github-actions Bot added the arrow label Jul 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant