Skip to content

branch-4.1:[feat](paimon) support paimon-rust reader on BE - #66227

Merged
yiguolei merged 40 commits into
apache:branch-4.1from
pzhdfy:branch-4.1-paimon-rust
Sep 30, 2026
Merged

yiguolei merged 40 commits into
apache:branch-4.1from
pzhdfy:branch-4.1-paimon-rust

Conversation

@pzhdfy

@pzhdfy pzhdfy commented Jul 29, 2026 •

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Related PR: #65883 (for master , current closed)

this pr add paimon rust reader both in scanner v1 and v2.
the scanner v1 code is just for legacy, will be removed later.

Problem Summary:

Adds a third BE-side reader for Paimon FORMAT_JNI splits, backed by the
paimon-rust C bindings (libpaimon_c.a, statically linked). Rust Reader is gated by the session variable
enable_paimon_rust_reader (default false).

Compared with the existing readers:

  • vs paimon-jni: no JVM round-trip on the hot path — the split is
    deserialized in-process and rows arrive via the Arrow C Data Interface,
    which shortens the scanner critical section and removes JNI copy cost.

Architecture

FE (PaimonScanNode): when enable_paimon_rust_reader is on and the split
is a DataSplit, encode it with paimon's native binary serialization
(PaimonUtil.encodeDataSplitToString), stamp the range with
TPaimonReaderType.PAIMON_RUST, and attach db_name / table_name /
paimon_table so BE can open the table through a catalog.

BE (FileScanner::_get_next_reader): dispatches on reader_type. On
PAIMON_RUST it instantiates PaimonRustReader, which:

  1. paimon_catalog_create({warehouse, metastore=filesystem, ...})
    • warehouse is derived from the table root path by stripping
      /<db>.db/<table> (paimon FS convention).
  2. paimon_identifier_new(db, tbl) → paimon_catalog_get_table
  3. paimon_table_new_read_builder → projection (case-insensitive) →
    optional filter from PaimonRustPredicateConverter (translates Doris
    push-down conjuncts into paimon-rust predicates, best-effort so any
    non-representable conjunct is silently dropped and re-applied by the
    engine).
  4. paimon_plan_from_split_bytes(split_bytes) — one BE scanner reads
    exactly its FE-planned split (no re-planning).
  5. paimon_table_read_to_arrow → streamed arrow record batches → block.

Partition columns are back-filled in on_after_read_block from
FE-provided columns_from_path*, mirroring PaimonCppReader. OSS/S3
hadoop-style credential keys (fs.oss.* / fs.s3a.*) are remapped to
AWS_ACCESS_KEY / AWS_ENDPOINT / ... so paimon-rust's FileIO can
authenticate.

Thirdparty

  • Introduces paimon-rust-2fb5e49 (built with Rust 1.91.0, feature
    paimon/storage-hdfs, --locked).
  • Auto-installs cbindgen and regenerates the C header from the Rust
    extern "C" surface via a locally-written cbindgen.toml
    (language=C, include_guard=PAIMON_C_H, pragma_once=true, cpp_compat=true),
    so the shipped paimon.h always matches the built .a.

Release note

Add enable_paimon_rust_reader session variable. When enabled, Paimon
non-native reads on BE use the paimon-rust reader instead of paimon-jni /
paimon-cpp.

Check List (For Author)

  • Test

    • Unit Test
    • Manual test (add detailed scripts or steps below)
      1. CREATE CATALOG paimon_fs PROPERTIES ("type"="paimon", "paimon.catalog.type"="filesystem", "warehouse"="file:///media/ssd1/test_paimon/warehouse/"); when using "warehouse"="hdfs://.../warehouse/", add HADOOP_CONF_DIR=xx in be.conf
      2. SET enable_paimon_rust_reader=true; SET force_jni_scanner=1
      3. SELECT from a partitioned/DV paimon table; results must match enable_paimon_rust_reader=false and force_jni_scanner=0.
      4. SELECT count(*) — should hit table-level row count push-down.
      5. WHERE a=1 AND b>2 — BE INFO log should show paimon-rust predicate pushdown: applied.
    • Regression test
    • No need to test or manual test.
  • Behavior changed:

    • No. Guarded by enable_paimon_rust_reader (default false); when off, all paths are unchanged.
  • Does this need documentation?

    • No.
    • Yes.

Check List (For Reviewer who merge this PR)

  • Confirm the release note
  • Confirm test cases
  • Confirm document
  • Add branch pick label

@pzhdfy
pzhdfy requested a review from yiguolei as a code owner July 29, 2026 08:10
@hello-stephen

Copy link
Copy Markdown
Contributor

Thank you for your contribution to Apache Doris.
Don't know what should be done next? See How to process your PR.

Please clearly describe your PR:

  1. What problem was fixed (it's best to include specific error reporting information). How it was fixed.
  2. Which behaviors were modified. What was the previous behavior, what is it now, why was it modified, and what possible impacts might there be.
  3. What features were added. Why was this function added?
  4. Which code was refactored and why was this part of the code refactored?
  5. Which functions were optimized and what is the difference before and after the optimization?

@pzhdfy pzhdfy closed this Jul 30, 2026
@pzhdfy pzhdfy reopened this Sep 1, 2026
@pzhdfy
pzhdfy force-pushed the branch-4.1-paimon-rust branch from b07fa00 to b1aa749 Compare September 1, 2026 08:45
@pzhdfy
pzhdfy force-pushed the branch-4.1-paimon-rust branch 3 times, most recently from 9d13ef7 to 69e66d9 Compare September 15, 2026 09:50

@Gabriel39 Gabriel39 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rechecked these findings against the updated head (69e66d9). The relevant implementation is unchanged. These comments focus on issues introduced by the Rust reader path; existing FE LIKE handling and ordinary timestamp-literal truncation are not counted as separate new regressions. This is a static review of the call chain and the pinned Rust dependency; I have not run this PR's build or end-to-end tests.

Comment thread be/src/format/table/paimon_rust_predicate_converter.cpp Outdated
Comment thread be/src/format_v2/table/paimon_rust_predicate_converter.cpp
Comment thread be/src/format_v2/table/paimon_rust_table_reader.cpp Outdated
@pzhdfy
pzhdfy requested a review from Gabriel39 September 16, 2026 09:20
@Gabriel39

Copy link
Copy Markdown
Contributor

Reviewed head 0d62a55072b5e094aca46eea05e5ffbfd0c64e28. Thanks for addressing the earlier findings. There are still the following issues and test gaps to resolve:

  1. [P1] Do not strip lossy column casts before predicate pushdown.

    _resolve_field calls expr_without_cast. For a DECIMAL(10,2) column containing 1.24, CAST(amount AS DECIMAL(10,1)) = 1.2 must retain the row, but this converter builds equality against the original column and Rust rejects 1.24. The Doris residual cannot recover that row. The FE converter already rejects casted operands, and its existing rejectDecimalScaleCast test establishes that this cast survives planning. The pinned Rust predicate implementation accepts decimal literals with different scales and compares their mathematical values, so it does not reject this unsafe predicate as a type mismatch.

    Please reject casted operands unless equivalence has been established. Add converter tests and an actual Rust/JNI differential regression for decimal scale reduction and CAST-related NULL semantics.

  2. [P2] Serialize the effective table options used by the query.

    This path reads source.getPaimonTable() and serializes its schema at line 457, whereas JNI serializes the processed table. For reader-only relation options such as t@options('read.batch-size'='1'), the snapshot path reuses the cached table and getProcessedTable() subsequently applies the relation options. Serializing the original table drops that override. The C API treats the separately supplied options as FileIO properties only, while Rust obtains its read batch size from the schema options.

    Please serialize the same effective table used for planning/JNI, and add tests for relation-option precedence and the options actually received by the Rust reader.

  3. [P2] Fix the Spark DDL in the new regression.

    test_paimon_rust_reader_eq_for_null.groovy sends TIMESTAMP(6) to Spark at lines 56 and 65. Spark's datatype parser accepts TIMESTAMP without precision parameters, so this setup is rejected before the assertions. Please use supported Spark syntax and explicitly establish NTZ/LTZ semantics; simply removing (6) does not establish the NTZ semantics claimed by the comments.

  4. [P2] Ensure the specialized regression actually exercises Rust.

    The two comparison legs only toggle enable_paimon_rust_reader. These append tables can be converted into raw native splits, which getSplits() prioritizes when force_jni_scanner is false. Both legs can therefore use the native reader, bypassing the new converter and materializer.

    Please set force_jni_scanner=true for the differential comparisons, restore the setting afterward, and verify the actual reader path through the profile or equivalent instrumentation. For the fractional-timestamp join, also force/verify an IN runtime filter arriving before split opening; an unconstrained join does not guarantee that path. The separate V2 smoke suite forces logical splits but does not cover these specialized cases. Please run the corrected external suite with Paimon tests enabled and provide the results.

Directory placement: Please move paimon_rust_predicate_converter.cpp and .h from be/src/format/table/ to be/src/format_v2/table/, and move the corresponding test from be/test/format/table/ to be/test/format_v2/table/. Update the includes and any build references accordingly. This converter is consumed by the V2 Rust reader and relies on V2's rewritten table-global slot references; its implementation and tests should live alongside that V2 path.

This follow-up is based on static call-chain and dependency-source review. I have not run this PR's build or end-to-end tests.

@Gabriel39

Copy link
Copy Markdown
Contributor

run buildall

@Gabriel39

Copy link
Copy Markdown
Contributor

/review

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Static review of exact head 1762b2a4a93dae6f7867aa1c30c7436040d396c2. I am requesting changes for 11 verified defects.

Critical checkpoints:

  • Correctness and predicate semantics: three P1 issues can suppress an earlier error or wrongly prune rows through NaN and casted-IN semantic mismatches. Other numeric, LIKE, NULL-safe, timestamp, and residual paths were rechecked; existing comments for column-to-column NULL-safe equality and fractional timestamps were not duplicated.
  • Security and storage configuration: three P1 issues expose credentials, drop configured S3 authentication modes, or make standard OSS catalogs fail to open. Provider option precedence, table-cache identity, and additional scheme dispatch were checked without another distinct finding.
  • Lifecycle, resources, and performance: Arrow C ownership, handle teardown, EOF/error/abort paths, split reuse, projection, partition/default fill, and metadata COUNT behavior were verified. One P1 issue leaves Scanner V2's adaptive row cap disconnected from the physical Rust stream.
  • Compatibility and table semantics: ordinary schema evolution, snapshot/branch/relation-option, merge-on-read, deletion-vector, and same-version V1/V2 fallback paths were checked. A P1 issue routes incremental scans through the ordinary reader, and a P2 issue lacks a rolling-upgrade backend capability gate.
  • Third-party/build reproducibility: static link and generated-header integration were inspected. A P1 issue trusts an unchecked ambient aarch64 crate, and a P2 issue uses unpinned online tool installation despite offline mode.
  • Tests and completion: the changed unit/regression coverage was reviewed, but builds and tests were not run because this review task explicitly prohibits them. Two fresh full passes and an independent risk pass converged with NO_NEW_VALUABLE_FINDINGS; all 26 changed files and every candidate status were swept.

No additional user-provided review focus was supplied. Existing resolved threads for NULL-safe equality, fractional timestamp filters, session timezone materialization, and same-version Scanner V1 fallback were treated as duplicate fences.

Comment thread be/src/format_v2/table/paimon_rust_predicate_converter.cpp
Comment thread be/src/format_v2/table/paimon_rust_predicate_converter.cpp
Comment thread be/src/format_v2/table/paimon_rust_predicate_converter.cpp
Comment thread be/src/format_v2/table/paimon_rust_table_reader.cpp Outdated
Comment thread be/src/format_v2/table/paimon_rust_table_reader.cpp Outdated
Comment thread be/src/format_v2/table/paimon_rust_table_reader.h Outdated
Comment thread thirdparty/build-thirdparty.sh Outdated
Comment thread thirdparty/build-thirdparty.sh Outdated
@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 72.22% (26/36) 🎉
Increment coverage report
Complete coverage report

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 40.61% (478/1177) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 74.36% (31477/42328)
Line Coverage 58.68% (351410/598867)
Region Coverage 55.44% (293514/529419)
Branch Coverage 56.24% (132449/235523)

@pzhdfy
pzhdfy force-pushed the branch-4.1-paimon-rust branch from a392214 to 96ad0ff Compare September 20, 2026 06:34
@Gabriel39

Copy link
Copy Markdown
Contributor

run buildall

@Gabriel39

Copy link
Copy Markdown
Contributor

/review

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Static review of exact head 96ad0ffdfd24e52185054047b36d0ce5116e67ff. I am requesting changes for five additional verified defects.

Critical checkpoints:

  • Compatibility and table semantics: two P1 issues route supported fallback-read and unrestricted query-authorized scans to a Rust path that deterministically fails at split/table open. Incremental, branch/snapshot, schema-history, system-table, storage-provider, and rolling-upgrade paths were rechecked against the current threads; no additional distinct issue was substantiated.
  • Third-party/build reproducibility: two P2 issues make the aarch64 build non-retryable after a post-update failure and leave the documented exact Rust-toolchain invariant unenforced across the two linked static libraries. Existing cbindgen/offline and crate-provenance threads were treated as duplicate fences.
  • Regression coverage: one P2 issue compares unordered or partially ordered row sets positionally, so equivalent JNI and Rust results can flake.
  • Predicate correctness, lifecycle, security, and resources: these paths were rechecked. Two real predicate defects (LIKE parsing and casted binary literals) were excluded from this PR-specific set because the authoritative base FE/JNI path already produces the same observable false-pruning; existing live findings were not duplicated.
  • Completion and validation: two review rounds, three independent Round 2 passes, and a final sweep covered all 26 authoritative changed paths and converged with NO_NEW_VALUABLE_FINDINGS. This is static evidence only; builds and tests were prohibited and were not run.

No additional user-provided review focus was supplied.

Comment thread thirdparty/build-thirdparty.sh Outdated
Comment thread thirdparty/build-thirdparty.sh Outdated
Comment thread regression-test/suites/external_table_p0/paimon/test_paimon_rust_reader_v2.groovy Outdated
@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 81.63% (40/49) 🎉
Increment coverage report
Complete coverage report

@Gabriel39

Copy link
Copy Markdown
Contributor

/review

@Gabriel39

Copy link
Copy Markdown
Contributor

run buildall

@hello-stephen

Copy link
Copy Markdown
Contributor

Cloud UT Coverage Report

Increment line coverage 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 73.27% (1826/2492)
Line Coverage 61.12% (32882/53800)
Region Coverage 48.66% (31117/63943)
Branch Coverage 51.61% (9661/18720)

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Static review found seven distinct issues that should be resolved before merge: six correctness/capability failures in the new Rust Paimon path and one Rust third-party rebuild/recovery defect.

Critical checkpoints covered:

  • FE selection, protocol, and capability gating: deletion-vector merge modes and ORC TIMESTAMP_LTZ remain incorrectly Rust-eligible.
  • BE predicate semantics: LIKE wildcard/escape handling and casted binary RHS values can create false-negative pushdown.
  • Schema evolution: the Rust C read-builder re-resolves the FE-pinned snapshot and can discard a schema-only ALTER.
  • Storage/auth: enabled COS/OBS/GCS/Azure schemes are routed to parsers whose credential key families are never supplied.
  • FFI ownership, split lifecycle, scanner dispatch, wire compatibility, and residual filtering were traced; no additional distinct issue survived convergence.
  • Third-party reproducibility/recovery: the shared toolchain stamp is committed before a successful artifact and has no supported rotation path.
  • Tests were reviewed for differential and capability coverage; the inline comments identify the missing cases.

Existing inline threads and replies were treated as duplicate fences and were not repeated. No additional user focus was provided. This was a static-only review as required; I did not run builds or tests.

Comment thread be/src/format_v2/table/paimon_rust_predicate_converter.cpp Outdated
Comment thread be/src/format_v2/table/paimon_rust_predicate_converter.cpp
Comment thread be/src/format_v2/table/paimon_rust_table_reader.cpp Outdated
Comment thread be/src/format_v2/table/paimon_rust_table_reader.cpp Outdated
Comment thread thirdparty/build-thirdparty.sh Outdated
@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 83.64% (46/55) 🎉
Increment coverage report
Complete coverage report

@hello-stephen

Copy link
Copy Markdown
Contributor

BE UT Coverage Report

Increment line coverage 47.80% (588/1230) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 60.08% (26125/43487)
Line Coverage 44.77% (270083/603327)
Region Coverage 40.60% (214316/527814)
Branch Coverage 42.08% (99121/235569)

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 45.37% (539/1188) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 74.58% (31548/42302)
Line Coverage 58.75% (351637/598498)
Region Coverage 55.53% (293749/528998)
Branch Coverage 56.33% (132541/235307)

@pzhdfy

pzhdfy commented Sep 22, 2026

Copy link
Copy Markdown
Contributor Author

/review

suxiaogang223 added a commit to suxiaogang223/doris that referenced this pull request Oct 10, 2026
### What problem does this PR solve?

Issue Number: apache#65086

Related PR: apache#66227

Problem Summary: Preserve the Paimon Rust reader FileScannerV2 coverage from branch-4.1 after forward-porting the implementation to master. Verify complete Rust split payloads, reject missing schema metadata, and keep PAIMON_CPP splits on the V1 fallback.

### Release note

None

### Check List (For Author)

- Test: Unit Test
    - Test code added; execution requires a BE unit-test build
    - `./build-support/check-format.sh`
    - `./build-support/check-build-hygiene.sh`
- Behavior changed: No
- Does this need documentation: No
suxiaogang223 added a commit to suxiaogang223/doris that referenced this pull request Oct 10, 2026
### What problem does this PR solve?

Issue Number: apache#65086

Related PR: apache#66227

Problem Summary: The branch-4.1 tests exercised Paimon Rust reader routing through the legacy fe-core PaimonScanNode, which no longer exists on master. Recreate that coverage at master's connector boundary and generic backend-capability intersection, including mixed-version backends, session gates, storage credentials, HDFS options, nested projections, external files, and ORC local-zone timestamps.

### Release note

None

### Check List (For Author)

- Test: Unit Test
    - `./run-fe-ut.sh --run org.apache.doris.datasource.scan.PluginDrivenScanNodeBackendCapabilityTest,org.apache.doris.connector.paimon.PaimonRustReaderSelectorTest`
- Behavior changed: No
- Does this need documentation: No
suxiaogang223 added a commit to suxiaogang223/doris that referenced this pull request Oct 10, 2026
### What problem does this PR solve?

Issue Number: apache#65086

Related PR: apache#66227

Problem Summary: The Paimon Rust predicate converter must keep null-aware runtime filters residual, but master does not expose the RuntimeFilterExpr null-aware flag that branch-4.1 receives from the Lance runtime-filter work. Expose the existing immutable state so the converter can preserve NULL probe rows instead of incorrectly pushing the unwrapped IN predicate.

### Release note

None

### Check List (For Author)

- Test: BE compilation
- Behavior changed: No
- Does this need documentation: No
suxiaogang223 added a commit to suxiaogang223/doris that referenced this pull request Oct 10, 2026
### What problem does this PR solve?

Issue Number: apache#65086

Related PR: apache#66227

Problem Summary: The Paimon Rust reader batch-size unit test derived its fixture path from `__FILE__`. The master BE build rewrites source paths, so the test resolved the fixture relative to the build tree and read an empty split file. Use the repository-root-relative test data path expected by `run-be-ut.sh` so the real Rust reader fixture is loaded reliably.

### Release note

None

### Check List (For Author)

- Test: Unit Test
    - `./run-be-ut.sh --run --filter='PaimonRustTableReaderTest.*:PaimonRustPredicateConverterTest.*:PaimonReaderTest.*:FileScannerV2Test.PaimonRustSplitUsesV2Scanner' -j 12`
- Behavior changed: No
- Does this need documentation: No
suxiaogang223 added a commit to suxiaogang223/doris that referenced this pull request Oct 10, 2026
### What problem does this PR solve?

Issue Number: None

Related PR: apache#66227

Problem Summary: The master connector framework did not propagate name-based nested projections when no stable nested field IDs were available. Paimon could therefore select the Rust reader for a projected nested value and BE decoded the projected Arrow struct as the full Doris struct. Master also differs from branch-4.1 in credential selection, branch resolution, and TIMESTAMP_LTZ mapping. Propagate nested projection state to connector handles, make Paimon fall back to JNI for nested projections, and align the regression fixtures with master semantics.

### Release note

None

### Check List (For Author)

- Test: Unit Test, FE build, and Regression test

    - PaimonRustReaderSelectorTest

    - PluginDrivenScanNodeProjectionTest

    - test_paimon_rust_reader_compatibility

    - test_paimon_rust_reader_eq_for_null

- Behavior changed: No. The Rust reader remains disabled by default and unsupported nested projections fall back to JNI.

- Does this need documentation: No
pzhdfy pushed a commit to pzhdfy/doris that referenced this pull request Oct 13, 2026
Ports the internal PK-vector search (ann.patch, bleem ce52f81) onto the
community paimon 2.1 java client and the paimon-rust baac87c eager Top-K C
API, and wires it through the FileScannerV2 rust table reader.

FE
- New PushDownVectorTopNIntoPaimonScan rewrite: TopN[dis] -> Project
  [dis := dist_fn(vec, q)] -> [Filter] -> PaimonScan becomes an index-only
  ANN scan producing the reader-generated __paimon_search_score_to_dis
  column; every dist_fn occurrence is replaced by that slot. Gated on
  enable_paimon_rust_reader AND enable_file_scanner_v2 (the V1 scanner
  rejects PAIMON_RUST). AnnTopNInfo carries query vector / column / folded
  limit / TVectorMetric through the scan plumbing.
- PaimonScanNode plans one BucketVectorSearchSplit per (partition, bucket)
  via newBatchVectorSearchBuilder and serializes it with Paimon's
  DataOutputSerializer (the community client no longer ships
  BucketVectorSearchSplitSerializer). The logical search request reuses the
  community TExternalSearchRequest (field 39 of TFileScanRangeParams);
  Paimon-only tuning travels in the new TPaimonVectorSearchOptions (field
  5), filtered to field-/algorithm-scoped keys because
  primaryKeyVectorIndexOptions seeds itself with the whole table property
  bag (thrift-fatal nulls, credentials, redundancy).
- PaimonUtil maps Paimon VECTOR to ARRAY<FLOAT> so the distance functions
  type-check; the JNI connector reads VECTOR columns via getVector.

BE
- PaimonRustTableReader gains a vector mode: the scan range carries a
  TPaimonVectorPayload (TPaimonFileDesc field 20) and the reader runs the
  eager Top-K chain paimon_bucket_vector_search_split_deserialize ->
  new_scan -> new_read -> plan_from_bucket_splits -> vector_read_read,
  then converts paimon-rust's __paimon_search_score into the metric-native
  distance in place while filling the block (L2: sqrt(1/score - 1) with a
  catastrophic-cancellation clamp and negative sentinels for corrupt
  scores; inner_product: identity).

Deliberately not ported from the internal patch: Alluxio path rewriting
(no community equivalent), the parquet nested lazy-read page-skip
optimization, and the internal-only shade/pom version bumps.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
(cherry picked from commit 06e99cb)

Port notes (rebased onto the merged PR apache#66227, which grew further after the ann branch forked at 8272fae):
- PlanNodes.thrift: TFileScanRange field 39 is taken upstream by
  parquet_timestamp_semantics_version (40 by contains_native_parquet), so
  external_search_request is renumbered to field 41 on this branch.
- PaimonScanNode: keep the upstream gate chain (restTokenTable, externalFileSplit,
  deduplicateIgnoreDelete, rustUnsupportedMergeOption, scan.mode default check,
  all-backend isPaimonRustReaderSupported, PaimonRustReaderCapabilities). A
  vector split bypasses only the per-split PaimonRustReaderCapabilities check:
  its whitelist describes the batch reader (single-file PK buckets, zero delete
  rows), while a vector bucket legitimately spans multiple files and applies
  deletion vectors inside the search itself; all table/session-level gates still
  apply and a vector split that fails them throws loudly as before.
- paimon_rust_table_reader_test.cpp: keep both the upstream
  AdaptiveBatchSizeBoundsWideStringReads fixture test and the ported vector /
  score-transform tests.

Conflicts:
	be/test/format_v2/table/paimon_rust_table_reader_test.cpp
	fe/fe-core/src/main/java/org/apache/doris/datasource/paimon/source/PaimonScanNode.java
	fe/fe-core/src/test/java/org/apache/doris/datasource/paimon/PaimonUtilTest.java
	gensrc/thrift/PlanNodes.thrift
suxiaogang223 added a commit to suxiaogang223/doris that referenced this pull request Oct 13, 2026
Issue Number: None

Related PR: apache#66227

Related PR: apache#68320

Problem Summary: Several unreleased master Thrift additions reused wire ids that branch-4.1 already assigned to Paimon and Iceberg fields, and master assigned different numeric values to the external table sink partition enum. Keep the branch-4.1 meanings at their established ids, move master-only fields to new trailing ids, and retain the deprecated branch routing fields ahead of the generic master routing representation. Also reserve the Paimon Rust reader capability fields at their branch ids so its later forward-port does not recreate the conflicts.

None

- Test: No compilation or unit tests per current validation plan
    - build-support/clang-format.sh
    - build-support/check-format.sh
    - git diff --check
- Behavior changed: No user-visible behavior; unreleased master wire ids are aligned with branch-4.1.
- Does this need documentation: No
suxiaogang223 added a commit to suxiaogang223/doris that referenced this pull request Oct 13, 2026
Issue Number: None

Related PR: apache#66227

Related PR: apache#68320

Problem Summary: Several unreleased master Thrift additions reused wire ids that branch-4.1 already assigned to Paimon and Iceberg fields, and master assigned different numeric values to the external table sink partition enum. Keep the branch-4.1 meanings at their established ids, move master-only fields to new trailing ids, and retain the deprecated branch routing fields ahead of the generic master routing representation. Also reserve the Paimon Rust reader capability fields at their branch ids so its later forward-port does not recreate the conflicts.

None

- Test: No compilation or unit tests per current validation plan
    - build-support/clang-format.sh
    - build-support/check-format.sh
    - git diff --check
- Behavior changed: No user-visible behavior; unreleased master wire ids are aligned with branch-4.1.
- Does this need documentation: No
suxiaogang223 added a commit that referenced this pull request Oct 13, 2026
)

### What problem does this PR solve?

Issue Number: #65086

Related PR: #65868

Related PR: #66227

Related PR: #68320

Problem Summary:

Master and branch-4.1 assigned incompatible meanings or numeric values
to several external-table Thrift fields. In particular,
`TReportExecStatusParams` field 34 carried opaque connector commit data
on master but typed Paimon commit messages on branch-4.1. The external
table sink partition enum and several Paimon, Iceberg, routing,
query-option, and backend-capability fields also used different wire
ids.

This change keeps the branch-4.1 field meanings and enum values at their
established ids, moves unreleased master-only fields to new trailing
ids, and keeps Paimon and Iceberg commit data on independent fields. It
also preserves the master transaction flow, final-report ownership
transfer, Thrift message budget, acknowledgement, and cleanup behavior.

### Release note

None

### Check List (For Author)

- Test
    - [ ] Regression test
    - [ ] Unit Test
    - [x] Manual test (add detailed scripts or steps below)
        - `./build.sh --fe -j 12`
        - `ENABLE_PCH=OFF ./build.sh --be -j 12`
        - FE, BE, BE Java extensions, and CDC client build successfully.
- BE `doris_be` links successfully and passes the GLIBC 2.17
compatibility check.
        - `build-support/check-format.sh`
        - `build-support/check-build-hygiene.sh`
        - `git diff --check origin/master..HEAD`
    - [ ] No need to test or manual test. Explain why:
- [ ] This is a refactor/code format and no logic has been changed.
        - [ ] Previous test can cover this change.
        - [ ] No code files have been changed.
        - [ ] Other reason

- Behavior changed:
- [x] No. The change aligns wire compatibility for unreleased master
fields.
    - [ ] Yes.

- Does this need documentation?
    - [x] No.
    - [ ] Yes.

### Check List (For Reviewer who merge this PR)

- [ ] Confirm the release note
- [ ] Confirm test cases
- [ ] Confirm document
- [ ] Add branch pick label
suxiaogang223 pushed a commit to suxiaogang223/doris that referenced this pull request Oct 13, 2026
)

Related PR: apache#65883  (for master , current closed)

**this pr add paimon rust reader  both in scanner v1 and v2.
the scanner v1 code is just for legacy, will be removed later.**

  Problem Summary:

Adds a third BE-side reader for Paimon FORMAT_JNI splits, backed by the
`paimon-rust` C bindings (`libpaimon_c.a`, statically linked). Rust
Reader is gated by the session variable
  `enable_paimon_rust_reader` (default `false`).

  Compared with the existing readers:
  - **vs paimon-jni**: no JVM round-trip on the hot path — the split is
deserialized in-process and rows arrive via the Arrow C Data Interface,
which shortens the scanner critical section and removes JNI copy cost.

  **Architecture**

FE (`PaimonScanNode`): when `enable_paimon_rust_reader` is on and the
split
  is a `DataSplit`, encode it with paimon's native binary serialization
  (`PaimonUtil.encodeDataSplitToString`), stamp the range with
  `TPaimonReaderType.PAIMON_RUST`, and attach `db_name` / `table_name` /
  `paimon_table` so BE can open the table through a catalog.

  BE (`FileScanner::_get_next_reader`): dispatches on `reader_type`. On
  `PAIMON_RUST` it instantiates `PaimonRustReader`, which:

  1. `paimon_catalog_create({warehouse, metastore=filesystem, ...})`
     - warehouse is derived from the table root path by stripping
       `/<db>.db/<table>` (paimon FS convention).
  2. `paimon_identifier_new(db, tbl)` → `paimon_catalog_get_table`
  3. `paimon_table_new_read_builder` → projection (case-insensitive) →
optional filter from `PaimonRustPredicateConverter` (translates Doris
     push-down conjuncts into paimon-rust predicates, best-effort so any
non-representable conjunct is silently dropped and re-applied by the
     engine).
  4. `paimon_plan_from_split_bytes(split_bytes)` — one BE scanner reads
     exactly its FE-planned split (no re-planning).
5. `paimon_table_read_to_arrow` → streamed arrow record batches → block.

  Partition columns are back-filled in `on_after_read_block` from
  FE-provided `columns_from_path*`, mirroring `PaimonCppReader`. OSS/S3
  hadoop-style credential keys (`fs.oss.*` / `fs.s3a.*`) are remapped to
  `AWS_ACCESS_KEY` / `AWS_ENDPOINT` / ... so paimon-rust's FileIO can
  authenticate.

  **Thirdparty**

  - Introduces `paimon-rust-2fb5e49` (built with Rust 1.91.0, feature
    `paimon/storage-hdfs`, `--locked`).
  - Auto-installs `cbindgen` and regenerates the C header from the Rust
    extern "C" surface via a locally-written `cbindgen.toml`
(`language=C, include_guard=PAIMON_C_H, pragma_once=true,
cpp_compat=true`),
    so the shipped `paimon.h` always matches the built `.a`.

  ### Release note

  Add `enable_paimon_rust_reader` session variable. When enabled, Paimon
non-native reads on BE use the paimon-rust reader instead of paimon-jni
/
  paimon-cpp.

  ### Check List (For Author)

  - Test
      - [x] Unit Test
      - [x] Manual test (add detailed scripts or steps below)
1. `CREATE CATALOG paimon_fs PROPERTIES ("type"="paimon",
"paimon.catalog.type"="filesystem",
"warehouse"="file:///media/ssd1/test_paimon/warehouse/");` when using
"warehouse"="hdfs://.../warehouse/", add HADOOP_CONF_DIR=xx in be.conf
        2. `SET enable_paimon_rust_reader=true; SET force_jni_scanner=1`
3. `SELECT` from a partitioned/DV paimon table; results must match
`enable_paimon_rust_reader=false and force_jni_scanner=0`.
4. `SELECT count(*)` — should hit table-level row count push-down.
5. `WHERE a=1 AND b>2` — BE INFO log should show `paimon-rust predicate
pushdown: applied`.
      - [x] Regression test
      - [ ] No need to test or manual test.

  - Behavior changed:
- [x] No. Guarded by `enable_paimon_rust_reader` (default `false`); when
off, all paths are unchanged.

  - Does this need documentation?
      - [ ] No.
- [x] Yes. <!-- Add doris-website PR link here for the new session
variable -->

  ### Check List (For Reviewer who merge this PR)

  - [ ] Confirm the release note
  - [ ] Confirm test cases
  - [ ] Confirm document
  - [ ] Add branch pick label

---------

Co-authored-by: dengfangyuan <dengfangyuan@kuaishou.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Gabriel <gabrielleebuaa@gmail.com>
suxiaogang223 added a commit to suxiaogang223/doris that referenced this pull request Oct 13, 2026
Issue Number: apache#65086

Related PR: apache#66227
Related PR: apache#68562

Problem Summary: Adapt the branch-4.1 Paimon Rust reader to master's connector architecture and current APIs. Convert Paimon table locations to strings at the connector boundary, use JUnit 5 for the backend capability test, and align the reverse type-mapping contract and tests with the precision-preserving implementation required by the Rust reader.

None

- Test: Unit Test
    - `./run-fe-ut.sh --run org.apache.doris.system.BackendPaimonRustCapabilityTest,org.apache.doris.connector.paimon.PaimonTypeMappingToPaimonTest`
    - `./build.sh --fe --clean`
    - `./build-support/check-format.sh`
    - `./build-support/check-build-hygiene.sh`
- Behavior changed: No
- Does this need documentation: No
suxiaogang223 added a commit to suxiaogang223/doris that referenced this pull request Oct 13, 2026
### What problem does this PR solve?

Issue Number: apache#65086

Related PR: apache#66227

Problem Summary: Preserve the Paimon Rust reader FileScannerV2 coverage from branch-4.1 after forward-porting the implementation to master. Verify complete Rust split payloads, reject missing schema metadata, and keep PAIMON_CPP splits on the V1 fallback.

### Release note

None

### Check List (For Author)

- Test: Unit Test
    - Test code added; execution requires a BE unit-test build
    - `./build-support/check-format.sh`
    - `./build-support/check-build-hygiene.sh`
- Behavior changed: No
- Does this need documentation: No
suxiaogang223 added a commit to suxiaogang223/doris that referenced this pull request Oct 13, 2026
### What problem does this PR solve?

Issue Number: apache#65086

Related PR: apache#66227

Problem Summary: The branch-4.1 tests exercised Paimon Rust reader routing through the legacy fe-core PaimonScanNode, which no longer exists on master. Recreate that coverage at master's connector boundary and generic backend-capability intersection, including mixed-version backends, session gates, storage credentials, HDFS options, nested projections, external files, and ORC local-zone timestamps.

### Release note

None

### Check List (For Author)

- Test: Unit Test
    - `./run-fe-ut.sh --run org.apache.doris.datasource.scan.PluginDrivenScanNodeBackendCapabilityTest,org.apache.doris.connector.paimon.PaimonRustReaderSelectorTest`
- Behavior changed: No
- Does this need documentation: No
suxiaogang223 added a commit to suxiaogang223/doris that referenced this pull request Oct 13, 2026
### What problem does this PR solve?

Issue Number: apache#65086

Related PR: apache#66227

Problem Summary: The Paimon Rust predicate converter must keep null-aware runtime filters residual, but master does not expose the RuntimeFilterExpr null-aware flag that branch-4.1 receives from the Lance runtime-filter work. Expose the existing immutable state so the converter can preserve NULL probe rows instead of incorrectly pushing the unwrapped IN predicate.

### Release note

None

### Check List (For Author)

- Test: BE compilation
- Behavior changed: No
- Does this need documentation: No
suxiaogang223 added a commit to suxiaogang223/doris that referenced this pull request Oct 13, 2026
### What problem does this PR solve?

Issue Number: apache#65086

Related PR: apache#66227

Problem Summary: The Paimon Rust reader batch-size unit test derived its fixture path from `__FILE__`. The master BE build rewrites source paths, so the test resolved the fixture relative to the build tree and read an empty split file. Use the repository-root-relative test data path expected by `run-be-ut.sh` so the real Rust reader fixture is loaded reliably.

### Release note

None

### Check List (For Author)

- Test: Unit Test
    - `./run-be-ut.sh --run --filter='PaimonRustTableReaderTest.*:PaimonRustPredicateConverterTest.*:PaimonReaderTest.*:FileScannerV2Test.PaimonRustSplitUsesV2Scanner' -j 12`
- Behavior changed: No
- Does this need documentation: No
suxiaogang223 added a commit to suxiaogang223/doris that referenced this pull request Oct 13, 2026
### What problem does this PR solve?

Issue Number: None

Related PR: apache#66227

Problem Summary: The master connector framework did not propagate name-based nested projections when no stable nested field IDs were available. Paimon could therefore select the Rust reader for a projected nested value and BE decoded the projected Arrow struct as the full Doris struct. Master also differs from branch-4.1 in credential selection, branch resolution, and TIMESTAMP_LTZ mapping. Propagate nested projection state to connector handles, make Paimon fall back to JNI for nested projections, and align the regression fixtures with master semantics.

### Release note

None

### Check List (For Author)

- Test: Unit Test, FE build, and Regression test

    - PaimonRustReaderSelectorTest

    - PluginDrivenScanNodeProjectionTest

    - test_paimon_rust_reader_compatibility

    - test_paimon_rust_reader_eq_for_null

- Behavior changed: No. The Rust reader remains disabled by default and unsupported nested projections fall back to JNI.

- Does this need documentation: No
suxiaogang223 added a commit to suxiaogang223/doris that referenced this pull request Oct 13, 2026
### What problem does this PR solve?

Issue Number: apache#65086

Related PR: apache#66227, apache#68320, apache#68837

Problem Summary: The Paimon Rust reader could admit current-schema nanosecond timestamps outside Arrow nanosecond range, ignore the force_jni_scanner escape hatch, and keep returning Doris blocks at the initial row cap after adaptive sizing changed it. Route precision 7-9 timestamps through JNI, honor force_jni_scanner, and slice retained Arrow batches according to the latest Doris row cap. The rolling-upgrade Thrift field conflict is now handled by prerequisite PR apache#68837 and is intentionally not duplicated here.

### Release note

Paimon Rust reads now honor timestamp, force-JNI, and adaptive block-size safeguards.

### Check List (For Author)

- Test: Unit Test
    - Before rebase: targeted FE unit tests, FE checkstyle, affected BE object compilation, BE format, build hygiene, and clang-tidy
    - After rebase: conflict and diff checks only; full compilation intentionally skipped
    - External regression test not run locally
- Behavior changed: Yes, unsafe or explicitly forced Paimon Rust scans now fall back to JNI
- Does this need documentation: No
suxiaogang223 pushed a commit to suxiaogang223/doris that referenced this pull request Oct 13, 2026
)

Related PR: apache#65883  (for master , current closed)

**this pr add paimon rust reader  both in scanner v1 and v2.
the scanner v1 code is just for legacy, will be removed later.**

  Problem Summary:

Adds a third BE-side reader for Paimon FORMAT_JNI splits, backed by the
`paimon-rust` C bindings (`libpaimon_c.a`, statically linked). Rust
Reader is gated by the session variable
  `enable_paimon_rust_reader` (default `false`).

  Compared with the existing readers:
  - **vs paimon-jni**: no JVM round-trip on the hot path — the split is
deserialized in-process and rows arrive via the Arrow C Data Interface,
which shortens the scanner critical section and removes JNI copy cost.

  **Architecture**

FE (`PaimonScanNode`): when `enable_paimon_rust_reader` is on and the
split
  is a `DataSplit`, encode it with paimon's native binary serialization
  (`PaimonUtil.encodeDataSplitToString`), stamp the range with
  `TPaimonReaderType.PAIMON_RUST`, and attach `db_name` / `table_name` /
  `paimon_table` so BE can open the table through a catalog.

  BE (`FileScanner::_get_next_reader`): dispatches on `reader_type`. On
  `PAIMON_RUST` it instantiates `PaimonRustReader`, which:

  1. `paimon_catalog_create({warehouse, metastore=filesystem, ...})`
     - warehouse is derived from the table root path by stripping
       `/<db>.db/<table>` (paimon FS convention).
  2. `paimon_identifier_new(db, tbl)` → `paimon_catalog_get_table`
  3. `paimon_table_new_read_builder` → projection (case-insensitive) →
optional filter from `PaimonRustPredicateConverter` (translates Doris
     push-down conjuncts into paimon-rust predicates, best-effort so any
non-representable conjunct is silently dropped and re-applied by the
     engine).
  4. `paimon_plan_from_split_bytes(split_bytes)` — one BE scanner reads
     exactly its FE-planned split (no re-planning).
5. `paimon_table_read_to_arrow` → streamed arrow record batches → block.

  Partition columns are back-filled in `on_after_read_block` from
  FE-provided `columns_from_path*`, mirroring `PaimonCppReader`. OSS/S3
  hadoop-style credential keys (`fs.oss.*` / `fs.s3a.*`) are remapped to
  `AWS_ACCESS_KEY` / `AWS_ENDPOINT` / ... so paimon-rust's FileIO can
  authenticate.

  **Thirdparty**

  - Introduces `paimon-rust-2fb5e49` (built with Rust 1.91.0, feature
    `paimon/storage-hdfs`, `--locked`).
  - Auto-installs `cbindgen` and regenerates the C header from the Rust
    extern "C" surface via a locally-written `cbindgen.toml`
(`language=C, include_guard=PAIMON_C_H, pragma_once=true,
cpp_compat=true`),
    so the shipped `paimon.h` always matches the built `.a`.

  ### Release note

  Add `enable_paimon_rust_reader` session variable. When enabled, Paimon
non-native reads on BE use the paimon-rust reader instead of paimon-jni
/
  paimon-cpp.

  ### Check List (For Author)

  - Test
      - [x] Unit Test
      - [x] Manual test (add detailed scripts or steps below)
1. `CREATE CATALOG paimon_fs PROPERTIES ("type"="paimon",
"paimon.catalog.type"="filesystem",
"warehouse"="file:///media/ssd1/test_paimon/warehouse/");` when using
"warehouse"="hdfs://.../warehouse/", add HADOOP_CONF_DIR=xx in be.conf
        2. `SET enable_paimon_rust_reader=true; SET force_jni_scanner=1`
3. `SELECT` from a partitioned/DV paimon table; results must match
`enable_paimon_rust_reader=false and force_jni_scanner=0`.
4. `SELECT count(*)` — should hit table-level row count push-down.
5. `WHERE a=1 AND b>2` — BE INFO log should show `paimon-rust predicate
pushdown: applied`.
      - [x] Regression test
      - [ ] No need to test or manual test.

  - Behavior changed:
- [x] No. Guarded by `enable_paimon_rust_reader` (default `false`); when
off, all paths are unchanged.

  - Does this need documentation?
      - [ ] No.
- [x] Yes. <!-- Add doris-website PR link here for the new session
variable -->

  ### Check List (For Reviewer who merge this PR)

  - [ ] Confirm the release note
  - [ ] Confirm test cases
  - [ ] Confirm document
  - [ ] Add branch pick label

---------

Co-authored-by: dengfangyuan <dengfangyuan@kuaishou.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Gabriel <gabrielleebuaa@gmail.com>
suxiaogang223 added a commit to suxiaogang223/doris that referenced this pull request Oct 13, 2026
Issue Number: apache#65086

Related PR: apache#66227
Related PR: apache#68562

Problem Summary: Adapt the branch-4.1 Paimon Rust reader to master's connector architecture and current APIs. Convert Paimon table locations to strings at the connector boundary, use JUnit 5 for the backend capability test, and align the reverse type-mapping contract and tests with the precision-preserving implementation required by the Rust reader.

None

- Test: Unit Test
    - `./run-fe-ut.sh --run org.apache.doris.system.BackendPaimonRustCapabilityTest,org.apache.doris.connector.paimon.PaimonTypeMappingToPaimonTest`
    - `./build.sh --fe --clean`
    - `./build-support/check-format.sh`
    - `./build-support/check-build-hygiene.sh`
- Behavior changed: No
- Does this need documentation: No
suxiaogang223 added a commit to suxiaogang223/doris that referenced this pull request Oct 13, 2026
### What problem does this PR solve?

Issue Number: apache#65086

Related PR: apache#66227

Problem Summary: Preserve the Paimon Rust reader FileScannerV2 coverage from branch-4.1 after forward-porting the implementation to master. Verify complete Rust split payloads, reject missing schema metadata, and keep PAIMON_CPP splits on the V1 fallback.

### Release note

None

### Check List (For Author)

- Test: Unit Test
    - Test code added; execution requires a BE unit-test build
    - `./build-support/check-format.sh`
    - `./build-support/check-build-hygiene.sh`
- Behavior changed: No
- Does this need documentation: No
suxiaogang223 added a commit to suxiaogang223/doris that referenced this pull request Oct 13, 2026
### What problem does this PR solve?

Issue Number: apache#65086

Related PR: apache#66227

Problem Summary: The branch-4.1 tests exercised Paimon Rust reader routing through the legacy fe-core PaimonScanNode, which no longer exists on master. Recreate that coverage at master's connector boundary and generic backend-capability intersection, including mixed-version backends, session gates, storage credentials, HDFS options, nested projections, external files, and ORC local-zone timestamps.

### Release note

None

### Check List (For Author)

- Test: Unit Test
    - `./run-fe-ut.sh --run org.apache.doris.datasource.scan.PluginDrivenScanNodeBackendCapabilityTest,org.apache.doris.connector.paimon.PaimonRustReaderSelectorTest`
- Behavior changed: No
- Does this need documentation: No
suxiaogang223 added a commit to suxiaogang223/doris that referenced this pull request Oct 13, 2026
### What problem does this PR solve?

Issue Number: apache#65086

Related PR: apache#66227

Problem Summary: The Paimon Rust predicate converter must keep null-aware runtime filters residual, but master does not expose the RuntimeFilterExpr null-aware flag that branch-4.1 receives from the Lance runtime-filter work. Expose the existing immutable state so the converter can preserve NULL probe rows instead of incorrectly pushing the unwrapped IN predicate.

### Release note

None

### Check List (For Author)

- Test: BE compilation
- Behavior changed: No
- Does this need documentation: No
suxiaogang223 added a commit to suxiaogang223/doris that referenced this pull request Oct 13, 2026
### What problem does this PR solve?

Issue Number: apache#65086

Related PR: apache#66227

Problem Summary: The Paimon Rust reader batch-size unit test derived its fixture path from `__FILE__`. The master BE build rewrites source paths, so the test resolved the fixture relative to the build tree and read an empty split file. Use the repository-root-relative test data path expected by `run-be-ut.sh` so the real Rust reader fixture is loaded reliably.

### Release note

None

### Check List (For Author)

- Test: Unit Test
    - `./run-be-ut.sh --run --filter='PaimonRustTableReaderTest.*:PaimonRustPredicateConverterTest.*:PaimonReaderTest.*:FileScannerV2Test.PaimonRustSplitUsesV2Scanner' -j 12`
- Behavior changed: No
- Does this need documentation: No
suxiaogang223 added a commit to suxiaogang223/doris that referenced this pull request Oct 13, 2026
### What problem does this PR solve?

Issue Number: None

Related PR: apache#66227

Problem Summary: The master connector framework did not propagate name-based nested projections when no stable nested field IDs were available. Paimon could therefore select the Rust reader for a projected nested value and BE decoded the projected Arrow struct as the full Doris struct. Master also differs from branch-4.1 in credential selection, branch resolution, and TIMESTAMP_LTZ mapping. Propagate nested projection state to connector handles, make Paimon fall back to JNI for nested projections, and align the regression fixtures with master semantics.

### Release note

None

### Check List (For Author)

- Test: Unit Test, FE build, and Regression test

    - PaimonRustReaderSelectorTest

    - PluginDrivenScanNodeProjectionTest

    - test_paimon_rust_reader_compatibility

    - test_paimon_rust_reader_eq_for_null

- Behavior changed: No. The Rust reader remains disabled by default and unsupported nested projections fall back to JNI.

- Does this need documentation: No
suxiaogang223 added a commit to suxiaogang223/doris that referenced this pull request Oct 13, 2026
### What problem does this PR solve?

Issue Number: apache#65086

Related PR: apache#66227, apache#68320, apache#68837

Problem Summary: The Paimon Rust reader could admit current-schema nanosecond timestamps outside Arrow nanosecond range, ignore the force_jni_scanner escape hatch, and keep returning Doris blocks at the initial row cap after adaptive sizing changed it. Route precision 7-9 timestamps through JNI, honor force_jni_scanner, and slice retained Arrow batches according to the latest Doris row cap. The rolling-upgrade Thrift field conflict is now handled by prerequisite PR apache#68837 and is intentionally not duplicated here.

### Release note

Paimon Rust reads now honor timestamp, force-JNI, and adaptive block-size safeguards.

### Check List (For Author)

- Test: Unit Test
    - Before rebase: targeted FE unit tests, FE checkstyle, affected BE object compilation, BE format, build hygiene, and clang-tidy
    - After rebase: conflict and diff checks only; full compilation intentionally skipped
    - External regression test not run locally
- Behavior changed: Yes, unsafe or explicitly forced Paimon Rust scans now fall back to JNI
- Does this need documentation: No
suxiaogang223 added a commit to suxiaogang223/doris that referenced this pull request Oct 14, 2026
### What problem does this PR solve?

Issue Number: apache#65086

Related PR: apache#66227, apache#68320, apache#68837

Problem Summary: Paimon Rust reads could pass a sliced Arrow RecordBatch with a non-zero array offset into Doris SerDes, causing adaptive wide-string reads to fail. Explicit Rust-reader tests could also continue through native planning or force JNI while expecting Rust profiles. Read the requested row range directly from the original Arrow batch, give an explicitly enabled compatible Rust reader priority over native planning while preserving force-JNI and metadata-column behavior, and align the affected regression suites with those routing semantics.

### Release note

Fix Paimon Rust reader adaptive batches and explicit reader selection.

### Check List (For Author)

- Test: Unit Test
    - PaimonRustTableReaderTest.AdaptiveBatchSizeBoundsWideStringReads
    - External regression tests not run locally
- Behavior changed: Yes, explicitly enabled compatible Paimon Rust reads take priority over native planning; force JNI and metadata-column scans retain their existing behavior
- Does this need documentation: No
morningman added a commit to morningman/doris that referenced this pull request Oct 14, 2026
### What problem does this PR solve?

Issue Number: None

Related PR: apache#66227

Problem Summary: The previous commit made the two completion-state helpers of `Profile` synchronized on the Profile monitor, as branch-4.1 apache#66227 does. That inverts the lock order with `ProfileManager`: `ProfileManager.getProfile()` renders a profile under the manager's read lock, and `getProfileByLevel()` then waits for the Profile monitor, while `Profile.updateSummary()` holds the monitor and calls `ProfileManager.pushProfile()`, which waits for the manager's write lock (`clearExecutionProfiles()` and `removeProfile()` do the same). Viewing a running profile at the moment its query finishes could therefore hang the query and every later profile operation. The helpers now synchronize on a dedicated lock instead. Under it they only take the execution profile's report lock and the summary's info-string lock, and neither of those is held while waiting for the Profile monitor or a manager lock, so the storage and display updates stay serialized without a cycle.

### Release note

None

### Check List (For Author)

- Test: Unit Test
    - `ProfileCompletionStateTest#renderingDoesNotWaitForProfileMonitor` renders a profile while the test holds the Profile monitor; with the synchronized helpers it times out. `ProfileCompletionStateTest` and `ProfileManagerTest` pass (36 tests).
- Behavior changed: No
- Does this need documentation: No

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by one committer.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants