Repository navigation
[improvement](fe) Upgrade Paimon to 2.1.0 - #69343
Conversation
|
Thank you for your contribution to Apache Doris. Please clearly describe your PR:
|
|
run buildall |
FE UT Coverage ReportIncrement line coverage `` 🎉 |
### What problem does this PR solve? Issue Number: N/A Related PR: apache#69343 Problem Summary: Upgrade the shared FE connector and BE scanner SDK pin from 2.0.0 to Paimon 2.1.0. Remove the upstream-deleted file-based privilege wrappers and their reflection-based reconstruction. Update filesystem schema and snapshot fixtures, verify default and checked integer overflow modes, and cover corrected pre-epoch date casts and query-auth file-statistics restrictions. Match scanner test JVM access to the existing BE java.nio opening required by Arrow Variant buffer views. ### Release note Upgrade the Paimon Java SDK from 1.4.2 to 2.1.0. The SDK removes legacy file-based privileges, rejects raw file statistics on query-auth tables, corrects pre-epoch timestamp-to-date casts, and supports per-field checked integer aggregation while preserving wrapping overflow by default. ### Check List (For Author) - Test: Unit Test / Manual test - FE connector: 831 passed, 1 live-connectivity test skipped. - BE scanner: 142 passed. S3 shade: 1 passed. - Maven validate/Checkstyle and plugin packaging passed. - Checked scanner duplicate classes, SPI isolation, dependency closure, and API stamps: 162 JARs, no failures. - Verified matching 2.1.0 SDKs and byte-for-byte S3 embedded runtime. - Full build blocked by missing local Paimon Rust third-party artifacts; native BE and cluster regression tests were not run. - Behavior changed: Yes, adopts the Paimon 2.1.0 behavior described above. - Does this need documentation: No, upstream changes are in the release note.
### What problem does this PR solve? Issue Number: N/A Related PR: apache#69343 Problem Summary: Paimon 2.1 adds file_indexes, whose backend reader re-plans files after Doris strips its catalog loader, and latest-delta, which Doris would incorrectly resolve to a full snapshot. Pin file_indexes to the catalog-published snapshot and reject the unimplemented delta OPTIONS mode with guidance to use explicit @incr ranges. Add persisted tests for both cases and for nullable primary-key metadata, serialization, and NULL-key deduplication across commits. ### Release note Fix catalog snapshot visibility for Paimon file_indexes and explicitly reject unsupported latest-delta OPTIONS reads instead of reading a full snapshot. ### Check List (For Author) - Test: Unit Test / Manual test: run-fe-ut.sh with temporary Paimon module scope, Checkstyle enabled, and install packaging; 834 passed and 1 live-connectivity test skipped. FE plugin ZIP produced. The runner was restored. Native BE/Rust and cluster regressions were not run because the local third-party Paimon native library/header are missing. - Behavior changed: Yes, pin new system-table reads and reject an unsupported startup mode rather than returning incorrect rows. - Does this need documentation: No, compatibility impact is recorded in the PR description and release note.
### What problem does this PR solve? Issue Number: N/A Related PR: apache#69343 Problem Summary: Exercise the upgraded SDK in a real Doris cluster. Verify nullable primary-key deduplication through JNI and a profile-confirmed Rust reader, bitmap file-index metadata, rejection of unsupported latest-delta OPTIONS, and wrapping versus checked sum overflow. Generate the expected output with the regression runner and verify it in a normal run. Update the oversized-write error assertion to Paimon 2.1's diagnostic while retaining the existing row and snapshot atomicity checks. ### Release note None ### Check List (For Author) - Test: Regression test / Unit Test / Manual test - New compatibility suite: generated output and normal replay passed. - Read compatibility matrix: 13 suites passed. - Metadata and transaction matrix: 6 suites passed. - Paimon ASAN native UT: 108 tests in 14 suites passed. - Java scanner: 142 tests passed; S3 shade: 1 test passed. - Native BE ASAN build and deployed plugin checks passed. - Manual backward read of 1.4.2 tables through JNI and Rust matched the Spark oracle. - Behavior changed: No (test coverage and updated SDK diagnostic assertion only) - Does this need documentation: No
|
run buildall |
|
/review |
There was a problem hiding this comment.
Request changes: two verified issues in the newly exposed $file_indexes path: [P1] loss of the deferred catalog query check and [P2] loss of the catalog snapshot pin during JNI reconstruction.
Static review covered all 35 changed paths at 967cf6af6255e3fb011e99460ef74b706e736322, using the supplied aggregate diff. No existing inline threads or additional user focus were supplied.
Critical checkpoint conclusions:
- Goal and proof: the shared SDK upgrade and removed-API adaptations are consistent with Paimon 2.1, but the new system-table integration has the two inline defects. The direct backend-table test omits the real JNI source replacement; no denied-query test covers
$file_indexes. - Scope and reuse: the production changes are focused on the upgrade and reuse the existing branch, cache, and scan helpers.
- Concurrency and locks: no new Doris threads, locks, or shared mutable state. External catalog publication across FE/BE stages is relevant to the snapshot finding.
- Lifecycle and initialization: no new resource owner or static initialization dependency. Catalog-loader removal is the lifecycle boundary responsible for the lost query check; existing cache/catalog cleanup remains intact.
- Configuration: no new FE/BE deployment knob or dynamic configuration propagation. The new SDK startup literal is explicitly rejected for OPTIONS; existing manifest caps remain branch-specific.
- Compatibility: both Java endpoints share SDK 2.1.0, and patch/shade linkage was inspected. Mixed 1.4.2/2.1.0 JNI splits and commit serialization are incompatible; coordinated same-SDK deployment is an explicit PR restriction, not an additional inline finding. Legacy file privileges are intentionally removed upstream and documented in the PR.
- Thrift/Protobuf: no definitions, field IDs, or enum values change.
- Parallel paths: normal, fallback/chain, REST schema binding, metadata-cache/statistics, JNI, native/Rust, and deferred system-source paths were traced. The two findings require separate snapshot and query-check fixes.
- Conditions and errors: the latest-delta guard explains the full-snapshot conflict and directs users to explicit @incr; both OPTIONS resolution and statement fencing reach it. Incremental resets preserve explicit ranges. No further new selector defect was substantiated.
- Test coverage: inspected the new nullable-key, persisted-index, overflow, timestamp, serde and regression cases. The transport and denied-query gaps above remain. Builds and tests were prohibited and were not run.
- Expected results: ordered NULL-key merges, bitmap record counts, wrapping/checked arithmetic, pre-epoch date and revised diagnostic match the SDK source. Actual generation provenance and runtime output were not independently verified.
- Observability: existing error context and metrics are sufficient for these API changes; the regression checks a completed Rust-reader profile. No separate new observability defect found.
- Transactions and persistence: no Doris EditLog/recovery implementation changes. SDK commit messages retain explicit version framing; mixed SDK operation remains outside the declared deployment scope.
- Writes and atomicity: the SDK write path and nullable-key mapping were inspected; the failed-write regression retains its row/snapshot atomicity assertions. Runtime crash/commit behavior was not validated by this static review.
- FE/BE variables: no new protocol variable is added. Existing serialized-table and serialized-system-source payloads were traced end to end; their mismatch causes the snapshot finding.
- Performance and memory: no new scan loop, large allocation, lock contention, or complexity regression was substantiated. Existing caps and conservative JNI fallback remain in effect.
- Further review and user focus: all changed files and initial risks received dispositions, including a missed-issue recheck by every reviewer. There was no additional user focus.
Limits: source review only; author-reported builds, packages, native tests and cluster results were not rerun. Live HMS/REST services and mixed-SDK deployment were not exercised. The SDK system views retain their existing two-phase partition-marker and fallback-only inventory limitations and do not establish full statement MVCC. No candidate remains unverified; the two accepted defects remain to be fixed.
Review converged after 3 round(s).
TPC-H: Total hot run time: 28054 ms |
TPC-DS: Total hot run time: 150200 ms |
ClickBench: Total hot run time: 24.19 s |
FE Regression Coverage ReportIncrement line coverage |
### What problem does this PR solve? Issue Number: N/A Related PR: N/A Problem Summary: Doris currently uses Paimon 1.4.2. Upgrade the shared SDK version to 2.0.0 so the FE connector and BE JNI scanner continue to serialize and deserialize with the same SDK. Adapt test fixtures to the new Table branch API, Snapshot operation parameter, and grouped format-file splits. Update integer aggregation tests to expect the checked overflow behavior introduced by Paimon 2.0.0, while preserving the existing Rust reader eligibility rules and the common/S3 compatibility patches. ### Release note Upgrade the Paimon Java SDK from 1.4.2 to 2.0.0. Integer sum and product aggregation now report overflow instead of returning wrapped values, following Paimon 2.0.0 behavior. ### Check List (For Author) - Test: Unit tests through run-fe-ut.sh with a temporary, restored Paimon-only module scope: FE connector 836 passed and 1 live-connectivity test skipped; BE scanner 144 passed. Maven validate/Checkstyle passed for the Paimon modules and their dependencies. Verified that FE/BE test SDK artifacts are version 2.0.0 and that S3 shade removes outer multi-release classes while retaining 1,227 embedded classes. Full build.sh build was blocked by missing LLVM 20 in the local third-party environment; external-cluster regression tests were not run. - Behavior changed: Yes, use Paimon 2.0.0 SDK behavior, including checked integer aggregation overflow. - Does this need documentation: No
### What problem does this PR solve? Issue Number: N/A Related PR: apache#69343 Problem Summary: Upgrade the shared FE connector and BE scanner SDK pin from 2.0.0 to Paimon 2.1.0. Remove the upstream-deleted file-based privilege wrappers and their reflection-based reconstruction. Update filesystem schema and snapshot fixtures, verify default and checked integer overflow modes, and cover corrected pre-epoch date casts and query-auth file-statistics restrictions. Match scanner test JVM access to the existing BE java.nio opening required by Arrow Variant buffer views. ### Release note Upgrade the Paimon Java SDK from 1.4.2 to 2.1.0. The SDK removes legacy file-based privileges, rejects raw file statistics on query-auth tables, corrects pre-epoch timestamp-to-date casts, and supports per-field checked integer aggregation while preserving wrapping overflow by default. ### Check List (For Author) - Test: Unit Test / Manual test - FE connector: 831 passed, 1 live-connectivity test skipped. - BE scanner: 142 passed. S3 shade: 1 passed. - Maven validate/Checkstyle and plugin packaging passed. - Checked scanner duplicate classes, SPI isolation, dependency closure, and API stamps: 162 JARs, no failures. - Verified matching 2.1.0 SDKs and byte-for-byte S3 embedded runtime. - Full build blocked by missing local Paimon Rust third-party artifacts; native BE and cluster regression tests were not run. - Behavior changed: Yes, adopts the Paimon 2.1.0 behavior described above. - Does this need documentation: No, upstream changes are in the release note.
### What problem does this PR solve? Issue Number: N/A Related PR: apache#69343 Problem Summary: Paimon 2.1 adds file_indexes, whose backend reader re-plans files after Doris strips its catalog loader, and latest-delta, which Doris would incorrectly resolve to a full snapshot. Pin file_indexes to the catalog-published snapshot and reject the unimplemented delta OPTIONS mode with guidance to use explicit @incr ranges. Add persisted tests for both cases and for nullable primary-key metadata, serialization, and NULL-key deduplication across commits. ### Release note Fix catalog snapshot visibility for Paimon file_indexes and explicitly reject unsupported latest-delta OPTIONS reads instead of reading a full snapshot. ### Check List (For Author) - Test: Unit Test / Manual test: run-fe-ut.sh with temporary Paimon module scope, Checkstyle enabled, and install packaging; 834 passed and 1 live-connectivity test skipped. FE plugin ZIP produced. The runner was restored. Native BE/Rust and cluster regressions were not run because the local third-party Paimon native library/header are missing. - Behavior changed: Yes, pin new system-table reads and reject an unsupported startup mode rather than returning incorrect rows. - Does this need documentation: No, compatibility impact is recorded in the PR description and release note.
### What problem does this PR solve? Issue Number: N/A Related PR: apache#69343 Problem Summary: Exercise the upgraded SDK in a real Doris cluster. Verify nullable primary-key deduplication through JNI and a profile-confirmed Rust reader, bitmap file-index metadata, rejection of unsupported latest-delta OPTIONS, and wrapping versus checked sum overflow. Generate the expected output with the regression runner and verify it in a normal run. Update the oversized-write error assertion to Paimon 2.1's diagnostic while retaining the existing row and snapshot atomicity checks. ### Release note None ### Check List (For Author) - Test: Regression test / Unit Test / Manual test - New compatibility suite: generated output and normal replay passed. - Read compatibility matrix: 13 suites passed. - Metadata and transaction matrix: 6 suites passed. - Paimon ASAN native UT: 108 tests in 14 suites passed. - Java scanner: 142 tests passed; S3 shade: 1 test passed. - Native BE ASAN build and deployed plugin checks passed. - Manual backward read of 1.4.2 tables through JNI and Rust matched the Spark oracle. - Behavior changed: No (test coverage and updated SDK diagnostic assertion only) - Does this need documentation: No
### What problem does this PR solve? Issue Number: N/A Related PR: apache#69343 Problem Summary: Paimon 2.1 file_indexes defers catalog query checks until the BE read, where its catalog loader has already been removed. The second serialized system-source payload also lost the catalog snapshot bound when JNI rebuilt the wrapper. Transfer the deferred query check to the FE and pin the transported source. Adapt timestamp-policy projection validation and the four-argument authorization callback to the 2.1 reader API, and serialize real JSON policy definitions in scanner tests. Regenerate the affected snapshots system-table output for the added SDK columns. ### Release note Keep catalog query authorization and catalog-published snapshots when reading Paimon file_indexes, and preserve timestamp-policy filtering and masking with SDK 2.1. ### Check List (For Author) - Test: Unit Test: FE connector 844 passed/1 skipped, Java scanner 175, native Paimon/JNI/Rust 144, S3 shade 1. Regression test: 51 Paimon suites passed; opt-in KEY_DYNAMIC stress skipped. Manual test: ASAN BE and FE/Java builds, plugin layout checks, legacy 1.4.2 data reads, CI failure triage. - Behavior changed: Yes, preserve query authorization, snapshot bounds and timestamp policy enforcement with Paimon 2.1 - Does this need documentation: No
967cf6a to
9337b7c
Compare
|
run buildall |
|
/review |
There was a problem hiding this comment.
Reviewed all 39 changed paths at 9337b7c using static analysis. Request changes for one new P1: nullable primary keys newly supported by SDK 2.1 invalidate Doris MERGE's target-presence test, silently dropping matched UPDATE/DELETE operations on NULL keys.
The two prior file_indexes reports are addressed at this head: deferred catalog query checks run on the FE before loader removal (4335228948), and the transported system-source payload receives the snapshot pin before JNI rebuild (4335228960). They are not reposted, and no existing P0/P1 finding remains applicable. No additional user focus was supplied.
Critical checkpoint conclusions:
- Goal and proof: the shared SDK upgrade and API adaptations are covered by focused tests, but the nullable-key tests exercise insert/read/deduplication rather than Doris MERGE; the inline finding identifies the missing SQL semantic case.
- Scope and reuse: changes stay within the Paimon SDK migration, directly affected wrappers/callbacks, and compatibility tests; existing branch and runtime-option helpers are reused.
- Concurrency and locking: changed production paths add no threads, locks, or new shared mutable state. No introduced lock-order or heavy-under-lock problem was found.
- Lifecycle and initialization: source preparation retains the authentication/classloader scope; reader/test resources close on the examined exit paths. No new resource owner or static initialization dependency was introduced.
- Configuration: no Doris configuration key was added. The common OPTIONS validation rejects latest-delta with an actionable error before snapshot pinning can widen that request.
- Compatibility: both Java endpoints inherit the shared SDK version. Legacy file-based privileges are removed upstream and require migration. Mixed 1.4.2/2.1 Java table/commit serialization is not generally compatible; coordinated FE/BE SDK deployment remains the PR's documented requirement.
- Shared definitions: no Thrift/Protobuf or connector SPI surface changed; release-branch field-ID and SPI-baseline checks are not applicable.
- Parallel paths: traced FE metadata/schema binding, both serialized system-table payloads, JNI reconstruction, fallback/chain branches, Rust selection, and nullable fixed-bucket routing. No additional introduced issue was substantiated in these paths.
- Conditional behavior: file_indexes joins the existing deferred-check/snapshot paths; selected masks and logical timestamp precision are preserved through the new SDK callback. Removed privilege-specific branches correspond to removed SDK classes.
- Test coverage: inspected new serialized-source/JNI controls, allow/deny cases, timestamp/nested/hidden-field policy fixtures, nullable-key roundtrips and reader profiles, overflow modes, delta rejection, and failed-write atomicity checks. NULL-key MERGE UPDATE/DELETE needs coverage with the fix.
- Changed results: appended nullable snapshot fields and DESC rows agree with the SDK schema; obsolete golden blocks have no remaining qt callers; new ordered result values and the revised write-error substring agree with the inspected mechanisms. Golden generation provenance was not independently verified.
- Observability: changed failure paths retain exceptions and existing scanner diagnostics. No newly introduced critical stage requiring additional telemetry was identified.
- Transactions and persistence: no Doris EditLog, replay, transaction ownership, or failover state machine was changed. Commit framing remains aligned for matching SDK deployments; mixed-SDK limits are stated above.
- Data writes and atomicity: the existing failed-insert regression retains row/snapshot checks. The new P1 occurs before writing and can silently omit an intended row change; it requires correction or explicit rejection.
- FE/BE transport: no Doris protocol field was added. The source payload now preserves the catalog pin; both endpoints' Java object serialization depends on matching SDK jars.
- Performance and memory: no new native allocation, cache owner, executor, or unbounded hot-loop work was introduced in the changed code; no additional substantiated performance defect was found.
- Other concerns and user focus: no additional introduced finding beyond the inline P1. There were no extra user focus points.
No builds, tests, or source edits were performed under this review contract. Runtime packaging, HMS/REST integration, native/Rust execution, and mixed-version rollout were not independently exercised. Convergence describes the completed static review process, not runtime certification.
Review converged after 2 round(s).
### What problem does this PR solve? Issue Number: N/A Related PR: apache#69343 Problem Summary: With Paimon 2.1 nullable primary keys, a NULL-safe MERGE can join a target row whose first primary key is NULL. Changelog branch selection then treated that row as absent and silently dropped matched UPDATE and DELETE changes. Treat every surviving INNER JOIN row as matched for MATCHED-only MERGE. For MERGE with INSERT branches, project a non-null presence marker on the target before the outer join and inspect its null-extended output by ExprId. Keep private marker slots outside the user expression-binding scope so same-named source columns retain their values. Add nullable single/composite-key SQL coverage, branch and cardinality checks, marker-name collision coverage, and focused planner unit tests. ### Release note Fix matched MERGE UPDATE and DELETE silently omitting Paimon rows with NULL primary keys under NULL-safe equality. ### Check List (For Author) - Test: Unit Test: 38 related FE tests passed. Regression test: 9 Paimon suites passed, including nullable-key MERGE with generated/replayed expected output and all six existing write suites containing MERGE. Manual test: FE build and before/after NULL-key UPDATE/DELETE reproduction. - Behavior changed: Yes, matched NULL-key rows are updated/deleted and target presence is independent of key values - Does this need documentation: No
|
/review |
There was a problem hiding this comment.
Reviewed all 43 changed paths at b6ad0f2. No new actionable findings. Review converged in round 1: both complete reviewers and the separate risk reviewer returned NO_NEW_VALUABLE_FINDINGS on the unchanged empty inline set; all candidates and risk focuses have evidence-based dispositions. No additional user review focus was supplied.
The earlier nullable-key MERGE P1, file_indexes deferred-check P1, and JNI source snapshot P2 are resolved on this head. MATCHED-only joins use their INNER JOIN semantics; INSERT-capable plans use the null-extended target marker by ExprId without exposing it to user expression binding. file_indexes performs the deferred catalog check before loader removal, and its separately transported source carries the catalog snapshot pin through actual JNI reconstruction. No existing P0/P1 remains to carry as a blocking comment ID.
Inspected flows: catalog/cache -> bound schema and scan selectors -> FE split planning plus serialized table/source -> JNI reconstruction and policy callbacks or conservative Rust selection; MERGE join -> branch selection -> row-change projection -> cardinality assertions -> existing commit/rollback boundary.
Critical checkpoint conclusions:
| Checkpoint | Conclusion |
|---|---|
| Goal and evidence | Shared SDK 2.1 upgrade and affected adapters are consistent on static inspection; targeted unit and SQL tests cover the changed behavior. |
| Scope and reuse | Changes stay focused on SDK adaptations, file_indexes transport, unsupported delta startup, and nullable target presence; existing branch/cardinality and connector helpers are reused. |
| Concurrency and locks | New state is query/read local; no new worker, shared mutable state, lock acquisition order, or metadata-lock IO region was found. |
| Lifecycle and initialization | Reader wrappers retain normal close propagation; cache construction cleanup, catalog-loader removal, fallback ownership and static initialization remain consistent. |
| Configuration | No new global configuration; existing option precedence and branch-local caps remain. latest-delta fails explicitly before full-snapshot conversion. |
| Compatibility | FE/scanner share paimon.version. SDK schema/Snapshot fixtures, serialized rule definitions, and callback signatures are adapted. FE and BE Java extensions must deploy the same SDK. |
| Thrift/protobuf | No changed definitions or field IDs; release-branch ID comparison is inapplicable. |
| Parallel paths | Checked data/system scans, source-payload reconstruction, REST/filesystem schema provenance, explicit selectors, fallback/chain boundaries, and native/JNI/Rust selection. |
| Conditional checks | New checks have concrete triggers: unsupported delta semantics, join shape and lost marker. Nullable target detection follows actual join output nullability. |
| Test coverage | Includes NULL single/composite keys, ordinary/NULL-safe matches, branch priority, insert-only paths, marker collisions, duplicate failures, actual source pinning, denied deferred checks, and overflow modes. |
| Changed results | New golden labels match ordered SQL calls; nullable rows, overflow values and added snapshot fields are consistent. Removed stale labels have no corresponding suite calls. |
| Observability | Unsupported modes and invariant failures remain explicit; existing scan profiles and transaction errors cover the changed paths. |
| Persistence and failover | No Doris EditLog/replay or persisted transaction format changes; existing schema/snapshot coordinates and rollback paths remain. |
| Writes and atomicity | Private marker stays outside final sink output. Cardinality checks group full key tuples, including NULLs; failure still prevents commit and follows rollback. |
| FE/BE variables | Existing transport keys are reused; both system-table payload paths and the SDK policy callback boundary were checked. |
| Performance and memory | One small constant marker projection is added only for INSERT-capable MERGE. No new unbounded allocation, executor growth or asymptotic regression was established. |
| Other concerns | No unresolved PR-introduced candidate remains after the missed-issue rechecks and final sweep. |
Validation limits: this invocation was static only; no builds or tests were run, and golden generation was not independently executed. Mixed 1.4.2/2.1.0 rolling deployments and all newly introduced upstream layouts are not validated. Removal of upstream file-based privileges requires the migration already noted in the PR. Existing two-phase system-table metadata timing and the independent constant-source composite NULL-safe optimizer limitation remain understood limitations, not new findings from this change.
Review converged after 1 round(s).
|
run buildall |
TPC-H: Total hot run time: 28278 ms |
TPC-DS: Total hot run time: 150264 ms |
ClickBench: Total hot run time: 24.59 s |
FE UT Coverage ReportIncrement line coverage |
FE Regression Coverage ReportIncrement line coverage |
TPC-H: Total hot run time: 28678 ms |
TPC-DS: Total hot run time: 150628 ms |
ClickBench: Total hot run time: 24.43 s |
FE Regression Coverage ReportIncrement line coverage |
2 similar comments
FE Regression Coverage ReportIncrement line coverage |
FE Regression Coverage ReportIncrement line coverage |
|
PR approved by at least one committer and no changes requested. |
…ble source (#69569) ### What problem does this PR solve? Issue Number: None Related PR: #68897, #69343 Problem Summary: **In short.** This PR only adds tests. Some Paimon system tables are planned on the BE. For them, the JNI scanner rebuilds the system table from the source table that the FE sends in `doris.serialized-system-source`. In a version-managed catalog, that payload must be pinned to the snapshot the catalog publishes. #69343 added this pin. This PR adds the two cases its tests do not cover: a `scan.fallback-branch` pair, and an explicit relation snapshot that must still take precedence over the pin. **Background.** Six Paimon system tables are planned on the BE: `$files`, `$file_indexes`, `$partitions`, `$manifests`, `$statistics` and `$table_indexes` (`PaimonScanParams#resolvesSnapshotOnBackend`). For these tables the FE sends two payloads: - `serialized_table` is built by `tableForBackend`. - `doris.serialized-system-source` was added in #66247 so that a smaller BE can cap the manifest parallelism. The FE always sends it when the system table has a source. When it is present, `PaimonJniScanner#applyBackendManifestParallelism` rebuilds the system table from this payload instead of from `serialized_table`. A version-managed catalog (REST) owns the committed snapshot pointer. Once the catalog loader is removed, Paimon falls back to listing the snapshot directory, and that directory can already contain a snapshot the catalog has not published. #65867 therefore pins `scan.snapshot-id` to the catalog's pointer (`PaimonScanPlanProvider#pinCatalogSnapshot`). **The problem, and what it cost.** Before #69343, only `serialized_table` carried that pin. The side channel shipped the source unpinned, and the BE rebuilt from the side channel. So in a REST catalog these six system tables were planned on the newest snapshot in storage rather than the published one, on every branch. Inside the publication window, `$partitions` could list partitions of a snapshot the catalog had not published yet. The review of #68897 pointed this out for chain tables. #69343 (the Paimon 2.1.0 upgrade) now prepares the side-channel source in the same order as `tableForBackend` (`prepareSystemSource`): 1. Pin the catalog snapshot, branch by branch. 2. Apply the relation's `@options` over the pin. 3. Drop the catalog loader. Its tests cover `$file_indexes` on a single-branch table, on the FE and through the JNI rebuild. **How this PR fixes it.** Two FE unit tests in `PaimonBackendBoundTableTest` read the side channel out of `paimon.options_json`: - `systemSourcePinsEachFallbackBranchToItsOwnCatalogSnapshot` builds `$partitions` over a fallback pair whose two catalogs point at snapshots 2 and 1. Each branch of the transported source carries its own pointer and no catalog loader. A chain table nests the same pairs. - `relationSnapshotOutranksTheCatalogPinOnTheSystemSource` uses a catalog that points at snapshot 2 and `@options('scan.snapshot-id'='1')`. The transported source says 1. Paimon 2.1.0 still has the two limitations documented on `pinCatalogSnapshot`: - `$files` emits its marker splits from `SnapshotReader#partitions`. - `$snapshots` and `$buckets` read without `scan.snapshot-id`. So that javadoc stays as written. **Results.** | `prepareSystemSource` | `PaimonBackendBoundTableTest` | |---|---| | as on master (pin, then `@options`) | 38 / 38 pass | | without the pin | the new fallback case and the existing `$file_indexes` case fail | | pin applied after the relation options | the new relation-snapshot case fails (`expected: <1> but was: <2>`) | All 847 tests of fe-connector-paimon pass, with 1 skipped as before, and checkstyle passes. No regression suite is added: it would need a version-managed (REST) Paimon catalog whose pointer lags the snapshot directory, and the docker fixtures do not provide one.
### What problem does this PR solve? Related PR: apache#69343, apache#69493 Problem Summary: Bring the Paimon 2.1 upgrade on branch-4.2 in line with master's compatibility handling. A nullable primary key cannot identify whether a MERGE target row is present: MATCHED-only NULL-safe joins lost valid updates/deletes, while outer joins need a separate presence marker. Use the existing join shape and bind user expressions before exposing the private marker. Reject latest-delta OPTIONS before snapshot pinning can silently turn a delta read into a full read. Match master after removal of the legacy privilege delegates and carry over SDK compatibility tests, file-index snapshot coverage and generated regression results. ### Release note Fix Paimon MERGE matched UPDATE/DELETE for nullable primary keys. Reject scan.mode=latest-delta in OPTIONS with guidance to use explicit @incr ranges. ### Check List (For Author) - Test: Added/adapted FE and JNI unit tests and master's external regression suites. Static self-review and whitespace checks completed (preserving generated result-file separators). No local build, Checkstyle, unit tests or regression execution, as requested. Result files are copied from master apache#69343 rather than generated locally. - Behavior changed: Yes; preserve NULL-key MERGE matches and reject an unsupported delta mode instead of reading a full snapshot. - Does this need documentation: No; the rejection provides the supported alternative.
### What problem does this PR solve? Related PR: apache#69886, apache#70075, apache#69343 Problem Summary: Master now provides paimon-rust v0.5.0-rc1 and Java Paimon 2.1.0. Rebase the writer on master instead of carrying separate dependency upgrades. Reuse the upstream Java v14 serializer with bounded accumulated output, remove the v11 and legacy DataFileMeta encoding patch, and regenerate the real two-writer interop fixture. Reject old protocol requests before writer admission. Preserve master's vector-search field 42 and use optional field 43 for the shared descriptor; retain master's SPI additions and bump the write diagnostics surface to API 30. The previous BE UT crash was caused by a validation test bypassing init() and reading an uninitialized scan-params pointer. Explicitly initialize its missing-descriptor input. ### Release note Rust Paimon writes use the Java v14 commit protocol matching master's Paimon 2.1.0 SDK and inherit master's paimon-rust dependency version. ### Check List (For Author) - Test: Third-party build with Rust 1.94.0; real C FFI append, codec bounds, version rejection, message ranges and resource release; FE/Java build with Checkstyle; Paimon connector 904 tests (one skip); connector SPI 152 tests; six Paimon JNI static layout checks; Thrift generation/field audit; clang-format 16, header hygiene, shell syntax and whitespace checks. JNI Paimon 186 and FE integration 36 tests passed. BE compilation, native tests, clang-tidy against the new build and SQL regression are deferred at the user's request to leave resources for another PR. - Behavior changed: Yes; Rust commit messages now use v14 instead of v11. - Does this need documentation: Yes; existing feature documentation remains pending with the draft PR.
### What problem does this PR solve? Related PR: apache#69886, apache#70075, apache#69343 Problem Summary: Master now provides paimon-rust v0.5.0-rc1 and Java Paimon 2.1.0. Rebase the writer on master instead of carrying separate dependency upgrades. Reuse the upstream Java v14 serializer with bounded accumulated output, remove the v11 and legacy DataFileMeta encoding patch, and regenerate the real two-writer interop fixture. Reject old protocol requests before writer admission. Preserve master's vector-search field 42 and use optional field 43 for the shared descriptor; retain master's SPI additions and bump the write diagnostics surface to API 30. The previous BE UT crash was caused by a validation test bypassing init() and reading an uninitialized scan-params pointer. Explicitly initialize its missing-descriptor input. ### Release note Rust Paimon writes use the Java v14 commit protocol matching master's Paimon 2.1.0 SDK and inherit master's paimon-rust dependency version. ### Check List (For Author) - Test: Third-party build with Rust 1.94.0; real C FFI append, codec bounds, version rejection, message ranges and resource release; FE/Java build with Checkstyle; Paimon connector 904 tests (one skip); connector SPI 152 tests; six Paimon JNI static layout checks; Thrift generation/field audit; clang-format 16, header hygiene, shell syntax and whitespace checks. JNI Paimon 186 and FE integration 36 tests passed. BE compilation, native tests, clang-tidy against the new build and SQL regression are deferred at the user's request to leave resources for another PR. - Behavior changed: Yes; Rust commit messages now use v14 instead of v11. - Does this need documentation: Yes; existing feature documentation remains pending with the draft PR.
### What problem does this PR solve? Issue Number: N/A Related PR: apache#70103, apache#69343 Problem Summary: The backported Paimon merge planner adds its target-presence marker to the left join input, but PaimonMergeCommand still places the source on the left. Unmatched source rows therefore select MATCHED and write NULL target keys instead of inserting. Reuse MergeUtils to keep the target on the left and preserve the source with RIGHT OUTER JOIN when INSERT is present. Add command-level tests for both join layouts. Keep logical splits when the compatibility case asserts Rust execution and use the 4.2 MERGE diagnostics in nullable-key error expectations. ### Release note Fix Paimon MERGE INTO incorrectly classifying unmatched source rows as matched on branch-4.2, including NULL key writes to non-nullable primary keys. ### Check List (For Author) - Test: FE/JNI build and Checkstyle; 490 FE unit tests passed, 2 environment-gated tests skipped; 47 regression framework unit tests passed; all 6 affected Paimon regression suites passed against existing golden outputs using the PR's successful CI ASAN BE and the repository's Spark/Paimon fixtures. - Behavior changed: Yes, unmatched Paimon MERGE source rows select INSERT. - Does this need documentation: No, restores the intended MERGE semantics.
What problem does this PR solve?
Issue Number: N/A
Related PR: N/A
Problem Summary:
Upgrade the Paimon Java SDK from 1.4.2 to 2.1.0, the latest stable release published on October 12, 2026 (upstream release). Pin the FE connector and BE JNI scanner to the same shared
paimon.version, since tables, splits, and commit messages cross the FE/BE boundary using Paimon's serialization.Adapt the connector to the removal of Paimon's file-based
Privilege*API in 2.1.0, removing its obsolete catalog/table wrappers and reflection-based delegate reconstruction. Preserve catalog query authorization, fallback/chain branch semantics, statement-bound schemas and snapshots, and Doris metadata-cache governance. Update local test fixtures toFileSystemSchemaManagerand the extendedSnapshotconstructor. Give scanner tests thejava.nioaccess already enabled in the BE JVM for Arrow Variant buffer views. Update the oversized-write negative test to the SDK's revised diagnostic while retaining its snapshot/row atomicity checks. Retain the branch/scan API adaptations and grouped format-file split fixture required since 2.0. Verify both the default wrapping and explicitly enabled checked integer-overflow modes in 2.1, as well as the corrected pre-epoch timestamp-to-date cast. Keep the existing Rust reader eligibility rules and common/S3 compatibility patches. Fix changelog MERGE target-presence detection for nullable primary keys: matched-only plans use their INNER JOIN semantics, while plans with INSERT branches use a pre-join marker. Keep that private marker outside user expression resolution. Preserve catalog query authorization for the new$file_indexessystem table and pin both serialized table payloads to the catalog-published snapshot before stripping their catalog loaders. Adapt timestamp precision repair to the SDK's authorization projection validation and four-argument policy callback; use real JSON policy definitions in serialized scanner fixtures. Rejectscan.mode=latest-deltain Doris@options, because the existing full-snapshot pinning would silently widen a delta scan; explicit@incrranges remain available.The FE and BE Java extensions must be deployed with the same SDK version. This change does not establish compatibility between mixed 1.4.2/2.1.0 SDKs during a rolling upgrade.
Paimon 2.1 feature impact on Doris
primary-key.nullable=true$file_indexeslatest-deltabatch startup mode@optionsinstead of silently converting it to a full-snapshot read. A real three-snapshot test proves the difference (one delta row versus three full-snapshot rows).file.format=arrowstorage format. Doris keeps its current Arrow-to-Paimon-row writer; using the new bundle API is a separate performance change requiring memory/lifecycle validation and benchmarks.FileSystemSchemaManager. The REST additions inspect schema history; they do not replace the SDK table's filesystem schema manager. Doris does not call the new display APIs in this PR.java.nioaccess as the BE JVM. The targeted Java, native and cluster checks below cover existing supported paths, but do not establish native/Rust compatibility for every newly introduced table option or file layout.Release note
Upgrade the Paimon Java SDK from 1.4.2 to 2.1.0. Fix NULL-safe MERGE matched UPDATE/DELETE silently omitting rows with NULL primary keys. Paimon 2.1 keeps wrapping integer
sum/productoverflow by default and supports per-fieldfields.<field>.sum.fail-on-overflow/fields.<field>.product.fail-on-overflowoptions for checked arithmetic. Timestamp-to-date casts before the Unix epoch now use the preceding calendar date. The SDK rejects raw$files,$file_key_ranges,$binlog, and$statisticstables on query-auth tables because column masks cannot be applied to their physical metadata. Doris now preserves query authorization and pins$file_indexesto the catalog-visible snapshot and explicitly rejects the unimplementedlatest-deltaOPTIONS mode instead of returning a full snapshot. Paimon's legacy file-based privilege system is no longer supported by the upstream SDK; deployments using it must migrate authorization before upgrading.Check List (For Author)
Test
Regression test
Unit Test
Manual test
Build: FE/Java extensions and ASAN BE passed after rebasing onto master
5e3ed84abb0; both Java endpoints package SDK 2.1.0. All 9 JNI plugins passed layout checks.Unit tests: FE connector 844 passed, 1 live-connectivity test skipped; Java scanner 175 passed; native Paimon/JNI/Rust 144 passed; S3 shade 1 passed. The MERGE follow-up passed 38 related FE tests.
Cluster regression: 51 Paimon suites passed after rebase; the MERGE follow-up passed 9 targeted suites, including the new nullable-key regression. The opt-in KEY_DYNAMIC resource stress suite was skipped. System-table expected output was regenerated with the runner and replayed successfully.
Backward reads: Paimon 1.4.2 append/PK data matched its Spark oracle again; completed profiles confirmed Rust append reads and JNI fallback for multi-file PK merges.
Scope: S3/filesystem Paimon catalog. File cache was disabled for a local Btrfs inode-stat issue, and the host swap startup check was skipped. Paimon HMS/REST catalogs and mixed-SDK rolling upgrades were not validated.
Behavior changed:
$file_indexes, and explicit rejection of unsupportedlatest-deltaOPTIONS reads.Does this need documentation?
Self-review
Validation follow-up scope: fix nullable-key MERGE target-presence detection, then preserve deferred
$file_indexesauthorization and its JNI source snapshot pin, adapt timestamp-policy validation and callbacks to SDK 2.1, and refresh affected system-table expected output through the regression runner.Goal and scope: shared SDK upgrade plus directly affected API/behavior adaptations. New search and batching features remain separate work; no new connector SPI or native ABI is introduced.
Correctness and parallel paths: FE binding, serialized BE system-table reconstruction, JNI SDK behavior, and reader selection were inspected.
$file_indexespreserves deferred catalog authorization and carries the snapshot pin through both FE/BE payloads; timestamp policies validate and execute against repaired precision; MERGE uses INNER JOIN semantics or a null-extended target marker rather than testing a nullable key, and user expressions retain their original binding scope; both OPTIONS resolution and statement-fence pinning rejectlatest-delta.Concurrency and lifecycle: production adaptations add no threads, locks, shared mutable state, native allocations, or resource owners. Java fixtures close their catalog/writer/commit/reader resources; the new cluster suite restores modified session variables in
finallyand preserves tables for debugging. The existing writer-lifecycle regression passed 120 successive inserts and verified compaction writer threads return to zero after each phase.Performance: reuse the existing row repair and SDK policy evaluation; bind source snapshots during FE planning. MERGE adds one constant target projection only when INSERT branches need unmatched rows. No performance improvement is claimed.
Compatibility and configuration: upstream file privileges are removed, and mixed SDK rolling upgrades remain unverified. No configuration keys, Thrift/Protobuf definitions, new FE/BE variables, or persistence formats are added by Doris. Storage access for
$file_indexesuses the existing configured catalog endpoint and base-table SELECT privilege; there is no new artifact-download property.Tests and results: FE scan-properties tests cover denied
$file_indexesauthorization and catalog-published snapshot bounds; an actual serialized JNI reconstruction test covers the second payload. Serialized timestamp-policy tests retain row filters, masking, fallback and nested/hidden-column coverage. MERGE tests cover nullable single/composite keys, ordinary and NULL-safe equality, branch priority, duplicate-match rejection without row changes, and same-named user columns; the new golden is generated and replayed by the regression runner. The system-table golden now includes SDK 2.1'soperationandwriter_versionfields. Builds, unit tests, cluster replay and legacy-data reads passed after rebase; limits are listed above.Other CI failures: the P0 view case passed in isolation; it shares and drops
v_distinct_agg_rewritewithtest_mtmvin the same database. The Iceberg failure was reproduced asDESC digestexpecting nullableYesbut returningNo: master's source-nullability change predates the test's old expectation. Those Iceberg and P0 files are unchanged from the base; no unrelated golden was modified.Independent optimizer limitation: a one-row constant source with multiple NULL-safe join keys can become an empty relation even when an internal OLAP table has a matching NULL row. This also reproduces in an ordinary SELECT on an internal table; optimizer files are unchanged by this PR. The composite-key DELETE regression uses a multi-row source with an unmatched control. That standalone optimizer defect remains outside this SDK adaptation.
Transactions, writes and observability: no transaction/recovery implementation is changed. The transaction regression confirms an oversized failed insert publishes neither rows nor a snapshot. Completed query profiles prove Rust selection and JNI fallback, rather than relying only on enable flags. Unsupported delta mode fails with an actionable diagnostic; existing system-table planning diagnostics apply to snapshot pinning.
Check List (For Reviewer who merge this PR)