Skip to content

Commit ae62146

Browse files
authored
fix(table): fail closed for query-auth batch vector search (#551)
1 parent f38096a commit ae62146

1 file changed

Lines changed: 53 additions & 0 deletions

File tree

crates/paimon/src/table/vector_search_builder.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,10 @@ impl<'a> BatchVectorSearchBuilder<'a> {
644644
}
645645

646646
pub async fn execute(&self) -> crate::Result<Vec<SearchResult>> {
647+
// Fail closed before validation and empty-table fast paths: batch search
648+
// returns data-derived results outside `TableScan`/`TableRead`.
649+
CoreOptions::new(self.table.schema().options()).ensure_read_authorized()?;
650+
647651
let vector_column =
648652
self.vector_column
649653
.as_deref()
@@ -2364,6 +2368,55 @@ mod tests {
23642368
);
23652369
}
23662370

2371+
#[tokio::test]
2372+
async fn test_batch_vector_search_auth_check_precedes_validation() {
2373+
let table = crate::table::query_auth_table();
2374+
let err = table
2375+
.new_batch_vector_search_builder()
2376+
.execute()
2377+
.await
2378+
.unwrap_err();
2379+
2380+
assert!(
2381+
matches!(err, crate::Error::Unsupported { ref message } if message.contains("query-auth.enabled")),
2382+
"batch vector search must check query auth before validating parameters"
2383+
);
2384+
}
2385+
2386+
#[tokio::test]
2387+
async fn test_batch_vector_search_empty_table_fails_closed_when_query_auth_enabled() {
2388+
let table = crate::table::query_auth_table();
2389+
let err = table
2390+
.new_batch_vector_search_builder()
2391+
.with_vector_column("id")
2392+
.with_query_vectors(vec![vec![1.0]])
2393+
.with_limit(1)
2394+
.execute()
2395+
.await
2396+
.unwrap_err();
2397+
2398+
assert!(
2399+
matches!(err, crate::Error::Unsupported { ref message } if message.contains("query-auth.enabled")),
2400+
"batch vector search must fail closed before the empty-table fast path"
2401+
);
2402+
}
2403+
2404+
#[tokio::test]
2405+
async fn test_batch_vector_search_empty_table_unchanged_without_query_auth() {
2406+
let table = vector_test_table();
2407+
let results = table
2408+
.new_batch_vector_search_builder()
2409+
.with_vector_column("embedding")
2410+
.with_query_vectors(vec![vec![1.0]])
2411+
.with_limit(1)
2412+
.execute()
2413+
.await
2414+
.unwrap();
2415+
2416+
assert_eq!(results.len(), 1);
2417+
assert!(results[0].is_empty());
2418+
}
2419+
23672420
#[tokio::test]
23682421
async fn test_batch_evaluate_no_matching_field_returns_empty_per_query() {
23692422
let file_io = crate::io::FileIOBuilder::new("memory").build().unwrap();

0 commit comments

Comments
 (0)