[feature](lance) Add Rust-based Lance format reader for AI-native dat… - #62182
Conversation
|
Thank you for your contribution to Apache Doris. Please clearly describe your PR:
|
9825d0e to
6f655a4
Compare
|
run buildall |
FE UT Coverage ReportIncrement line coverage |
|
we need to install cargo toolchain to make rust ffi compile |
BE UT Coverage ReportIncrement line coverage Increment coverage report
|
BE Regression && UT Coverage ReportIncrement line coverage Increment coverage report
|
|
run buildall |
|
TeamCity pipeline will use regression-test/pipeline/common/custom_env.sh when compiling, please set BUILD_RUST_READERS=on in it for test. |
BE UT Coverage ReportIncrement line coverage Increment coverage report
|
BE Regression && UT Coverage ReportIncrement line coverage Increment coverage report
|
|
run buildall |
FE UT Coverage ReportIncrement line coverage |
a02a47a to
9dcf75e
Compare
|
run buildall |
d306c78 to
f0bad39
Compare
|
run buildall |
Cloud UT Coverage ReportIncrement line coverage Increment coverage report
|
FE UT Coverage ReportIncrement line coverage |
|
run buildall |
Upstream master refactored GenericReader virtual methods: get_next_block -> _do_get_next_block (protected hook) get_columns(name_to_type, missing_cols) -> _get_columns_impl(name_to_type) Update LanceRustReader's overrides to match the new signatures so CI (which builds our PR on top of current master) compiles. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…o lance-support
|
run buildall |
|
run buildall |
1 similar comment
|
run buildall |
|
run buildall |
|
so many PR per day.... |
FE Regression Coverage ReportIncrement line coverage |
BE Regression && UT Coverage ReportIncrement line coverage Increment coverage report
|
| fuzzy = true, | ||
| description = {"使用 Rust Lance 读取器读取 Lance 格式数据", | ||
| "Use Rust-based Lance reader for Lance format data"}) | ||
| private boolean enableRustLanceReader = false; |
There was a problem hiding this comment.
Do we really need this variable?
|
PR approved by at least one committer and no changes requested. |
|
PR approved by anyone and no changes requested. |
|
Hi @BiteTheDDDDt @tomz-alt , just saw this great integration! We are working on https://github.com/lance-format/lance-c which is a standard c/c++ api for lance and want to see if we can unify our interface. We are running it with Velox and happy to talk more if you guys are interested |
|
which version of apache doris is released this furture GA ? |
apache#62182) Add native Lance format support to Doris via Rust FFI integration, enabling SQL queries over AI-native Lance datasets from local disk and S3. [Lance](https://lancedb.github.io/lance/) is a columnar format designed for vector search, multimodal data (images, embeddings), and fast random access -- widely used in AI/ML pipelines. ## Quick Examples **Read from S3:** ```sql SELECT * FROM s3( "uri" = "s3://bucket/embeddings.lance/data/fragment.lance", "format" = "lance", "s3.access_key" = "...", "s3.secret_key" = "...", "s3.region" = "us-east-1", "s3.endpoint" = "https://s3.us-east-1.amazonaws.com" ) ORDER BY id LIMIT 10; ``` **Read from local disk (for testing):** ```sql -- Get backend_id from: SHOW BACKENDS; SELECT * FROM local( "file_path" = "data/my_dataset.lance/data/fragment.lance", "backend_id" = "<backend_id from SHOW BACKENDS>", "format" = "lance" ) ORDER BY id LIMIT 10; ``` **Aggregation across multi-fragment dataset:** ```sql SELECT count(*), min(id), max(id) FROM s3( "uri" = "s3://bucket/large.lance/data/fragment.lance", "format" = "lance", "s3.access_key" = "...", "s3.secret_key" = "...", "s3.region" = "us-east-1", "s3.endpoint" = "https://s3.us-east-1.amazonaws.com" ); ``` ## Architecture - **Data exchange**: Arrow C Data Interface (zero-copy between Rust and C++) - **Async containment**: block_on() with single-threaded tokio runtime (zero extra OS threads) - **Build gating**: BUILD_RUST_READERS=OFF by default, zero impact on existing builds ## What Works (Verified on Live Cluster) | Feature | Status | |---------|--------| | SELECT * / column projection | Tested | | WHERE filter / LIMIT / COUNT(*) | Tested | | SUM() / AVG() aggregation | Tested | | Multi-fragment datasets (3 fragments, 15 rows) | Tested | | S3 access with AWS credentials | Tested | | Schema inference (fetch_table_schema) | Tested | | Time travel version (config wired) | Config ready | | Vector ANN search / FTS / filter pushdown | Config ready | ## Known Limitations - **TVF path only**: No CREATE CATALOG support yet. Must use local() or s3() TVF - **Directory-based format workaround**: Lance datasets are directories. The TVF file_path must point to a single `.lance` data file inside the dataset; the reader auto-strips the path back to the dataset root and reads all fragments. If the TVF glob matches multiple `.lance` files (multi-fragment dataset), each scan range reopens the full dataset causing **duplicate rows**. Workaround: ensure the file_path glob matches exactly one data file per dataset - **No Doris data cache integration**: Lance reads bypass BlockFileCache. S3 reads are not cached on local SSD - **No filter/vector pushdown from FE**: The Rust config supports filter, vector_search, full_text_search but the FE planner does not populate them yet - **BUILD_RUST_READERS=OFF default**: Requires explicit opt-in and Rust toolchain - **Binary size**: Rust static lib ~430MB (.a), adds ~50-80MB to final doris_be after LTO ## How to Build ```bash # Rust tests only: cd be/src/rust/doris-native && cargo test # Full BE with Lance: BUILD_RUST_READERS=ON ./build.sh --be # Regression test: ./run-regression-test.sh --run -s test_lance_tvf ``` ## Changes **Thrift** (2 files): FORMAT_LANCE = 19, TLanceFileDesc, enable_rust_lance_reader **FE** (4 files): LanceFileFormatProperties, FileFormatProperties factory, FileFormatConstants, SessionVariable **BE - Rust** (be/src/rust/doris-native/, 6 files): error.rs, lance_reader.rs (LanceReaderConfig with S3/version/vector/FTS support), ffi.rs (extern C functions), lib.rs **BE - C++** (5 files): lance_ffi.h, lance_rust_reader.h/cpp (GenericReader with Arrow import), file_scanner.cpp (FORMAT_LANCE dispatch), internal_service.cpp (fetch_table_schema) **Build** (3 files): rust.cmake (Corrosion v0.5), CMakeLists.txt (BUILD_RUST_READERS option), format/CMakeLists.txt **Tests** (4 files): 24 Rust tests, C++ GTest (7), C++ standalone (8), Groovy regression (9) ## Future Work - **Lance Catalog**: CREATE CATALOG for dataset discovery (eliminates TVF path limitations and backend_id requirement) - **Fragment-level scan ranges**: FE lists fragments and creates one scan range per fragment with fragment ID, avoiding duplicate reads - **FE filter/vector pushdown**: Pass WHERE predicates and ANN queries to lance-rs scanner - **Doris BlockFileCache integration**: Route lance I/O through Doris cache for S3 data caching - **Lance Session cache**: Shared IndexCache for vector/FTS index reuse across queries - **Time travel SQL**: FOR VERSION AS OF N via LanceMvccSnapshot --------- Co-authored-by: tom zhang <tom.zhang@velodb.io> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: Mingyu Chen (Rayner) <yunyou@selectdb.com>
…tive data (#62182) (#65303) ### What problem does this PR solve? This reverts commit b613c37. #62182 will be later support lance catalog full. Problem Summary: ### Release note None ### Check List (For Author) - Test <!-- At least one of them must be included. --> - [ ] Regression test - [ ] Unit Test - [ ] Manual test (add detailed scripts or steps below) - [ ] 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 <!-- Add your reason? --> - Behavior changed: - [ ] No. - [ ] Yes. <!-- Explain the behavior change --> - Does this need documentation? - [ ] No. - [ ] Yes. <!-- Add document PR link here. eg: apache/doris-website#1214 --> ### Check List (For Reviewer who merge this PR) - [ ] Confirm the release note - [ ] Confirm test cases - [ ] Confirm document - [ ] Add branch pick label <!-- Add branch pick label that this PR should merge into -->
Summary
Add native Lance format support to Doris via Rust FFI integration, enabling SQL queries over AI-native Lance datasets from local disk and S3.
Lance is a columnar format designed for vector search, multimodal data (images, embeddings), and fast random access -- widely used in AI/ML pipelines.
Quick Examples
Read from S3:
Read from local disk (for testing):
Aggregation across multi-fragment dataset:
Architecture
What Works (Verified on Live Cluster)
Known Limitations
.lancedata file inside the dataset; the reader auto-strips the path back to the dataset root and reads all fragments. If the TVF glob matches multiple.lancefiles (multi-fragment dataset), each scan range reopens the full dataset causing duplicate rows. Workaround: ensure the file_path glob matches exactly one data file per datasetHow to Build
Changes
Thrift (2 files): FORMAT_LANCE = 19, TLanceFileDesc, enable_rust_lance_reader
FE (4 files): LanceFileFormatProperties, FileFormatProperties factory, FileFormatConstants, SessionVariable
BE - Rust (be/src/rust/doris-native/, 6 files): error.rs, lance_reader.rs (LanceReaderConfig with S3/version/vector/FTS support), ffi.rs (extern C functions), lib.rs
BE - C++ (5 files): lance_ffi.h, lance_rust_reader.h/cpp (GenericReader with Arrow import), file_scanner.cpp (FORMAT_LANCE dispatch), internal_service.cpp (fetch_table_schema)
Build (3 files): rust.cmake (Corrosion v0.5), CMakeLists.txt (BUILD_RUST_READERS option), format/CMakeLists.txt
Tests (4 files): 24 Rust tests, C++ GTest (7), C++ standalone (8), Groovy regression (9)
Future Work