mirror of
https://github.com/lancedb/lancedb.git
synced 2026-08-23 22:48:22 +00:00
fix(rust): reject bitmap indexes on JSON fields (#3895)
## Summary - reject whole-document `lance.json` fields during native BITMAP index preparation - preserve BITMAP support for raw `LargeBinary` fields - return guidance to use a JSON-path scalar index or FTS instead - add regression coverage for the logical JSON type while retaining the existing raw binary coverage ## Root cause Native scalar-index validation resolved the complete Arrow field but checked BITMAP compatibility only against its physical data type. Because `lance.json` is stored as `LargeBinary`, it was incorrectly accepted under the raw binary compatibility rule. The fix reuses Lance’s `lance_arrow::json::is_json_field` helper before physical type validation. Remote serialization is unchanged, so remote clients continue to send the requested BITMAP type for server-side validation. ## Validation - `cargo fmt --all -- --check` - `cargo test --quiet --features remote -p lancedb test_create_bitmap_index -- --nocapture` - `cargo check --quiet --features remote --tests --examples` - `cargo clippy --quiet --features remote --tests --examples` - `cargo test --quiet --features remote --tests` Fixes #3889 <!-- lance-gatekeeper-fix:v1 agent=e097fc02a548edc0d0be2e18c65c03a3 generation=1 --> Co-authored-by: Gatefixer <313497061+lancedb-gatefixer[bot]@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
c0df2c63b6
commit
5468f3d490
@@ -12,6 +12,7 @@ use arrow_schema::{DataType, Field};
|
||||
use lance::index::DatasetIndexExt;
|
||||
use lance::index::vector::VectorIndexParams;
|
||||
use lance::index::vector::utils::infer_vector_dim;
|
||||
use lance_arrow::json::is_json_field;
|
||||
use lance_index::IndexType;
|
||||
use lance_index::scalar::{BuiltinIndexType, ScalarIndexParams};
|
||||
use lance_index::vector::bq::RQBuildParams;
|
||||
@@ -219,6 +220,14 @@ impl NativeTable {
|
||||
)))
|
||||
}
|
||||
Index::Bitmap(_) => {
|
||||
if is_json_field(field) {
|
||||
return Err(Error::Schema {
|
||||
message: format!(
|
||||
"A BITMAP index cannot be created on the whole-document lance.json field `{}`. Create a JSON-path scalar index for structured equality or range predicates, or use FTS for document search",
|
||||
field.name()
|
||||
),
|
||||
});
|
||||
}
|
||||
Self::validate_index_type(field, "Bitmap", supported_bitmap_data_type)?;
|
||||
Ok(Box::new(ScalarIndexParams::for_builtin(
|
||||
BuiltinIndexType::Bitmap,
|
||||
@@ -1465,6 +1474,35 @@ mod tests {
|
||||
assert_eq!(stats.distance_type, None);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_create_bitmap_index_rejects_lance_json() {
|
||||
let conn = connect("memory://").execute().await.unwrap();
|
||||
let schema = Arc::new(Schema::new(vec![lance_arrow::json::json_field(
|
||||
"metadata", true,
|
||||
)]));
|
||||
let table = conn
|
||||
.create_empty_table("json_bitmap", schema)
|
||||
.execute()
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let err = table
|
||||
.create_index(&["metadata"], Index::Bitmap(Default::default()))
|
||||
.execute()
|
||||
.await
|
||||
.expect_err("a whole-document lance.json field must not support a bitmap index");
|
||||
let message = err.to_string();
|
||||
assert!(
|
||||
message.contains("lance.json"),
|
||||
"unexpected error: {message}"
|
||||
);
|
||||
assert!(
|
||||
message.contains("JSON-path scalar index"),
|
||||
"unexpected error: {message}"
|
||||
);
|
||||
assert!(message.contains("FTS"), "unexpected error: {message}");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_create_label_list_index() {
|
||||
let conn = connect("memory://").execute().await.unwrap();
|
||||
|
||||
Reference in New Issue
Block a user