Skip to content
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 91 additions & 2 deletions parquet-variant-compute/src/variant_array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

//! [`VariantArray`] implementation

use crate::VariantArrayBuilder;
use crate::type_conversion::{generic_conversion_single_value, primitive_conversion_single_value};
use arrow::array::{Array, ArrayRef, AsArray, BinaryViewArray, StructArray};
use arrow::buffer::NullBuffer;
Expand Down Expand Up @@ -207,7 +208,7 @@ impl ExtensionType for VariantType {
/// assert_eq!(variant_array.value(0), Variant::from("such wow"));
/// ```
///
#[derive(Clone, Debug)]
#[derive(Debug, Clone, PartialEq)]
pub struct VariantArray {
/// Reference to the underlying StructArray
inner: StructArray,
Expand Down Expand Up @@ -439,6 +440,20 @@ impl From<VariantArray> for ArrayRef {
}
}

impl<'m, 'v> FromIterator<Option<Variant<'m, 'v>>> for VariantArray {
fn from_iter<T: IntoIterator<Item = Option<Variant<'m, 'v>>>>(iter: T) -> Self {
let mut b = VariantArrayBuilder::new(0);
b.extend(iter);
b.build()
}
}

impl<'m, 'v> FromIterator<Variant<'m, 'v>> for VariantArray {
fn from_iter<T: IntoIterator<Item = Variant<'m, 'v>>>(iter: T) -> Self {
Self::from_iter(iter.into_iter().map(Some))
}
}

/// An iterator over [`VariantArray`]
///
/// This iterator returns `Option<Option<Variant<'a, 'a>>>` where:
Expand Down Expand Up @@ -724,7 +739,7 @@ impl From<ShreddedVariantFieldArray> for StructArray {
/// (partial shredding).
///
/// [Parquet Variant Shredding Spec]: https://github.com/apache/parquet-format/blob/master/VariantShredding.md#value-shredding
#[derive(Clone, Debug)]
#[derive(Debug, Clone, PartialEq)]
pub struct ShreddingState {
value: Option<BinaryViewArray>,
typed_value: Option<ArrayRef>,
Expand Down Expand Up @@ -1141,6 +1156,7 @@ mod test {
use super::*;
use arrow::array::{BinaryViewArray, Int32Array};
use arrow_schema::{Field, Fields};
use parquet_variant::ShortString;

#[test]
fn invalid_not_a_struct_array() {
Expand Down Expand Up @@ -1405,4 +1421,77 @@ mod test {
assert!(i.next().is_none());
assert!(i.next_back().is_none());
}

#[test]
fn test_from_variant_opts_into_variant_array() {
let v = vec![None, Some(Variant::Null), Some(Variant::BooleanFalse), None];

let variant_array = VariantArray::from_iter(v);

assert_eq!(variant_array.len(), 4);

assert!(variant_array.is_null(0));

assert!(!variant_array.is_null(1));
assert_eq!(variant_array.value(1), Variant::Null);

assert!(!variant_array.is_null(2));
assert_eq!(variant_array.value(2), Variant::BooleanFalse);

assert!(variant_array.is_null(3));
}

#[test]
fn test_from_variants_into_variant_array() {
let v = vec![
Variant::Null,
Variant::BooleanFalse,
Variant::ShortString(ShortString::try_new("norm").unwrap()),
];

let variant_array = VariantArray::from_iter(v);

assert_eq!(variant_array.len(), 3);

assert!(!variant_array.is_null(0));
assert_eq!(variant_array.value(0), Variant::Null);

assert!(!variant_array.is_null(1));
assert_eq!(variant_array.value(1), Variant::BooleanFalse);

assert!(!variant_array.is_null(3));
assert_eq!(
variant_array.value(2),
Variant::ShortString(ShortString::try_new("norm").unwrap())
);
}

#[test]
fn test_variant_equality() {
let v_iter = [None, Some(Variant::BooleanFalse), Some(Variant::Null), None];
let v = VariantArray::from_iter(v_iter.clone());

{
let v_copy = v.clone();
assert_eq!(v, v_copy);
}

{
let v_iter_reversed = {
let mut v = v_iter.clone();
v.reverse();

v
};

let v_reversed = VariantArray::from_iter(v_iter_reversed);

assert_ne!(v, v_reversed);
}

{
let v_sliced = v.slice(0, 1);
assert_ne!(v, v_sliced);
}
}
}
Loading