Skip to content

fix: repair native vector writes and data evolution read ranges - #1090

Merged
JingsongLi merged 2 commits into
apache:mainfrom
JingsongLi:codex/fix-native-vector-write
Oct 10, 2026
Merged

JingsongLi merged 2 commits into
apache:mainfrom
JingsongLi:codex/fix-native-vector-write

Conversation

@JingsongLi

@JingsongLi JingsongLi commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

Purpose

Fix the native writer failure reported by apache/paimon#10482. Its Native CI run has 149 failures and 195 setup errors, all caused by rejecting otherwise valid Arrow FixedSizeList inputs for VECTOR fields.

The shared input normalizer already canonicalizes ARRAY and MAP child aliases, but omits FixedSizeList. PyArrow's child field differs from Paimon's element field, so vectors fail schema validation before writing.

Changes

  • Normalize fixed-size vector child fields to the table schema and reuse the payload buffers, including sliced inputs.
  • Retain dimension and element-type validation, following Java ParquetRowDataWriter's positional vector elements and vector-length checks.
  • Validate element nullability even when the input schema already matches. NULL vectors and NULL containing ROWs mask their hidden elements.
  • Add core regression tests for aliases, slices, buffer reuse, NULL parents, invalid dimensions/types, and foreign inputs carrying visible NULL elements under NOT NULL declarations.

Validation

  • Reproduced the failure with the existing PyPaimon batch_vector_lookup_test.py and the new vector write regression test before the fix.
  • Core normalizer: 19 tests passed; TableWrite: 77 passed; DataEvolutionWriter: 18 passed.
  • Rebuilt the Python extension and passed 24 REST vector roundtrips covering Append/Data Evolution, Batch/Stream, FLOAT/DOUBLE, child aliases, sliced input, NULL vectors and NULL elements.
  • Rust 1.98.0 Clippy for paimon and pypaimon_rust, all targets with warnings denied, passed; formatting and diff checks passed.

The Python counterpart continues to install Rust main. This fix must merge before its Native CI can pass.

Additional failures uncovered after normalization

  • Validate dedicated vector formats against the compiled writer factories during writer construction. This lets Python select its existing writer for unavailable formats before any Native batch is accepted.
  • Scope each VectorBunch to its prepared merge group's first row ID and logical row count. A Python-planned split can contain multiple independent groups; using the first anchor of the whole split silently NULL-filled later groups, causing incorrect vector search results on retained tag snapshots.
  • Reproduced the multi-group range bug in a core test before the fix; added filtered reads across two noncontiguous groups and assertions for both vector values.

Final verification

  • 202 focused core tests passed: normalizer 19, DataEvolutionReader 83, TableWrite 78, DataEvolutionWriter 18, format factories 4.
  • Rebuilt the Python extension and ran all five Native CI flags: 1090 passed, 13 subtests passed, covering the original CI failures and related writer/reader/update/merge/index tests.
  • Additional focused Python suites: 251 passed, 2 subtests passed.
  • Rust 1.98.0 all-target Clippy for paimon and pypaimon_rust, formatting and diff checks passed.

Python follow-up commit: apache/paimon#10482. Its CI continues to use Rust main and therefore depends on this PR merging.

@JingsongLi JingsongLi changed the title fix: normalize Arrow fixed-size vector write inputs fix: repair native vector writes and data evolution read ranges Oct 10, 2026

@leaves12138 leaves12138 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.

Reviewed 5d02d3e, using the Python counterpart apache/paimon#10482 at 51f2c376. No blocking findings.

The FixedSizeList normalization preserves Java's positional vector elements and dimension checks without relaxing element types or visible NOT NULL constraints. Parent NULL masking and sliced payload-buffer reuse remain correct. The additional reader change correctly scopes vector selection to each prepared merge group; unavailable vector factories are rejected before writer construction can accept data.

Independent validation, with Rust 1.94.1, Python 3.10, PyArrow 19.0.1 and a freshly rebuilt extension:

  • Core: 3,918 passed, 6 ignored; formatting check passed.
  • Python bindings: 417 passed, using a Native-generated smoke warehouse rather than Java Docker fixtures.
  • Reviewer cases: 115 input/NULL/slice/validation cases and 10 combined Python-planned split cases with unequal group sizes, FLOAT/DOUBLE, and full/partial/empty selections passed.
  • Related Python suites: 969 passed, 7 skipped, 4 subtests passed, with all five Native CI flags enabled. Plan/read/write/commit counters and all six update-kind counters were positive. The skips require Python >= 3.11 for Vortex.

I also reproduced the original child-field schema rejection against an older extension, and the later-group vector NULL-fill bug against the previous normalization-only wheel; the rebuilt head passes both scenarios.

Validation boundaries: Java alignment was checked against source, not a Java/Python interoperability run or production storage. NULL-vector Classic reads encounter an independently reproduced pure-PyArrow 19 Parquet issue; Native values were checked instead. Nested required-element cases were read directly through the Rust binding because the Python target-schema parser already loses vector-element nullability. These baseline issues are not regressions introduced here.

The Python counterpart still installs Rust main; its complete Native CI needs to be rerun after this fix merges.

@JingsongLi
JingsongLi merged commit 2825759 into apache:main Oct 10, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants