Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 3 additions & 12 deletions lance_ray/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -551,19 +551,10 @@ def create_scalar_index(
f"Column {column} must be string type for {index_type} "
f"index, got {value_type}"
)
case "BTREE":
is_supported = (
pa.types.is_integer(value_type)
or pa.types.is_floating(value_type)
or pa.types.is_string(value_type)
)
if not is_supported:
raise TypeError(
f"Column {column} must be numeric or string type for BTREE "
f"index, got {value_type}"
)
case _:
# For other index types, skip strict validation to maintain compatibility
# Let pylance own scalar type compatibility for the index builder.
# Mirroring its Arrow type matrix here can reject newly-supported
# types before the lower layer gets a chance to handle them.
pass

use_segment_workflow = (
Expand Down
50 changes: 49 additions & 1 deletion tests/test_vector_index_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def id(self):

class _FakeLanceSchema:
def field(self, column):
if column not in {"value", "text"}:
if column not in {"value", "text", "large_text"}:
raise KeyError(column)
return _FakeLanceField()

Expand All @@ -82,6 +82,8 @@ def field(self, column):
return _FakeField(column, index_mod.pa.int64())
if column == "text":
return _FakeField(column, index_mod.pa.string())
if column == "large_text":
return _FakeField(column, index_mod.pa.large_string())
else:
raise KeyError(column)

Expand All @@ -91,6 +93,7 @@ def __iter__(self):
_FakeField("vector"),
_FakeField("value", index_mod.pa.int64()),
_FakeField("text", index_mod.pa.string()),
_FakeField("large_text", index_mod.pa.large_string()),
]
)

Expand Down Expand Up @@ -323,6 +326,51 @@ def fake_map_async_with_pool(**kwargs):
assert fake_dataset.commit_kwargs["segments"] == ["segment"]


def test_create_scalar_index_defers_large_string_scalar_validation(monkeypatch):
"""LargeString scalar compatibility should be delegated to pylance."""

captured = {}
fake_dataset = _FakeDataset()

def fake_handle_scalar_segment_index(**kwargs):
captured["fragment_handler_kwargs"] = kwargs
return lambda fragment_ids: {
"status": "success",
"fragment_ids": fragment_ids,
"segment_index": "segment",
}

def fake_map_async_with_pool(**kwargs):
kwargs["create_fragment_handler"]()
return [
{
"status": "success",
"fragment_ids": [0, 1],
"segment_index": "segment",
}
]

monkeypatch.setattr(index_mod, "LanceDataset", lambda *args, **kwargs: fake_dataset)
monkeypatch.setattr(
index_mod,
"_handle_scalar_segment_index",
fake_handle_scalar_segment_index,
)
monkeypatch.setattr(index_mod, "_map_async_with_pool", fake_map_async_with_pool)

updated_dataset = index_mod.create_scalar_index(
uri="memory://fake",
column="large_text",
index_type="BTREE",
num_workers=2,
)

assert updated_dataset is fake_dataset
assert captured["fragment_handler_kwargs"]["column"] == "large_text"
assert captured["fragment_handler_kwargs"]["index_type"] == "BTREE"
assert fake_dataset.commit_kwargs["segments"] == ["segment"]


def test_create_index_passes_block_size_to_loads_and_handler(monkeypatch):
"""The vector index path should use block_size for driver and worker loads."""

Expand Down
Loading