Skip to content

Commit 1b17001

Browse files
[Variant] Impl Extend for VariantArrayBuilder (#8611)
# Rationale for this change This PR adds support for bulk insertion of `Option<Variant>` values into a `VariantArray` [Similar to other builders such as `GenericByteViewBuilder`](https://docs.rs/arrow/latest/arrow/array/builder/struct.GenericByteViewBuilder.html#impl-Extend%3COption%3CV%3E%3E-for-GenericByteViewBuilder%3CT%3E), it now implements the `Extend` trait For example: ```rs let mut b = VariantArrayBuilder::new(2); b.extend([None, Some(Variant::Null)]; let v = b.build(); ```
1 parent 973e6fc commit 1b17001

File tree

1 file changed

+46
-4
lines changed

1 file changed

+46
-4
lines changed

parquet-variant-compute/src/variant_array_builder.rs

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ use std::sync::Arc;
4545
/// # use arrow::array::Array;
4646
/// # use parquet_variant::{Variant, VariantBuilder, VariantBuilderExt};
4747
/// # use parquet_variant_compute::VariantArrayBuilder;
48+
/// # use parquet_variant::ShortString;
4849
/// // Create a new VariantArrayBuilder with a capacity of 100 rows
4950
/// let mut builder = VariantArrayBuilder::new(100);
5051
/// // append variant values
@@ -56,9 +57,13 @@ use std::sync::Arc;
5657
/// .with_field("foo", "bar")
5758
/// .finish();
5859
///
60+
/// // bulk insert a list of values
61+
/// // `Option::None` is a null value
62+
/// builder.extend([None, Some(Variant::from("norm"))]);
63+
///
5964
/// // create the final VariantArray
6065
/// let variant_array = builder.build();
61-
/// assert_eq!(variant_array.len(), 3);
66+
/// assert_eq!(variant_array.len(), 5);
6267
/// // // Access the values
6368
/// // row 1 is not null and is an integer
6469
/// assert!(!variant_array.is_null(0));
@@ -70,6 +75,12 @@ use std::sync::Arc;
7075
/// let value = variant_array.value(2);
7176
/// let obj = value.as_object().expect("expected object");
7277
/// assert_eq!(obj.get("foo"), Some(Variant::from("bar")));
78+
/// // row 3 is null
79+
/// assert!(variant_array.is_null(3));
80+
/// // row 4 is not null and is a short string
81+
/// assert!(!variant_array.is_null(4));
82+
/// let value = variant_array.value(4);
83+
/// assert_eq!(value, Variant::ShortString(ShortString::try_new("norm").unwrap()));
7384
/// ```
7485
#[derive(Debug)]
7586
pub struct VariantArrayBuilder {
@@ -162,6 +173,17 @@ impl VariantArrayBuilder {
162173
}
163174
}
164175

176+
impl<'m, 'v> Extend<Option<Variant<'m, 'v>>> for VariantArrayBuilder {
177+
fn extend<T: IntoIterator<Item = Option<Variant<'m, 'v>>>>(&mut self, iter: T) {
178+
for v in iter {
179+
match v {
180+
Some(v) => self.append_variant(v),
181+
None => self.append_null(),
182+
}
183+
}
184+
}
185+
}
186+
165187
/// Builder-specific state for array building that manages array-level offsets and nulls. See
166188
/// [`VariantBuilderExt`] for details.
167189
#[derive(Debug)]
@@ -438,14 +460,18 @@ fn binary_view_array_from_buffers(buffer: Vec<u8>, offsets: Vec<usize>) -> Binar
438460
mod test {
439461
use super::*;
440462
use arrow::array::Array;
441-
use parquet_variant::Variant;
463+
use parquet_variant::{ShortString, Variant};
442464

443465
/// Test that both the metadata and value buffers are non nullable
444466
#[test]
445467
fn test_variant_array_builder_non_nullable() {
446468
let mut builder = VariantArrayBuilder::new(10);
447-
builder.append_null(); // should not panic
448-
builder.append_variant(Variant::from(42i32));
469+
470+
builder.extend([
471+
None, // should not panic
472+
Some(Variant::from(42_i32)),
473+
]);
474+
449475
let variant_array = builder.build();
450476

451477
assert_eq!(variant_array.len(), 2);
@@ -500,6 +526,22 @@ mod test {
500526
assert_eq!(list.len(), 2);
501527
}
502528

529+
#[test]
530+
fn test_extend_variant_array_builder() {
531+
let mut b = VariantArrayBuilder::new(3);
532+
b.extend([None, Some(Variant::Null), Some(Variant::from("norm"))]);
533+
534+
let variant_array = b.build();
535+
536+
assert_eq!(variant_array.len(), 3);
537+
assert!(variant_array.is_null(0));
538+
assert_eq!(variant_array.value(1), Variant::Null);
539+
assert_eq!(
540+
variant_array.value(2),
541+
Variant::ShortString(ShortString::try_new("norm").unwrap())
542+
);
543+
}
544+
503545
#[test]
504546
fn test_variant_value_array_builder_basic() {
505547
let mut builder = VariantValueArrayBuilder::new(10);

0 commit comments

Comments
 (0)