This is an automated email from the ASF dual-hosted git repository.
Jefffrey pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git
The following commit(s) were added to refs/heads/main by this push:
new 1583c8e656 [parquet] Add some tests to cover selective list child
padding (#10258)
1583c8e656 is described below
commit 1583c8e6563dca80f1380c93089a7c1052776943
Author: Andrew Lamb <[email protected]>
AuthorDate: Sat Jul 4 21:38:08 2026 -0400
[parquet] Add some tests to cover selective list child padding (#10258)
~Draft as it includes #9848 from @HippoBaro as well~
- Follow on from #9848 from @HippoBaro
There were a few uncovered cases I found via code coverage, so this PR
adds additional coverage
Changes:
- Adds an ArrowWriter round-trip test for List<Utf8View> with an item
null, a null parent list, and a long string to exercise selective
padding end to end.
- Adds a short definition-level bitmap test that covers the unfiltered
full-word append path.
---
parquet/src/arrow/arrow_writer/mod.rs | 17 +++++++++++++++++
parquet/src/arrow/record_reader/definition_levels.rs | 20 ++++++++++++++++++++
2 files changed, 37 insertions(+)
diff --git a/parquet/src/arrow/arrow_writer/mod.rs
b/parquet/src/arrow/arrow_writer/mod.rs
index e985c183ed..95d433a461 100644
--- a/parquet/src/arrow/arrow_writer/mod.rs
+++ b/parquet/src/arrow/arrow_writer/mod.rs
@@ -3862,6 +3862,23 @@ mod tests {
one_column_roundtrip(Arc::new(list), true);
}
+ #[test]
+ fn list_utf8_view_selective_padding_roundtrip() {
+ let item = Arc::new(Field::new_list_field(DataType::Utf8View, true));
+ let mut builder =
ListBuilder::new(StringViewBuilder::new()).with_field(item);
+ builder.values().append_value("a");
+ builder.values().append_null();
+ builder.append(true);
+ // The null parent list covers selective padding dropping values below
+ // the list definition level while preserving the preceding item null.
+ builder.append(false);
+ // The long string covers the non-inlined Utf8View buffer path.
+ builder.values().append_value("large payload over 12 bytes");
+ builder.append(true);
+
+ one_column_roundtrip(Arc::new(builder.finish()), true);
+ }
+
#[test]
fn struct_single_column() {
let a_values = Int32Array::from(vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
diff --git a/parquet/src/arrow/record_reader/definition_levels.rs
b/parquet/src/arrow/record_reader/definition_levels.rs
index 0720c6cdbe..a104c93a2c 100644
--- a/parquet/src/arrow/record_reader/definition_levels.rs
+++ b/parquet/src/arrow/record_reader/definition_levels.rs
@@ -504,6 +504,26 @@ mod tests {
use crate::encodings::rle::RleEncoder;
use rand::{Rng, rng};
+ #[test]
+ fn test_build_validity_bitmap_unfiltered_word_chunk() {
+ // 65 levels forces the unfiltered path to process one full u64 word
+ // with append_word, plus a remainder bit.
+ let def_levels = (0..65)
+ .map(|i| if i % 3 == 0 { 2 } else { 1 })
+ .collect::<Vec<_>>();
+ let mut bitmap = BooleanBufferBuilder::new(0);
+
+ assert_eq!(
+ build_filtered_validity_bitmap(&def_levels, None, None, 2, &mut
bitmap),
+ def_levels.len()
+ );
+
+ let bitmap = bitmap.finish();
+ for (idx, def) in def_levels.iter().enumerate() {
+ assert_eq!(bitmap.value(idx), *def >= 2);
+ }
+ }
+
#[test]
fn test_packed_decoder() {
let mut rng = rng();