Skip to content

feat(DirectoryNamespace): implement update_table and delete_from_table DML methods #6922

@XuQianJin-Stars

Description

@XuQianJin-Stars

Summary

DirectoryNamespace (the filesystem-backed LanceNamespace implementation in
rust/lance-namespace-impls/src/dir.rs) currently falls back to the trait's
default not_supported implementation for two DML operations:

  • update_table(UpdateTableRequest) -> UpdateTableResponse
  • delete_from_table(DeleteFromTableRequest) -> DeleteFromTableResponse

Both methods are already wired through the Java side
(DirectoryNamespace.java updateTable / deleteFromTable) and exposed by the
lance-namespace-reqwest-client model, but calling them today returns
OperationNotSupported. This issue tracks adding the Rust-side implementation
so users of dir:// namespaces can perform row-level updates and deletes
through the namespace API, on par with what Dataset::update /
Dataset::delete already provide for direct dataset access.

Motivation

  • DML is a baseline capability for any catalog; without it the directory
    namespace cannot back interactive workflows or downstream systems
    (e.g. GooseFS / LanceDB integrations) that drive Lance via the namespace
    trait.
  • The underlying primitives (UpdateBuilder, Dataset::delete) are stable
    and well-tested in lance core — exposing them through the namespace layer
    is a small, isolated piece of work with no schema/metadata changes.
  • Closes the first two unsupported operations listed in
    LANCE_UNSUPPORTED_OPS.md §1.2.

Proposed API behavior

update_table

Field Source / Validation
id resolved via existing namespace path resolution; missing → TableNotFound
updates: List<List<String>> each inner list must be [column, expression]; non-empty, no duplicate columns, no empty column names → InvalidInput
predicate? optional; if present, applied through UpdateBuilder::update_where
Response.updated_rows metrics.rows_updated from UpdateBuilder::execute()
Response.version new dataset version after commit

delete_from_table

Field Source / Validation
id resolved as above
predicate required, non-empty / non-whitespace → otherwise InvalidInput
Response.version new dataset version after Dataset::delete

Note: the namespace response model has no deleted_rows field, so the
DeleteResult.num_deleted_rows returned by lance core is intentionally
dropped at the namespace boundary.

Error mapping

Cause Mapped error
Predicate / expression parse failure (DataFusionError) InvalidInput
lance_core::Error::InvalidInput from delete InvalidInput
Missing table TableNotFound (via existing load_dataset)

Test plan

Add unit tests in rust/lance-namespace-impls/src/dir.rs#tests:

  • test_update_full_table — full-table update bumps version by 1
  • test_update_with_predicate — only matching rows updated
  • test_update_invalid_expression — surfaces InvalidInput
  • test_update_duplicate_columnsInvalidInput
  • test_delete_with_predicate — row count decreases, version + 1
  • test_delete_empty_predicateInvalidInput
  • test_delete_table_not_foundTableNotFound

CI gate: cargo fmt --check, cargo clippy -D warnings,
cargo test -p lance-namespace-impls --lib dir::tests all green.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions