mirror of
https://github.com/lancedb/lancedb.git
synced 2026-08-18 12:08:35 +00:00
rust: create_index returns the server-minted job id
BaseTable::create_index and IndexBuilder::execute now return Option<String> -- the job id the server mints when an index build is deferred to a background job (pending vector index on a remote table). Native builds are synchronous and return None; older servers with empty response bodies parse as None. The pyo3 binding forwards the id to python; nodejs keeps its unit return. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+1
-1
@@ -165,7 +165,7 @@ impl Table {
|
||||
if let Some(train) = train {
|
||||
builder = builder.train(train);
|
||||
}
|
||||
builder.execute().await.default_error()
|
||||
builder.execute().await.default_error().map(|_| ())
|
||||
}
|
||||
|
||||
#[napi(catch_unwind)]
|
||||
|
||||
+2
-2
@@ -794,8 +794,8 @@ impl Table {
|
||||
}
|
||||
|
||||
future_into_py(self_.py(), async move {
|
||||
op.execute().await.infer_error()?;
|
||||
Ok(())
|
||||
let job_id = op.execute().await.infer_error()?;
|
||||
Ok(job_id)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -118,8 +118,12 @@ async fn create_empty_table(db: &Connection) -> Result<LanceDbTable> {
|
||||
|
||||
async fn create_index(table: &LanceDbTable) -> Result<()> {
|
||||
// --8<-- [start:create_index]
|
||||
table.create_index(&["vector"], Index::Auto).execute().await
|
||||
table
|
||||
.create_index(&["vector"], Index::Auto)
|
||||
.execute()
|
||||
.await?;
|
||||
// --8<-- [end:create_index]
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn search(table: &LanceDbTable) -> Result<Vec<RecordBatch>> {
|
||||
|
||||
@@ -283,7 +283,10 @@ impl IndexBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
pub async fn execute(self) -> Result<()> {
|
||||
/// Returns the server-minted job id when the index build was deferred to
|
||||
/// a background job (remote tables only); `None` when the build completed
|
||||
/// synchronously within this call.
|
||||
pub async fn execute(self) -> Result<Option<String>> {
|
||||
self.parent.clone().create_index(self).await
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2109,7 +2109,7 @@ impl<S: HttpSend> BaseTable for RemoteTable<S> {
|
||||
Ok(delete_response)
|
||||
}
|
||||
|
||||
async fn create_index(&self, mut index: IndexBuilder) -> Result<()> {
|
||||
async fn create_index(&self, mut index: IndexBuilder) -> Result<Option<String>> {
|
||||
self.check_mutable().await?;
|
||||
let request = self
|
||||
.client
|
||||
@@ -2202,14 +2202,28 @@ impl<S: HttpSend> BaseTable for RemoteTable<S> {
|
||||
|
||||
let (request_id, response) = self.send(request, true).await?;
|
||||
|
||||
self.check_table_response(&request_id, response).await?;
|
||||
let response = self.check_table_response(&request_id, response).await?;
|
||||
|
||||
// The server returns a job id only when the build was deferred to a
|
||||
// background job (pending vector index). Older servers return an
|
||||
// empty body; treat anything unparseable as "no job".
|
||||
#[derive(serde::Deserialize)]
|
||||
struct CreateIndexResponse {
|
||||
job_id: Option<String>,
|
||||
}
|
||||
let job_id = response
|
||||
.text()
|
||||
.await
|
||||
.ok()
|
||||
.and_then(|body| serde_json::from_str::<CreateIndexResponse>(&body).ok())
|
||||
.and_then(|r| r.job_id);
|
||||
|
||||
if let Some(wait_timeout) = index.wait_timeout {
|
||||
let index_name = index.name.unwrap_or_else(|| format!("{}_idx", column));
|
||||
self.wait_for_index(&[&index_name], wait_timeout).await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
Ok(job_id)
|
||||
}
|
||||
|
||||
/// Poll until the columns are fully indexed. Will return Error::Timeout if the columns
|
||||
@@ -4639,6 +4653,42 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_create_index_returns_deferred_job_id() {
|
||||
let table =
|
||||
Table::new_with_handler("my_table", move |request| match request.url().path() {
|
||||
"/v1/table/my_table/describe/" => {
|
||||
let schema = Schema::new(vec![Field::new(
|
||||
"vector",
|
||||
DataType::FixedSizeList(
|
||||
Arc::new(Field::new("item", DataType::Float32, true)),
|
||||
128,
|
||||
),
|
||||
false,
|
||||
)]);
|
||||
http::Response::builder()
|
||||
.status(200)
|
||||
.body(describe_response(&schema))
|
||||
.unwrap()
|
||||
}
|
||||
"/v1/table/my_table/create_index/" => http::Response::builder()
|
||||
.status(200)
|
||||
.body(r#"{"job_id": "0a1b2c3d-4e5f-6789-abcd-ef0123456789"}"#.to_string())
|
||||
.unwrap(),
|
||||
path => panic!("Unexpected path: {}", path),
|
||||
});
|
||||
|
||||
let job_id = table
|
||||
.create_index(&["vector"], Index::IvfPq(Default::default()))
|
||||
.execute()
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
job_id.as_deref(),
|
||||
Some("0a1b2c3d-4e5f-6789-abcd-ef0123456789")
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_create_index_nested_field_paths() {
|
||||
let schema = nested_index_schema();
|
||||
|
||||
@@ -582,7 +582,10 @@ pub trait BaseTable: std::fmt::Display + std::fmt::Debug + Send + Sync {
|
||||
/// Update rows in the table.
|
||||
async fn update(&self, update: UpdateBuilder) -> Result<UpdateResult>;
|
||||
/// Create an index on the provided column(s).
|
||||
async fn create_index(&self, index: IndexBuilder) -> Result<()>;
|
||||
///
|
||||
/// Returns the server-minted job id when the build was deferred to a
|
||||
/// background job (remote tables only); `None` for synchronous builds.
|
||||
async fn create_index(&self, index: IndexBuilder) -> Result<Option<String>>;
|
||||
/// List the indices on the table.
|
||||
async fn list_indices(&self) -> Result<Vec<IndexConfig>>;
|
||||
/// Drop an index from the table.
|
||||
@@ -3031,7 +3034,7 @@ impl BaseTable for NativeTable {
|
||||
Ok(AddResult { version })
|
||||
}
|
||||
|
||||
async fn create_index(&self, opts: IndexBuilder) -> Result<()> {
|
||||
async fn create_index(&self, opts: IndexBuilder) -> Result<Option<String>> {
|
||||
if opts.columns.len() != 1 {
|
||||
return Err(Error::Schema {
|
||||
message: "Multi-column (composite) indices are not yet supported".to_string(),
|
||||
@@ -3054,7 +3057,8 @@ impl BaseTable for NativeTable {
|
||||
}
|
||||
builder.await?;
|
||||
self.dataset.update(dataset);
|
||||
Ok(())
|
||||
// Native builds are synchronous -- there is never a background job.
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
async fn drop_index(&self, index_name: &str) -> Result<()> {
|
||||
|
||||
Reference in New Issue
Block a user