From cdd193bac71b343e8a6372dccac6eb54db932e9a Mon Sep 17 00:00:00 2001 From: yangjie01 Date: Tue, 24 Mar 2026 13:25:44 +0800 Subject: [PATCH 1/5] init --- rust/lance-namespace-impls/src/dir.rs | 26 +++++++++-------- .../lance-namespace-impls/src/dir/manifest.rs | 28 +++++++++++-------- 2 files changed, 31 insertions(+), 23 deletions(-) diff --git a/rust/lance-namespace-impls/src/dir.rs b/rust/lance-namespace-impls/src/dir.rs index e2cac3504aa..681f2867d15 100644 --- a/rust/lance-namespace-impls/src/dir.rs +++ b/rust/lance-namespace-impls/src/dir.rs @@ -39,6 +39,7 @@ use lance_namespace::models::{ use lance_core::{Error, Result, box_error}; use lance_namespace::LanceNamespace; +use lance_namespace::NamespaceError; use lance_namespace::schema::arrow_schema_to_json; use crate::credentials::{ @@ -1198,9 +1199,10 @@ impl LanceNamespace for DirectoryNamespace { let status = self.check_table_status(&table_name).await; if !status.exists { - return Err(Error::namespace_source( - format!("Table does not exist: {}", table_name).into(), - )); + return Err(NamespaceError::TableNotFound { + message: table_name.to_string(), + } + .into()); } if status.is_deregistered { @@ -1346,9 +1348,10 @@ impl LanceNamespace for DirectoryNamespace { let status = self.check_table_status(&table_name).await; if !status.exists { - return Err(Error::namespace_source( - format!("Table does not exist: {}", table_name).into(), - )); + return Err(NamespaceError::TableNotFound { + message: table_name.to_string(), + } + .into()); } if status.is_deregistered { @@ -1564,9 +1567,10 @@ impl LanceNamespace for DirectoryNamespace { let status = self.check_table_status(&table_name).await; if !status.exists { - return Err(Error::namespace_source( - format!("Table does not exist: {}", table_name).into(), - )); + return Err(NamespaceError::TableNotFound { + message: table_name.to_string(), + } + .into()); } if status.is_deregistered { @@ -2236,7 +2240,7 @@ mod tests { result .unwrap_err() .to_string() - .contains("Table does not exist") + .contains("Table not found") ); } @@ -2270,7 +2274,7 @@ mod tests { result .unwrap_err() .to_string() - .contains("Table does not exist") + .contains("Table not found") ); } diff --git a/rust/lance-namespace-impls/src/dir/manifest.rs b/rust/lance-namespace-impls/src/dir/manifest.rs index 902c5462acc..97aa8b43642 100644 --- a/rust/lance-namespace-impls/src/dir/manifest.rs +++ b/rust/lance-namespace-impls/src/dir/manifest.rs @@ -1838,9 +1838,10 @@ impl LanceNamespace for ManifestNamespace { } } } - None => Err(Error::namespace_source( - format!("Table '{}' not found", object_id).into(), - )), + None => Err(NamespaceError::TableNotFound { + message: object_id.to_string(), + } + .into()), } } @@ -1862,9 +1863,10 @@ impl LanceNamespace for ManifestNamespace { if exists { Ok(()) } else { - Err(Error::namespace_source( - format!("Table '{}' not found", table_name).into(), - )) + Err(NamespaceError::TableNotFound { + message: table_name.to_string(), + } + .into()) } } @@ -2010,9 +2012,10 @@ impl LanceNamespace for ManifestNamespace { ..Default::default() }) } - None => Err(Error::namespace_source( - format!("Table '{}' not found", table_name).into(), - )), + None => Err(NamespaceError::TableNotFound { + message: table_name.to_string(), + } + .into()), } } @@ -2438,9 +2441,10 @@ impl LanceNamespace for ManifestNamespace { Self::construct_full_uri(&self.root, &info.location)? } None => { - return Err(Error::namespace_source( - format!("Table '{}' not found", object_id).into(), - )); + return Err(NamespaceError::TableNotFound { + message: object_id.to_string(), + } + .into()); } }; From e30aedd533a8a1ffd5df36e8d2e8160caf2a7fdc Mon Sep 17 00:00:00 2001 From: yangjie01 Date: Tue, 24 Mar 2026 14:15:35 +0800 Subject: [PATCH 2/5] format --- rust/lance-namespace-impls/src/dir.rs | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/rust/lance-namespace-impls/src/dir.rs b/rust/lance-namespace-impls/src/dir.rs index 681f2867d15..187665aa3be 100644 --- a/rust/lance-namespace-impls/src/dir.rs +++ b/rust/lance-namespace-impls/src/dir.rs @@ -2236,12 +2236,7 @@ mod tests { let result = namespace.describe_table(request).await; assert!(result.is_err()); - assert!( - result - .unwrap_err() - .to_string() - .contains("Table not found") - ); + assert!(result.unwrap_err().to_string().contains("Table not found")); } #[tokio::test] @@ -2270,12 +2265,7 @@ mod tests { request.id = Some(vec!["nonexistent".to_string()]); let result = namespace.table_exists(request).await; assert!(result.is_err()); - assert!( - result - .unwrap_err() - .to_string() - .contains("Table not found") - ); + assert!(result.unwrap_err().to_string().contains("Table not found")); } #[tokio::test] From 24f4e218a235290c19e20e4757697b108b11c64a Mon Sep 17 00:00:00 2001 From: yangjie01 Date: Tue, 24 Mar 2026 14:50:58 +0800 Subject: [PATCH 3/5] add type check --- rust/lance-namespace-impls/src/dir.rs | 24 +++++++++++++++---- .../lance-namespace-impls/src/dir/manifest.rs | 20 +++++++++++++--- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/rust/lance-namespace-impls/src/dir.rs b/rust/lance-namespace-impls/src/dir.rs index 187665aa3be..73ec8a9b372 100644 --- a/rust/lance-namespace-impls/src/dir.rs +++ b/rust/lance-namespace-impls/src/dir.rs @@ -2002,10 +2002,24 @@ mod tests { use arrow_ipc::reader::StreamReader; use lance::dataset::Dataset; use lance_core::utils::tempfile::{TempStdDir, TempStrDir}; + use lance_namespace::error::{ErrorCode, NamespaceError}; use lance_namespace::models::{ CreateTableRequest, JsonArrowDataType, JsonArrowField, JsonArrowSchema, ListTablesRequest, }; use lance_namespace::schema::convert_json_arrow_schema; + + /// Assert that a `lance_core::Error` wraps a `NamespaceError::TableNotFound`. + fn assert_table_not_found(err: &lance_core::Error) { + match err { + lance_core::Error::Namespace { source, .. } => { + let ns_err = source + .downcast_ref::() + .expect("source should be NamespaceError"); + assert_eq!(ns_err.code(), ErrorCode::TableNotFound); + } + other => panic!("Expected Namespace error, got: {other}"), + } + } use std::io::Cursor; use std::sync::Arc; @@ -2235,8 +2249,9 @@ mod tests { request.id = Some(vec!["nonexistent".to_string()]); let result = namespace.describe_table(request).await; - assert!(result.is_err()); - assert!(result.unwrap_err().to_string().contains("Table not found")); + let err = result.unwrap_err(); + assert_table_not_found(&err); + assert!(err.to_string().contains("Table not found")); } #[tokio::test] @@ -2264,8 +2279,9 @@ mod tests { let mut request = TableExistsRequest::new(); request.id = Some(vec!["nonexistent".to_string()]); let result = namespace.table_exists(request).await; - assert!(result.is_err()); - assert!(result.unwrap_err().to_string().contains("Table not found")); + let err = result.unwrap_err(); + assert_table_not_found(&err); + assert!(err.to_string().contains("Table not found")); } #[tokio::test] diff --git a/rust/lance-namespace-impls/src/dir/manifest.rs b/rust/lance-namespace-impls/src/dir/manifest.rs index 97aa8b43642..dd893d418d0 100644 --- a/rust/lance-namespace-impls/src/dir/manifest.rs +++ b/rust/lance-namespace-impls/src/dir/manifest.rs @@ -2462,12 +2462,26 @@ mod tests { use bytes::Bytes; use lance_core::utils::tempfile::TempStdDir; use lance_namespace::LanceNamespace; + use lance_namespace::error::{ErrorCode, NamespaceError}; use lance_namespace::models::{ CreateNamespaceRequest, CreateTableRequest, DescribeTableRequest, DropTableRequest, ListTablesRequest, TableExistsRequest, }; use rstest::rstest; + /// Assert that a `lance_core::Error` wraps a `NamespaceError::TableNotFound`. + fn assert_table_not_found(err: &lance_core::Error) { + match err { + lance_core::Error::Namespace { source, .. } => { + let ns_err = source + .downcast_ref::() + .expect("source should be NamespaceError"); + assert_eq!(ns_err.code(), ErrorCode::TableNotFound); + } + other => panic!("Expected Namespace error, got: {other}"), + } + } + fn create_test_ipc_data() -> Vec { use arrow::array::{Int32Array, StringArray}; use arrow::datatypes::{DataType, Field, Schema}; @@ -2555,7 +2569,7 @@ mod tests { let mut request = TableExistsRequest::new(); request.id = Some(vec!["nonexistent".to_string()]); let result = dir_namespace.table_exists(request).await; - assert!(result.is_err()); + assert_table_not_found(&result.unwrap_err()); // Create table let buffer = create_test_ipc_data(); @@ -2591,7 +2605,7 @@ mod tests { let mut request = DescribeTableRequest::new(); request.id = Some(vec!["nonexistent".to_string()]); let result = dir_namespace.describe_table(request).await; - assert!(result.is_err()); + assert_table_not_found(&result.unwrap_err()); // Create table let buffer = create_test_ipc_data(); @@ -2813,7 +2827,7 @@ mod tests { let mut drop_request = DropTableRequest::new(); drop_request.id = Some(vec!["nonexistent".to_string()]); let result = dir_namespace.drop_table(drop_request).await; - assert!(result.is_err()); + assert_table_not_found(&result.unwrap_err()); } #[rstest] From f13e7c81bd6cf66f3a39a65d23bb0cba930b25d6 Mon Sep 17 00:00:00 2001 From: yangjie01 Date: Tue, 24 Mar 2026 15:09:37 +0800 Subject: [PATCH 4/5] fix test --- rust/lance-namespace-impls/src/dir.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rust/lance-namespace-impls/src/dir.rs b/rust/lance-namespace-impls/src/dir.rs index 73ec8a9b372..55ab9e57aa6 100644 --- a/rust/lance-namespace-impls/src/dir.rs +++ b/rust/lance-namespace-impls/src/dir.rs @@ -4644,8 +4644,8 @@ mod tests { ); let err_msg = result.unwrap_err().to_string(); assert!( - err_msg.contains("does not exist"), - "Error should mention table does not exist, got: {}", + err_msg.contains("not found"), + "Error should mention table not found, got: {}", err_msg ); } From 36affa9487af1a1d9eafd7aaba529b44c449b2ca Mon Sep 17 00:00:00 2001 From: yangjie01 Date: Tue, 24 Mar 2026 15:56:14 +0800 Subject: [PATCH 5/5] add new tests --- rust/lance-namespace-impls/src/dir.rs | 21 +++++++++++++++++ .../lance-namespace-impls/src/dir/manifest.rs | 23 +++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/rust/lance-namespace-impls/src/dir.rs b/rust/lance-namespace-impls/src/dir.rs index 55ab9e57aa6..6e6e61674b7 100644 --- a/rust/lance-namespace-impls/src/dir.rs +++ b/rust/lance-namespace-impls/src/dir.rs @@ -3788,6 +3788,27 @@ mod tests { assert!(dataset.is_ok(), "Physical table data should still exist"); } + #[tokio::test] + async fn test_deregister_nonexistent_table_v1() { + use lance_namespace::models::DeregisterTableRequest; + + let temp_dir = TempStdDir::default(); + let temp_path = temp_dir.to_str().unwrap(); + + let namespace = DirectoryNamespaceBuilder::new(temp_path) + .manifest_enabled(false) + .dir_listing_enabled(true) + .build() + .await + .unwrap(); + + let mut request = DeregisterTableRequest::new(); + request.id = Some(vec!["nonexistent".to_string()]); + let err = namespace.deregister_table(request).await.unwrap_err(); + assert_table_not_found(&err); + assert!(err.to_string().contains("Table not found")); + } + #[tokio::test] async fn test_deregister_table_v1_already_deregistered() { use lance_namespace::models::DeregisterTableRequest; diff --git a/rust/lance-namespace-impls/src/dir/manifest.rs b/rust/lance-namespace-impls/src/dir/manifest.rs index dd893d418d0..248edd1edf2 100644 --- a/rust/lance-namespace-impls/src/dir/manifest.rs +++ b/rust/lance-namespace-impls/src/dir/manifest.rs @@ -2830,6 +2830,29 @@ mod tests { assert_table_not_found(&result.unwrap_err()); } + #[rstest] + #[case::with_optimization(true)] + #[case::without_optimization(false)] + #[tokio::test] + async fn test_deregister_nonexistent_table(#[case] inline_optimization: bool) { + use lance_namespace::models::DeregisterTableRequest; + + let temp_dir = TempStdDir::default(); + let temp_path = temp_dir.to_str().unwrap(); + + let dir_namespace = DirectoryNamespaceBuilder::new(temp_path) + .inline_optimization_enabled(inline_optimization) + .build() + .await + .unwrap(); + + let mut request = DeregisterTableRequest::new(); + request.id = Some(vec!["nonexistent".to_string()]); + let err = dir_namespace.deregister_table(request).await.unwrap_err(); + assert_table_not_found(&err); + assert!(err.to_string().contains("Table not found")); + } + #[rstest] #[case::with_optimization(true)] #[case::without_optimization(false)]