Symptom
When decoding an empty inline-bitpacking block (num_values == 0) through the block-level decompressor InlineBitpacking::decompress (the BlockDecompressor impl in rust/lance-encoding/src/encodings/physical/bitpacking.rs), the chunk validations added in #7696 reject it as a corrupt file:
Encountered corrupt file inline_bitpacking: Inline bitpacking chunk is too small for 4-byte header: 0 bytes
instead of returning an empty DataBlock::FixedWidth.
Context
This path is pre-existing (not introduced by #7696). On main it already panicked via the old assert!(data.len() >= std::mem::size_of::<T>()). #7696 hardened unchunk and added the num_values == 0 empty-block short-circuit to the MiniBlockDecompressor::decompress impl, but not to the BlockDecompressor::decompress impl, leaving the two decompressor entry points asymmetric. Because the hardening also converted the assert! into Error::corrupt_file_at_path, the empty-block case through the block-level path now surfaces as a spurious "corrupt file" error rather than a panic — which is arguably worse for callers that distinguish corrupt-file errors from legitimate empty results.
Expected
BlockDecompressor for InlineBitpacking::decompress should short-circuit on num_values == 0 and return an empty FixedWidthDataBlock (same behavior as the MiniBlockDecompressor impl), so both decompressor paths agree and empty columns/blocks are not misreported as file corruption.
Suggested fix
Add the num_values == 0 short-circuit to BlockDecompressor::decompress, sharing an empty_block(uncompressed_bit_width) helper with the mini-block path to avoid the duplication the fix would otherwise introduce.
/cc @u70b3
Symptom
When decoding an empty inline-bitpacking block (
num_values == 0) through the block-level decompressorInlineBitpacking::decompress(theBlockDecompressorimpl inrust/lance-encoding/src/encodings/physical/bitpacking.rs), the chunk validations added in #7696 reject it as a corrupt file:instead of returning an empty
DataBlock::FixedWidth.Context
This path is pre-existing (not introduced by #7696). On
mainit already panicked via the oldassert!(data.len() >= std::mem::size_of::<T>()). #7696 hardenedunchunkand added thenum_values == 0empty-block short-circuit to theMiniBlockDecompressor::decompressimpl, but not to theBlockDecompressor::decompressimpl, leaving the two decompressor entry points asymmetric. Because the hardening also converted theassert!intoError::corrupt_file_at_path, the empty-block case through the block-level path now surfaces as a spurious "corrupt file" error rather than a panic — which is arguably worse for callers that distinguish corrupt-file errors from legitimate empty results.Expected
BlockDecompressor for InlineBitpacking::decompressshould short-circuit onnum_values == 0and return an emptyFixedWidthDataBlock(same behavior as theMiniBlockDecompressorimpl), so both decompressor paths agree and empty columns/blocks are not misreported as file corruption.Suggested fix
Add the
num_values == 0short-circuit toBlockDecompressor::decompress, sharing anempty_block(uncompressed_bit_width)helper with the mini-block path to avoid the duplication the fix would otherwise introduce./cc @u70b3