fix(parquet): address VECTOR review feedback on nested reads and shared helpers - #1
Merged
cursor[bot] merged 4 commits intoAug 17, 2026
Conversation
`ContainsVectorType`, `ContainsVectorField` and `ValidateVectorElements` were duplicated across schema validation, the Parquet write path and the VECTOR read wrapper. Move them into `VectorUtils` and let every caller share one implementation. While validating a FixedSizeList, also reject a VECTOR whose child does not hold `length * list_size` values. Arrow does not verify this when importing an array over the C data interface, so the element scan reading the child validity bitmap could run past its end on the write path. Keep the name and metadata of a MAP entries field when rebuilding a nested type for reads and writes, instead of falling back to Arrow's defaults. Co-authored-by: 小明同学 <ChaomingZhangCN@users.noreply.github.com>
`NormalizeRecordBatchOffsets` had no FixedSizeList branch, so every sliced VECTOR column fell back to a full copy of its values. Slice the child instead, the way the list and struct layouts already do, since a contiguous slice of the parent always spans a contiguous range of the child. Co-authored-by: 小明同学 <ChaomingZhangCN@users.noreply.github.com>
A file written by Paimon Rust or Python exposes a VECTOR column as Arrow FixedSizeList, so the read schema handed to the Parquet plugin keeps that type too. `HasSameNestedProjectionShape` had no FixedSizeList branch and rejected such a schema as a partial projection inside list/map, and `CollectLeafIndices` and `SkipLeafIndices` treated a FixedSizeList as a leaf column. `FieldMappingBuilder::CreateDataCastExecutors` also has to exempt FixedSizeList from the scalar cast lookup, like the other nested types, because the reader reshapes those columns itself. Co-authored-by: 小明同学 <ChaomingZhangCN@users.noreply.github.com>
Move the `needs_vector_conversion` writer parameter before the memory pool, build VECTOR test arrays from JSON instead of Arrow builders, and drop the license header from the VECTOR fixture notes. Co-authored-by: 小明同学 <ChaomingZhangCN@users.noreply.github.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.
Purpose
Follow-up to the review feedback on apache/paimon-cpp#198 (VECTOR Parquet storage). It targets
codex/vector-parquet-mvpso the PR branch can absorb the changes.Addressed review points:
ContainsVectorType/ContainsVectorField/ValidateVectorElementswere duplicated in schema validation, the Parquet write converter and the VECTOR read wrapper. They now live in one place,VectorUtils(src/paimon/common/utils/arrow/vector_utils.{h,cpp}).FixedSizeListchild holdslength * list_sizevalues, so a caller passing a short child made the write-path nullability check index past the child's validity bitmap.VectorUtils::ValidateVectorElementsnow rejects that layout before scanning.HasSameNestedProjectionShape,CollectLeafIndicesandSkipLeafIndicesin the Parquet reader had noFIXED_SIZE_LISTbranch, so reading a file that stores VECTOR as ArrowFixedSizeList(Paimon Rust and Python writers) failed with "partial projection inside list/map" when the vector was nested in a LIST, and a vector column was otherwise treated as a leaf.FieldMappingBuilder::CreateDataCastExecutorsnow exemptsFIXED_SIZE_LISTfrom the scalar cast lookup, like the other nested types.NormalizeRecordBatchOffsetshad noFIXED_SIZE_LISTbranch, so sliced VECTOR columns were fully copied instead of having their buffers sliced.needs_vector_conversionmoved before the memory pool in theParquetFormatWriterconstructor, VECTOR test arrays built from JSON instead of Arrow builders, and the license header removed from the fixture notes.Tests
src/paimon/common/utils/arrow/vector_utils_test.cpp: helper detection across nested types, null-element rejection for both LIST and FixedSizeList VECTOR values, slice handling, and the truncated-child layout.arrow_utils_test.cpp: regression test that the write-path nullability check rejects aFixedSizeListwhose child is shorter than the declared dimension, plus afixed_size_listcase in the offset-normalization matrix so the zero-copy assertions cover it.parquet_vector_io_test.cpp: readinglist<fixed_size_list<float, 3>>from a file written by the plain Arrow Parquet writer (the Rust/Python physical layout), and an end-to-end read with a predicate pushed down on a non-vector column next to a VECTOR column.Validation status: the workspace had no configured build, so a Debug build with
PAIMON_BUILD_TESTS=ONwas configured from scratch (-DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++, since/usr/bin/c++is a Clang that cannot linklibstdc++here). All third-party dependencies are bundled, sopaimon-common-test,paimon-core-testandpaimon-parquet-format-testare still building Arrow/Parquet/ORC from source on this 4-core VM. Test results will be reported once the build finishes.API and Format
API: No change beyond PR apache#198.
VectorUtilsis an internal helper undersrc/paimon/common/utils/arrow/.Schema protocol: No.
Storage format: No. VECTOR is still persisted as a standard Parquet LIST; the reader change only widens which physical layouts can be read back.
Documentation
No new documentation. The VECTOR section added by PR apache#198 already records the append-only Parquet-only scope.
Generative AI tooling
Generated-by: Cursor Cloud Agent (Claude Opus 5)