Skip to content

[common] Stop nesting row-tracking vector wrappers per batch - #9634

Open
LuciferYang wants to merge 1 commit into
apache:masterfrom
LuciferYang:fix/columnar-rowiterator-rowtracking
Open

[common] Stop nesting row-tracking vector wrappers per batch#9634
LuciferYang wants to merge 1 commit into
apache:masterfrom
LuciferYang:fix/columnar-rowiterator-rowtracking

Conversation

@LuciferYang

Copy link
Copy Markdown
Contributor

Purpose

close #9633

ColumnarRowIterator.assignRowTracking wraps the _ROW_ID and _SEQUENCE_NUMBER vectors in a delegating LongColumnVector, and it runs once per batch while the wrapped vector lives on in the file's single ColumnarBatch. Batch N therefore wrapped batch N-1's wrapper, so reading one row walked one level of delegation per batch already read. Over a file that is quadratic, and with enough batches it ends in a StackOverflowError.

The wrapper is now a named TrackingLongColumnVector holding its base, and assignRowTracking strips an existing one before installing a new one, so the depth stays at one however many times it runs.

The same method also unboxed a nullable firstRowId: RawFileSplitRead says a file may carry no stored row id, and when the row's _rowid is null as well, firstRowId + returnedPosition() threw a NullPointerException. Both columns are now left untouched when their value is null, which is what the row-based branch of this method already did with firstRowId != null.

Tests

ColumnarRowIteratorTest.testAssignRowTrackingSkipsNullFirstRowId passes a null firstRowId and asserts the vector is the original instance, not a wrapper.

ColumnarRowIteratorTest.testRepeatedAssignRowTrackingDoesNotNest assigns 100000 times and then reads all four rows, covering both the stored-id and the fallback-to-firstRowId + position paths. The count is deliberate: nesting keeps returning correct values, so only a read deep enough to overflow the stack distinguishes the two versions.

Against the unfixed iterator the first fails on the vector identity and the second errors with StackOverflowError.

mvn -pl paimon-common -Dtest=ColumnarRowIteratorTest test on JDK 8: 3 tests, 0 failures. spotless:check and checkstyle:check on paimon-common are clean.

assignRowTracking wraps the _ROW_ID and _SEQUENCE_NUMBER vectors, and it
runs once per batch while the wrapped vector stays in the file's single
ColumnarBatch, so batch N wrapped batch N-1's wrapper. Reading a row
then walked one delegation level per batch already read, and enough
batches ended in a StackOverflowError.

Name the wrapper and strip an existing one before installing a new one.
Also leave both columns alone when firstRowId or snapshotId is null,
which the row-based branch of the same method already did.
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.

[Bug] Row-tracking vector wrappers nest once per batch and overflow the stack

1 participant