lance-format / lance-format/lance
Bug: scan fails after dropping the only original physical column and leaving all-null added columns
@Xuanwo is already working on this.
Since Jul 17, 2026.
- Dominant language
- Rust
- Stars
- 7.1k
- Forks
- 852
- Avg merge
- 3d 18h
- Merged PRs (30d)
- 272
Description
Summary
A Lance dataset can become unreadable after schema evolution if:
- The dataset is created with one physical column.
- A new nullable column is added as metadata-only / all-null.
- The original physical column is dropped.
- The dataset is scanned.
The remaining visible schema is valid and should be readable, but scanning fails because the remaining column has no physical data file in the original fragment.
Minimal Python repro
import lance
import pyarrow as pa
tmp_path = "tmp/test.lance"
schema = pa.schema({"id": pa.int64()})
table = pa.Table.from_batches([], schema=schema)
lance.write_dataset(data_obj=table, uri=tmp_path, schema=schema)
ds = lance.dataset(tmp_path)
table = pa.Table.from_pydict({"id": list(range(1, 10))})
ds.insert(table, mode="overwrite")
# This works ok
list(lance.dataset(tmp_path).scanner().to_batches())
# Add a new nullable column, without backfilling physical values
ds = lance.dataset(tmp_path)
ds.add_columns([pa.field("x", pa.int64())])
# Works ok: id plus x/nulls
list(lance.dataset(tmp_path).scanner().to_batches())
# Drop the only original physical column
ds = lance.dataset(tmp_path)
ds.drop_columns(["id"])
# Fails
list(lance.dataset(tmp_path).scanner().to_batches())
Actual behavior
Python scan fails with: Fail to find fragments as allTask.
A lower-level Rust regression test currently fails with: NotFound { uri: "Fragment 0 does not contain any data" }
Expected behavior
The dataset should remain readable after drop_columns.
After dropping id, scanning should return:
- schema: x: int64 nullable
- row count: 9
- values: x = null for all existing rows
drop_columns is metadata-only and should not make a dataset unreadable when the remaining visible columns are schema-evolution columns.
Why this matters
This breaks schema evolution workflows such as SQL DDL over Lance-backed tables:
create table t3(a int) store as lance;
insert into t3 select 1;
alter table t3 add column b int;
alter table t3 drop columns(a);
select * from t3;
Expected result:
b
----
NULL
Actual result: scan failure.
Where to check
Scanner / fragment task planning appears to assume each scanned fragment has at least one projected physical data column. After schema evolution, a fragment may have rows but no visible physical columns
because all visible columns are metadata-added all-null columns.
The scanner should still use fragment metadata row counts and synthesize null/default arrays for those columns.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.