Commit Graph
3371 Commits
Author SHA1 Message Date
Will Jones d44724a8d7 refactor: drop duplicated IoTrackingStore for lance-io's
`rust/lancedb/src/io/object_store/io_tracking.rs` was a near-verbatim copy of lance-io's `utils::tracking_store`, and had drifted behind it. It was `#[cfg(test)]`-only with two usages, both in tests, so this PR points those at `lance_io::utils::tracking_store::IOTracker` and deletes the copy.

lance-io's `test-util` feature is enabled as a dev-dependency, which brings the `assert_io_eq!` / `assert_io_lt!` macros. Those print the recorded requests (method, path, byte range) when an assertion fails, instead of just the counter that didn't match, so the IO-counting tests in `table/dataset.rs` now say *which* IO happened when they fail.

`test_stats_does_not_read_data_files` no longer plumbs an `object_store_wrapper` at all: every lance-io `ObjectStore` now carries its own tracker, reachable as `store.io_tracker()`. This also makes the test stronger — the optimized local reader bypasses the `object_store` layer, so reads that would have gone uncounted through a wrapper are recorded by the built-in tracker.

Fixes #4076

## Not included

Two lance-side items from the issue are left for follow-up there, since neither can be fixed from this repo:

- `IOTracker::wrap_paginated` returns `Some(original)` on the premise that a pushed-down listing counts itself, which only holds for the local lister — a paginated listing against S3 is invisible to the tracker. The deleted copy had the identical bug, so this is not a regression.
- The deleted copy had poison-tolerant locking (`unwrap_or_else(|e| e.into_inner())`, from #3196) where lance still `.unwrap()`s. That tolerance, and the two unit tests covering it, go away with the file; it is worth carrying upstream instead of re-forking here.
2026-10-30 15:29:27 +08:00
Jack Ye 6d126a3601 feat: add database storage integration APIs (#4618)
Adds database-owned S3 storage integrations with Secret-style namespace
paths in a separate keyspace. Use a regular database under the cluster
root for bootstrap integrations and Secrets. `default` is an example
name, with no enforced or automatically provisioned database; `system`
remains read-only. Authentication uses either an IAM role or two
existing Secret references, including cross-database references;
configuration metadata never contains credential values.

### Python experience

```python
catalog = lancedb.connect_catalog("https://my-server.example", api_key="secret")
db = catalog.connect_database("default")
info = db.create_storage_integration(
    "raw", "s3://customer-bucket/raw/",
    aws_role_arn="arn:aws:iam::123456789012:role/lancedb-access",
    aws_region="us-east-1",
)
print(info.configuration_instructions)
info = db.describe_storage_integration("raw")
print(list(db.list_storage_integrations()))
db.drop_storage_integration("raw")
```

For static credentials, replace `aws_role_arn` with
`aws_access_key_id_secret=SecretReference("s3_key_id",
database="default")` and
`aws_secret_access_key_secret=SecretReference("s3_secret_key",
database="default")`, imported from `lancedb.storage_integration`. Pass
`namespace_path` to address nested namespaces. Async database
connections expose the same APIs; listing is lazy. All four client
operations execute SQL through the existing SQL transport, with typed
Arrow result decoding and name-based listing cursors.

### SQL experience

```sql
CREATE STORAGE INTEGRATION default.public.raw
    STORAGE_PROVIDER = 'S3'
    STORAGE_PREFIX = 's3://customer-bucket/raw/'
    STORAGE_AWS_ROLE_ARN = 'arn:aws:iam::123456789012:role/lancedb-access'
    STORAGE_AWS_REGION = 'us-east-1';
DESCRIBE STORAGE INTEGRATION default.public.raw;
SHOW STORAGE INTEGRATIONS IN default.public;
DROP STORAGE INTEGRATION IF EXISTS default.public.raw;

CREATE STORAGE INTEGRATION default.public.raw
    STORAGE_PROVIDER = 'S3'
    STORAGE_PREFIX = 's3://customer-bucket/raw/'
    STORAGE_AWS_ACCESS_KEY_ID_SECRET = default.public.s3_key_id
    STORAGE_AWS_SECRET_ACCESS_KEY_SECRET = default.public.s3_secret_key;
```

CREATE and DESCRIBE return configuration and a single sentence of setup
guidance. IAM mode also returns the deployment role principal, stable
external ID, customer trust policy, and prefix-scoped permissions
policy. Registration does not verify access. Creation requires namespace
CREATE_STORAGE_INTEGRATION plus parent USAGE; Secret references require
source database, namespace, and Secret USAGE. Describe requires object
USAGE; drop requires OWNERSHIP. SQL supports GRANT/REVOKE for these
objects and their creation privilege.

Includes client documentation and Flight SQL regression coverage; no
dedicated storage-integration REST endpoints are used. Local
builds/tests are excluded by request.
2026-10-30 00:26:42 -07:00
Xuanwo a39a31807f fix(python): pin an available pylance wheel on macOS
## Problem

The Python test extra pins `pylance==15.0.0b7` for every platform. On macOS, pip cannot resolve that pin: the configured `lance-format` index publishes b7 wheels for Linux and Windows but not macOS, while public PyPI returns HTTP 404 for the version and the `lancedb` index contains no 15.x release. The macOS Python dependency installation consequently cannot resolve the pin.

## Change

- Keep the exact `pylance==15.0.0b7` test pin on non-macOS platforms.
- Use `pylance==15.0.0b4` on macOS. This is the newest release in this range with a macOS wheel (`cp310-abi3-macosx_11_0_arm64`).
- Refresh `python/uv.lock` for the platform-specific resolutions.

The production Rust/Lance inputs are unchanged: `Cargo.lock` is byte-identical to `main` and remains on Lance `15.0.0-beta.7`. No tests, assertions, coverage, or CI checks are removed or weakened.

## Validation

- Confirmed the wheel identity from the configured index and matched its published SHA-256 to `uv.lock`; wheel metadata reports `Name: pylance`, `Version: 15.0.0b4`.
- Verified the b4 APIs used by the Python tests (`blob_field`, `blob_array`, `BlobType`, `Blob`, `dataset`, `write_dataset`, `FFILanceTableProvider`, and `DirectoryNamespace`). The Python test suite does not reference the b7-only `mark_sstables_as_compacted`, `mem_wal_dir_id`, `mem_wal_index_details`, `clustering_id`, `LanceFragment`, `IndexSegment`, `UpdateConfig`, or `max_source_fragments` changes.
- Verified scalar read/write interoperability in both directions between b4 and the beta.7 LanceDB native binding, plus beta.7 reads of a b4-written blob dataset with byte and null fidelity.
- `uv lock --check` with both configured Fury indexes and `unsafe-best-match`.
- CI dependency tests.
- Ruff 0.9.9 format and lint checks.
- Targeted Python tests: 911 passed, 22 skipped.
- Full Python suite (`-m "not slow and not s3_test"`): 2858 passed, 157 skipped, 70 deselected.
2026-10-30 14:00:16 +08:00
Brendan ClementandClaude Opus 5.5 ca343a5c06 docs: fix table, accuracy and structure problems found in the pre-launch review (#4745)
## Summary

Fixes the problems a page-by-page review of the docs found before
launch, after checking each one against the current source and, where
noted, the code. The matching fixes for the dataset and Geneva pages,
which live in `lancedb/docs`, are in lancedb/docs#402.

**Tables**
- `integrations/embedding/cohere`: each input-type description was split
across two table rows and wrapped in literal quotes
(`"`search_document`"`). Now one row per type.
- `integrations/embedding/gemini`: removes the same stray quotes from
the task-type table.
- `integrations/ai/langchain`: the MMR search table's `kwargs` row was
missing a cell, so its description sat under Type.
- Six reranker pages (answerdotai, cohere, colbert, jina, openai,
voyageai): closes the backtick before `_relevance_score`.
- `indexing/vector-index`: finishes a cell cut off at "with scalar".
- `sql/dql/dedupe`: labels the empty header cell in the resolution
table.

**Corrections**
- `curation/sampling`: sampling works in LanceDB Embedded through the
Python SDK, so the page is available in both, with the SQL sections
marked Enterprise.
- `feature-engineering/index`, `add-computed-column`: automatic refresh
is on by default for each computed column and takes effect once a
deployment enables its scheduler. `refresh-column` already said so;
these two implied it was off.
- `indexing/scalar-index`, `indexing/index`: `LABEL_LIST` accelerates
`array_has_all`/`array_has_any`; `array_contains_*` doesn't exist. Also
merges scalar-index's two "nested fields" sections into one.
- `integrations/embedding/ibm`: lists the four current models from
`CURRENT_MODELS` (it listed a deprecated one) and explains that the
default stays a legacy ID so existing tables reload with their model.
- `integrations/reranking/openai`: the class is `OpenaiReranker`, not
`OpenAI()`.
- `integrations/ai/synthetic-data-kit`: the CLI is `synthetic-data-kit`
throughout, each step runs one command, each step passes the file it
writes to the next, and `save-as` uses `-f`/`-o`.
- `integrations/data/dlt`: `secrets.toml` defines `api_token`, which the
pipeline reads, and the run command runs the file the page creates.
- `search/vector-search`: the multivector walkthrough connected to
Enterprise in step 1 and a local path in step 2. It now runs locally
throughout, with a note on connecting to Enterprise, and is renamed so
it doesn't read as a duplicate of the short section above.

**Structure and wording**
- `integrations/embedding/nvidia`: adds headings, and drops test-suite
details aimed at contributors.
- `integrations/ai/genkit`: makes the retrieval test a real heading and
describes the query step.
- `integrations/data/voxel51`: replaces a raw MkDocs `!!! note` with a
`<Note>`.
- `sql/ddl/table`, `sql/ddl/job`: "Errors and limits" is a real heading,
not bold text.
- `curation/windowing`: sidebar title matches the curation overview
("Rank and Deduplicate").
- `deployment/storage`, `basics/agentic-skills`: fixes a garbled
sentence and a stale reference to the quickstart.


**Checked:** no new Vale alerts on the changed pages. Assembled together
with lancedb/docs#402, the site passes `mint validate` and `mint
broken-links --check-anchors --check-redirects`. Every changed page was
reviewed in a local preview.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 21:26:37 -04:00
3306e5fbf2 chore: update lance dependency to v15.0.0-beta.7 (#4746)
Updates Rust workspace and Java Lance dependencies to
[v15.0.0-beta.7](https://github.com/lance-format/lance/releases/tag/v15.0.0-beta.7),
and pins Python tests to the published `pylance==15.0.0b7` release with
refreshed Cargo and uv lockfiles. No compatibility fixes were required.

Validation: workspace Clippy with all features and warnings denied,
Cargo formatting, uv lock consistency, and all 18 CI-script tests pass;
repository-wide Ruff diagnostics are pre-existing.

---------

Co-authored-by: Lu Qiu <lu@lancedb.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-29 16:49:26 -07:00
d5013459eb chore: update lance dependency to v15.0.0-beta.6 (#4742)
Updates Rust and Java Lance dependencies to
[v15.0.0-beta.6](https://github.com/lance-format/lance/releases/tag/v15.0.0-beta.6),
pins Python tests to published pylance 15.0.0b6, and refreshes both
lockfiles.

Aligns Arrow 59, DataFusion 55, and PyO3 0.29; adapts execution plans
and MemWAL directory handling, updates the ABI metadata test, and
removes the obsolete Lance Arrow patch now fixed upstream.

Validation: workspace clippy with all features/tests and warnings
denied, cargo fmt, Python/CI Ruff checks, uv lock check, 16 CI-script
tests, and targeted Python regressions (54 passed, 28 skipped);
repository-wide Ruff retains existing documentation-example failures,
and the upstream macOS wheel build failed while Linux and Windows wheels
are published.

---------

Co-authored-by: Daniel Rammer <hamersaw@protonmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 16:14:09 -05:00
alexcastgonz 03c7d1f199 fix(python): add the missing f prefix to the permutation split error (#4709) 2026-10-29 13:03:32 -07:00
Colin Patrick McCabe 301ccad3aa feat: add a LanceDB command line (#4600)
Add a LanceDB command line with the following functionality:

- `lancedb auth`: log in with OAuth, check cached OAuth session status,
or log out.
- `lancedb profile`: Create, edit, list, show, select, and delete
connection profiles.
- When no subcommand is given, we will attempt to create a SQL shell.

Update ci/check_cargo_lock.py and its regression tests to allow
pruning dependency edges while their target packages remain in
Cargo.lock. Removing the CLI from the Python source distribution
can disable optional features such as Axum tracing, even though
other SDK dependencies still require the tracing package.
2026-10-29 12:39:46 -07:00
Brendan ClementandClaude Opus 5.5 2347e97e56 docs: list features in the landing page comparison table (#4743)
## Summary

Replaces the generated availability table under **Compare features** on
the landing page with a hand-written list of features, grouped by area,
with separate Embedded and Enterprise columns.

The generated table listed every page that declares `availability`,
including overview and basic CRUD pages. Rows such as "Overview"
appeared three times without context, and pages like Insert, Update,
Database and the integrations showed up as if they were features.

| Area | Features |
| --- | --- |
| Search | Vector, full-text and hybrid search, filtering, reranking,
query plans, distributed search |
| Indexing | Vector, full-text and scalar indexes |
| SQL and curation | SQL, aggregation, sampling, joins, ranking and
deduplication, near-duplicate detection, chunking, changes since a
version, views |
| Feature engineering | Computed columns, materialized views, embedding
registry |
| Training | PyTorch data loader, permutations, distributed training |
| Data management | Branches, compaction and cleanup, background jobs,
Real Time engine |
| Security | Authentication, authorization |

Each ✅/❌ matches the linked page's `availability` on `main`; SQL, which
declares none, is Enterprise-only. Functions are left out until it's
settled whether they are published.

The same list, limited to 1.10 features, is in the Enterprise 1.10
editions in lancedb/docs#398.

Checked by assembling the docs site with this change: `mint validate`
passes and `mint broken-links --check-anchors --check-redirects` finds
no broken links. Vale reports no new warnings.

After this merges, the committed `lancedb` skill in lancedb/docs needs a
rebuild (`make assemble && make skill`).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 11:55:30 -07:00
lancedb-gatefixer[bot] a4f52cd205 fix(python): add a Blob V2 array construction helper (#4734)
Fixes #4733

PyArrow expects Blob V2 storage structs when constructing a record batch
and cannot infer the extension array from raw bytes. LanceDB already
converts binary values during ingestion, but batch writers had no
supported array constructor.

Add `lancedb.schema.blob_array(payloads)` for iterables of inline bytes
and nulls, using the same extension type resolver as `blob()`. The
helper preserves empty blobs and null blobs and works with both
pylance's type and LanceDB's fallback. Document the descriptor fields,
exclusive inline/external representations, batch construction, and
existing binary conversion in synchronous and asynchronous
`create_table` / `add` APIs.

Validation:
- Reproduced the reported `ArrowTypeError` on the original code; both
new regression cases fail against the original schema module.
- 256 focused blob tests and schema doctests passed; one optional PyAV
test skipped.
- Both new regression cases also passed with PyArrow 25, with and
without pylance imports.
- Python package Ruff checks and formatting passed.
- MkDocs build passed, with an existing unrelated `SecretReference`
cross-reference warning. Repository-wide Ruff reports 48 existing errors
in `docs/web-tests`.

<!-- lance-gatekeeper-fix:v1 agent=20d1a296d76ff5eb914c0848428a747a
generation=1 -->

Co-authored-by: Gatefixer <313497061+lancedb-gatefixer[bot]@users.noreply.github.com>
2026-10-29 11:28:54 -07:00
Brendan ClementandClaude Opus 5.5 dcddd541c8 docs: link home page sections through /index (#4740)
## Summary

Changes links to home page sections from `/#<anchor>` to
`/index#<anchor>`.

The docs site's Assemble CI fails `mint broken-links --check-anchors` on
every `/#architecture` link since #4732 moved the Architecture page onto
the home page. The anchor exists; Mint 4.2.888's checker can't resolve
any anchor on the root page `/`, but resolves `/index#…`.
`docs.lancedb.com/index` serves the home page, so readers land in the
same place.

Verified by assembling the site with this change and the matching
Enterprise docs change: `mint validate` passes and `mint broken-links
--check-anchors --check-redirects` finds no broken links. The
`docs.json` redirects keep `/#architecture`, which the checker accepts.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 10:59:09 -07:00
Brendan ClementandClaude Opus 5.5 1d15bb3ada docs: address staging review comments (#4715)
## Summary

Addresses some comments on the staging branch. Rebased onto #4732, which
rebuilt `index.mdx` and the quickstart and reverted the landing copy to
the pre-v0.4 headings; the final copy is reapplied here.

| Comment | Page | Change |
| --- | --- | --- |
| Taylor: drop the comma | `index.mdx` | "one, unified platform" → "one
unified platform" |
| Taylor: "Preparing t…" + "Data doesn't slow down" | `index.mdx` |
"Training data and experimentation slow down…" → "Preparing training
data and running experiments slow down…" |
| Fei: subtitles should align with the new home page | `index.mdx` |
Follows the final homepage copy (v0.4): "Train on the right data faster"
with the hero subtitle, "Accelerate the data flywheel for model
research" with its intro, and the five v0.4 sections as steps, each
linking to the page that backs it (search, curation, branches, versions,
computed columns and materialized views, `StreamingDataset`). Wording
the docs can't back yet is left out: "zero-copy", "lineage", "cached
across clouds". Anchors renamed to match; nothing links to the old ones
|
| Fei: quickstart seems OSS-only | `quickstart.mdx` | Tip at the top:
for Enterprise only the connection changes, linking the Enterprise
connection in step 2 |

Fei's "list all Enterprise features as a catalog" comment is now covered
by #4732's feature comparison table (`/#compare`), so the separate table
this PR added to `basics/offerings.mdx` was dropped along with that
page.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 10:38:14 -07:00
Brendan ClementandClaude Opus 5.5 8440574f2a docs: use the new overview diagrams on the landing page (#4714)
## Summary

Updates the overview diagrams on the landing page. Rebased onto #4732,
which moved the architecture and offerings content into `index.mdx` and
drew it as Mermaid diagrams; this PR replaces those with the guide's
diagrams.

- **Architecture** (`#architecture`): the suite diagram
(`lancedb-suite.svg`) replaces the first Mermaid diagram. Its Enterprise
boxes read Search, Data exploration & curation, Feature engineering,
Training, matching the guide's product hierarchy.
- **LanceDB Embedded** (`#1-lancedb-oss`): adds the guide's Embedded
diagram. Its storage box reads "Local Disk or Object Storage", since
Embedded supports both.
- **LanceDB Enterprise** (`#2-lancedb-enterprise`): the guide's
Distributed diagram replaces the second Mermaid diagram. This also drops
that diagram's "column + MV refresh" label; automatic refresh is still
gated.
- **Functions** are still unpublished, so the "Functions ·" label is
removed from the Distributed diagram's jobs fleet. At release, restore
the designer's original image from the Notion guide.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 10:38:11 -07:00
Jack Ye ddb318567a docs: complete SQL reference, enrich Functions drafts, rename OSS to Embedded (#4732)
## Summary

- Complete the SQL reference: `ATTACH DATABASE`, the `CHANGES` clause,
and
`dedupe()`/`duplicate_pairs()` (verified against current sophon source;
these were recently renamed from
`vector_dedup`/`vector_duplicate_pairs`).
  Fix the blob-column default-projection claim and add the previously
  undocumented `blob_descriptor()`.
- Enrich the gated Functions draft (still `.mintignore`'d, pre-release):
  chained Functions over blob outputs, GPU-produced blobs, Secrets,
  multi-input/output binding, `code=[module]` packaging.
- Upgrade the materialized-view and computed-column auto-refresh drafts
with
  precise, verified catch-up semantics, and add the missing `ALTER
  MATERIALIZED VIEW` / `CREATE ... WITH(...)` sections (also gated — the
  automatic-refresh scheduler is still dev/staging-only).
- Thread one running example (video frames → GPU extract/caption → dedup
→
auto-refreshing materialized view) through Functions, materialized
views,
and the LeRobotDataset integration guide instead of a separate tutorial.
- Rename "LanceDB OSS"/"OSS" to "LanceDB Embedded"/"Embedded" throughout
  (52 files); activate the existing availability-comparison mechanism on
  `basics/offerings.mdx` for a full feature-by-feature comparison table.
2026-10-29 10:16:03 -07:00
Divyanshu Singh 005a9a353a ci(java): run Java 11 and 17 builds in parallel with matrix strategy
Split the Java 17 workflow into a matrix for Java 11 and Java 17.
Run Checkstyle once in a dedicated Java 17 job and skip the lifecycle-bound Checkstyle execution in the matrix builds to avoid redundant work.

Closes #1331.
2026-10-29 18:33:13 +08:00
Taylor a065b4b9c6 feat(python): add NVIDIA Nemotron embedding provider
Adds a Python `nvidia` embedding provider for Nemotron 3.5 Embed 1B and 8B. It works with NVIDIA's hosted API and self-hosted NIM `/v1` endpoints, and uses the existing `openai` client. The OpenAI provider can't send NVIDIA's passage/query input types or pick Nemotron's dimensions.

- Documents are embedded as `passage`, searches as `query`.
- Default dimensions are 2048 (1B) and 4096 (8B), and `dim` is checked against each model's supported range. Self-hosted model IDs need an explicit `dim`.
- Response count, order, dimensions and values are checked. Null and empty text get a null vector without a request.
- Each request is retried on its own with LanceDB's retry policy. Invalid input or responses fail immediately.
- `NVIDIA_API_KEY` is only sent to the hosted API. Custom endpoints need an explicit `api_key` (a `$var:` reference), and endpoints restored from table metadata must be allowed with `allow_endpoint`.
- Request dimensions are sent through `extra_body`, preserving the NVIDIA wire contract while supporting the declared minimum `openai==1.6.1`.

Python and text only. Docs are in `integrations/embedding/nvidia`.

Originally authored by Taylor (@tsmithv11).

### Testing

- `test_nvidia_embeddings.py`: 45 passed, 2 deselected with both the locked `openai==2.44.0` and minimum `openai==1.6.1`. These use the real OpenAI client with mock HTTP transport and real local tables.
- Embedding, registry, field-metadata and trust suites: 163 passed, 4 skipped, 10 deselected.
- Historical live experiments: hosted 8B passed a five-request smoke test; hosted 1B returned HTTP 500. No live request was made in this stage, so current hosted 1B availability was not verified. Enterprise coverage uses the repository mock HTTP server, not a live deployment.
2026-10-29 18:10:50 +08:00
BHAWESHBHASKAR 891774343e feat(python): add CombinedFieldsQuery for BM25F full text search
Add a typed Python `CombinedFieldsQuery` for BM25F search across multiple columns.

The query mirrors Lance's combined-fields semantics with ordered per-column boosts and AND/OR term matching. Convert it in both directions at the PyO3 boundary, including nested Boolean queries, and document the Python typed convenience entry.

Closes #4652.
2026-10-29 17:29:22 +08:00
Yang Cen 06b6625a94 docs: validate release branches before Lance stable approval (#4711)
Freeze the SDK product baseline on a release branch before validating a
Lance RC, so later main commits do not change the candidate. Require the
RC pin PR's CI and applicable reviews to complete with no blocking
findings before Lance stable publication. Draft-skipped reviews are
missing evidence, and green CI does not clear a request-changes
recommendation.

After the upstream release, update only the validated dependency
references, rerun checks and refresh review, then publish from the
verified release branch. Document Cargo override boundaries, exact
commit/artifact evidence, and the workflow's actual stable input
(`type=stable`).

Validation: Markdown fences, public-scope and diff checks passed; the
documented workflow inputs were checked against the repository workflow.
2026-10-29 17:06:55 +08:00
Jay Pokale 280ca41061 feat(python): support time and timedelta values in table.update
Support `time` and `timedelta` values in `table.update` by generating explicit Arrow casts.

- Preserve Arrow duration/time units and pandas nanosecond precision.
- Reject timezone-aware `time` values before data can be changed.
- Cover time64 us/ns, duration s/us/ns, negative timedeltas, filters, and nanosecond round trips.
2026-10-29 16:08:20 +08:00
Wyatt Alt 41c1a2a8b1 feat(python): declare Debian system packages on a Function
Adds `apt` to `@udf` and `system_packages` to the Rust `PythonEnvironmentSpec`. The server adds the packages to the Function's image before installing its Python environment, for shared libraries that pip and conda cannot provide, such as FFmpeg's for torchcodec. The field is omitted when empty, so existing Function identities are unchanged.
2026-10-29 15:28:36 +08:00
Ishita Singh 079711d4ad feat(python): list registered embedding functions
Closes #1605.

Adds `EmbeddingFunctionRegistry.list_functions()` to expose registered lookup names in registration order without accessing `_functions`. The method returns an independent snapshot, and every returned name can be passed to `get()`.

Tests cover empty registries, aliases and class names, registration order, snapshot isolation, and reset.
2026-10-29 13:56:27 +08:00
geoffgscott 7ea10fa1e0 feat(node): expose targetPartitionSize on IVF index options (#4594)
The Node SDK's vector index options only take `numPartitions`. The Rust index builders (`target_partition_size` in `rust/lancedb/src/index/vector.rs`) and the Python SDK already support a target partition size, so this adds `targetPartitionSize` to `IvfPqOptions`, `IvfRqOptions`, `IvfFlatOptions`, `HnswPqOptions` and `HnswSqOptions` and passes it to their builders. When both are set, `numPartitions` is used, as it is for Rust and Python callers.

The reason to want it: an index built from a partition count records no target partition size, so `table.optimize()` splits and joins it against the index type's default and can merge small partitions down to one or two. Building with a target records it in the index details, and optimize keeps to it. https://github.com/lance-format/lance/pull/10154 fixes this on the Lance side for indexes built from a partition count; this lets Node users set the size directly.

The new tests build IvfPq, IvfFlat, IvfRq, IvfHnswPq and IvfHnswSq indexes with `targetPartitionSize` and check the size recorded in the index details, and check that `numPartitions` wins when both are set. Each option's doc comment states that index type's default target. Docs regenerated with `pnpm run docs`.
2026-10-29 13:13:00 +08:00
Lei Xu 03bd909dab test(python): resolve aliased projections in the torch remote mock server
Map dynamic projections by output name to their source columns in the remote
torch test mock so permutation take queries preserve the aliased ordering
column. Run the regression in the embeddings-installed Python test job and
require torch to import so a missing dependency cannot skip coverage.
2026-10-29 12:19:44 +08:00
max 9ffd3d33e1 test(python): remove fixed per-test delays from mock HTTP servers
The Python test jobs spend much of their pytest time waiting on the in-process mock HTTP servers.

1. Each server ran `serve_forever()` with the default 0.5 s poll interval, so every `server.shutdown()` blocked for up to 0.5 s. Around 300 tests use such a server (test_remote_db, test_authz/test_catalog, test_listing, the permutation helpers), about 150 s per test job on every platform. A shared `start_server_thread()` helper in `tests/utils.py` serves with a 0.01 s poll interval, so shutdown returns in about 10 ms.
2. The servers bind IPv4 only, but clients used `http://localhost:<port>`. The client tries ::1 first and falls back after the happy-eyeballs delay, about 0.3 s per connection on Windows. The mock handlers close the connection after each response, so one listing test took 9.5 s on Windows CI versus 0.6 s on Linux. Clients now use 127.0.0.1, as test_catalog, test_listing and test_namespace already do.

Measured on Windows with the 0.41.0b6 wheel and `-m "not slow and not s3_test"`: full suite 546.7 s to 212.3 s; test_remote_db.py, test_listing.py and test_catalog.py together 284 s to 14 s on current main. Collected test ids are identical (1898) and pass/fail/skip results match. No assertion, test or marker changed.
2026-10-29 11:31:23 +08:00
lancedb-gatefixer[bot]andXuanwo 913ee160b0 test(python): cover vector index prewarming by name (#3859)
## Summary

- cover vector-index prewarming through the Python API using the logical
index name returned by list_indices
- prevent regression to interpreting a vector index name as a schema
column

## Root cause

The Lance version used by the reported release opened a vector index by
treating the prewarm argument as a column before resolving the index
metadata. Current LanceDB dependencies contain the upstream
metadata-based resolution, but LanceDB only exercised prewarming for FTS
indexes, leaving the vector behavior unguarded.

## Validation

- uv run --extra tests pytest
python/tests/test_index.py::test_create_vector_index -q
- python/.venv/bin/ruff format --check python/python/tests/test_index.py
- python/.venv/bin/ruff check .

Fixes #2897

<!-- lance-gatekeeper-fix:v1 agent=c2f8273221061d8e2b6f7393066e68c6
generation=1 -->

Co-authored-by: Gatefixer <313497061+lancedb-gatefixer[bot]@users.noreply.github.com>
Co-authored-by: Xuanwo <github@xuanwo.io>
2026-10-29 10:45:34 +08:00
Bilal Atique 65954bf9cc docs(python): document connection_factory on StreamingDataset
Closes #3693.

`columns` is documented on `StreamingDataset` now, but `connection_factory` still wasn't. This adds it to the parameter list, in signature order.

The text follows `__getstate__` / `__setstate__`: with a factory, pickling the dataset replaces the table's reopen state with its name, and each DataLoader worker calls the factory to reopen the table. The factory is pickled along with the rest of the dataset, so it has to be picklable, and credentials stay out of the pickle only when the factory loads them in the worker instead of capturing them (the same guidance as `Permutation.with_connection_factory`). Without a factory, the table's own reopen state is pickled.

This picks up #3697, which documented the same parameter and was closed by its author without a merge.
2026-10-29 09:52:15 +08:00
Wyatt Alt 3506b43c03 feat(python): accept input_schema or output_schema alone in @udf (#4731)
Binding a nullable column needed an explicit input schema, and that
forced spelling out the output schema too. Either schema can now be
given alone; the other side is inferred from annotations.

The udf docstring now says a bare annotation is non-nullable and
`Optional[T]` binds a nullable column, and that a `bytes` input counts
against the per-row input limit, with Blob V2 and `BlobReader` for large
values.
2026-10-29 09:16:32 +08:00
medimedi 088f4d670e docs(rust): use LanceDB Arrow re-exports (#3908)
## Summary

- explain that Rust callers should use the Arrow crates re-exported by `lancedb::arrow`
- update the crate quick-start doctests to build Arrow values from those re-exports
- update the checked-in `simple` example so it cannot drift to an incompatible Arrow crate version

Fixes #1207.

## Validation

- `cargo fmt --all -- --check`
- `cargo metadata --no-deps --format-version 1 --quiet`
- static checks that the documented crates are publicly re-exported and both examples use them
- `git diff --check`
- attempted `cargo check --quiet -p lancedb --example simple`; dependency compilation stopped in the unmodified `lance-encoding` build script because `protoc` is not installed in this environment
2026-10-29 08:44:10 +08:00
Wyatt Alt 5fbf9fd9f0 docs(python): note that packaged Functions import lance_blob.BlobReader (#4730)
Function authors annotate inputs with lancedb.BlobReader, but the
packaged source binds that annotation to the worker's
lance_blob.BlobReader, so grepping the artifact for the client class
finds nothing. Say so on the class.
2026-10-29 08:01:12 +08:00
lancedb-gatefixer[bot] 04e509278e fix(python): clarify schemas for batch UDF annotations (#4727)
`@udf` documented batch annotations without explaining that `pa.Array`
and `pa.RecordBatch` do not specify concrete Arrow element types or
field schemas. Document the requirement for both explicit schemas
(including class `__call__` methods), add an array example, and make
inference errors point callers to `input_schema` and `output_schema`.

Fixes #4721

Validation:
- Five new regression cases pass; all four diagnostic cases fail with
the original implementation.
- Function packaging, first-class Function slice 1/2 tests, and UDF
doctests: 168 passed, 3 failed. This includes the upstream BlobReader
annotation coverage. The three existing packaging tests fail while
importing temporary modules, before UDF registration; all three failures
also reproduce with the unchanged source and tests at `057a39a1`.
- Rebuilt the native extension in the uv-managed tests/dev environment.
- Python lint and formatting checks pass (`ruff check python`, `ruff
format --check python`); `cargo fmt --all` also passes without changes.
- Repository-wide `ruff check .` reports 48 existing errors under
`docs/web-tests`.

<!-- lance-gatekeeper-fix:v1 agent=2c6567ee3f128d3a0c3b9c68e36eca38
generation=1 -->

Co-authored-by: Gatefixer <313497061+lancedb-gatefixer[bot]@users.noreply.github.com>
2026-10-28 16:37:57 -07:00
lancedb-gatefixer[bot] 741cb9ad4e fix(python): implement remote namespace and table existence checks (#4725)
Remote Python connections inherited the unsupported-operation stubs for
`namespace_exists` and `table_exists`, so both raised
`NotImplementedError` even when namespace and table operations worked.

Add the missing remote overrides, async methods, and PyO3 bindings using
the existing namespace describe and table open paths. Only an explicit
not-found result returns `False`; permission, transport, and server
errors propagate. This preserves authentication, dynamic headers,
retries, and nested namespace handling, and rechecks cached tables
before reporting that they exist.

The async namespace helper also recognizes native `NamespaceNotFound`
errors so missing local namespaces return `False`. The table and
namespace guides document Python remote support and distinguish it from
the unsupported `exists` routes used by direct REST namespace clients.

Validation:
- All 40 focused regression cases pass, covering successful and missing
lookups, local and remote namespaces, dynamic headers, permission/server
errors, invalid table identifiers, and cached tables that disappear.
- The original inherited stubs reproduce the reported
`NotImplementedError`; the local namespace regression reproduced the
native missing-namespace `RuntimeError` before its fix.
- Full remote connection suite: 255 passed. Local namespace tests: 14
passed.
- `cargo clippy --quiet -p lancedb-python --features remote --lib`,
`cargo fmt --all`, Python Ruff lint, and Python formatting checks pass.
- Root `ruff check .` reports 48 existing errors in documentation
examples under `docs/web-tests`; the Python subtree passes and those
unrelated files are unchanged.

Fixes #4722

<!-- lance-gatekeeper-fix:v1 agent=4d369a0681756fdb5a8b35853d7f5607
generation=1 -->

---------

Co-authored-by: Gatefixer <313497061+lancedb-gatefixer[bot]@users.noreply.github.com>
2026-10-28 16:08:43 -07:00
lancedb-gatefixer[bot] fc5170cbed fix(python): expose function source digests (#4729)
Function descriptions include `source_digest`, but both the Rust
response model and Python `FunctionVersion` discarded it. Clients
therefore could not compare a catalog entry with
`udf_def.registration_request.artifact.digest`.

Preserve the digest through Rust serialization and expose it on Python
`FunctionVersion`, with a documented Rust accessor. Missing or null
digests decode as `None`, keeping older responses compatible. Regression
tests cover serialization, immutability, registration jobs, get, and
synchronous/asynchronous list responses while keeping the image digest
independent.

Validation:
- Confirmed that the original Python model silently discarded a
server-provided source digest.
- Rebuilt the Python extension in the uv-managed environment; both
focused Function test files passed (106 tests).
- Focused Rust Function model tests passed (10 tests).
- Full workspace `cargo check --quiet --features remote --tests
--examples` and `cargo clippy --quiet --features remote --tests
--examples` passed.
- Rust formatting and Ruff checks/formatting for changed Python files
passed.
- Repository-wide Ruff reports 138 existing violations in unchanged
docs/CI files.

Fixes #4723

<!-- lance-gatekeeper-fix:v1 agent=c145f25136f7b908217e04bde8a2548b
generation=1 -->

Co-authored-by: Gatefixer <313497061+lancedb-gatefixer[bot]@users.noreply.github.com>
2026-10-28 16:04:04 -07:00
lancedb-gatefixer[bot] 3035636bed fix(python): restore blob extensions in table schemas (#4728)
Reading a Blob v2 table in a fresh process could return its storage
struct if neither `blob()` nor pylance had registered the extension.
Both local and remote schema reads were affected, so `field.type` could
depend on import order.

Restore metadata-only blob fields on every table schema read through the
existing BlobType resolver and Arrow's schema deserializer. Preserve
nested fields, nullability, custom metadata, and both supported storage
layouts. The fallback deserializer now honors the stored shape too.

Fresh-process regressions cover local and remote tables, sync/async
reads, and operation with and without pylance. The four native cases
failed before removing the native-table guard. Existing merge-insert
tests now require the restored extension type while continuing to verify
updated and inserted blob contents.

Validation:

- All 12 fresh-process local/remote schema regression cases pass.
- `uv run --extra tests pytest python/tests/test_table.py
python/tests/test_blob.py python/tests/test_namespace.py
python/tests/test_util.py -q -m 'not slow and not s3_test'`: 835 passed,
11 skipped.
- Python package Ruff lint and formatting checks pass.
- Repository-wide `ruff check .` reports 48 pre-existing diagnostics in
unchanged `docs/web-tests` files.

Fixes #4719

<!-- lance-gatekeeper-fix:v1 agent=67c656bb5889e698efce5f2fd9d58ea7
generation=1 -->

---------

Co-authored-by: Gatefixer <313497061+lancedb-gatefixer[bot]@users.noreply.github.com>
2026-10-28 16:02:41 -07:00
lancedb-gatefixer[bot] ca60b402aa fix(python): reject invalid punctuation in UDF names (#4724)
Function names containing periods or hyphens passed `@udf` validation
and failed only when registered with the server. Restrict the name
pattern to ASCII letters, digits, and underscores, preserving the
existing first-character rule so invalid names fail when the decorator
runs.

Document the accepted format and add regression coverage for dotted and
hyphenated names, including trailing punctuation, alongside valid name
overrides.

Fixes #4720

Validation:

- The four new invalid-name cases failed before the validator change
because no `ValueError` was raised.
- `cd python && uv run --extra tests pytest
python/tests/test_first_class_function_slice2.py -q`: 86 passed.
- Ruff 0.9.9: `ruff check python` and `ruff format --check python`
passed.
- Repository-root `ruff check .` reports 48 pre-existing errors in
`docs/web-tests/`.

<!-- lance-gatekeeper-fix:v1 agent=5e2441d3d264b685a6cee3c3c21ab048
generation=1 -->

Co-authored-by: Gatefixer <313497061+lancedb-gatefixer[bot]@users.noreply.github.com>
2026-10-28 15:57:48 -07:00
lancedb-gatefixer[bot] 5f6f7b591d fix(python): bind packaged BlobReader annotations to the worker type (#4726)
Packaged UDFs omit globals used only in postponed annotations, so a
`BlobReader` input has a correct wire signature but
`typing.get_type_hints()` on the loaded function raises `NameError`.

Use the resolved input signature to bind reader annotations to an
imported `lance_blob.BlobReader` alias. Preserve signature nullability
and avoid collisions with existing globals. Regression tests cover
functions and callable classes, eager and postponed annotations,
aliases, forward references, qualified names, and body globals.

Validation:

- Confirmed the new regression fails with `NameError: name 'BlobReader'
is not defined` against the original packager at
`057a39a1c70e15c78461bb7e3db8cef4c067cd3e`.
- The packaging, first-class Function slice 1 and 2, and BlobReader
suites pass all 159 tests with Python file-import directory caches
refreshed before lookups. The standard run passes 156 tests; three
temporary-module import failures reproduce unchanged on the original
packager because directory timestamps do not advance between file writes
in this environment. All 37 new regression cases pass in the standard
run.
- Python Ruff lint and formatting checks pass. Repository-wide Ruff lint
reports 48 existing errors in documentation examples.

Fixes #4718

<!-- lance-gatekeeper-fix:v1 agent=a32bb6efa79217b3c1c5c9d7a7ff9928
generation=1 -->

Co-authored-by: Gatefixer <313497061+lancedb-gatefixer[bot]@users.noreply.github.com>
2026-10-28 15:27:22 -07:00
Nishil Rathod 84fc48198b docs: add guide for using LanceDB in VS Code extensions
Closes #1849

This was lancedb/docs#371. After lancedb/docs#355 moved the open-source pages, their navigation and the snippet tests into this repository's `docs/web` and `docs/web-tests`, that PR could no longer merge there, so I've moved the same change here.

## Why

#1849 asks for an example of LanceDB in a VS Code extension, because people kept running into problems there (#927, #1713). An earlier attempt, #3682, added a README link. @prrao87 asked for something else instead: a quick guide on the docs site, under **Integrations › AI Platforms & Frameworks**, showing how to use LanceDB in an extension and what results look like. The author of #3682 agreed and closed it. This PR is that guide.

## What it adds

- **`docs/web/integrations/ai/vscode.mdx`**: a new page, also added to `docs/web/docs.json`. It builds a small extension with two commands. One indexes the workspace's Markdown into a LanceDB table using the built-in `huggingface` embedding function, so no API key is needed. The other searches it by meaning. The page covers the parts that are specific to VS Code:
  - storing the table under `context.storageUri` instead of a relative path, which is the cause of #927;
  - `@types/node` ≥ 22 and `skipLibCheck`, which covers #1713 and the DOM-type errors from `apache-arrow`/onnxruntime typings;
  - pinning `apache-arrow` inside LanceDB's peer range;
  - marking `@lancedb/lancedb` and `@huggingface/transformers` as esbuild externals, and removing `node_modules/**` from the template's `.vscodeignore`;
  - storing each file's URI so a hit opens in the right folder of a multi-root workspace;
  - building one VSIX per platform with `vsce package --target`, with a table mapping each target to LanceDB's native package, and a note that the sample's local model (via `onnxruntime-node`) doesn't run on Alpine;
  - keeping the Transformers.js model cache in `globalStorageUri`, which only works if it's loaded with `import()`;
  - a troubleshooting table listing each error message with its cause and fix.
- **`docs/web-tests/ts/vscode_search.ts`** and **`vscode_search.test.ts`**: the LanceDB code the page shows (connect, chunk, index, search), plus jest tests for it.
- **`docs/web-tests/ts/vscode_extension.ts`**: the extension's `src/extension.ts`. Jest can't run it because it needs the VS Code extension host, so it was tested in a real extension instead (see below). This follows the precedent of `integrations.ts`.
- **`docs/web/snippets/vscode_search.mdx`** and **`vscode_extension.mdx`**: generated with the command in CONTRIBUTING.md.

## Changes from lancedb/docs#371

- **New paths only.** The page, tests and snippets are the same content, at their paths in this repository.
- **One link.** `/tables/update` doesn't exist under `docs/web`, so the `mergeInsert` link now points to `/ingestion/merge-insert`.
- **Heading anchors.** Every heading now has an explicit `{#anchor}`, as CONTRIBUTING.md asks.

## How I tested it

- **Snippet tests.** In this repository at `c2c8269f`, `vscode_search.test.ts` passes (2 tests) with the pinned `@lancedb/lancedb` 0.31.0. On Windows the `npm test` script fails before it starts, because it runs `node` on the `.bin/jest` shell shim. I ran `node --experimental-vm-modules node_modules/jest/bin/jest.js --testEnvironment jest-environment-node-single-context vscode_search` instead.
- **Lint.** `biome ci` is clean for the three new files, and they carry the SPDX header that `license-header-check.yml` looks for.
- **Snippets.** I regenerated them with CONTRIBUTING.md's command, `mdx_snippets_gen.py -s docs/web-tests/py -s docs/web-tests/ts -s docs/web-tests/rs -o docs/web/snippets`, run with `python` since I don't have `uv`. It reproduces the two new snippet files exactly, once the Windows CRLF endings are normalised. As CONTRIBUTING.md warns, it also rewrites `build_with_ai_agents.mdx`, `integrations.mdx`, `search.mdx` and `storage.mdx`. I left those out.
- **Links.** `mint broken-links` from `docs/web` reports no entries on the new page, and its three internal links (`/embedding/quickstart`, `/ingestion/merge-insert`, `/search/full-text-search`) resolve to pages here.
- **Real extension.** I built a sample extension from exactly the code on the page, scaffolded with `yo code` (TypeScript + esbuild) and using `@lancedb/lancedb` 0.39.0. I ran it with `@vscode/test-cli` in VS Code 1.140 on Windows x64. The integration test runs both commands against a six-file workspace and checks the top hits. The "Sample results" block on the page is copied from that run, and after the review fixes below it reproduces line for line in VS Code 1.141.
- **Multi-root workspace.** A second test configuration opens two folders that both contain `docs/auth.md`. It types a query and picks the top hit through the real picker, then checks that the right folder's file opens at the right line. It fails on the code before the review fix and passes after it.
- **Packaged VSIX.** I packaged `vsce package --target win32-x64` (200 MB, or 148 MB with the onnxruntime trimming in the Tip). Then I unpacked it outside the project and ran the same tests against the unpacked copy, so they couldn't pick up the project's `node_modules`. They pass.
- **Negative checks behind the troubleshooting rows:**
  - With `node_modules/**` left in `.vscodeignore`, activation fails with `Cannot find module '@lancedb/lancedb'` and the commands report `command '…' not found`.
  - Without the externals, esbuild fails with `No loader is configured for ".node" files`.
  - Installing LanceDB into a project that already has `apache-arrow` 21 fails with `ERESOLVE`.
  - `require("@huggingface/transformers")` returns a different `env` object from `import()`.
- **Rendering.** For lancedb/docs#371, `mint dev` rendered the page, its 14 code blocks and the sidebar entry. I haven't re-rendered it from `docs/web`; only the paths, one link and the heading anchors changed.

**Not tested:**
- macOS. I couldn't reproduce the read-only working directory from #927; the page's fix (an absolute storage path) doesn't depend on the OS.
- Linux and macOS VSIX builds.

## Notes for reviewers

- I added `_distance` to `.select(...)`, because LanceDB warns that it will stop adding the column automatically.

## AI disclosure

I used Claude Code to research the issue and its history, write the sample extension, the tests and this page, move the change here, and draft this description. I ran every check listed above myself, and the outputs quoted on the page come from those runs.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-10-29 05:25:00 +08:00
Will JonesandClaude Opus 5.5 4d7a64712f docs: adopt Embedded/Distributed terminology across docs and SDKs (#4713)
## Summary

Adopts the product terminology guide across the docs site pages, SDK
docstrings and error messages. "LanceDB OSS" and local mode become
**LanceDB Embedded**. "Remote" as the execution model becomes **LanceDB
Distributed**, which LanceDB Enterprise provides. Where free vs paid is
the point, pages contrast "LanceDB Embedded (open source)" with "LanceDB
Enterprise". This is a first trial of the Embedded name, so reviewers
can judge it in context.

- **Embedded vs Distributed** for where execution runs (`optimize()`,
consistency, branching, maintenance). Main pages define it once:
"LanceDB Enterprise runs LanceDB Distributed: …"
- **LanceDB Cloud** is kept only for legacy-Cloud specifics (`db://`
region, the brute-force KNN limit) and marked legacy. "Cloud and
Enterprise" becomes Enterprise or Distributed.
- **Plan executor** becomes "executor" or the fleet name.
- **Error messages** change, e.g. `optimize is not supported for remote
tables.` → `... in LanceDB Distributed.` Tests that match on them are
updated.
- **Vale rules** (`EmbeddedName`, `OSSProduct`, `RemoteExecution`,
`DistributedEnterprise`, `LegacyCloud`, `InternalNames`) enforce the
terms in prose.

Unchanged: identifiers (`availability.oss`, the `remote` module and
feature, `RemoteTable`, `db://`), heading anchors, internal code
comments, and Geneva.

## Evidence

- Rust lib tests for the changed messages and the Python tests in
`test_remote_db.py`, `test_materialized_views.py` and `test_table.py`
pass locally.
- Not run locally:
- The Node tests: `remote.test.ts` and `table.test.ts` have updated
assertions.
  - Vale.
  - The `experimental_functions`-marked materialized-view tests.
- `docs/src` API reference was hand-edited to match the docstrings
rather than regenerated.

## Merge Risk

**Door:** two-way; prose and message text only.
**Blast Radius:** `docs`, `error-messages`: callers matching on old
error strings would break.

Companion PRs: lancedb/docs (assembler labels, STYLE.md) and sophon
(Enterprise pages).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 14:04:41 -07:00
Wyatt Alt b4cbaf2f67 docs: show stateful class Functions
The Functions page only showed a plain function, so it never said where a class's `__init__` runs. Users loading a large model need to know it is not the client: registration reads the signature and ships the source.

This adds a section on class Functions: `__init__` runs once per instance on the worker, then `__call__` per row or batch and `close()` on retirement, state is per instance, and `__init__` parameters are initialization fields set per binding. The example's test asserts that registering the class does not construct it.
2026-10-29 04:41:23 +08:00
JiMyung Lee 057a39a1c7 docs: row counts in list_indices can be set for remote tables
Remote list_indices fills num_indexed_rows / num_unindexed_rows from the
server's enriched response and only leaves them unset for servers that
do not report them. The Node and Rust documentation previously implied
those fields were always unavailable for remote tables.

Synchronize the generated TypeScript API reference with the Node source
comments.

Closes #4301

Co-authored-by: desty <lee.ji.myung@gmail.com>
2026-10-29 04:03:30 +08:00
Joshua Snider edb79d38e3 docs: correct the documented default retry statuses (#3964)
#2349 changed the default retryable status codes to `[409, 429, 500, 502, 503, 504]`, but only the Rust docstring was updated. The Python and TypeScript bindings — and the generated TypeScript API reference — still document the old `[429, 500, 502, 503]`.

The actual default is set in `ResolvedRetryConfig::try_from` in `rust/lancedb/src/remote/retry.rs`, and `rust/lancedb/src/remote/client.rs` already documents it correctly. This brings the other three in line.

Docs only — no behavior change.

Split out from #3963 per the "one problem at a time" guidance in `CONTRIBUTING.md`.
2026-10-29 03:05:40 +08:00
J Ganesh Kumar Reddy 12d86ea251 feat(nodejs): add col() expression builder for camelCase column names
## Summary

Fixes #3211 by exposing the shared Rust/DataFusion expression builder through Node bindings. Case-sensitive references such as `col("firstName")` can be composed and passed to `where()`, while SQL strings remain supported.

The expression-object representation follows [the design requested on #3290](https://github.com/lancedb/lancedb/pull/3290#discussion_r3632371998). That earlier PR remains open; no claim is made that the issue was unclaimed or that maintainers have selected this implementation.

## Review corrections

- Construct the named native struct correctly and parse casts through `arrow_schema::DataType`.
- Preserve numeric values: use Int64 only for JavaScript safe integers; retain Float64 otherwise. Explicit `litInt` rejects unsupported numbers with a documented `RangeError`.
- Correct test syntax/API calls and align SQL assertions with the shared dialect, including reserved and case-sensitive names.
- Use typed, isolated temporary test tables with cleanup, and cover an actual large-number filter threshold.
- Document the public methods and commit generated API documentation.

Synced with current main `0bceaaf3` through a normal merge. The diff is limited to seven Node source/test/config files and eleven generated documentation files; no Rust core change.

## Validation

[Linux validation run](https://github.com/Ganesh1729-ui/lancedb/actions/runs/38244794288) on Node 24 / Rust 1.97.0 with the repository's `ci` profile and `remote,lancedb/metrics-otel` features:

- Rebuilt native addon, TypeScript build, Biome, Rust formatting and native Clippy pass.
- Expression/query/Arrow/table suites: **1,129 passed**; expression suite repeated: **42 passed**.
- Using the original JavaScript numeric dispatch with the rebuilt addon: **8 regressions fail, 2 controls pass**.
- Strict TypeDoc generation passes. Final local typing/docs/lint checks pass; the PR source equals the validated source except for the separate validation workflow, which is excluded from this PR.

Full provider/model/S3, other feature combinations and OS/Node matrices were not run in this follow-up. Upstream checks and maintainer review remain separate.

## AI assistance

AI was used for implementation, review and testing. No prior human review is claimed.
2026-10-29 02:18:16 +08:00
Lance Release ece54d8917 Bump version: 0.41.0-beta.16 → 0.41.0-beta.17 2026-10-28 17:31:48 +00:00
Brendan Clement 882be89778 docs: clarify how to contribute website documentation
The contributor guide mixes up shared documentation, Enterprise placeholders and the SDK reference. It also describes section merging that the assembler doesn't do.

This replaces the overlapping instructions with guidance on where to write, how whole-page replacement works, how to preview changes and how to keep unfinished docs hidden. It explains that source changes enter a saved release edition before they appear on staging, and points SDK contributors to the existing reference guide.
2026-10-29 00:40:13 +08:00
659ea11ac4 fix(embeddings): default Cohere to embed-multilingual-v3.0, the v2.0 models are retired (#4698)
Cohere retired `embed-english-v2.0`, `embed-english-light-v2.0` and
`embed-multilingual-v2.0` on April 4, 2026
([deprecations](https://docs.cohere.com/docs/deprecations), which lists
`embed-english-v3.0`, `embed-multilingual-v3.0` and `embed-v4.0` as the
embedding alternatives). `CohereEmbeddingFunction` still defaulted to
`embed-multilingual-v2.0`, so every call without an explicit `name`
fails.

The default is now `embed-multilingual-v3.0`, the multilingual v3 model,
and the retired models are removed from the docstring and the Cohere
integration page (the page also listed `embed-english-v2.0` as the
default, which did not match the code). The docs example, its generated
snippet, the docs test and the slow Cohere test use the new name.

This changes the default vector size: `ndims()` returns 1024 for
`embed-multilingual-v3.0`, where the old default gave 768. Tables
created from a schema that uses `cohere.ndims()` get 1024-dimension
vectors from now on. A table that already holds 768-dimension vectors
from the retired model needs a re-embed with a current model, since the
old model can no longer be called. The `ndims()` entries for the v2
names are left as they are.

Test: `test_cohere_default_model_is_not_a_retired_v2_model` in
`python/python/tests/test_embeddings.py` checks the default name and
that `ndims()` is 1024. The repository's pytest session could not be run
for this change (its `conftest.py` needs a newer native module than the
released wheel); the body of that test was run against the released
`lancedb` 0.40.0 with this version of `cohere.py` in place, where it
passes, and it returns `embed-multilingual-v2.0` / 768 without the
change. ruff check and format are clean on the touched Python files. No
Cohere request was made.

This change was made with Claude Code.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: Xuanwo <github@xuanwo.io>
2026-10-29 00:16:28 +08:00
Brendan Clement 4359688f32 ci: let the Vale action install its pinned CLI (#4708)
Let the pinned Vale action install Vale 3.24.0 instead of maintaining a
separate download and extraction step
2026-10-28 23:26:40 +08:00
Brendan Clement 149cf1052a fix(ci): bundle Vale rules to avoid private release downloads (#4707)
The prose check fails because it downloads its Vale rules from the
now-private docs repository.

Keep the five unchanged rules from `vale-lancedb-v0.1.0` in this
repository and disable `vale sync` in CI. This also works for
contributors without access to the docs repository. The update
instructions record the release and archive checksum.
2026-10-28 08:16:42 -07:00
Lance Release 45f987a29b Bump version: 0.41.0-beta.15 → 0.41.0-beta.16 2026-10-28 05:01:52 +00:00
Wyatt Alt bb6aa1a147 feat: add a cascade option to drop_database (#4697)
The remote catalog could only drop an empty database: it always asked
the server for a restricted drop.

`DropDatabaseRequest::cascade`, `drop_database(..., cascade=True)` in
Python and `dropDatabase(name, { cascade: true })` in TypeScript ask the
server to drop everything in the database first. The name stays taken
until the server finishes cleaning up the dropped objects' storage. A
restricted drop remains the default.
2026-10-27 21:51:10 -07:00
Jack YeandXuanwo 45dbf5eff5 fix: use SQL for all remote materialized view APIs (#4673)
Remote materialized-view APIs now use SQL for the full lifecycle. Create
and refresh already submit SQL; this change moves describe, paginated
listing, and drop onto `DESCRIBE MATERIALIZED VIEW`, `SHOW MATERIALIZED
VIEWS`, and `DROP MATERIALIZED VIEW`.

Async create, refresh, and drop return the existing Job handle with
`job_type = "query"`. The handle has one `id`: the connection-scoped SQL
query ID, also accepted by `describe_query`. Submission starts the
query, the job drains its result once, and repeated waits reuse the
completed result. Synchronous drop waits for catalog removal; physical
cleanup proceeds in the background.

Listing uses namespace-scoped keyset pagination with opaque resume
tokens. Streamed and deferred SQL responses share the same path. Adds
transport coverage and updates Python/TypeScript documentation for
query-backed drop jobs.

---------

Co-authored-by: Xuanwo <github@xuanwo.io>
2026-10-28 04:37:00 +08:00
Jay PokaleandXuanwo f6a348ac5b fix(python): keep FTS scores in RRF and MRR rerankers with return_score="all" (#4677)
`RRFReranker.rerank_hybrid` and `MRRReranker.rerank_hybrid` merge the
vector and FTS results with the base `merge_results`, which keeps only
the first copy of a duplicated row. With `return_score="all"`, a row
that both searches found therefore comes back with `_score = None`, even
though the FTS search scored it. `LinearCombinationReranker` already
copies the FTS score onto such rows.

Reproduction against `lancedb` 0.40.0:

```python
import pyarrow as pa
from lancedb.rerankers import RRFReranker

vector = pa.table({"_rowid": pa.array([1, 2], pa.uint64()), "text": ["a", "b"],
                   "_distance": pa.array([0.1, 0.2], pa.float32())})
fts = pa.table({"_rowid": pa.array([2, 3], pa.uint64()), "text": ["b", "c"],
                "_score": pa.array([5.0, 4.0], pa.float32())})
RRFReranker(return_score="all").rerank_hybrid("q", vector, fts).to_pylist()
# row 2: _distance=0.2, _score=None   (expected _score=5.0)
```

`table.search(query_type="hybrid")` is not affected, because
`_combine_hybrid_results` restores the original `_distance` and `_score`
by `_rowid` after reranking. The wrong value shows up when
`rerank_hybrid` is called directly, for example from a custom reranker
that wraps RRF or MRR.

The fix uses `_merge_and_keep_scores` when `return_score="all"`, the
same pattern the model-based rerankers (`CohereReranker`,
`CrossEncoderReranker`, `JinaReranker`, `OpenaiReranker`,
`VoyageAIReranker`, ...) already use. The relevance-only path is
unchanged.

Tests: added `test_rank_fusion_return_score_all_keeps_both_scores` for
both rerankers. It fails without the fix and passes with it. I ran it
against the released 0.40.0 package with this branch's
`rerankers/{base,rrf,mrr}.py` dropped in; `rrf.py` and `mrr.py` on
`main` are identical to 0.40.0. The other reranker tests give the same
results with and without the change. `ruff format` and `ruff check` are
clean.

I used an AI assistant (Claude) while working on this; I reviewed and
tested the change.

Co-authored-by: Xuanwo <github@xuanwo.io>
2026-10-28 03:33:36 +08:00