[feat](paimon) support paimon-rust reader on BE - #65883
Conversation
Port two behaviors from paimon_cpp_reader to keep paimon-rust reader on feature parity with the cpp path: - Fill partition columns from FE-provided `columns_from_path*` in `on_before_init_reader` / `on_after_read_block` (defensive: paimon-rust arrow output may not carry partition columns). - Remap common OSS/S3 hadoop-style credential keys (fs.oss.*, fs.s3a.*) to AWS_ACCESS_KEY / AWS_SECRET_KEY / AWS_ENDPOINT / ... in `_build_options` so OSS/S3-backed paimon tables can authenticate.
|
Thank you for your contribution to Apache Doris. Please clearly describe your PR:
|
| } | ||
| identifier_ptr identifier(id_res.identifier); | ||
|
|
||
| paimon_result_get_table tbl_res = |
There was a problem hiding this comment.
BE should not reopen the catalog to obtain the table here. FE has already resolved and serialized the Paimon table in TFileScanRangeParams.serialized_table and planned the exact split; the JNI reader restores that table context and executes the split directly. Re-resolving it through paimon_catalog_get_table may observe different table/schema state and unnecessarily restricts this path to the derived filesystem-catalog layout. Please deserialize/restore the FE-provided table information for the Rust reader instead of doing a catalog lookup in BE.
There was a problem hiding this comment.
跟paimon_rust社区同学沟通回复(后面发布后 会切换table获取接口):
paimon-rust 将提供通用的 catalog-free 接口 paimon_table_from_schema_json。Doris FE 直接传递 table_path、完整的 TableSchema JSON、database/table_name、branch 和文件系统访问配置,Rust 侧直接构造 Table,不创建 Catalog,也不会重新加载
或覆盖 FE 已解析的 schema。branch 仅决定 schema/snapshot/tag 的读取路径,读取仍可使用 FE 生成的 splits;如需 Rust 侧 time travel,可继续使用现有的 read-builder options。POC 代码已推送到 JunRuiLee/paimon-rust 的 feat/resolved-table-c-api 分
支,commit 为 9c39365。
…nstruction
Add org.apache.paimon.table.TableDescriptor (paimon-api) and
TableDescriptorSerializer (paimon-core): a slim, versioned JSON wire form that
serializes a resolved FileStoreTable into {path, full TableSchema, options} so a
non-Java reader (e.g. paimon-rust / paimon-cpp) can rebuild the table for
scan/read without a catalog lookup or JVM-only state. Non-main branches are
carried verbatim so a reader can fail fast rather than silently read main.
Motivated by the Doris Paimon-external-table integration (apache/doris#65883),
where the compute node re-resolves the table through a catalog; this lets it
consume the FE-planned table instead.
…nstruction
Add org.apache.paimon.table.TableDescriptor (paimon-api) and
TableDescriptorSerializer (paimon-core): a slim, versioned JSON wire form that
serializes a resolved FileStoreTable into {path, full TableSchema, options} so a
non-Java reader (e.g. paimon-rust / paimon-cpp) can rebuild the table for
scan/read without a catalog lookup or JVM-only state. Non-main branches are
carried verbatim so a reader can fail fast rather than silently read main.
Motivated by the Doris Paimon-external-table integration (apache/doris#65883),
where the compute node re-resolves the table through a catalog; this lets it
consume the FE-planned table instead.
…nstruction
Add org.apache.paimon.table.TableDescriptor (paimon-api) and
TableDescriptorSerializer (paimon-core): a slim, versioned JSON wire form that
serializes a resolved FileStoreTable into {path, full TableSchema, options} so a
non-Java reader (e.g. paimon-rust / paimon-cpp) can rebuild the table for
scan/read without a catalog lookup or JVM-only state. Non-main branches are
carried verbatim so a reader can fail fast rather than silently read main.
Motivated by the Doris Paimon-external-table integration (apache/doris#65883),
where the compute node re-resolves the table through a catalog; this lets it
consume the FE-planned table instead.
…nstruction
Add org.apache.paimon.table.TableDescriptor (paimon-api) and
TableDescriptorSerializer (paimon-core): a slim, versioned JSON wire form that
serializes a resolved FileStoreTable into {path, full TableSchema, options} so a
non-Java reader (e.g. paimon-rust / paimon-cpp) can rebuild the table for
scan/read without a catalog lookup or JVM-only state. Non-main branches are
carried verbatim so a reader can fail fast rather than silently read main.
Motivated by the Doris Paimon-external-table integration (apache/doris#65883),
where the compute node re-resolves the table through a catalog; this lets it
consume the FE-planned table instead.
…nstruction
Add org.apache.paimon.table.TableDescriptor (paimon-api) and
TableDescriptorSerializer (paimon-core): a slim, versioned JSON wire form that
serializes a resolved FileStoreTable into {path, full TableSchema, options} so a
non-Java reader (e.g. paimon-rust / paimon-cpp) can rebuild the table for
scan/read without a catalog lookup or JVM-only state. Non-main branches are
carried verbatim so a reader can fail fast rather than silently read main.
Motivated by the Doris Paimon-external-table integration (apache/doris#65883),
where the compute node re-resolves the table through a catalog; this lets it
consume the FE-planned table instead.
…nstruction
Add org.apache.paimon.table.TableDescriptor (paimon-api) and
TableDescriptorSerializer (paimon-core): a slim, versioned JSON wire form that
serializes a resolved FileStoreTable into {path, full TableSchema, options} so a
non-Java reader (e.g. paimon-rust / paimon-cpp) can rebuild the table for
scan/read without a catalog lookup or JVM-only state. Non-main branches are
carried verbatim so a reader can fail fast rather than silently read main.
Motivated by the Doris Paimon-external-table integration (apache/doris#65883),
where the compute node re-resolves the table through a catalog; this lets it
consume the FE-planned table instead.
|
@pzhdfy Thank you for the contibution! Just to clarify, paimon-cpp has already been donated from the Alibaba repository Alibaba repo to the Apache repo and is currently in the release process. It is now the official Paimon standard-format implementation under the Apache community, and we expect it to continue tracking the upstream standard as the Paimon community evolves. So, I’m not sure “bespoke C++ port” is a accurate wording here. Also, paimon-cpp has been widely used in production within Alibaba for about 2 years, with both stability and performance validated in large-scale scenarios. Given that Doris’s backend is implemented in C++, I wonder whether the C++ path might be a more natural fit to prioritize here. |
3.paimon-rust is 2x~3x faster than paimon-java when read MOR ,and close to doris native reader when read DV( only slow 10%,because arrow convert to doris block)
|
|
@pzhdfy Thanks for the reply. If
Looking forward to seeing more testing and results. |
What problem does this PR solve?
Problem Summary:
another pr for branch-4.1: #66227
we current will keep iterating on branch-4.1, because our internal doris forks from branch-4.1
and this pr for master will be closed later, becuase paimon-rust reader is based on scanner v1, and all the scanner v1 code will be removed, we will refactor paimon-rust reader to scanner v2 in the future, and open a new pull request.
Adds a third BE-side reader for Paimon FORMAT_JNI splits, backed by the
paimon-rustC bindings (libpaimon_c.a, statically linked). Rust Reader is gated by the session variableenable_paimon_rust_reader(defaultfalse).Compared with the existing readers:
deserialized in-process and rows arrive via the Arrow C Data Interface,
which shortens the scanner critical section and removes JNI copy cost.
(schema, DV, snapshots, predicates), so features/fixes propagate may be more fast and different.
Our goal is not to replace paimon-cpp, just give user a choice to switch at query time.
Architecture
FE (
PaimonScanNode): whenenable_paimon_rust_readeris on and the splitis a
DataSplit, encode it with paimon's native binary serialization(
PaimonUtil.encodeDataSplitToString), stamp the range withTPaimonReaderType.PAIMON_RUST, and attachdb_name/table_name/paimon_tableso BE can open the table through a catalog.BE (
FileScanner::_get_next_reader): dispatches onreader_type. OnPAIMON_RUSTit instantiatesPaimonRustReader, which:paimon_catalog_create({warehouse, metastore=filesystem, ...})/<db>.db/<table>(paimon FS convention).paimon_identifier_new(db, tbl)→paimon_catalog_get_tablepaimon_table_new_read_builder→ projection (case-insensitive) →optional filter from
PaimonRustPredicateConverter(translates Dorispush-down conjuncts into paimon-rust predicates, best-effort so any
non-representable conjunct is silently dropped and re-applied by the
engine).
paimon_plan_from_split_bytes(split_bytes)— one BE scanner readsexactly its FE-planned split (no re-planning).
paimon_table_read_to_arrow→ streamed arrow record batches → block.Partition columns are back-filled in
on_after_read_blockfromFE-provided
columns_from_path*, mirroringPaimonCppReader. OSS/S3hadoop-style credential keys (
fs.oss.*/fs.s3a.*) are remapped toAWS_ACCESS_KEY/AWS_ENDPOINT/ ... so paimon-rust's FileIO canauthenticate.
Thirdparty
paimon-rust-2fb5e49(built with Rust 1.91.0, featurepaimon/storage-hdfs,--locked).cbindgenand regenerates the C header from the Rustextern "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.halways matches the built.a.Release note
Add
enable_paimon_rust_readersession variable. When enabled, Paimonnon-native reads on BE use the paimon-rust reader instead of paimon-jni /
paimon-cpp.
Check List (For Author)
Test
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.confSET enable_paimon_rust_reader=true; SET force_jni_scanner=1;SELECTfrom a partitioned/DV paimon table; results must matchenable_paimon_rust_reader=false and force_jni_scanner=0.SELECT count(*)— should hit table-level row count push-down.WHERE a=1 AND b>2— BE INFO log should showpaimon-rust predicate pushdown: applied.Behavior changed:
enable_paimon_rust_reader(defaultfalse); when off, all paths are unchanged.Does this need documentation?
Check List (For Reviewer who merge this PR)