[vortex] Preserve physical row order in scans - #9003
Conversation
fa65679 to
b6784b3
Compare
|
@JingsongLi Hi, could you please take a look? Thanks! |
There was a problem hiding this comment.
Pull request overview
Note
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
This PR fixes a correctness issue where VortexRecordsReader relied on monotonically increasing returnedPosition() while the underlying Vortex scan could return partitions out of physical row order, potentially mismatching Vortex vector rows with main-file rows.
Changes:
- Force ordered Vortex scans by default in
VortexRecordsReader. - Add a regression test that validates physical row order is preserved across multiple scan partitions.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| paimon-vortex/paimon-vortex-format/src/main/java/org/apache/paimon/format/vortex/VortexRecordsReader.java | Requests ordered(true) on Vortex scans to preserve physical row order and align returnedPosition() with row IDs. |
| paimon-vortex/paimon-vortex-format/src/test/java/org/apache/paimon/format/vortex/VortexReaderWriterTest.java | Adds a regression test intended to demonstrate unordered scans can misorder results and ordered scans preserve physical row order. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| List<Integer> unorderedIds = readIds(testFile, selectedRows, false); | ||
| assertFalse( | ||
| expectedIds.equals(unorderedIds), | ||
| "The unordered scan unexpectedly preserved physical row order"); | ||
| assertEquals(expectedIds, readIds(testFile, selectedRows, true)); |
| int previousWorkerCount = NativeRuntime.workerCount(); | ||
| NativeRuntime.setWorkerThreads(2); | ||
| try { | ||
| List<Integer> unorderedIds = readIds(testFile, selectedRows, false); | ||
| assertFalse( | ||
| expectedIds.equals(unorderedIds), | ||
| "The unordered scan unexpectedly preserved physical row order"); | ||
| assertEquals(expectedIds, readIds(testFile, selectedRows, true)); | ||
|
|
||
| try (VortexRecordsReader reader = | ||
| new VortexRecordsReader( | ||
| testFile, | ||
| rowType, | ||
| rowType, | ||
| selectedRows, | ||
| null, | ||
| Collections.emptyMap())) { | ||
| int readCount = 0; | ||
| FileRecordIterator<InternalRow> batch; | ||
| while ((batch = reader.readBatch()) != null) { | ||
| InternalRow row; | ||
| while ((row = batch.next()) != null) { | ||
| assertEquals(batch.returnedPosition(), row.getInt(0)); | ||
| readCount++; | ||
| } | ||
| } | ||
| assertEquals(selectedRows.length, readCount); | ||
| } | ||
| } finally { | ||
| NativeRuntime.setWorkerThreads(previousWorkerCount); | ||
| } |
| private static String payload(int rowId) { | ||
| char[] chars = new char[4_096]; | ||
| int state = rowId + 1; | ||
| for (int i = 0; i < chars.length; i++) { | ||
| state = state * 1_103_515_245 + 12_345; | ||
| chars[i] = (char) ('a' + ((state >>> 16) & 15)); | ||
| } | ||
| return new String(chars); | ||
| } |
Vortex scans are unordered by default, while Paimon derives returned positions monotonically. Request ordered scans so dedicated Vortex files stay aligned with their corresponding main-file rows. Generated-by: OpenAI Codex
b6784b3 to
fbebd5a
Compare
Purpose
VortexRecordsReaderderivesreturnedPosition()from a monotonically increasing iterator, but the VortexDataSource/ScanAPI is unordered by default. If internal scan partitions complete out of order, dedicated Vortex vector rows can be paired with the wrong rows from the main data file.This change explicitly requests ordered Vortex scans and adds a deterministic test for the scan contract.
This PR is kept as a draft while waiting for issue assignment and maintainer feedback.
Fixes #9002.
Tests
mvn -pl paimon-vortex/paimon-vortex-format -am -Pfast-build -DfailIfNoTests=false -DwildcardSuites=none -Dtest=VortexRecordsReaderTest#testScanPreservesPhysicalRowOrder testexpected: <true> but was: <false>.mvn -pl paimon-vortex/paimon-vortex-format -am -Pfast-build -DfailIfNoTests=false -DwildcardSuites=none -Dtest=VortexRecordsReaderTest,VortexReaderWriterTest test(15 tests passed)mvn -pl paimon-vortex/paimon-vortex-format -am -DskipTests packagegit diff --check