Repository navigation
[Feature](file scanner) Support JNI and WAL in V2 - #66008
Conversation
|
Thank you for your contribution to Apache Doris. Please clearly describe your PR:
|
|
run buildall |
|
/review |
|
Codex automated review failed and did not complete. Error: You've hit your usage limit. Visit https://chatgpt.com/codex/settings/usage to purchase more credits or try again at Jul 30th, 2026 7:58 AM. Please inspect the workflow logs and rerun the review after the underlying issue is resolved. |
TPC-H: Total hot run time: 22803 ms |
TPC-DS: Total hot run time: 116052 ms |
ClickBench: Total hot run time: 18.32 s |
FE UT Coverage ReportIncrement line coverage `` 🎉 |
1fb57f6 to
29819b5
Compare
|
run buildall |
|
/review |
TPC-H: Total hot run time: 22859 ms |
|
Codex automated review failed and did not complete. Error: You've hit your usage limit. Visit https://chatgpt.com/codex/settings/usage to purchase more credits or try again at Jul 30th, 2026 7:58 AM. Please inspect the workflow logs and rerun the review after the underlying issue is resolved. |
TPC-DS: Total hot run time: 117327 ms |
ClickBench: Total hot run time: 18.8 s |
|
run buildall |
|
/review |
TPC-H: Total hot run time: 23128 ms |
TPC-DS: Total hot run time: 117267 ms |
ClickBench: Total hot run time: 18.61 s |
|
Codex automated review failed and did not complete. Error: You've hit your usage limit. Visit https://chatgpt.com/codex/settings/usage to purchase more credits or try again at Jul 30th, 2026 7:58 AM. Please inspect the workflow logs and rerun the review after the underlying issue is resolved. |
BE UT Coverage ReportIncrement line coverage Increment coverage report
|
BE Regression && UT Coverage ReportIncrement line coverage Increment coverage report
|
|
/review |
|
PR approved by at least one committer and no changes requested. |
…or scan path Upstream #66008 ("[Feature](file scanner) Support JNI and WAL in V2") deleted the paimon-cpp arm from `PaimonScanNode.setPaimonParams`: the JNI arm now always emits `PAIMON_JNI` with a Java-object-serialized split and no longer ships `paimon_table`. That file is gone from this branch (paimon lives in fe-connector-paimon), so the rebase surfaced it as a modify/delete conflict; this commit ports the capability instead of the code. The port is mandatory, not cosmetic. #66008 also stopped excluding `FORMAT_JNI` from `_should_use_file_scanner_v2`, so with the default `enable_file_scanner_v2 = true` every paimon JNI scan now runs on FileScannerV2 -- and `file_scanner_v2.cpp:is_supported_jni_table_format` rejects a `PAIMON_CPP` range, which `_validate_scan_range` turns into a hard `Status::NotSupported`. Scanner selection happens once per scan node (`_init_scanners`), so there is no per-range fallback to the V1 scanner that still implements `PaimonCppReader`; reaching it now requires `set enable_file_scanner_v2 = false`. Since `enable_paimon_cpp_reader` is `fuzzy = true` and three upstream suites (`test_paimon_cpp_reader`, `test_paimon_partition_pk_delete_refs`, `test_paimon_partition_schema_filter_refs`) set it to true explicitly, keeping the cpp arm would fail those paimon queries outright. - PaimonScanRange: drop `cppReaderSplit` and the `paimon.table_location` property; the JNI arm sets `PAIMON_JNI` unconditionally and no longer calls `setPaimonTable` (`paimon_table` is read only by the V1 `PaimonCppReader`). - PaimonScanPlanProvider: drop `isCppReaderEnabled` / `ENABLE_PAIMON_CPP_READER`, the native-binary arm of `encodeSplit` (now 1-arg), and the `tableLocation` threading plus its now-unused `getTableLocation`. Tests: `PaimonScanRangeReaderTypeTest` loses its cpp case and gains a no-`paimon_table` assertion; `PaimonScanPlanProviderTest` replaces the three cpp-format tests with `encodeSplitAlwaysUsesJavaSerializationForDataSplit` (asserting the wire is Java serde and is NOT the paimon-cpp native encoding, with a round-trip precondition so the negative is non-vacuous) and a planScan-level `cppReaderSessionFlagNoLongerChangesThePlan`; `PaimonScanExplainTest` drops `.tableLocation(...)`. No regression-test change is needed: the three upstream suites only compare results with the flag off vs on, which now trivially match. Verified: module 382/382 (1 pre-existing live-connectivity skip), checkstyle 0, full FE reactor `install -DskipTests` (153 modules, test-compile included) BUILD SUCCESS. Both new assertions mutation-checked RED (`PAIMON_JNI` -> `PAIMON_CPP`; re-adding `setPaimonTable`) and GREEN after revert. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01Kz9q8R1MZQNHXVFr1L9AWU
…or scan path Upstream #66008 ("[Feature](file scanner) Support JNI and WAL in V2") deleted the paimon-cpp arm from `PaimonScanNode.setPaimonParams`: the JNI arm now always emits `PAIMON_JNI` with a Java-object-serialized split and no longer ships `paimon_table`. That file is gone from this branch (paimon lives in fe-connector-paimon), so the rebase surfaced it as a modify/delete conflict; this commit ports the capability instead of the code. The port is mandatory, not cosmetic. #66008 also stopped excluding `FORMAT_JNI` from `_should_use_file_scanner_v2`, so with the default `enable_file_scanner_v2 = true` every paimon JNI scan now runs on FileScannerV2 -- and `file_scanner_v2.cpp:is_supported_jni_table_format` rejects a `PAIMON_CPP` range, which `_validate_scan_range` turns into a hard `Status::NotSupported`. Scanner selection happens once per scan node (`_init_scanners`), so there is no per-range fallback to the V1 scanner that still implements `PaimonCppReader`; reaching it now requires `set enable_file_scanner_v2 = false`. Since `enable_paimon_cpp_reader` is `fuzzy = true` and three upstream suites (`test_paimon_cpp_reader`, `test_paimon_partition_pk_delete_refs`, `test_paimon_partition_schema_filter_refs`) set it to true explicitly, keeping the cpp arm would fail those paimon queries outright. - PaimonScanRange: drop `cppReaderSplit` and the `paimon.table_location` property; the JNI arm sets `PAIMON_JNI` unconditionally and no longer calls `setPaimonTable` (`paimon_table` is read only by the V1 `PaimonCppReader`). - PaimonScanPlanProvider: drop `isCppReaderEnabled` / `ENABLE_PAIMON_CPP_READER`, the native-binary arm of `encodeSplit` (now 1-arg), and the `tableLocation` threading plus its now-unused `getTableLocation`. Tests: `PaimonScanRangeReaderTypeTest` loses its cpp case and gains a no-`paimon_table` assertion; `PaimonScanPlanProviderTest` replaces the three cpp-format tests with `encodeSplitAlwaysUsesJavaSerializationForDataSplit` (asserting the wire is Java serde and is NOT the paimon-cpp native encoding, with a round-trip precondition so the negative is non-vacuous) and a planScan-level `cppReaderSessionFlagNoLongerChangesThePlan`; `PaimonScanExplainTest` drops `.tableLocation(...)`. No regression-test change is needed: the three upstream suites only compare results with the flag off vs on, which now trivially match. Verified: module 382/382 (1 pre-existing live-connectivity skip), checkstyle 0, full FE reactor `install -DskipTests` (153 modules, test-compile included) BUILD SUCCESS. Both new assertions mutation-checked RED (`PAIMON_JNI` -> `PAIMON_CPP`; re-adding `setPaimonTable`) and GREEN after revert. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01Kz9q8R1MZQNHXVFr1L9AWU
… test with the planScan request object Rebase onto `1aa5ae9597e` reported zero textual conflicts and still produced a broken tree -- the exact failure mode a "clean" rebase hides. Upstream's `port apache#66008's paimon-cpp removal to the paimon connector scan path` added `PaimonScanPlanProviderTest.cppReaderSessionFlagNoLongerChangesThePlan`, which pins that `enable_paimon_cpp_reader` no longer changes the plan (the flag is `fuzzy = true` and three upstream suites set it explicitly, so a PAIMON_CPP range would hard-fail every paimon query under the default `enable_file_scanner_v2 = true`). It calls the seven-argument `planScan(session, handle, columns, filter, limit, requiredPartitions, countPushdown)`. This branch's later `one planScan, one request object` replaced those four overloads with `planScan(session, ConnectorScanRequest)`. The new test method and the signature change never touched the same lines, so the three-way merge took both sides without a conflict and the break surfaced only at test-compile: "method planScan cannot be applied to given types". The port is exact, not approximate. Every argument upstream passed is the builder's default -- filter `Optional.empty()`, limit `-1`, requiredPartitions `null` (normalizePartitions maps it to empty), countPushdown `false` -- so the test asks the provider for the same scan it asked for before, and the assertions it makes (reader_type stays PAIMON_JNI, `paimon_table` is no longer shipped, split wire format identical with the flag on and off) are unchanged. Call style matches the neighbouring `ignorePaimonCppIsNoOpParity`. Verification: full-reactor test-compile BUILD SUCCESS (75 modules, 0 errors); fe-connector-paimon 390/390 (1 pre-existing live-connectivity skip) including `cppReaderSessionFlagNoLongerChangesThePlan`, fe-connector-iceberg 1151/1151 (5 pre-existing live-endpoint skips), fe-connector-api 110/110. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
### What problem does this PR solve?
Problem Summary:
FileScannerV2 did not accept `FORMAT_JNI` or `FORMAT_WAL`, so these
scans remained on the legacy scanner path.
This change:
- routes supported `FORMAT_JNI` scans through FileScannerV2, including
compatible Paimon JNI/native split shapes;
- adds an independent V2 WAL reader with unique-column-id mapping,
block-version validation, checksum-backed WAL file reads, projection,
and filtering;
- does not include or call the legacy WAL reader implementation.
For Paimon compatibility, old FE plans may describe native Parquet/ORC
files as `FORMAT_JNI` without a `paimon_split`. A real JNI split also
carries physical `file_format` metadata, so native-format conversion
must first exclude ranges classified as JNI splits. This preserves old
native plans without misclassifying real JNI splits.
`FORMAT_AVRO` remains unsupported because the corresponding V1 reader is
no longer available on master.
### Release note
FileScannerV2 now supports JNI scans and WAL files.
### Check List (For Author)
- Test
- [x] Unit Test
Verified with:
- `./run-be-ut.sh --run
--filter='PaimonHybridReaderTest.*:FileScannerV2Test.*:WalReaderV2Test.*'
-j 8` (34 tests passed)
- Behavior changed:
- [x] Yes. Eligible JNI and WAL scans use FileScannerV2 when
`enable_file_scanner_v2` is enabled.
- Does this need documentation?
- [x] No.
### Check List (For Reviewer who merge this PR)
- [ ] Confirm the release note
- [ ] Confirm test cases
- [ ] Confirm document
- [ ] Add branch pick label
apache#66008 removed the getTableLocation() / isEnablePaimonCppReader() calls from PaimonScanNode#setPaimonParams but kept the stubs for them in three tests, so PaimonScanNodeTest fails at class level with UnnecessaryStubbingException on master. Delete the four dead stubs; the tests keep asserting what they always asserted. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
…or scan path Upstream #66008 ("[Feature](file scanner) Support JNI and WAL in V2") deleted the paimon-cpp arm from `PaimonScanNode.setPaimonParams`: the JNI arm now always emits `PAIMON_JNI` with a Java-object-serialized split and no longer ships `paimon_table`. That file is gone from this branch (paimon lives in fe-connector-paimon), so the rebase surfaced it as a modify/delete conflict; this commit ports the capability instead of the code. The port is mandatory, not cosmetic. #66008 also stopped excluding `FORMAT_JNI` from `_should_use_file_scanner_v2`, so with the default `enable_file_scanner_v2 = true` every paimon JNI scan now runs on FileScannerV2 -- and `file_scanner_v2.cpp:is_supported_jni_table_format` rejects a `PAIMON_CPP` range, which `_validate_scan_range` turns into a hard `Status::NotSupported`. Scanner selection happens once per scan node (`_init_scanners`), so there is no per-range fallback to the V1 scanner that still implements `PaimonCppReader`; reaching it now requires `set enable_file_scanner_v2 = false`. Since `enable_paimon_cpp_reader` is `fuzzy = true` and three upstream suites (`test_paimon_cpp_reader`, `test_paimon_partition_pk_delete_refs`, `test_paimon_partition_schema_filter_refs`) set it to true explicitly, keeping the cpp arm would fail those paimon queries outright. - PaimonScanRange: drop `cppReaderSplit` and the `paimon.table_location` property; the JNI arm sets `PAIMON_JNI` unconditionally and no longer calls `setPaimonTable` (`paimon_table` is read only by the V1 `PaimonCppReader`). - PaimonScanPlanProvider: drop `isCppReaderEnabled` / `ENABLE_PAIMON_CPP_READER`, the native-binary arm of `encodeSplit` (now 1-arg), and the `tableLocation` threading plus its now-unused `getTableLocation`. Tests: `PaimonScanRangeReaderTypeTest` loses its cpp case and gains a no-`paimon_table` assertion; `PaimonScanPlanProviderTest` replaces the three cpp-format tests with `encodeSplitAlwaysUsesJavaSerializationForDataSplit` (asserting the wire is Java serde and is NOT the paimon-cpp native encoding, with a round-trip precondition so the negative is non-vacuous) and a planScan-level `cppReaderSessionFlagNoLongerChangesThePlan`; `PaimonScanExplainTest` drops `.tableLocation(...)`. No regression-test change is needed: the three upstream suites only compare results with the flag off vs on, which now trivially match. Verified: module 382/382 (1 pre-existing live-connectivity skip), checkstyle 0, full FE reactor `install -DskipTests` (153 modules, test-compile included) BUILD SUCCESS. Both new assertions mutation-checked RED (`PAIMON_JNI` -> `PAIMON_CPP`; re-adding `setPaimonTable`) and GREEN after revert. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01Kz9q8R1MZQNHXVFr1L9AWU
… test with the planScan request object Rebase onto `1aa5ae9597e` reported zero textual conflicts and still produced a broken tree -- the exact failure mode a "clean" rebase hides. Upstream's `port apache#66008's paimon-cpp removal to the paimon connector scan path` added `PaimonScanPlanProviderTest.cppReaderSessionFlagNoLongerChangesThePlan`, which pins that `enable_paimon_cpp_reader` no longer changes the plan (the flag is `fuzzy = true` and three upstream suites set it explicitly, so a PAIMON_CPP range would hard-fail every paimon query under the default `enable_file_scanner_v2 = true`). It calls the seven-argument `planScan(session, handle, columns, filter, limit, requiredPartitions, countPushdown)`. This branch's later `one planScan, one request object` replaced those four overloads with `planScan(session, ConnectorScanRequest)`. The new test method and the signature change never touched the same lines, so the three-way merge took both sides without a conflict and the break surfaced only at test-compile: "method planScan cannot be applied to given types". The port is exact, not approximate. Every argument upstream passed is the builder's default -- filter `Optional.empty()`, limit `-1`, requiredPartitions `null` (normalizePartitions maps it to empty), countPushdown `false` -- so the test asks the provider for the same scan it asked for before, and the assertions it makes (reader_type stays PAIMON_JNI, `paimon_table` is no longer shipped, split wire format identical with the flag on and off) are unchanged. Call style matches the neighbouring `ignorePaimonCppIsNoOpParity`. Verification: full-reactor test-compile BUILD SUCCESS (75 modules, 0 errors); fe-connector-paimon 390/390 (1 pre-existing live-connectivity skip) including `cppReaderSessionFlagNoLongerChangesThePlan`, fe-connector-iceberg 1151/1151 (5 pre-existing live-endpoint skips), fe-connector-api 110/110. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Problem Summary:
FileScannerV2 did not accept `FORMAT_JNI` or `FORMAT_WAL`, so these
scans remained on the legacy scanner path.
This change:
- routes supported `FORMAT_JNI` scans through FileScannerV2, including
compatible Paimon JNI/native split shapes;
- adds an independent V2 WAL reader with unique-column-id mapping,
block-version validation, checksum-backed WAL file reads, projection,
and filtering;
- does not include or call the legacy WAL reader implementation.
For Paimon compatibility, old FE plans may describe native Parquet/ORC
files as `FORMAT_JNI` without a `paimon_split`. A real JNI split also
carries physical `file_format` metadata, so native-format conversion
must first exclude ranges classified as JNI splits. This preserves old
native plans without misclassifying real JNI splits.
`FORMAT_AVRO` remains unsupported because the corresponding V1 reader is
no longer available on master.
FileScannerV2 now supports JNI scans and WAL files.
- Test
- [x] Unit Test
Verified with:
- `./run-be-ut.sh --run
--filter='PaimonHybridReaderTest.*:FileScannerV2Test.*:WalReaderV2Test.*'
-j 8` (34 tests passed)
- Behavior changed:
- [x] Yes. Eligible JNI and WAL scans use FileScannerV2 when
`enable_file_scanner_v2` is enabled.
- Does this need documentation?
- [x] No.
- [ ] Confirm the release note
- [ ] Confirm test cases
- [ ] Confirm document
- [ ] Add branch pick label
…or scan path Upstream #66008 ("[Feature](file scanner) Support JNI and WAL in V2") deleted the paimon-cpp arm from `PaimonScanNode.setPaimonParams`: the JNI arm now always emits `PAIMON_JNI` with a Java-object-serialized split and no longer ships `paimon_table`. That file is gone from this branch (paimon lives in fe-connector-paimon), so the rebase surfaced it as a modify/delete conflict; this commit ports the capability instead of the code. The port is mandatory, not cosmetic. #66008 also stopped excluding `FORMAT_JNI` from `_should_use_file_scanner_v2`, so with the default `enable_file_scanner_v2 = true` every paimon JNI scan now runs on FileScannerV2 -- and `file_scanner_v2.cpp:is_supported_jni_table_format` rejects a `PAIMON_CPP` range, which `_validate_scan_range` turns into a hard `Status::NotSupported`. Scanner selection happens once per scan node (`_init_scanners`), so there is no per-range fallback to the V1 scanner that still implements `PaimonCppReader`; reaching it now requires `set enable_file_scanner_v2 = false`. Since `enable_paimon_cpp_reader` is `fuzzy = true` and three upstream suites (`test_paimon_cpp_reader`, `test_paimon_partition_pk_delete_refs`, `test_paimon_partition_schema_filter_refs`) set it to true explicitly, keeping the cpp arm would fail those paimon queries outright. - PaimonScanRange: drop `cppReaderSplit` and the `paimon.table_location` property; the JNI arm sets `PAIMON_JNI` unconditionally and no longer calls `setPaimonTable` (`paimon_table` is read only by the V1 `PaimonCppReader`). - PaimonScanPlanProvider: drop `isCppReaderEnabled` / `ENABLE_PAIMON_CPP_READER`, the native-binary arm of `encodeSplit` (now 1-arg), and the `tableLocation` threading plus its now-unused `getTableLocation`. Tests: `PaimonScanRangeReaderTypeTest` loses its cpp case and gains a no-`paimon_table` assertion; `PaimonScanPlanProviderTest` replaces the three cpp-format tests with `encodeSplitAlwaysUsesJavaSerializationForDataSplit` (asserting the wire is Java serde and is NOT the paimon-cpp native encoding, with a round-trip precondition so the negative is non-vacuous) and a planScan-level `cppReaderSessionFlagNoLongerChangesThePlan`; `PaimonScanExplainTest` drops `.tableLocation(...)`. No regression-test change is needed: the three upstream suites only compare results with the flag off vs on, which now trivially match. Verified: module 382/382 (1 pre-existing live-connectivity skip), checkstyle 0, full FE reactor `install -DskipTests` (153 modules, test-compile included) BUILD SUCCESS. Both new assertions mutation-checked RED (`PAIMON_JNI` -> `PAIMON_CPP`; re-adding `setPaimonTable`) and GREEN after revert. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01Kz9q8R1MZQNHXVFr1L9AWU
Problem Summary:
FileScannerV2 did not accept `FORMAT_JNI` or `FORMAT_WAL`, so these
scans remained on the legacy scanner path.
This change:
- routes supported `FORMAT_JNI` scans through FileScannerV2, including
compatible Paimon JNI/native split shapes;
- adds an independent V2 WAL reader with unique-column-id mapping,
block-version validation, checksum-backed WAL file reads, projection,
and filtering;
- does not include or call the legacy WAL reader implementation.
For Paimon compatibility, old FE plans may describe native Parquet/ORC
files as `FORMAT_JNI` without a `paimon_split`. A real JNI split also
carries physical `file_format` metadata, so native-format conversion
must first exclude ranges classified as JNI splits. This preserves old
native plans without misclassifying real JNI splits.
`FORMAT_AVRO` remains unsupported because the corresponding V1 reader is
no longer available on master.
FileScannerV2 now supports JNI scans and WAL files.
- Test
- [x] Unit Test
Verified with:
- `./run-be-ut.sh --run
--filter='PaimonHybridReaderTest.*:FileScannerV2Test.*:WalReaderV2Test.*'
-j 8` (34 tests passed)
- Behavior changed:
- [x] Yes. Eligible JNI and WAL scans use FileScannerV2 when
`enable_file_scanner_v2` is enabled.
- Does this need documentation?
- [x] No.
- [ ] Confirm the release note
- [ ] Confirm test cases
- [ ] Confirm document
- [ ] Add branch pick label
…or scan path Upstream #66008 ("[Feature](file scanner) Support JNI and WAL in V2") deleted the paimon-cpp arm from `PaimonScanNode.setPaimonParams`: the JNI arm now always emits `PAIMON_JNI` with a Java-object-serialized split and no longer ships `paimon_table`. That file is gone from this branch (paimon lives in fe-connector-paimon), so the rebase surfaced it as a modify/delete conflict; this commit ports the capability instead of the code. The port is mandatory, not cosmetic. #66008 also stopped excluding `FORMAT_JNI` from `_should_use_file_scanner_v2`, so with the default `enable_file_scanner_v2 = true` every paimon JNI scan now runs on FileScannerV2 -- and `file_scanner_v2.cpp:is_supported_jni_table_format` rejects a `PAIMON_CPP` range, which `_validate_scan_range` turns into a hard `Status::NotSupported`. Scanner selection happens once per scan node (`_init_scanners`), so there is no per-range fallback to the V1 scanner that still implements `PaimonCppReader`; reaching it now requires `set enable_file_scanner_v2 = false`. Since `enable_paimon_cpp_reader` is `fuzzy = true` and three upstream suites (`test_paimon_cpp_reader`, `test_paimon_partition_pk_delete_refs`, `test_paimon_partition_schema_filter_refs`) set it to true explicitly, keeping the cpp arm would fail those paimon queries outright. - PaimonScanRange: drop `cppReaderSplit` and the `paimon.table_location` property; the JNI arm sets `PAIMON_JNI` unconditionally and no longer calls `setPaimonTable` (`paimon_table` is read only by the V1 `PaimonCppReader`). - PaimonScanPlanProvider: drop `isCppReaderEnabled` / `ENABLE_PAIMON_CPP_READER`, the native-binary arm of `encodeSplit` (now 1-arg), and the `tableLocation` threading plus its now-unused `getTableLocation`. Tests: `PaimonScanRangeReaderTypeTest` loses its cpp case and gains a no-`paimon_table` assertion; `PaimonScanPlanProviderTest` replaces the three cpp-format tests with `encodeSplitAlwaysUsesJavaSerializationForDataSplit` (asserting the wire is Java serde and is NOT the paimon-cpp native encoding, with a round-trip precondition so the negative is non-vacuous) and a planScan-level `cppReaderSessionFlagNoLongerChangesThePlan`; `PaimonScanExplainTest` drops `.tableLocation(...)`. No regression-test change is needed: the three upstream suites only compare results with the flag off vs on, which now trivially match. Verified: module 382/382 (1 pre-existing live-connectivity skip), checkstyle 0, full FE reactor `install -DskipTests` (153 modules, test-compile included) BUILD SUCCESS. Both new assertions mutation-checked RED (`PAIMON_JNI` -> `PAIMON_CPP`; re-adding `setPaimonTable`) and GREEN after revert. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01Kz9q8R1MZQNHXVFr1L9AWU
…or scan path Upstream #66008 ("[Feature](file scanner) Support JNI and WAL in V2") deleted the paimon-cpp arm from `PaimonScanNode.setPaimonParams`: the JNI arm now always emits `PAIMON_JNI` with a Java-object-serialized split and no longer ships `paimon_table`. That file is gone from this branch (paimon lives in fe-connector-paimon), so the rebase surfaced it as a modify/delete conflict; this commit ports the capability instead of the code. The port is mandatory, not cosmetic. #66008 also stopped excluding `FORMAT_JNI` from `_should_use_file_scanner_v2`, so with the default `enable_file_scanner_v2 = true` every paimon JNI scan now runs on FileScannerV2 -- and `file_scanner_v2.cpp:is_supported_jni_table_format` rejects a `PAIMON_CPP` range, which `_validate_scan_range` turns into a hard `Status::NotSupported`. Scanner selection happens once per scan node (`_init_scanners`), so there is no per-range fallback to the V1 scanner that still implements `PaimonCppReader`; reaching it now requires `set enable_file_scanner_v2 = false`. Since `enable_paimon_cpp_reader` is `fuzzy = true` and three upstream suites (`test_paimon_cpp_reader`, `test_paimon_partition_pk_delete_refs`, `test_paimon_partition_schema_filter_refs`) set it to true explicitly, keeping the cpp arm would fail those paimon queries outright. - PaimonScanRange: drop `cppReaderSplit` and the `paimon.table_location` property; the JNI arm sets `PAIMON_JNI` unconditionally and no longer calls `setPaimonTable` (`paimon_table` is read only by the V1 `PaimonCppReader`). - PaimonScanPlanProvider: drop `isCppReaderEnabled` / `ENABLE_PAIMON_CPP_READER`, the native-binary arm of `encodeSplit` (now 1-arg), and the `tableLocation` threading plus its now-unused `getTableLocation`. Tests: `PaimonScanRangeReaderTypeTest` loses its cpp case and gains a no-`paimon_table` assertion; `PaimonScanPlanProviderTest` replaces the three cpp-format tests with `encodeSplitAlwaysUsesJavaSerializationForDataSplit` (asserting the wire is Java serde and is NOT the paimon-cpp native encoding, with a round-trip precondition so the negative is non-vacuous) and a planScan-level `cppReaderSessionFlagNoLongerChangesThePlan`; `PaimonScanExplainTest` drops `.tableLocation(...)`. No regression-test change is needed: the three upstream suites only compare results with the flag off vs on, which now trivially match. Verified: module 382/382 (1 pre-existing live-connectivity skip), checkstyle 0, full FE reactor `install -DskipTests` (153 modules, test-compile included) BUILD SUCCESS. Both new assertions mutation-checked RED (`PAIMON_JNI` -> `PAIMON_CPP`; re-adding `setPaimonTable`) and GREEN after revert. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01Kz9q8R1MZQNHXVFr1L9AWU
## Proposed changes Backport the requested changes to `branch-4.1` in master merge order, skipping changes already present in this PR: 1. #62438 2. #65329 (merged prerequisite for the nested-schema cases) 3. #65960 4. #65965 5. #65972 6. #65998 7. #66002 8. #65992 9. #66021 10. #66036 11. #66008 12. #66073 13. #66056 (explicitly requested; current open-PR head, appended after the merged sequence) The branch-specific compatibility commits preserve the selected master behavior on `branch-4.1`, including master wire IDs for file formats and the merged Paimon test helper prerequisite. No regression expected output, test assertion, or test input was changed to make validation pass. ## Validation - Full BE ASAN build passed. - Full FE build passed. - Targeted BE ASAN unit tests: 332 tests from 13 suites passed. - Targeted FE Iceberg unit tests: 41 passed, 0 failed. - Iceberg write regression: 20 suites, 0 failed, 0 fatal. - `PaimonScanNodeTest`: all 16 test bodies completed with 0 assertion failures; the class reports one Mockito teardown error because #66008 left four now-unused stubs on master. The still-open #65867 contains the upstream test-only cleanup commit. This PR intentionally does not alter those test cases. - Final rebase against the latest `branch-4.1` completed; the branch was already up to date. - Working-tree, formatting, and sensitive-information audits completed. Existing EOF blank lines in picked regression output files are preserved. --------- Co-authored-by: daidai <[email protected]> Co-authored-by: Mingyu Chen (Rayner) <[email protected]>
…or scan path Upstream #66008 ("[Feature](file scanner) Support JNI and WAL in V2") deleted the paimon-cpp arm from `PaimonScanNode.setPaimonParams`: the JNI arm now always emits `PAIMON_JNI` with a Java-object-serialized split and no longer ships `paimon_table`. That file is gone from this branch (paimon lives in fe-connector-paimon), so the rebase surfaced it as a modify/delete conflict; this commit ports the capability instead of the code. The port is mandatory, not cosmetic. #66008 also stopped excluding `FORMAT_JNI` from `_should_use_file_scanner_v2`, so with the default `enable_file_scanner_v2 = true` every paimon JNI scan now runs on FileScannerV2 -- and `file_scanner_v2.cpp:is_supported_jni_table_format` rejects a `PAIMON_CPP` range, which `_validate_scan_range` turns into a hard `Status::NotSupported`. Scanner selection happens once per scan node (`_init_scanners`), so there is no per-range fallback to the V1 scanner that still implements `PaimonCppReader`; reaching it now requires `set enable_file_scanner_v2 = false`. Since `enable_paimon_cpp_reader` is `fuzzy = true` and three upstream suites (`test_paimon_cpp_reader`, `test_paimon_partition_pk_delete_refs`, `test_paimon_partition_schema_filter_refs`) set it to true explicitly, keeping the cpp arm would fail those paimon queries outright. - PaimonScanRange: drop `cppReaderSplit` and the `paimon.table_location` property; the JNI arm sets `PAIMON_JNI` unconditionally and no longer calls `setPaimonTable` (`paimon_table` is read only by the V1 `PaimonCppReader`). - PaimonScanPlanProvider: drop `isCppReaderEnabled` / `ENABLE_PAIMON_CPP_READER`, the native-binary arm of `encodeSplit` (now 1-arg), and the `tableLocation` threading plus its now-unused `getTableLocation`. Tests: `PaimonScanRangeReaderTypeTest` loses its cpp case and gains a no-`paimon_table` assertion; `PaimonScanPlanProviderTest` replaces the three cpp-format tests with `encodeSplitAlwaysUsesJavaSerializationForDataSplit` (asserting the wire is Java serde and is NOT the paimon-cpp native encoding, with a round-trip precondition so the negative is non-vacuous) and a planScan-level `cppReaderSessionFlagNoLongerChangesThePlan`; `PaimonScanExplainTest` drops `.tableLocation(...)`. No regression-test change is needed: the three upstream suites only compare results with the flag off vs on, which now trivially match. Verified: module 382/382 (1 pre-existing live-connectivity skip), checkstyle 0, full FE reactor `install -DskipTests` (153 modules, test-compile included) BUILD SUCCESS. Both new assertions mutation-checked RED (`PAIMON_JNI` -> `PAIMON_CPP`; re-adding `setPaimonTable`) and GREEN after revert. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01Kz9q8R1MZQNHXVFr1L9AWU
…or scan path Upstream #66008 ("[Feature](file scanner) Support JNI and WAL in V2") deleted the paimon-cpp arm from `PaimonScanNode.setPaimonParams`: the JNI arm now always emits `PAIMON_JNI` with a Java-object-serialized split and no longer ships `paimon_table`. That file is gone from this branch (paimon lives in fe-connector-paimon), so the rebase surfaced it as a modify/delete conflict; this commit ports the capability instead of the code. The port is mandatory, not cosmetic. #66008 also stopped excluding `FORMAT_JNI` from `_should_use_file_scanner_v2`, so with the default `enable_file_scanner_v2 = true` every paimon JNI scan now runs on FileScannerV2 -- and `file_scanner_v2.cpp:is_supported_jni_table_format` rejects a `PAIMON_CPP` range, which `_validate_scan_range` turns into a hard `Status::NotSupported`. Scanner selection happens once per scan node (`_init_scanners`), so there is no per-range fallback to the V1 scanner that still implements `PaimonCppReader`; reaching it now requires `set enable_file_scanner_v2 = false`. Since `enable_paimon_cpp_reader` is `fuzzy = true` and three upstream suites (`test_paimon_cpp_reader`, `test_paimon_partition_pk_delete_refs`, `test_paimon_partition_schema_filter_refs`) set it to true explicitly, keeping the cpp arm would fail those paimon queries outright. - PaimonScanRange: drop `cppReaderSplit` and the `paimon.table_location` property; the JNI arm sets `PAIMON_JNI` unconditionally and no longer calls `setPaimonTable` (`paimon_table` is read only by the V1 `PaimonCppReader`). - PaimonScanPlanProvider: drop `isCppReaderEnabled` / `ENABLE_PAIMON_CPP_READER`, the native-binary arm of `encodeSplit` (now 1-arg), and the `tableLocation` threading plus its now-unused `getTableLocation`. Tests: `PaimonScanRangeReaderTypeTest` loses its cpp case and gains a no-`paimon_table` assertion; `PaimonScanPlanProviderTest` replaces the three cpp-format tests with `encodeSplitAlwaysUsesJavaSerializationForDataSplit` (asserting the wire is Java serde and is NOT the paimon-cpp native encoding, with a round-trip precondition so the negative is non-vacuous) and a planScan-level `cppReaderSessionFlagNoLongerChangesThePlan`; `PaimonScanExplainTest` drops `.tableLocation(...)`. No regression-test change is needed: the three upstream suites only compare results with the flag off vs on, which now trivially match. Verified: module 382/382 (1 pre-existing live-connectivity skip), checkstyle 0, full FE reactor `install -DskipTests` (153 modules, test-compile included) BUILD SUCCESS. Both new assertions mutation-checked RED (`PAIMON_JNI` -> `PAIMON_CPP`; re-adding `setPaimonTable`) and GREEN after revert. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01Kz9q8R1MZQNHXVFr1L9AWU
### What problem does this PR solve?
Problem Summary:
FileScannerV2 did not accept `FORMAT_JNI` or `FORMAT_WAL`, so these
scans remained on the legacy scanner path.
This change:
- routes supported `FORMAT_JNI` scans through FileScannerV2, including
compatible Paimon JNI/native split shapes;
- adds an independent V2 WAL reader with unique-column-id mapping,
block-version validation, checksum-backed WAL file reads, projection,
and filtering;
- does not include or call the legacy WAL reader implementation.
For Paimon compatibility, old FE plans may describe native Parquet/ORC
files as `FORMAT_JNI` without a `paimon_split`. A real JNI split also
carries physical `file_format` metadata, so native-format conversion
must first exclude ranges classified as JNI splits. This preserves old
native plans without misclassifying real JNI splits.
`FORMAT_AVRO` remains unsupported because the corresponding V1 reader is
no longer available on master.
### Release note
FileScannerV2 now supports JNI scans and WAL files.
### Check List (For Author)
- Test
- [x] Unit Test
Verified with:
- `./run-be-ut.sh --run
--filter='PaimonHybridReaderTest.*:FileScannerV2Test.*:WalReaderV2Test.*'
-j 8` (34 tests passed)
- Behavior changed:
- [x] Yes. Eligible JNI and WAL scans use FileScannerV2 when
`enable_file_scanner_v2` is enabled.
- Does this need documentation?
- [x] No.
### Check List (For Reviewer who merge this PR)
- [ ] Confirm the release note
- [ ] Confirm test cases
- [ ] Confirm document
- [ ] Add branch pick label
### What problem does this PR solve? Heavy ALTER operations can write base and shadow columns with the same ID into Group Commit WALs. V2 rejects these valid headers as corruption. Accept duplicate IDs while preserving physical column order and the existing first-column mapping. Related PR: #66008 ### Release note Fix Group Commit WAL replay failures during heavy schema changes with FileScannerV2.
### What problem does this PR solve? Heavy ALTER operations can write base and shadow columns with the same ID into Group Commit WALs. V2 rejects these valid headers as corruption. Accept duplicate IDs while preserving physical column order and the existing first-column mapping. Related PR: #66008 ### Release note Fix Group Commit WAL replay failures during heavy schema changes with FileScannerV2.
### What problem does this PR solve? Heavy ALTER operations can write base and shadow columns with the same ID into Group Commit WALs. V2 rejects these valid headers as corruption. Accept duplicate IDs while preserving physical column order and the existing first-column mapping. Related PR: #66008 ### Release note Fix Group Commit WAL replay failures during heavy schema changes with FileScannerV2.
What problem does this PR solve?
Problem Summary:
FileScannerV2 did not accept
FORMAT_JNIorFORMAT_WAL, so these scans remained on the legacy scanner path.This change:
FORMAT_JNIscans through FileScannerV2, including compatible Paimon JNI/native split shapes;For Paimon compatibility, old FE plans may describe native Parquet/ORC files as
FORMAT_JNIwithout apaimon_split. A real JNI split also carries physicalfile_formatmetadata, so native-format conversion must first exclude ranges classified as JNI splits. This preserves old native plans without misclassifying real JNI splits.FORMAT_AVROremains unsupported because the corresponding V1 reader is no longer available on master.Release note
FileScannerV2 now supports JNI scans and WAL files.
Check List (For Author)
Test
Verified with:
./run-be-ut.sh --run --filter='PaimonHybridReaderTest.*:FileScannerV2Test.*:WalReaderV2Test.*' -j 8(34 tests passed)Behavior changed:
enable_file_scanner_v2is enabled.Does this need documentation?
Check List (For Reviewer who merge this PR)