Repository navigation
feat(data): declare a stable physical Arrow schema on task streams - #1062
Open
kamcheungting-db wants to merge 1 commit into
Open
kamcheungting-db wants to merge 1 commit into
kamcheungting-db wants to merge 1 commit into
Conversation
ProjectionContext::Make now takes the reader's physical input Arrow schema and builds its reusable projection state from it. The context owns deep copies of the input and output Arrow schemas: each selected output field becomes a deep copy of its physical counterpart, preserving the physical layout, nested list offset widths, metadata, and type-specific flags such as sorted map keys, while only top-level names and nullability come from the projected schema. The borrowed logical-schema pointers and their accessors are removed, so schema inputs are only used during construction. FileScanTaskReader::Open resolves the physical schema before emitting any batch so pass-through, filtered, and projected batches all match the schema reported by the stream, including files that mix list and large_list layouts. Tests cover both projection backends (nanoarrow and Arrow compute): mixed list layouts, sorted-map flags under nullability changes, zero-column projections, and 36 task-reader scenarios that destroy the reader before consuming the stream and validate retained batches after the stream is released.
This branch has not been deployed
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.
Problem
A
FileScanTaskReaderstream uses the merge-on-read path whenever a task carries v2 position or equality deletes. Until now that stream declared its schema by converting the logical Iceberg projected schema withToArrowSchema(), which always yields the canonical Arrow layout (e.g. 32-bitlist).The batches it emits, however, follow the physical layout produced by the file reader, which can legitimately differ:
ReaderProperties::kArrowUseLargeListasks the Parquet reader forlarge_list(64-bit offsets),ARROW:schemametadata can store a mix oflistandlarge_list,So one and the same stream could emit two different physical layouts at once:
What this PR does
ProjectionContext— the reusable state behindProjectBatch— is now built from the reader's physical Arrow schema and owns deep copies of both its input and output Arrow schemas. The stream declares exactly the schema its batches are made of, no matter which path produces them.How it works
Key changes
ProjectionContext::Makenow takes the physical inputArrowSchema(the old 3-argument overload is removed) and:input_arrow_schema_as an owned deep copy of it;output_arrow_schema_by deep-copying, for each output field, the selected physical child and then applying only the top-level name and nullability from the projected schema — the physical layout, nested list offset widths, metadata (field ids, extension annotations) and type-specific flags (e.g. sorted map keys) are preserved;Schema*members and theinput_schema()/output_schema()accessors are gone — schema inputs are only read during construction.FileScanTaskReader::Openresolvesreader->Schema()once, before the first batch, so pass-through and projected batches derive from the same layout, and schema errors surface atOpeninstead of mid-stream. The pass-through flag is renamedproject_all_columnsto say what it actually means.MergeOnReadStreamSourceno longer cachesreader_->Schema()nor stores schemashared_ptrs; it uses the context's owned input schema forComputeAliveRows, andSchema()returns an independent deep copy on every call (results stay valid after the stream is released).There is no public API change:
ProjectionContextis an internal utility, and theFileScanTaskReaderbehavior change is the guarantee itself — every batch now matches the schema the stream reports.Testing
arrow_c_data_util_test.cc— all existing projection tests now run through the production path with a physical schema, on both backends (nanoarrow and Arrow compute). New cases:PreservesPhysicalListLayoutsWithBothBackends— mixed nested list layouts survive selection, reordering and renaming;PreservesPhysicalMapFlagsWhenChangingNullability—keys_sortedsurvives a nullability change;EmptyProjectionPreservesRowCount— zero-column projection keeps the alive row count;file_scan_task_reader_test.cc:EmptyProjectionPreservesLiveRowCount— position deletes plus a zero-column projection still streams the correct number of live rows;FileScanTaskPhysicalSchemaTest— 36 scenarios: 6 delete-batch selections (delete first row / a second-batch row / no-op / whole first batch / all rows / empty split) × {all columns, pruned} × {list, large_list, stored mixed schema}. Each scenario checks the declared schema before, between and after batches; imports every batch against it; destroys the task reader before consuming the stream; and re-validates the retained batches after the stream is released.data_test: 231 tests pass with both projection backends;pre-commit(clang-format included) is clean.Related
FileScanTaskReader::Open resolves the physical schema before emitting any batch so pass-through, filtered, and projected batches all match the schema reported by the stream, including files that mix list and large_list layouts.
Tests cover both projection backends (nanoarrow and Arrow compute): mixed list layouts, sorted-map flags under nullability changes, zero-column projections, and 36 task-reader scenarios that destroy the reader before consuming the stream and validate retained batches after the stream is released.