Skip to content

bug(python): Create scalar index on merge column make merge_insert update all fail completely without raising error #3515

Description

@manhld0206

LanceDB version

0.33.0

What happened?

Create scalar index on merge column make merge_insert update all fail completely without raising error.
Dropping the index will fix it.

This is related to #3177 but I don't need to run optimize to see the error so the root cause is probably the create_scalar_index function

lancedb version: 0.33.0
lance(pylance) version: 0.7.0

Are there known steps to reproduce?

import tempfile

import lance
import lancedb
import pyarrow as pa
import pyarrow.compute as pc

print(lance.__version__)
print(lancedb.__version__)

with tempfile.TemporaryDirectory() as tempdir:
    db = lancedb.connect(
        tempdir,
    )

    schema = pa.schema(
        [
            pa.field("vector", pa.list_(pa.float32(), 4), nullable=True),
            pa.field("path", pa.string(), nullable=False),
            pa.field("status", pa.utf8()),
            pa.field("file_size", pa.int64()),
        ]
    )

    # 1. Create table with 1000 rows
    tbl = db.create_table("test", schema=schema)
    records = [{"vector": None, "path": f"/img/{i}.jpg", "status": "pending", "file_size": 1000 + i} for i in range(1000)]
    print(tbl.add(pa.Table.from_pylist(records, schema=schema)))
    print(tbl.count_rows())

    # 2. Create scalar index on the merge key
    tbl.create_scalar_index("path", index_type="BTREE")

    # 3. merge_insert 128 rows
    updates = [{"path": f"/img/{i}.jpg", "vector": [0.1] * 4, "status": "indexed"} for i in range(128)]
    print(tbl.merge_insert("path").when_matched_update_all().execute(pa.Table.from_pylist(updates)))

    arrow = tbl.to_arrow().select(["status"])
    n_indexed = pc.sum(pc.equal(arrow.column("status"), "indexed")).as_py()
    print(f"Indexed: {n_indexed}")  # Expected: 128, Actual: 0

    # 4. Drop index will fix the problem
    tbl.drop_index("path_idx")
    print(tbl.merge_insert("path").when_matched_update_all().execute(pa.Table.from_pylist(updates)))

    arrow = tbl.to_arrow().select(["status"])
    n_indexed = pc.sum(pc.equal(arrow.column("status"), "indexed")).as_py()
    print(f"Indexed: {n_indexed}")  # Expected: 128, Actual: 128

Result

7.0.0
0.33.0
AddResult(version=2)
1000
MergeResult(version=4, num_updated_rows=0, num_inserted_rows=0, num_deleted_rows=0, num_attempts=1)
Indexed: 0
MergeResult(version=6, num_updated_rows=128, num_inserted_rows=0, num_deleted_rows=0, num_attempts=1)
Indexed: 128

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions