Compare commits

..

6 Commits

Author SHA1 Message Date
Wyatt Alt bc76671b62 add nodejs test 2026-02-28 22:18:37 -08:00
Wyatt Alt bc814e1f66 lint js docs 2026-02-28 21:50:40 -08:00
Wyatt Alt 82a6e5a196 doctest update 2026-02-28 20:25:29 -08:00
Wyatt Alt b3100f0e7c add test 2026-02-28 19:26:00 -08:00
Wyatt Alt 8ec60e3c9d feat: add num_deleted to delete result 2026-02-28 19:26:00 -08:00
Lance Release 0498ac1f2f Bump version: 0.27.0-beta.2 → 0.27.0-beta.3 2026-02-28 01:31:51 +00:00
23 changed files with 103 additions and 27 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
[tool.bumpversion] [tool.bumpversion]
current_version = "0.27.0-beta.2" current_version = "0.27.0-beta.3"
parse = """(?x) parse = """(?x)
(?P<major>0|[1-9]\\d*)\\. (?P<major>0|[1-9]\\d*)\\.
(?P<minor>0|[1-9]\\d*)\\. (?P<minor>0|[1-9]\\d*)\\.
Generated
+3 -3
View File
@@ -4749,7 +4749,7 @@ dependencies = [
[[package]] [[package]]
name = "lancedb" name = "lancedb"
version = "0.27.0-beta.2" version = "0.27.0-beta.3"
dependencies = [ dependencies = [
"ahash", "ahash",
"anyhow", "anyhow",
@@ -4831,7 +4831,7 @@ dependencies = [
[[package]] [[package]]
name = "lancedb-nodejs" name = "lancedb-nodejs"
version = "0.27.0-beta.2" version = "0.27.0-beta.3"
dependencies = [ dependencies = [
"arrow-array", "arrow-array",
"arrow-ipc", "arrow-ipc",
@@ -4851,7 +4851,7 @@ dependencies = [
[[package]] [[package]]
name = "lancedb-python" name = "lancedb-python"
version = "0.30.0-beta.2" version = "0.30.0-beta.3"
dependencies = [ dependencies = [
"arrow", "arrow",
"async-trait", "async-trait",
+1 -1
View File
@@ -14,7 +14,7 @@ Add the following dependency to your `pom.xml`:
<dependency> <dependency>
<groupId>com.lancedb</groupId> <groupId>com.lancedb</groupId>
<artifactId>lancedb-core</artifactId> <artifactId>lancedb-core</artifactId>
<version>0.27.0-beta.2</version> <version>0.27.0-beta.3</version>
</dependency> </dependency>
``` ```
+8
View File
@@ -8,6 +8,14 @@
## Properties ## Properties
### numDeletedRows
```ts
numDeletedRows: number;
```
***
### version ### version
```ts ```ts
+1 -1
View File
@@ -8,7 +8,7 @@
<parent> <parent>
<groupId>com.lancedb</groupId> <groupId>com.lancedb</groupId>
<artifactId>lancedb-parent</artifactId> <artifactId>lancedb-parent</artifactId>
<version>0.27.0-beta.2</version> <version>0.27.0-beta.3</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
+1 -1
View File
@@ -6,7 +6,7 @@
<groupId>com.lancedb</groupId> <groupId>com.lancedb</groupId>
<artifactId>lancedb-parent</artifactId> <artifactId>lancedb-parent</artifactId>
<version>0.27.0-beta.2</version> <version>0.27.0-beta.3</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>${project.artifactId}</name> <name>${project.artifactId}</name>
<description>LanceDB Java SDK Parent POM</description> <description>LanceDB Java SDK Parent POM</description>
+1 -1
View File
@@ -1,7 +1,7 @@
[package] [package]
name = "lancedb-nodejs" name = "lancedb-nodejs"
edition.workspace = true edition.workspace = true
version = "0.27.0-beta.2" version = "0.27.0-beta.3"
license.workspace = true license.workspace = true
description.workspace = true description.workspace = true
repository.workspace = true repository.workspace = true
+25
View File
@@ -450,6 +450,31 @@ describe.each([arrow15, arrow16, arrow17, arrow18])(
}, },
); );
describe("delete", () => {
let tmpDir: tmp.DirResult;
let table: Table;
beforeEach(async () => {
tmpDir = tmp.dirSync({ unsafeCleanup: true });
const conn = await connect(tmpDir.name);
table = await conn.createTable("delete_test", [
{ id: 1, value: "a" },
{ id: 2, value: "b" },
{ id: 3, value: "c" },
{ id: 4, value: "d" },
{ id: 5, value: "e" },
]);
});
afterEach(() => tmpDir.removeCallback());
test("returns num_deleted_rows", async () => {
const result = await table.delete("id > 3");
expect(result.numDeletedRows).toBe(2);
expect(result.version).toBe(2);
expect(await table.countRows()).toBe(3);
});
});
describe("merge insert", () => { describe("merge insert", () => {
let tmpDir: tmp.DirResult; let tmpDir: tmp.DirResult;
let table: Table; let table: Table;
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@lancedb/lancedb-darwin-arm64", "name": "@lancedb/lancedb-darwin-arm64",
"version": "0.27.0-beta.2", "version": "0.27.0-beta.3",
"os": ["darwin"], "os": ["darwin"],
"cpu": ["arm64"], "cpu": ["arm64"],
"main": "lancedb.darwin-arm64.node", "main": "lancedb.darwin-arm64.node",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@lancedb/lancedb-linux-arm64-gnu", "name": "@lancedb/lancedb-linux-arm64-gnu",
"version": "0.27.0-beta.2", "version": "0.27.0-beta.3",
"os": ["linux"], "os": ["linux"],
"cpu": ["arm64"], "cpu": ["arm64"],
"main": "lancedb.linux-arm64-gnu.node", "main": "lancedb.linux-arm64-gnu.node",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@lancedb/lancedb-linux-arm64-musl", "name": "@lancedb/lancedb-linux-arm64-musl",
"version": "0.27.0-beta.2", "version": "0.27.0-beta.3",
"os": ["linux"], "os": ["linux"],
"cpu": ["arm64"], "cpu": ["arm64"],
"main": "lancedb.linux-arm64-musl.node", "main": "lancedb.linux-arm64-musl.node",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@lancedb/lancedb-linux-x64-gnu", "name": "@lancedb/lancedb-linux-x64-gnu",
"version": "0.27.0-beta.2", "version": "0.27.0-beta.3",
"os": ["linux"], "os": ["linux"],
"cpu": ["x64"], "cpu": ["x64"],
"main": "lancedb.linux-x64-gnu.node", "main": "lancedb.linux-x64-gnu.node",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@lancedb/lancedb-linux-x64-musl", "name": "@lancedb/lancedb-linux-x64-musl",
"version": "0.27.0-beta.2", "version": "0.27.0-beta.3",
"os": ["linux"], "os": ["linux"],
"cpu": ["x64"], "cpu": ["x64"],
"main": "lancedb.linux-x64-musl.node", "main": "lancedb.linux-x64-musl.node",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@lancedb/lancedb-win32-arm64-msvc", "name": "@lancedb/lancedb-win32-arm64-msvc",
"version": "0.27.0-beta.2", "version": "0.27.0-beta.3",
"os": [ "os": [
"win32" "win32"
], ],
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@lancedb/lancedb-win32-x64-msvc", "name": "@lancedb/lancedb-win32-x64-msvc",
"version": "0.27.0-beta.2", "version": "0.27.0-beta.3",
"os": ["win32"], "os": ["win32"],
"cpu": ["x64"], "cpu": ["x64"],
"main": "lancedb.win32-x64-msvc.node", "main": "lancedb.win32-x64-msvc.node",
+2 -2
View File
@@ -1,12 +1,12 @@
{ {
"name": "@lancedb/lancedb", "name": "@lancedb/lancedb",
"version": "0.27.0-beta.2", "version": "0.27.0-beta.3",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@lancedb/lancedb", "name": "@lancedb/lancedb",
"version": "0.27.0-beta.2", "version": "0.27.0-beta.3",
"cpu": [ "cpu": [
"x64", "x64",
"arm64" "arm64"
+1 -1
View File
@@ -11,7 +11,7 @@
"ann" "ann"
], ],
"private": false, "private": false,
"version": "0.27.0-beta.2", "version": "0.27.0-beta.3",
"main": "dist/index.js", "main": "dist/index.js",
"exports": { "exports": {
".": "./dist/index.js", ".": "./dist/index.js",
+2
View File
@@ -753,12 +753,14 @@ impl From<lancedb::table::AddResult> for AddResult {
#[napi(object)] #[napi(object)]
pub struct DeleteResult { pub struct DeleteResult {
pub num_deleted_rows: i64,
pub version: i64, pub version: i64,
} }
impl From<lancedb::table::DeleteResult> for DeleteResult { impl From<lancedb::table::DeleteResult> for DeleteResult {
fn from(value: lancedb::table::DeleteResult) -> Self { fn from(value: lancedb::table::DeleteResult) -> Self {
Self { Self {
num_deleted_rows: value.num_deleted_rows as i64,
version: value.version as i64, version: value.version as i64,
} }
} }
+4 -4
View File
@@ -1331,7 +1331,7 @@ class Table(ABC):
1 2 [3.0, 4.0] 1 2 [3.0, 4.0]
2 3 [5.0, 6.0] 2 3 [5.0, 6.0]
>>> table.delete("x = 2") >>> table.delete("x = 2")
DeleteResult(version=2) DeleteResult(num_deleted_rows=1, version=2)
>>> table.to_pandas() >>> table.to_pandas()
x vector x vector
0 1 [1.0, 2.0] 0 1 [1.0, 2.0]
@@ -1345,7 +1345,7 @@ class Table(ABC):
>>> to_remove >>> to_remove
'1, 5' '1, 5'
>>> table.delete(f"x IN ({to_remove})") >>> table.delete(f"x IN ({to_remove})")
DeleteResult(version=3) DeleteResult(num_deleted_rows=1, version=3)
>>> table.to_pandas() >>> table.to_pandas()
x vector x vector
0 3 [5.0, 6.0] 0 3 [5.0, 6.0]
@@ -4215,7 +4215,7 @@ class AsyncTable:
1 2 [3.0, 4.0] 1 2 [3.0, 4.0]
2 3 [5.0, 6.0] 2 3 [5.0, 6.0]
>>> table.delete("x = 2") >>> table.delete("x = 2")
DeleteResult(version=2) DeleteResult(num_deleted_rows=1, version=2)
>>> table.to_pandas() >>> table.to_pandas()
x vector x vector
0 1 [1.0, 2.0] 0 1 [1.0, 2.0]
@@ -4229,7 +4229,7 @@ class AsyncTable:
>>> to_remove >>> to_remove
'1, 5' '1, 5'
>>> table.delete(f"x IN ({to_remove})") >>> table.delete(f"x IN ({to_remove})")
DeleteResult(version=3) DeleteResult(num_deleted_rows=1, version=3)
>>> table.to_pandas() >>> table.to_pandas()
x vector x vector
0 3 [5.0, 6.0] 0 3 [5.0, 6.0]
+6 -1
View File
@@ -112,19 +112,24 @@ impl From<lancedb::table::AddResult> for AddResult {
#[pyclass(get_all)] #[pyclass(get_all)]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct DeleteResult { pub struct DeleteResult {
pub num_deleted_rows: u64,
pub version: u64, pub version: u64,
} }
#[pymethods] #[pymethods]
impl DeleteResult { impl DeleteResult {
pub fn __repr__(&self) -> String { pub fn __repr__(&self) -> String {
format!("DeleteResult(version={})", self.version) format!(
"DeleteResult(num_deleted_rows={}, version={})",
self.num_deleted_rows, self.version
)
} }
} }
impl From<lancedb::table::DeleteResult> for DeleteResult { impl From<lancedb::table::DeleteResult> for DeleteResult {
fn from(result: lancedb::table::DeleteResult) -> Self { fn from(result: lancedb::table::DeleteResult) -> Self {
Self { Self {
num_deleted_rows: result.num_deleted_rows,
version: result.version, version: result.version,
} }
} }
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "lancedb" name = "lancedb"
version = "0.27.0-beta.2" version = "0.27.0-beta.3"
edition.workspace = true edition.workspace = true
description = "LanceDB: A serverless, low-latency vector database for AI applications" description = "LanceDB: A serverless, low-latency vector database for AI applications"
license.workspace = true license.workspace = true
+4 -1
View File
@@ -1227,7 +1227,10 @@ impl<S: HttpSend> BaseTable for RemoteTable<S> {
let body = response.text().await.err_to_http(request_id.clone())?; let body = response.text().await.err_to_http(request_id.clone())?;
if body.trim().is_empty() { if body.trim().is_empty() {
// Backward compatible with old servers // Backward compatible with old servers
return Ok(DeleteResult { version: 0 }); return Ok(DeleteResult {
num_deleted_rows: 0,
version: 0,
});
} }
let delete_response: DeleteResult = let delete_response: DeleteResult =
serde_json::from_str(&body).map_err(|e| Error::Http { serde_json::from_str(&body).map_err(|e| Error::Http {
+35 -2
View File
@@ -7,6 +7,9 @@ use crate::Result;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
pub struct DeleteResult { pub struct DeleteResult {
/// The number of rows that were deleted.
#[serde(default)]
pub num_deleted_rows: u64,
// The commit version associated with the operation. // The commit version associated with the operation.
// A version of `0` indicates compatibility with legacy servers that do not return // A version of `0` indicates compatibility with legacy servers that do not return
/// a commit version. /// a commit version.
@@ -20,10 +23,14 @@ pub struct DeleteResult {
pub(crate) async fn execute_delete(table: &NativeTable, predicate: &str) -> Result<DeleteResult> { pub(crate) async fn execute_delete(table: &NativeTable, predicate: &str) -> Result<DeleteResult> {
table.dataset.ensure_mutable()?; table.dataset.ensure_mutable()?;
let mut dataset = (*table.dataset.get().await?).clone(); let mut dataset = (*table.dataset.get().await?).clone();
dataset.delete(predicate).await?; let delete_result = dataset.delete(predicate).await?;
let num_deleted_rows = delete_result.num_deleted_rows;
let version = dataset.version().version; let version = dataset.version().version;
table.dataset.update(dataset); table.dataset.update(dataset);
Ok(DeleteResult { version }) Ok(DeleteResult {
num_deleted_rows,
version,
})
} }
#[cfg(test)] #[cfg(test)]
@@ -108,6 +115,32 @@ mod tests {
assert_eq!(current_schema, original_schema); assert_eq!(current_schema, original_schema);
} }
#[tokio::test]
async fn test_delete_returns_num_deleted_rows() {
let conn = connect("memory://").execute().await.unwrap();
let batch = record_batch!(("id", Int32, [1, 2, 3, 4, 5])).unwrap();
let table = conn
.create_table("test_num_deleted", batch)
.execute()
.await
.unwrap();
// Delete 2 rows (id > 3 means id=4 and id=5)
let result = table.delete("id > 3").await.unwrap();
assert_eq!(result.num_deleted_rows, 2);
assert_eq!(table.count_rows(None).await.unwrap(), 3);
// Delete 0 rows (no rows match)
let result = table.delete("id > 100").await.unwrap();
assert_eq!(result.num_deleted_rows, 0);
assert_eq!(table.count_rows(None).await.unwrap(), 3);
// Delete remaining rows
let result = table.delete("true").await.unwrap();
assert_eq!(result.num_deleted_rows, 3);
assert_eq!(table.count_rows(None).await.unwrap(), 0);
}
#[tokio::test] #[tokio::test]
async fn test_delete_false_increments_version() { async fn test_delete_false_increments_version() {
let conn = connect("memory://").execute().await.unwrap(); let conn = connect("memory://").execute().await.unwrap();