From df67ee402851bdb6b39d94518b8c934d354e948f Mon Sep 17 00:00:00 2001 From: Xuanwo Date: Wed, 12 Aug 2026 15:49:25 +0800 Subject: [PATCH] chore: pin Lance A4 substrate --- Cargo.lock | 84 +++++++------- Cargo.toml | 28 ++--- rust/lancedb/src/blob.rs | 20 +++- rust/lancedb/src/connection/create_table.rs | 7 +- rust/lancedb/src/table.rs | 4 + ...ma_metadata_updates_dependency_contract.rs | 103 ++++++++++++++++++ rust/lancedb/tests/blob_integration.rs | 49 ++++++--- 7 files changed, 216 insertions(+), 79 deletions(-) create mode 100644 rust/lancedb/src/table/schema_metadata_updates_dependency_contract.rs diff --git a/Cargo.lock b/Cargo.lock index 627915c47..1b0ddc89d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3455,8 +3455,8 @@ checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" [[package]] name = "fsst" -version = "11.0.0-beta.3" -source = "git+https://github.com/lance-format/lance.git?tag=v11.0.0-beta.3#f7d475539cefbd140cc46a828f3d843e68cd10f1" +version = "11.0.0-beta.4" +source = "git+https://github.com/lance-format/lance.git?rev=357d678be223f6e785d0ccaf39ac8a5ba1793dcc#357d678be223f6e785d0ccaf39ac8a5ba1793dcc" dependencies = [ "arrow-array", "rand 0.9.5", @@ -4815,8 +4815,8 @@ checksum = "e037a2e1d8d5fdbd49b16a4ea09d5d6401c1f29eca5ff29d03d3824dba16256a" [[package]] name = "lance" -version = "11.0.0-beta.3" -source = "git+https://github.com/lance-format/lance.git?tag=v11.0.0-beta.3#f7d475539cefbd140cc46a828f3d843e68cd10f1" +version = "11.0.0-beta.4" +source = "git+https://github.com/lance-format/lance.git?rev=357d678be223f6e785d0ccaf39ac8a5ba1793dcc#357d678be223f6e785d0ccaf39ac8a5ba1793dcc" dependencies = [ "arc-swap", "arrow", @@ -4890,8 +4890,8 @@ dependencies = [ [[package]] name = "lance-arrow" -version = "11.0.0-beta.3" -source = "git+https://github.com/lance-format/lance.git?tag=v11.0.0-beta.3#f7d475539cefbd140cc46a828f3d843e68cd10f1" +version = "11.0.0-beta.4" +source = "git+https://github.com/lance-format/lance.git?rev=357d678be223f6e785d0ccaf39ac8a5ba1793dcc#357d678be223f6e785d0ccaf39ac8a5ba1793dcc" dependencies = [ "arrow-array", "arrow-buffer", @@ -4913,7 +4913,7 @@ dependencies = [ [[package]] name = "lance-arrow-scalar" version = "58.0.0" -source = "git+https://github.com/lance-format/lance.git?tag=v11.0.0-beta.3#f7d475539cefbd140cc46a828f3d843e68cd10f1" +source = "git+https://github.com/lance-format/lance.git?rev=357d678be223f6e785d0ccaf39ac8a5ba1793dcc#357d678be223f6e785d0ccaf39ac8a5ba1793dcc" dependencies = [ "arrow-array", "arrow-buffer", @@ -4927,7 +4927,7 @@ dependencies = [ [[package]] name = "lance-arrow-stats" version = "58.0.0" -source = "git+https://github.com/lance-format/lance.git?tag=v11.0.0-beta.3#f7d475539cefbd140cc46a828f3d843e68cd10f1" +source = "git+https://github.com/lance-format/lance.git?rev=357d678be223f6e785d0ccaf39ac8a5ba1793dcc#357d678be223f6e785d0ccaf39ac8a5ba1793dcc" dependencies = [ "arrow-array", "arrow-schema", @@ -4936,8 +4936,8 @@ dependencies = [ [[package]] name = "lance-bitpacking" -version = "11.0.0-beta.3" -source = "git+https://github.com/lance-format/lance.git?tag=v11.0.0-beta.3#f7d475539cefbd140cc46a828f3d843e68cd10f1" +version = "11.0.0-beta.4" +source = "git+https://github.com/lance-format/lance.git?rev=357d678be223f6e785d0ccaf39ac8a5ba1793dcc#357d678be223f6e785d0ccaf39ac8a5ba1793dcc" dependencies = [ "arrayref", "crunchy", @@ -4947,8 +4947,8 @@ dependencies = [ [[package]] name = "lance-core" -version = "11.0.0-beta.3" -source = "git+https://github.com/lance-format/lance.git?tag=v11.0.0-beta.3#f7d475539cefbd140cc46a828f3d843e68cd10f1" +version = "11.0.0-beta.4" +source = "git+https://github.com/lance-format/lance.git?rev=357d678be223f6e785d0ccaf39ac8a5ba1793dcc#357d678be223f6e785d0ccaf39ac8a5ba1793dcc" dependencies = [ "arrow-array", "arrow-buffer", @@ -4988,8 +4988,8 @@ dependencies = [ [[package]] name = "lance-datafusion" -version = "11.0.0-beta.3" -source = "git+https://github.com/lance-format/lance.git?tag=v11.0.0-beta.3#f7d475539cefbd140cc46a828f3d843e68cd10f1" +version = "11.0.0-beta.4" +source = "git+https://github.com/lance-format/lance.git?rev=357d678be223f6e785d0ccaf39ac8a5ba1793dcc#357d678be223f6e785d0ccaf39ac8a5ba1793dcc" dependencies = [ "arrow", "arrow-array", @@ -5019,8 +5019,8 @@ dependencies = [ [[package]] name = "lance-datagen" -version = "11.0.0-beta.3" -source = "git+https://github.com/lance-format/lance.git?tag=v11.0.0-beta.3#f7d475539cefbd140cc46a828f3d843e68cd10f1" +version = "11.0.0-beta.4" +source = "git+https://github.com/lance-format/lance.git?rev=357d678be223f6e785d0ccaf39ac8a5ba1793dcc#357d678be223f6e785d0ccaf39ac8a5ba1793dcc" dependencies = [ "arrow", "arrow-array", @@ -5037,8 +5037,8 @@ dependencies = [ [[package]] name = "lance-derive" -version = "11.0.0-beta.3" -source = "git+https://github.com/lance-format/lance.git?tag=v11.0.0-beta.3#f7d475539cefbd140cc46a828f3d843e68cd10f1" +version = "11.0.0-beta.4" +source = "git+https://github.com/lance-format/lance.git?rev=357d678be223f6e785d0ccaf39ac8a5ba1793dcc#357d678be223f6e785d0ccaf39ac8a5ba1793dcc" dependencies = [ "proc-macro2", "quote", @@ -5047,8 +5047,8 @@ dependencies = [ [[package]] name = "lance-encoding" -version = "11.0.0-beta.3" -source = "git+https://github.com/lance-format/lance.git?tag=v11.0.0-beta.3#f7d475539cefbd140cc46a828f3d843e68cd10f1" +version = "11.0.0-beta.4" +source = "git+https://github.com/lance-format/lance.git?rev=357d678be223f6e785d0ccaf39ac8a5ba1793dcc#357d678be223f6e785d0ccaf39ac8a5ba1793dcc" dependencies = [ "arrow-arith", "arrow-array", @@ -5082,8 +5082,8 @@ dependencies = [ [[package]] name = "lance-file" -version = "11.0.0-beta.3" -source = "git+https://github.com/lance-format/lance.git?tag=v11.0.0-beta.3#f7d475539cefbd140cc46a828f3d843e68cd10f1" +version = "11.0.0-beta.4" +source = "git+https://github.com/lance-format/lance.git?rev=357d678be223f6e785d0ccaf39ac8a5ba1793dcc#357d678be223f6e785d0ccaf39ac8a5ba1793dcc" dependencies = [ "arrow-arith", "arrow-array", @@ -5114,8 +5114,8 @@ dependencies = [ [[package]] name = "lance-index" -version = "11.0.0-beta.3" -source = "git+https://github.com/lance-format/lance.git?tag=v11.0.0-beta.3#f7d475539cefbd140cc46a828f3d843e68cd10f1" +version = "11.0.0-beta.4" +source = "git+https://github.com/lance-format/lance.git?rev=357d678be223f6e785d0ccaf39ac8a5ba1793dcc#357d678be223f6e785d0ccaf39ac8a5ba1793dcc" dependencies = [ "arc-swap", "arrow", @@ -5182,8 +5182,8 @@ dependencies = [ [[package]] name = "lance-index-core" -version = "11.0.0-beta.3" -source = "git+https://github.com/lance-format/lance.git?tag=v11.0.0-beta.3#f7d475539cefbd140cc46a828f3d843e68cd10f1" +version = "11.0.0-beta.4" +source = "git+https://github.com/lance-format/lance.git?rev=357d678be223f6e785d0ccaf39ac8a5ba1793dcc#357d678be223f6e785d0ccaf39ac8a5ba1793dcc" dependencies = [ "arrow-array", "arrow-schema", @@ -5205,8 +5205,8 @@ dependencies = [ [[package]] name = "lance-io" -version = "11.0.0-beta.3" -source = "git+https://github.com/lance-format/lance.git?tag=v11.0.0-beta.3#f7d475539cefbd140cc46a828f3d843e68cd10f1" +version = "11.0.0-beta.4" +source = "git+https://github.com/lance-format/lance.git?rev=357d678be223f6e785d0ccaf39ac8a5ba1793dcc#357d678be223f6e785d0ccaf39ac8a5ba1793dcc" dependencies = [ "arrow", "arrow-array", @@ -5242,8 +5242,8 @@ dependencies = [ [[package]] name = "lance-linalg" -version = "11.0.0-beta.3" -source = "git+https://github.com/lance-format/lance.git?tag=v11.0.0-beta.3#f7d475539cefbd140cc46a828f3d843e68cd10f1" +version = "11.0.0-beta.4" +source = "git+https://github.com/lance-format/lance.git?rev=357d678be223f6e785d0ccaf39ac8a5ba1793dcc#357d678be223f6e785d0ccaf39ac8a5ba1793dcc" dependencies = [ "arrow-array", "arrow-buffer", @@ -5259,8 +5259,8 @@ dependencies = [ [[package]] name = "lance-namespace" -version = "11.0.0-beta.3" -source = "git+https://github.com/lance-format/lance.git?tag=v11.0.0-beta.3#f7d475539cefbd140cc46a828f3d843e68cd10f1" +version = "11.0.0-beta.4" +source = "git+https://github.com/lance-format/lance.git?rev=357d678be223f6e785d0ccaf39ac8a5ba1793dcc#357d678be223f6e785d0ccaf39ac8a5ba1793dcc" dependencies = [ "arrow", "async-trait", @@ -5272,8 +5272,8 @@ dependencies = [ [[package]] name = "lance-namespace-impls" -version = "11.0.0-beta.3" -source = "git+https://github.com/lance-format/lance.git?tag=v11.0.0-beta.3#f7d475539cefbd140cc46a828f3d843e68cd10f1" +version = "11.0.0-beta.4" +source = "git+https://github.com/lance-format/lance.git?rev=357d678be223f6e785d0ccaf39ac8a5ba1793dcc#357d678be223f6e785d0ccaf39ac8a5ba1793dcc" dependencies = [ "arrow", "arrow-ipc", @@ -5326,8 +5326,8 @@ dependencies = [ [[package]] name = "lance-select" -version = "11.0.0-beta.3" -source = "git+https://github.com/lance-format/lance.git?tag=v11.0.0-beta.3#f7d475539cefbd140cc46a828f3d843e68cd10f1" +version = "11.0.0-beta.4" +source = "git+https://github.com/lance-format/lance.git?rev=357d678be223f6e785d0ccaf39ac8a5ba1793dcc#357d678be223f6e785d0ccaf39ac8a5ba1793dcc" dependencies = [ "arrow-array", "arrow-buffer", @@ -5342,8 +5342,8 @@ dependencies = [ [[package]] name = "lance-table" -version = "11.0.0-beta.3" -source = "git+https://github.com/lance-format/lance.git?tag=v11.0.0-beta.3#f7d475539cefbd140cc46a828f3d843e68cd10f1" +version = "11.0.0-beta.4" +source = "git+https://github.com/lance-format/lance.git?rev=357d678be223f6e785d0ccaf39ac8a5ba1793dcc#357d678be223f6e785d0ccaf39ac8a5ba1793dcc" dependencies = [ "arrow", "arrow-array", @@ -5383,8 +5383,8 @@ dependencies = [ [[package]] name = "lance-testing" -version = "11.0.0-beta.3" -source = "git+https://github.com/lance-format/lance.git?tag=v11.0.0-beta.3#f7d475539cefbd140cc46a828f3d843e68cd10f1" +version = "11.0.0-beta.4" +source = "git+https://github.com/lance-format/lance.git?rev=357d678be223f6e785d0ccaf39ac8a5ba1793dcc#357d678be223f6e785d0ccaf39ac8a5ba1793dcc" dependencies = [ "arrow-array", "arrow-schema", @@ -5397,8 +5397,8 @@ dependencies = [ [[package]] name = "lance-tokenizer" -version = "11.0.0-beta.3" -source = "git+https://github.com/lance-format/lance.git?tag=v11.0.0-beta.3#f7d475539cefbd140cc46a828f3d843e68cd10f1" +version = "11.0.0-beta.4" +source = "git+https://github.com/lance-format/lance.git?rev=357d678be223f6e785d0ccaf39ac8a5ba1793dcc#357d678be223f6e785d0ccaf39ac8a5ba1793dcc" dependencies = [ "frostem", "icu_segmenter", diff --git a/Cargo.toml b/Cargo.toml index 936660d78..5fb97ace2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,20 +13,20 @@ categories = ["database-implementations"] rust-version = "1.91.0" [workspace.dependencies] -lance = { "version" = "=11.0.0-beta.3", default-features = false, "tag" = "v11.0.0-beta.3", "git" = "https://github.com/lance-format/lance.git" } -lance-core = { "version" = "=11.0.0-beta.3", "tag" = "v11.0.0-beta.3", "git" = "https://github.com/lance-format/lance.git" } -lance-datagen = { "version" = "=11.0.0-beta.3", "tag" = "v11.0.0-beta.3", "git" = "https://github.com/lance-format/lance.git" } -lance-file = { "version" = "=11.0.0-beta.3", "tag" = "v11.0.0-beta.3", "git" = "https://github.com/lance-format/lance.git" } -lance-io = { "version" = "=11.0.0-beta.3", default-features = false, "tag" = "v11.0.0-beta.3", "git" = "https://github.com/lance-format/lance.git" } -lance-index = { "version" = "=11.0.0-beta.3", "tag" = "v11.0.0-beta.3", "git" = "https://github.com/lance-format/lance.git" } -lance-linalg = { "version" = "=11.0.0-beta.3", "tag" = "v11.0.0-beta.3", "git" = "https://github.com/lance-format/lance.git" } -lance-namespace = { "version" = "=11.0.0-beta.3", "tag" = "v11.0.0-beta.3", "git" = "https://github.com/lance-format/lance.git" } -lance-namespace-impls = { "version" = "=11.0.0-beta.3", default-features = false, "tag" = "v11.0.0-beta.3", "git" = "https://github.com/lance-format/lance.git" } -lance-table = { "version" = "=11.0.0-beta.3", "tag" = "v11.0.0-beta.3", "git" = "https://github.com/lance-format/lance.git" } -lance-testing = { "version" = "=11.0.0-beta.3", "tag" = "v11.0.0-beta.3", "git" = "https://github.com/lance-format/lance.git" } -lance-datafusion = { "version" = "=11.0.0-beta.3", "tag" = "v11.0.0-beta.3", "git" = "https://github.com/lance-format/lance.git" } -lance-encoding = { "version" = "=11.0.0-beta.3", "tag" = "v11.0.0-beta.3", "git" = "https://github.com/lance-format/lance.git" } -lance-arrow = { "version" = "=11.0.0-beta.3", "tag" = "v11.0.0-beta.3", "git" = "https://github.com/lance-format/lance.git" } +lance = { version = "=11.0.0-beta.4", default-features = false, rev = "357d678be223f6e785d0ccaf39ac8a5ba1793dcc", git = "https://github.com/lance-format/lance.git" } +lance-core = { version = "=11.0.0-beta.4", rev = "357d678be223f6e785d0ccaf39ac8a5ba1793dcc", git = "https://github.com/lance-format/lance.git" } +lance-datagen = { version = "=11.0.0-beta.4", rev = "357d678be223f6e785d0ccaf39ac8a5ba1793dcc", git = "https://github.com/lance-format/lance.git" } +lance-file = { version = "=11.0.0-beta.4", rev = "357d678be223f6e785d0ccaf39ac8a5ba1793dcc", git = "https://github.com/lance-format/lance.git" } +lance-io = { version = "=11.0.0-beta.4", default-features = false, rev = "357d678be223f6e785d0ccaf39ac8a5ba1793dcc", git = "https://github.com/lance-format/lance.git" } +lance-index = { version = "=11.0.0-beta.4", rev = "357d678be223f6e785d0ccaf39ac8a5ba1793dcc", git = "https://github.com/lance-format/lance.git" } +lance-linalg = { version = "=11.0.0-beta.4", rev = "357d678be223f6e785d0ccaf39ac8a5ba1793dcc", git = "https://github.com/lance-format/lance.git" } +lance-namespace = { version = "=11.0.0-beta.4", rev = "357d678be223f6e785d0ccaf39ac8a5ba1793dcc", git = "https://github.com/lance-format/lance.git" } +lance-namespace-impls = { version = "=11.0.0-beta.4", default-features = false, rev = "357d678be223f6e785d0ccaf39ac8a5ba1793dcc", git = "https://github.com/lance-format/lance.git" } +lance-table = { version = "=11.0.0-beta.4", rev = "357d678be223f6e785d0ccaf39ac8a5ba1793dcc", git = "https://github.com/lance-format/lance.git" } +lance-testing = { version = "=11.0.0-beta.4", rev = "357d678be223f6e785d0ccaf39ac8a5ba1793dcc", git = "https://github.com/lance-format/lance.git" } +lance-datafusion = { version = "=11.0.0-beta.4", rev = "357d678be223f6e785d0ccaf39ac8a5ba1793dcc", git = "https://github.com/lance-format/lance.git" } +lance-encoding = { version = "=11.0.0-beta.4", rev = "357d678be223f6e785d0ccaf39ac8a5ba1793dcc", git = "https://github.com/lance-format/lance.git" } +lance-arrow = { version = "=11.0.0-beta.4", rev = "357d678be223f6e785d0ccaf39ac8a5ba1793dcc", git = "https://github.com/lance-format/lance.git" } ahash = "0.8" # Note that this one does not include pyarrow arrow = { version = "58.0.0", optional = false } diff --git a/rust/lancedb/src/blob.rs b/rust/lancedb/src/blob.rs index e1c18dd84..71680f14d 100644 --- a/rust/lancedb/src/blob.rs +++ b/rust/lancedb/src/blob.rs @@ -17,7 +17,7 @@ use arrow_array::builder::LargeBinaryBuilder; use arrow_schema::{DataType, Field, Schema}; use lance::dataset::{BlobRangeRequest as LanceBlobRangeRequest, Dataset, WriteParams}; use lance_arrow::FieldExt; -use lance_file::version::LanceFileVersion; +use lance_file::version::{ConcreteFileVersion, LanceFileVersion}; use lance_io::object_store::ObjectStore; use object_store::path::Path; @@ -333,8 +333,13 @@ pub(crate) fn ensure_blob_storage_version(schema: &Schema, params: &mut WritePar .data_storage_version .unwrap_or(LanceFileVersion::Stable) .resolve(); - if resolved < LanceFileVersion::V2_2 { - params.data_storage_version = Some(LanceFileVersion::V2_2); + // Exact formats deliberately have no Ord: capability is not implied by + // release order. Enumerate every current concrete variant explicitly. + match resolved { + ConcreteFileVersion::V1 | ConcreteFileVersion::V2_0 | ConcreteFileVersion::V2_1 => { + params.data_storage_version = Some(LanceFileVersion::V2_2); + } + ConcreteFileVersion::V2_2 | ConcreteFileVersion::V2_3 => {} } } @@ -499,7 +504,7 @@ mod tests { ensure_blob_storage_version(&blob_schema(), &mut params); assert_eq!( params.data_storage_version.unwrap().resolve(), - LanceFileVersion::V2_2 + LanceFileVersion::V2_2.resolve() ); } @@ -512,7 +517,7 @@ mod tests { ensure_blob_storage_version(&blob_schema(), &mut params); assert_eq!( params.data_storage_version.unwrap().resolve(), - LanceFileVersion::V2_2 + LanceFileVersion::V2_2.resolve() ); } @@ -523,7 +528,10 @@ mod tests { ..Default::default() }; ensure_blob_storage_version(&blob_schema(), &mut params); - assert_eq!(params.data_storage_version.unwrap(), LanceFileVersion::V2_3); + assert_eq!( + params.data_storage_version.unwrap().resolve(), + LanceFileVersion::V2_3.resolve() + ); } #[test] diff --git a/rust/lancedb/src/connection/create_table.rs b/rust/lancedb/src/connection/create_table.rs index b10141beb..414e34d7d 100644 --- a/rust/lancedb/src/connection/create_table.rs +++ b/rust/lancedb/src/connection/create_table.rs @@ -438,10 +438,9 @@ mod tests { .await .unwrap() .data_storage_format - .lance_file_version() - .unwrap(); - // Compare resolved versions since Stable/Next are aliases that resolve at storage time - assert_eq!(storage_format.resolve(), data_storage_version.resolve()); + .lance_file_format(); + // Compare concrete stored format to the resolved requested alias. + assert_eq!(storage_format, data_storage_version.resolve()); } #[tokio::test] diff --git a/rust/lancedb/src/table.rs b/rust/lancedb/src/table.rs index 61cdb9284..7f30b84e2 100644 --- a/rust/lancedb/src/table.rs +++ b/rust/lancedb/src/table.rs @@ -84,6 +84,10 @@ pub mod query; pub mod schema_evolution; pub mod update; pub mod write_progress; + +#[cfg(test)] +mod schema_metadata_updates_dependency_contract; + use crate::index::waiter::wait_for_index; pub use add_columns::AddColumnsBuilder; #[cfg(feature = "remote")] diff --git a/rust/lancedb/src/table/schema_metadata_updates_dependency_contract.rs b/rust/lancedb/src/table/schema_metadata_updates_dependency_contract.rs new file mode 100644 index 000000000..8d25864ef --- /dev/null +++ b/rust/lancedb/src/table/schema_metadata_updates_dependency_contract.rs @@ -0,0 +1,103 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: Copyright The LanceDB Authors + +//! Dependency-contract test for Lance A4 schema metadata attachment (B4p). +//! +//! Pins the exact generic Lance API shape LanceDB B4 will consume: +//! [`SchemaMetadataUpdates`], [`UpdateMap`], [`UpdateMapEntry`], +//! [`Transaction::with_schema_metadata_updates`], and the public +//! `with_schema_metadata_updates` methods on insert/update/delete builders. +//! +//! Neutral metadata keys only. No Function / UDF / Job semantics. + +use std::collections::HashMap; + +use lance::Result; +use lance::dataset::transaction::{ + Operation, SchemaMetadataUpdates, Transaction, UpdateMap, UpdateMapEntry, +}; +use lance::dataset::{DeleteBuilder, InsertBuilder, UpdateBuilder}; +use lance_table::format::Fragment; + +const FIELD_ID: i32 = 7; +const META_KEY: &str = "b4p.dependency.meta"; +const META_VALUE: &str = "neutral-value"; + +fn field_metadata_patch() -> SchemaMetadataUpdates { + SchemaMetadataUpdates { + schema_metadata_updates: None, + field_metadata_updates: HashMap::from([( + FIELD_ID, + UpdateMap { + update_entries: vec![UpdateMapEntry { + key: META_KEY.to_string(), + value: Some(META_VALUE.to_string()), + }], + replace: false, + }, + )]), + } +} + +/// Compile-time proof that InsertBuilder exposes the A4 attachment method. +#[allow(dead_code)] +fn typecheck_insert_builder_attachment<'a>( + builder: InsertBuilder<'a>, + updates: SchemaMetadataUpdates, +) -> Result> { + builder.with_schema_metadata_updates(updates) +} + +/// Compile-time proof that UpdateBuilder exposes the A4 attachment method. +#[allow(dead_code)] +fn typecheck_update_builder_attachment( + builder: UpdateBuilder, + updates: SchemaMetadataUpdates, +) -> Result { + builder.with_schema_metadata_updates(updates) +} + +/// Compile-time proof that DeleteBuilder exposes the A4 attachment method. +#[allow(dead_code)] +fn typecheck_delete_builder_attachment( + builder: DeleteBuilder, + updates: SchemaMetadataUpdates, +) -> Result { + builder.with_schema_metadata_updates(updates) +} + +#[test] +fn append_transaction_retains_schema_metadata_updates_patch() { + let updates = field_metadata_patch(); + assert!( + !updates.is_empty(), + "fixture must be a substantive non-empty field metadata patch" + ); + + let transaction = Transaction::new( + 0, + Operation::Append { + fragments: vec![Fragment::new(1)], + }, + None, + ) + .with_schema_metadata_updates(updates.clone()) + .expect("non-empty field metadata patch must attach to Append"); + + assert_eq!(transaction.schema_metadata_updates.as_ref(), Some(&updates)); + + let field_map = transaction + .schema_metadata_updates + .as_ref() + .expect("attached patch must be present") + .field_metadata_updates + .get(&FIELD_ID) + .expect("stable field id 7 must be present"); + assert!(!field_map.replace); + assert_eq!(field_map.update_entries.len(), 1); + assert_eq!(field_map.update_entries[0].key, META_KEY); + assert_eq!( + field_map.update_entries[0].value.as_deref(), + Some(META_VALUE) + ); +} diff --git a/rust/lancedb/tests/blob_integration.rs b/rust/lancedb/tests/blob_integration.rs index 77d49abd9..0c5469f1d 100644 --- a/rust/lancedb/tests/blob_integration.rs +++ b/rust/lancedb/tests/blob_integration.rs @@ -10,7 +10,7 @@ use arrow_array::{ use arrow_schema::{DataType, Field, Fields, Schema}; use futures::TryStreamExt; use lance::Dataset; -use lance_file::version::LanceFileVersion; +use lance_file::version::{ConcreteFileVersion, LanceFileVersion}; use lancedb::{ Connection, Error, Result, Table, blob::{BlobRangeRequest, blob}, @@ -61,7 +61,7 @@ async fn create_inline_blob_table( Ok(table) } -async fn storage_format_version(table: &Table) -> LanceFileVersion { +async fn storage_format_version(table: &Table) -> ConcreteFileVersion { table .as_native() .unwrap() @@ -69,9 +69,18 @@ async fn storage_format_version(table: &Table) -> LanceFileVersion { .await .unwrap() .data_storage_format - .lance_file_version() - .unwrap() - .resolve() + .lance_file_format() +} + +/// Blob v2 storage capability for the current concrete formats. +/// +/// Exact formats deliberately have no Ord: capability is not implied by release +/// order. Enumerate every current concrete variant explicitly. +fn supports_blob_v2_storage(version: ConcreteFileVersion) -> bool { + match version { + ConcreteFileVersion::V2_2 | ConcreteFileVersion::V2_3 => true, + ConcreteFileVersion::V1 | ConcreteFileVersion::V2_0 | ConcreteFileVersion::V2_1 => false, + } } async fn uses_stable_row_ids(table: &Table) -> bool { @@ -112,7 +121,9 @@ async fn declaring_blob_column_bumps_format_and_enables_stable_row_ids() -> Resu .execute() .await?; - assert!(storage_format_version(&table).await >= LanceFileVersion::V2_2); + assert!(supports_blob_v2_storage( + storage_format_version(&table).await + )); assert!(uses_stable_row_ids(&table).await); Ok(()) } @@ -127,7 +138,9 @@ async fn explicit_stable_row_id_setting_wins_over_blob_default() -> Result<()> { .execute() .await?; - assert!(storage_format_version(&table).await >= LanceFileVersion::V2_2); + assert!(supports_blob_v2_storage( + storage_format_version(&table).await + )); assert!(!uses_stable_row_ids(&table).await); Ok(()) } @@ -139,7 +152,9 @@ async fn non_blob_table_keeps_default_format_and_row_id_setting() -> Result<()> let schema = Arc::new(Schema::new(vec![Field::new("id", DataType::Int64, false)])); let table = db.create_empty_table("t", schema).execute().await?; - assert!(storage_format_version(&table).await < LanceFileVersion::V2_2); + assert!(!supports_blob_v2_storage( + storage_format_version(&table).await + )); assert!(!uses_stable_row_ids(&table).await); Ok(()) } @@ -171,7 +186,9 @@ async fn creating_with_blob_data_bumps_format() -> Result<()> { .unwrap(); let table = db.create_table("t", batch).execute().await?; - assert!(storage_format_version(&table).await >= LanceFileVersion::V2_2); + assert!(supports_blob_v2_storage( + storage_format_version(&table).await + )); assert!(uses_stable_row_ids(&table).await); assert_eq!(table.count_rows(None).await?, 1); Ok(()) @@ -281,7 +298,9 @@ async fn connection_level_stable_row_id_setting_wins_over_blob_default() -> Resu .execute() .await?; - assert!(storage_format_version(&table).await >= LanceFileVersion::V2_2); + assert!(supports_blob_v2_storage( + storage_format_version(&table).await + )); assert!(!uses_stable_row_ids(&table).await); Ok(()) } @@ -297,7 +316,9 @@ async fn namespace_create_applies_blob_defaults() -> Result<()> { .execute() .await?; - assert!(storage_format_version(&table).await >= LanceFileVersion::V2_2); + assert!(supports_blob_v2_storage( + storage_format_version(&table).await + )); assert!(uses_stable_row_ids(&table).await); Ok(()) } @@ -474,7 +495,9 @@ async fn fetch_blobs_round_trips_nested_blob_column() -> Result<()> { let batch = RecordBatch::try_new(schema, vec![Arc::new(info_array) as ArrayRef]).unwrap(); let table = db.create_table("t", batch).execute().await?; - assert!(storage_format_version(&table).await >= LanceFileVersion::V2_2); + assert!(supports_blob_v2_storage( + storage_format_version(&table).await + )); assert!(uses_stable_row_ids(&table).await); let ids = collect_row_ids(&table).await?; @@ -1305,7 +1328,7 @@ async fn optimize_preserves_blob_v2_null_and_empty_distinction() -> Result<()> { .await?; table.add(null_empty_input_batch()).execute().await?; assert!( - storage_format_version(&table).await >= LanceFileVersion::V2_2, + supports_blob_v2_storage(storage_format_version(&table).await), "blob v2 columns require storage >= 2.2" );