Skip to content

fix(file): verify 2.1+ nullability against name-selected columns - #9247

Open
jackylee-ch wants to merge 1 commit into
lance-format:mainfrom
jackylee-ch:fix/v21-nullability-name-selected
Open

jackylee-ch wants to merge 1 commit into
lance-format:mainfrom
jackylee-ch:fix/v21-nullability-name-selected

Conversation

@jackylee-ch

Copy link
Copy Markdown
Contributor

EncodingPipeline::verify_nullability_constraints zips batch.columns() against the schema fields positionally, while encode_batch selects each field's array with batch.column_by_name. When a batch orders its columns differently from the schema, the validated array is not the encoded one. Both directions bite: a legal null in a nullable field is rejected while the error names a field that has no nulls, and a null in a non-nullable field passes preflight and lands in a file declaring that field non-null.

#8507 fixed the same divergence for 2.0, describing it as "positional validation could diverge from name-based encoding", and the comment it removed pointed at this 2.1+ counterpart, which kept the positional pairing.

Select by name here too. A column the schema names but the batch lacks stays with encode_batch, which reports it.

Testing

cargo test --release -p lance-file --all-features (188 passed), plus fmt and clippy with -D warnings. The new test_structural_writer_verifies_name_selected_nullability covers both directions across 2.1, 2.2 and 2.3; all six cases fail on the positional pairing.

`EncodingPipeline::verify_nullability_constraints` zips `batch.columns()` against
the schema fields positionally, while `encode_batch` selects each field's array
with `batch.column_by_name`. When a batch orders its columns differently from the
schema, or carries extra ones, the array that gets validated is not the array that
gets encoded. Both directions bite: a legal null in a nullable field is rejected
while the error names a field that has no nulls, and a null in a non-nullable
field passes preflight and is written into a file whose schema declares that field
non-null, so readback hands Arrow an array contradicting its own field.

lance-format#8507 fixed this same divergence for 2.0 -- its root cause reads "the original
guard existed only in the file-writer wrapper, where positional validation could
diverge from name-based encoding" -- and the comment it removed pointed at the
2.1+ counterpart, which kept the positional pairing. Reordered batches are a
supported input, covered for 2.0 by
`test_v2_0_writer_atomically_rejects_reordered_null_structs`.

Select by name in the preflight too. A column the schema names but the batch lacks
stays with `encode_batch`, which already reports it, so no other behavior moves.

## Testing

`cargo test --release -p lance-file --all-features` (188 passed), plus `cargo fmt`
and clippy with `-D warnings`. The new
`test_structural_writer_verifies_name_selected_nullability` covers both directions
across 2.1, 2.2 and 2.3; all six cases fail on the positional pairing.
@github-actions github-actions Bot added A-encoding Encoding, IO, file reader/writer bug Something isn't working labels Sep 15, 2026

@lance-gatekeeper lance-gatekeeper Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gate recommendation: approve.

Validation now checks the same name-selected array that encoding writes, preserving reordered-batch behavior while rejecting nulls in non-nullable fields. This is the minimal 2.1–2.3 counterpart to #8507, with focused coverage for both mismatch directions.

@lance-gatekeeper lance-gatekeeper Bot added the K-approved Latest Gatekeeper recommendation permits acceptance. label Sep 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-encoding Encoding, IO, file reader/writer bug Something isn't working K-approved Latest Gatekeeper recommendation permits acceptance.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant