mirror of
https://github.com/lancedb/lancedb.git
synced 2026-11-13 14:16:54 +00:00
Published SDK builds currently expose local SQL computed columns and materialized-view execution that are not ready for release. Add the opt-in `experimental-functions` Cargo feature to the Rust core and forward it through the Python and Node bindings; published packages leave it disabled. Local declarations and refreshes now return `NotSupported` before mutating tables or spawning jobs, including prepared materialized-view creation. Remote Cloud/Enterprise client operations, Python UDF packaging, ordinary eager `add_columns`, and access to existing data remain available. Stored metadata and write protections stay active, and shared server commit helpers remain usable. CI covers both feature configurations. Existing local execution tests run with the feature enabled; default-build regressions cover early rejection, unchanged table versions, existing metadata protections, and normal eager transforms. API and source-build documentation explain the opt-in. Validation: Rust library tests pass with the feature disabled (1,869 tests) and enabled (1,947 tests), plus three default-build integration regressions. Python and TypeScript bindings were rebuilt and tested in both configurations, including mocked remote requests; Rust formatting, Python package lint, TypeScript lint/build, and generated docs were checked. Repository-wide Ruff still reports 48 pre-existing errors in unchanged `docs/web-tests` files.
59 lines
2.3 KiB
Python
59 lines
2.3 KiB
Python
# SPDX-License-Identifier: Apache-2.0
|
|
# SPDX-FileCopyrightText: Copyright The LanceDB Authors
|
|
|
|
import lancedb
|
|
import pytest
|
|
|
|
pytestmark = pytest.mark.skipif(
|
|
lancedb._lancedb._experimental_functions_enabled,
|
|
reason="tests the default build without experimental-functions",
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize("namespace", [False, True])
|
|
def test_default_build_rejects_local_functions(tmp_path, namespace):
|
|
db = (
|
|
lancedb.connect_namespace("dir", {"root": str(tmp_path)})
|
|
if namespace
|
|
else lancedb.connect(tmp_path)
|
|
)
|
|
table = db.create_table("source", [{"x": 1}, {"x": 2}])
|
|
version = table.version
|
|
operations = [
|
|
lambda: table.add_columns(computed={"doubled": "x * 2"}),
|
|
lambda: table.refresh_column("x"),
|
|
lambda: table.refresh_column_async("x"),
|
|
lambda: db.create_materialized_view("blocked", "source"),
|
|
lambda: db.create_materialized_view("blocked", "source", with_no_data=True),
|
|
lambda: db.create_materialized_view_async("blocked", "source"),
|
|
]
|
|
for operation in operations:
|
|
with pytest.raises(NotImplementedError, match="experimental-functions"):
|
|
operation()
|
|
assert table.version == version
|
|
assert db.table_names() == ["source"]
|
|
table.add_columns({"eager": "x * 2"})
|
|
assert table.to_arrow()["eager"].to_pylist() == [2, 4]
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_async_default_build_rejects_local_functions(tmp_path):
|
|
db = await lancedb.connect_async(tmp_path)
|
|
table = await db.create_table("source", [{"x": 1}, {"x": 2}])
|
|
version = await table.version()
|
|
operations = [
|
|
lambda: table.add_columns(computed={"doubled": "x * 2"}),
|
|
lambda: table.refresh_column("x"),
|
|
lambda: table.refresh_column_async("x"),
|
|
lambda: db.create_materialized_view("blocked", "source"),
|
|
lambda: db.create_materialized_view("blocked", "source", with_no_data=True),
|
|
lambda: db.create_materialized_view_async("blocked", "source"),
|
|
]
|
|
for operation in operations:
|
|
with pytest.raises(NotImplementedError, match="experimental-functions"):
|
|
await operation()
|
|
assert await table.version() == version
|
|
assert await db.table_names() == ["source"]
|
|
await table.add_columns({"eager": "x * 2"})
|
|
assert (await table.query().to_arrow())["eager"].to_pylist() == [2, 4]
|