Skip to main content

lance_namespace/
namespace.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright The Lance Authors
3
4//! Lance Namespace base interface and implementations.
5
6use async_trait::async_trait;
7use bytes::Bytes;
8use lance_core::{Error, Result};
9
10use lance_namespace_reqwest_client::models::{
11    AlterTableAddColumnsRequest, AlterTableAddColumnsResponse, AlterTableAlterColumnsRequest,
12    AlterTableAlterColumnsResponse, AlterTableDropColumnsRequest, AlterTableDropColumnsResponse,
13    AlterTransactionRequest, AlterTransactionResponse, AnalyzeTableQueryPlanRequest,
14    BatchDeleteTableVersionsRequest, BatchDeleteTableVersionsResponse, CountTableRowsRequest,
15    CreateNamespaceRequest, CreateNamespaceResponse, CreateTableIndexRequest,
16    CreateTableIndexResponse, CreateTableRequest, CreateTableResponse,
17    CreateTableScalarIndexResponse, CreateTableTagRequest, CreateTableTagResponse,
18    CreateTableVersionRequest, CreateTableVersionResponse, DeclareTableRequest,
19    DeclareTableResponse, DeleteFromTableRequest, DeleteFromTableResponse, DeleteTableTagRequest,
20    DeleteTableTagResponse, DeregisterTableRequest, DeregisterTableResponse,
21    DescribeNamespaceRequest, DescribeNamespaceResponse, DescribeTableIndexStatsRequest,
22    DescribeTableIndexStatsResponse, DescribeTableRequest, DescribeTableResponse,
23    DescribeTableVersionRequest, DescribeTableVersionResponse, DescribeTransactionRequest,
24    DescribeTransactionResponse, DropNamespaceRequest, DropNamespaceResponse,
25    DropTableIndexRequest, DropTableIndexResponse, DropTableRequest, DropTableResponse,
26    ExplainTableQueryPlanRequest, GetTableStatsRequest, GetTableStatsResponse,
27    GetTableTagVersionRequest, GetTableTagVersionResponse, InsertIntoTableRequest,
28    InsertIntoTableResponse, ListNamespacesRequest, ListNamespacesResponse,
29    ListTableIndicesRequest, ListTableIndicesResponse, ListTableTagsRequest, ListTableTagsResponse,
30    ListTableVersionsRequest, ListTableVersionsResponse, ListTablesRequest, ListTablesResponse,
31    MergeInsertIntoTableRequest, MergeInsertIntoTableResponse, NamespaceExistsRequest,
32    QueryTableRequest, RegisterTableRequest, RegisterTableResponse, RenameTableRequest,
33    RenameTableResponse, RestoreTableRequest, RestoreTableResponse, TableExistsRequest,
34    UpdateTableRequest, UpdateTableResponse, UpdateTableSchemaMetadataRequest,
35    UpdateTableSchemaMetadataResponse, UpdateTableTagRequest, UpdateTableTagResponse,
36};
37
38/// Base trait for Lance Namespace implementations.
39///
40/// This trait defines the interface that all Lance namespace implementations
41/// must provide. Each method corresponds to a specific operation on namespaces
42/// or tables.
43///
44/// # Error Handling
45///
46/// All operations may return the following common errors (via [`crate::NamespaceError`]):
47///
48/// - [`crate::ErrorCode::Unsupported`] - Operation not supported by this backend
49/// - [`crate::ErrorCode::InvalidInput`] - Invalid request parameters
50/// - [`crate::ErrorCode::PermissionDenied`] - Insufficient permissions
51/// - [`crate::ErrorCode::Unauthenticated`] - Invalid credentials
52/// - [`crate::ErrorCode::ServiceUnavailable`] - Service temporarily unavailable
53/// - [`crate::ErrorCode::Internal`] - Unexpected internal error
54///
55/// See individual method documentation for operation-specific errors.
56#[async_trait]
57pub trait LanceNamespace: Send + Sync + std::fmt::Debug {
58    /// List namespaces.
59    ///
60    /// # Errors
61    ///
62    /// Returns [`crate::ErrorCode::NamespaceNotFound`] if the parent namespace does not exist.
63    async fn list_namespaces(
64        &self,
65        _request: ListNamespacesRequest,
66    ) -> Result<ListNamespacesResponse> {
67        Err(Error::not_supported("list_namespaces not implemented"))
68    }
69
70    /// Describe a namespace.
71    ///
72    /// # Errors
73    ///
74    /// Returns [`crate::ErrorCode::NamespaceNotFound`] if the namespace does not exist.
75    async fn describe_namespace(
76        &self,
77        _request: DescribeNamespaceRequest,
78    ) -> Result<DescribeNamespaceResponse> {
79        Err(Error::not_supported("describe_namespace not implemented"))
80    }
81
82    /// Create a new namespace.
83    ///
84    /// # Errors
85    ///
86    /// Returns [`crate::ErrorCode::NamespaceAlreadyExists`] if a namespace with the same name already exists.
87    async fn create_namespace(
88        &self,
89        _request: CreateNamespaceRequest,
90    ) -> Result<CreateNamespaceResponse> {
91        Err(Error::not_supported("create_namespace not implemented"))
92    }
93
94    /// Drop a namespace.
95    ///
96    /// # Errors
97    ///
98    /// - [`crate::ErrorCode::NamespaceNotFound`] if the namespace does not exist.
99    /// - [`crate::ErrorCode::NamespaceNotEmpty`] if the namespace contains tables or child namespaces.
100    async fn drop_namespace(
101        &self,
102        _request: DropNamespaceRequest,
103    ) -> Result<DropNamespaceResponse> {
104        Err(Error::not_supported("drop_namespace not implemented"))
105    }
106
107    /// Check if a namespace exists.
108    ///
109    /// # Errors
110    ///
111    /// Returns [`crate::ErrorCode::NamespaceNotFound`] if the namespace does not exist.
112    async fn namespace_exists(&self, _request: NamespaceExistsRequest) -> Result<()> {
113        Err(Error::not_supported("namespace_exists not implemented"))
114    }
115
116    /// List tables in a namespace.
117    async fn list_tables(&self, _request: ListTablesRequest) -> Result<ListTablesResponse> {
118        Err(Error::not_supported("list_tables not implemented"))
119    }
120
121    /// Describe a table.
122    async fn describe_table(
123        &self,
124        _request: DescribeTableRequest,
125    ) -> Result<DescribeTableResponse> {
126        Err(Error::not_supported("describe_table not implemented"))
127    }
128
129    /// Register a table.
130    async fn register_table(
131        &self,
132        _request: RegisterTableRequest,
133    ) -> Result<RegisterTableResponse> {
134        Err(Error::not_supported("register_table not implemented"))
135    }
136
137    /// Check if a table exists.
138    async fn table_exists(&self, _request: TableExistsRequest) -> Result<()> {
139        Err(Error::not_supported("table_exists not implemented"))
140    }
141
142    /// Drop a table.
143    async fn drop_table(&self, _request: DropTableRequest) -> Result<DropTableResponse> {
144        Err(Error::not_supported("drop_table not implemented"))
145    }
146
147    /// Deregister a table.
148    async fn deregister_table(
149        &self,
150        _request: DeregisterTableRequest,
151    ) -> Result<DeregisterTableResponse> {
152        Err(Error::not_supported("deregister_table not implemented"))
153    }
154
155    /// Count rows in a table.
156    async fn count_table_rows(&self, _request: CountTableRowsRequest) -> Result<i64> {
157        Err(Error::not_supported("count_table_rows not implemented"))
158    }
159
160    /// Create a new table with data from Arrow IPC stream.
161    async fn create_table(
162        &self,
163        _request: CreateTableRequest,
164        _request_data: Bytes,
165    ) -> Result<CreateTableResponse> {
166        Err(Error::not_supported("create_table not implemented"))
167    }
168
169    /// Declare a table (metadata only operation).
170    async fn declare_table(&self, _request: DeclareTableRequest) -> Result<DeclareTableResponse> {
171        Err(Error::not_supported("declare_table not implemented"))
172    }
173
174    /// Insert data into a table.
175    async fn insert_into_table(
176        &self,
177        _request: InsertIntoTableRequest,
178        _request_data: Bytes,
179    ) -> Result<InsertIntoTableResponse> {
180        Err(Error::not_supported("insert_into_table not implemented"))
181    }
182
183    /// Merge insert data into a table.
184    async fn merge_insert_into_table(
185        &self,
186        _request: MergeInsertIntoTableRequest,
187        _request_data: Bytes,
188    ) -> Result<MergeInsertIntoTableResponse> {
189        Err(Error::not_supported(
190            "merge_insert_into_table not implemented",
191        ))
192    }
193
194    /// Update a table.
195    async fn update_table(&self, _request: UpdateTableRequest) -> Result<UpdateTableResponse> {
196        Err(Error::not_supported("update_table not implemented"))
197    }
198
199    /// Delete from a table.
200    async fn delete_from_table(
201        &self,
202        _request: DeleteFromTableRequest,
203    ) -> Result<DeleteFromTableResponse> {
204        Err(Error::not_supported("delete_from_table not implemented"))
205    }
206
207    /// Query a table.
208    async fn query_table(&self, _request: QueryTableRequest) -> Result<Bytes> {
209        Err(Error::not_supported("query_table not implemented"))
210    }
211
212    /// Create a table index.
213    async fn create_table_index(
214        &self,
215        _request: CreateTableIndexRequest,
216    ) -> Result<CreateTableIndexResponse> {
217        Err(Error::not_supported("create_table_index not implemented"))
218    }
219
220    /// List table indices.
221    async fn list_table_indices(
222        &self,
223        _request: ListTableIndicesRequest,
224    ) -> Result<ListTableIndicesResponse> {
225        Err(Error::not_supported("list_table_indices not implemented"))
226    }
227
228    /// Describe table index statistics.
229    async fn describe_table_index_stats(
230        &self,
231        _request: DescribeTableIndexStatsRequest,
232    ) -> Result<DescribeTableIndexStatsResponse> {
233        Err(Error::not_supported(
234            "describe_table_index_stats not implemented",
235        ))
236    }
237
238    /// Describe a transaction.
239    async fn describe_transaction(
240        &self,
241        _request: DescribeTransactionRequest,
242    ) -> Result<DescribeTransactionResponse> {
243        Err(Error::not_supported("describe_transaction not implemented"))
244    }
245
246    /// Alter a transaction.
247    async fn alter_transaction(
248        &self,
249        _request: AlterTransactionRequest,
250    ) -> Result<AlterTransactionResponse> {
251        Err(Error::not_supported("alter_transaction not implemented"))
252    }
253
254    /// Create a scalar index on a table.
255    async fn create_table_scalar_index(
256        &self,
257        _request: CreateTableIndexRequest,
258    ) -> Result<CreateTableScalarIndexResponse> {
259        Err(Error::not_supported(
260            "create_table_scalar_index not implemented",
261        ))
262    }
263
264    /// Drop a table index.
265    async fn drop_table_index(
266        &self,
267        _request: DropTableIndexRequest,
268    ) -> Result<DropTableIndexResponse> {
269        Err(Error::not_supported("drop_table_index not implemented"))
270    }
271
272    /// List all tables across all namespaces.
273    async fn list_all_tables(&self, _request: ListTablesRequest) -> Result<ListTablesResponse> {
274        Err(Error::not_supported("list_all_tables not implemented"))
275    }
276
277    /// Restore a table to a specific version.
278    async fn restore_table(&self, _request: RestoreTableRequest) -> Result<RestoreTableResponse> {
279        Err(Error::not_supported("restore_table not implemented"))
280    }
281
282    /// Rename a table.
283    async fn rename_table(&self, _request: RenameTableRequest) -> Result<RenameTableResponse> {
284        Err(Error::not_supported("rename_table not implemented"))
285    }
286
287    /// List all versions of a table.
288    async fn list_table_versions(
289        &self,
290        _request: ListTableVersionsRequest,
291    ) -> Result<ListTableVersionsResponse> {
292        Err(Error::not_supported("list_table_versions not implemented"))
293    }
294
295    /// Create a new table version entry.
296    ///
297    /// This operation supports `put_if_not_exists` semantics, where the operation
298    /// fails if the version already exists. This is used to coordinate concurrent
299    /// writes to a table through an external manifest store.
300    ///
301    /// # Arguments
302    ///
303    /// * `request` - Contains the table identifier, version number, manifest path,
304    ///   and optional metadata like size and ETag.
305    ///
306    /// # Errors
307    ///
308    /// - Returns an error if the version already exists (conflict).
309    /// - Returns [`crate::ErrorCode::TableNotFound`] if the table does not exist.
310    async fn create_table_version(
311        &self,
312        _request: CreateTableVersionRequest,
313    ) -> Result<CreateTableVersionResponse> {
314        Err(Error::not_supported("create_table_version not implemented"))
315    }
316
317    /// Describe a specific table version.
318    ///
319    /// Returns metadata about a specific version of a table, including the
320    /// manifest path, size, ETag, and timestamp.
321    ///
322    /// # Arguments
323    ///
324    /// * `request` - Contains the table identifier and optionally the version
325    ///   number. If version is not specified, returns the latest version.
326    ///
327    /// # Errors
328    ///
329    /// - Returns [`crate::ErrorCode::TableNotFound`] if the table does not exist.
330    /// - Returns an error if the specified version does not exist.
331    async fn describe_table_version(
332        &self,
333        _request: DescribeTableVersionRequest,
334    ) -> Result<DescribeTableVersionResponse> {
335        Err(Error::not_supported(
336            "describe_table_version not implemented",
337        ))
338    }
339
340    /// Batch delete table versions.
341    ///
342    /// Deletes multiple version records from a table. This operation supports
343    /// deleting ranges of versions for efficient bulk cleanup.
344    ///
345    /// # Arguments
346    ///
347    /// * `request` - Contains the table identifier and version ranges to delete.
348    ///
349    /// # Errors
350    ///
351    /// - Returns [`crate::ErrorCode::TableNotFound`] if the table does not exist.
352    async fn batch_delete_table_versions(
353        &self,
354        _request: BatchDeleteTableVersionsRequest,
355    ) -> Result<BatchDeleteTableVersionsResponse> {
356        Err(Error::not_supported(
357            "batch_delete_table_versions not implemented",
358        ))
359    }
360
361    /// Update table schema metadata.
362    async fn update_table_schema_metadata(
363        &self,
364        _request: UpdateTableSchemaMetadataRequest,
365    ) -> Result<UpdateTableSchemaMetadataResponse> {
366        Err(Error::not_supported(
367            "update_table_schema_metadata not implemented",
368        ))
369    }
370
371    /// Get table statistics.
372    async fn get_table_stats(
373        &self,
374        _request: GetTableStatsRequest,
375    ) -> Result<GetTableStatsResponse> {
376        Err(Error::not_supported("get_table_stats not implemented"))
377    }
378
379    /// Explain a table query plan.
380    async fn explain_table_query_plan(
381        &self,
382        _request: ExplainTableQueryPlanRequest,
383    ) -> Result<String> {
384        Err(Error::not_supported(
385            "explain_table_query_plan not implemented",
386        ))
387    }
388
389    /// Analyze a table query plan.
390    async fn analyze_table_query_plan(
391        &self,
392        _request: AnalyzeTableQueryPlanRequest,
393    ) -> Result<String> {
394        Err(Error::not_supported(
395            "analyze_table_query_plan not implemented",
396        ))
397    }
398
399    /// Add columns to a table.
400    async fn alter_table_add_columns(
401        &self,
402        _request: AlterTableAddColumnsRequest,
403    ) -> Result<AlterTableAddColumnsResponse> {
404        Err(Error::not_supported(
405            "alter_table_add_columns not implemented",
406        ))
407    }
408
409    /// Alter columns in a table.
410    async fn alter_table_alter_columns(
411        &self,
412        _request: AlterTableAlterColumnsRequest,
413    ) -> Result<AlterTableAlterColumnsResponse> {
414        Err(Error::not_supported(
415            "alter_table_alter_columns not implemented",
416        ))
417    }
418
419    /// Drop columns from a table.
420    async fn alter_table_drop_columns(
421        &self,
422        _request: AlterTableDropColumnsRequest,
423    ) -> Result<AlterTableDropColumnsResponse> {
424        Err(Error::not_supported(
425            "alter_table_drop_columns not implemented",
426        ))
427    }
428
429    /// List all tags for a table.
430    async fn list_table_tags(
431        &self,
432        _request: ListTableTagsRequest,
433    ) -> Result<ListTableTagsResponse> {
434        Err(Error::not_supported("list_table_tags not implemented"))
435    }
436
437    /// Get the version for a specific tag.
438    async fn get_table_tag_version(
439        &self,
440        _request: GetTableTagVersionRequest,
441    ) -> Result<GetTableTagVersionResponse> {
442        Err(Error::not_supported(
443            "get_table_tag_version not implemented",
444        ))
445    }
446
447    /// Create a tag for a table.
448    async fn create_table_tag(
449        &self,
450        _request: CreateTableTagRequest,
451    ) -> Result<CreateTableTagResponse> {
452        Err(Error::not_supported("create_table_tag not implemented"))
453    }
454
455    /// Delete a tag from a table.
456    async fn delete_table_tag(
457        &self,
458        _request: DeleteTableTagRequest,
459    ) -> Result<DeleteTableTagResponse> {
460        Err(Error::not_supported("delete_table_tag not implemented"))
461    }
462
463    /// Update a tag for a table.
464    async fn update_table_tag(
465        &self,
466        _request: UpdateTableTagRequest,
467    ) -> Result<UpdateTableTagResponse> {
468        Err(Error::not_supported("update_table_tag not implemented"))
469    }
470
471    /// Return a human-readable unique identifier for this namespace instance.
472    ///
473    /// This is used for equality comparison and hashing when the namespace is
474    /// used as part of a storage options provider. Two namespace instances with
475    /// the same ID are considered equal and will share cached resources.
476    ///
477    /// The ID should be human-readable for debugging and logging purposes.
478    /// For example:
479    /// - REST namespace: `"rest(endpoint=https://api.example.com)"`
480    /// - Directory namespace: `"dir(root=/path/to/data)"`
481    ///
482    /// Implementations should include all configuration that uniquely identifies
483    /// the namespace to provide semantic equality.
484    fn namespace_id(&self) -> String;
485}