Summary
Add Apache Lance as a new accepted sink format alongside delta, iceberg, and parquet.
Motivation
Lance is a modern columnar format designed for ML and analytical workloads, built Arrow-first from the ground up. It features versioned datasets (snapshots), native vector index support, and compatibility with S3/GCS/ADLS — making it a relevant target for data platforms that feed ML pipelines or vector search engines.
Technical Feasibility
The lance Rust crate is production-ready and integrates naturally with the existing Floe stack:
- Arrow-native:
Dataset::write() accepts RecordBatch directly — the existing Arrow conversion layer in Floe is immediately reusable.
- Versioned snapshots: Lance has a snapshot model similar to Iceberg, meaning Append and Overwrite semantics map cleanly.
- Cloud storage: Native support for S3, GCS, and ADLS via object_store — consistent with Floe's
Target enum.
- No
Target enum changes needed: Lance datasets are directory-based (like Delta), so SinkTarget.path maps directly.
Integration complexity is low — the pattern mirrors the existing Iceberg adapter.
Proposed Implementation
1. New adapter
Create crates/floe-core/src/io/write/lance.rs implementing AcceptedSinkAdapter:
use lance::dataset::{Dataset, WriteMode, WriteParams};
struct LanceAcceptedAdapter;
impl AcceptedSinkAdapter for LanceAcceptedAdapter {
fn write_accepted(&self, target, df, mode, ...) -> FloeResult<AcceptedWriteOutput> {
let batch = dataframe_to_record_batch(df)?;
let params = WriteParams {
mode: match mode {
WriteMode::Append => lance::dataset::WriteMode::Append,
WriteMode::Overwrite => lance::dataset::WriteMode::Overwrite,
_ => return Err(...),
},
..Default::default()
};
Dataset::write(stream_of(batch), &uri, Some(params)).await?;
}
}
2. Dispatch registration
// io/format.rs
"lance" => Ok(io::write::lance::lance_accepted_adapter()),
3. User config
sink:
accepted:
format: lance
path: s3://my-bucket/warehouse/my_dataset.lance
Write Modes
| Mode |
Support |
append |
✅ Native (WriteMode::Append) |
overwrite |
✅ Native (WriteMode::Overwrite) |
merge_scd1 |
❌ Out of scope (no row-level update API yet) |
merge_scd2 |
❌ Out of scope |
Out of Scope (for now)
- Vector index creation post-write
- SCD merge operations
- Lance compaction / dataset optimization hooks
Summary
Add Apache Lance as a new accepted sink format alongside
delta,iceberg, andparquet.Motivation
Lance is a modern columnar format designed for ML and analytical workloads, built Arrow-first from the ground up. It features versioned datasets (snapshots), native vector index support, and compatibility with S3/GCS/ADLS — making it a relevant target for data platforms that feed ML pipelines or vector search engines.
Technical Feasibility
The
lanceRust crate is production-ready and integrates naturally with the existing Floe stack:Dataset::write()acceptsRecordBatchdirectly — the existing Arrow conversion layer in Floe is immediately reusable.Targetenum.Targetenum changes needed: Lance datasets are directory-based (like Delta), soSinkTarget.pathmaps directly.Integration complexity is low — the pattern mirrors the existing Iceberg adapter.
Proposed Implementation
1. New adapter
Create
crates/floe-core/src/io/write/lance.rsimplementingAcceptedSinkAdapter:2. Dispatch registration
3. User config
Write Modes
appendWriteMode::Append)overwriteWriteMode::Overwrite)merge_scd1merge_scd2Out of Scope (for now)