1use arrow::{
18    array::{self, Array, ArrayRef, BinaryViewArray, StructArray},
19    compute::CastOptions,
20    datatypes::Field,
21    error::Result,
22};
23use arrow_schema::{ArrowError, DataType, FieldRef};
24use parquet_variant::{VariantPath, VariantPathElement};
25
26use crate::VariantArray;
27use crate::variant_array::BorrowedShreddingState;
28use crate::variant_to_arrow::make_variant_to_arrow_row_builder;
29
30use arrow::array::AsArray;
31use std::sync::Arc;
32
33pub(crate) enum ShreddedPathStep<'a> {
34    Success(BorrowedShreddingState<'a>),
36    Missing,
39    NotShredded,
43}
44
45pub(crate) fn follow_shredded_path_element<'a>(
51    shredding_state: &BorrowedShreddingState<'a>,
52    path_element: &VariantPathElement<'_>,
53    cast_options: &CastOptions,
54) -> Result<ShreddedPathStep<'a>> {
55    let missing_path_step = || match shredding_state.value_field() {
58        Some(_) => ShreddedPathStep::NotShredded,
59        None => ShreddedPathStep::Missing,
60    };
61
62    let Some(typed_value) = shredding_state.typed_value_field() else {
63        return Ok(missing_path_step());
64    };
65
66    match path_element {
67        VariantPathElement::Field { name } => {
68            let Some(struct_array) = typed_value.as_any().downcast_ref::<StructArray>() else {
71                if !cast_options.safe {
73                    return Err(ArrowError::CastError(format!(
74                        "Cannot access field '{}' on non-struct type: {}",
75                        name,
76                        typed_value.data_type()
77                    )));
78                }
79                return Ok(missing_path_step());
81            };
82
83            let Some(field) = struct_array.column_by_name(name) else {
85                return Ok(missing_path_step());
87            };
88
89            let struct_array = field.as_struct_opt().ok_or_else(|| {
90                ArrowError::InvalidArgumentError(format!(
94                    "Expected Struct array while following path, got {}",
95                    field.data_type(),
96                ))
97            })?;
98
99            let state = BorrowedShreddingState::try_from(struct_array)?;
100            Ok(ShreddedPathStep::Success(state))
101        }
102        VariantPathElement::Index { .. } => {
103            Err(ArrowError::NotYetImplemented(
106                "Pathing into shredded variant array index".into(),
107            ))
108        }
109    }
110}
111
112fn shredded_get_path(
116    input: &VariantArray,
117    path: &[VariantPathElement<'_>],
118    as_field: Option<&Field>,
119    cast_options: &CastOptions,
120) -> Result<ArrayRef> {
121    let make_target_variant =
124        |value: Option<BinaryViewArray>,
125         typed_value: Option<ArrayRef>,
126         accumulated_nulls: Option<arrow::buffer::NullBuffer>| {
127            let metadata = input.metadata_field().clone();
128            VariantArray::from_parts(metadata, value, typed_value, accumulated_nulls)
129        };
130
131    let shred_basic_variant =
133        |target: VariantArray, path: VariantPath<'_>, as_field: Option<&Field>| {
134            let as_type = as_field.map(|f| f.data_type());
135            let mut builder = make_variant_to_arrow_row_builder(
136                target.metadata_field(),
137                path,
138                as_type,
139                cast_options,
140                target.len(),
141            )?;
142            for i in 0..target.len() {
143                if target.is_null(i) {
144                    builder.append_null()?;
145                } else if !cast_options.safe {
146                    let value = target.try_value(i)?;
147                    builder.append_value(value)?;
148                } else {
149                    let _ = match target.try_value(i) {
150                        Ok(v) => builder.append_value(v)?,
151                        Err(_) => {
152                            builder.append_null()?;
153                            false }
155                    };
156                }
157            }
158            builder.finish()
159        };
160
161    let mut shredding_state = input.shredding_state().borrow();
164    let mut accumulated_nulls = input.inner().nulls().cloned();
165    let mut path_index = 0;
166    for path_element in path {
167        match follow_shredded_path_element(&shredding_state, path_element, cast_options)? {
168            ShreddedPathStep::Success(state) => {
169                if let Some(typed_value) = shredding_state.typed_value_field() {
171                    accumulated_nulls = arrow::buffer::NullBuffer::union(
172                        accumulated_nulls.as_ref(),
173                        typed_value.nulls(),
174                    );
175                }
176                shredding_state = state;
177                path_index += 1;
178                continue;
179            }
180            ShreddedPathStep::Missing => {
181                let num_rows = input.len();
182                let arr = match as_field.map(|f| f.data_type()) {
183                    Some(data_type) => Arc::new(array::new_null_array(data_type, num_rows)) as _,
184                    None => Arc::new(array::NullArray::new(num_rows)) as _,
185                };
186                return Ok(arr);
187            }
188            ShreddedPathStep::NotShredded => {
189                let target = make_target_variant(
190                    shredding_state.value_field().cloned(),
191                    None,
192                    accumulated_nulls,
193                );
194                return shred_basic_variant(target, path[path_index..].into(), as_field);
195            }
196        };
197    }
198
199    let target = make_target_variant(
201        shredding_state.value_field().cloned(),
202        shredding_state.typed_value_field().cloned(),
203        accumulated_nulls,
204    );
205
206    let Some(as_field) = as_field else {
208        return Ok(ArrayRef::from(target));
209    };
210
211    if let DataType::Struct(fields) = as_field.data_type() {
214        let children = fields
215            .iter()
216            .map(|field| {
217                shredded_get_path(
218                    &target,
219                    &[VariantPathElement::from(field.name().as_str())],
220                    Some(field),
221                    cast_options,
222                )
223            })
224            .collect::<Result<Vec<_>>>()?;
225
226        let struct_nulls = target.nulls().cloned();
227
228        return Ok(Arc::new(StructArray::try_new(
229            fields.clone(),
230            children,
231            struct_nulls,
232        )?));
233    }
234
235    shred_basic_variant(target, VariantPath::default(), Some(as_field))
237}
238
239pub fn variant_get(input: &ArrayRef, options: GetOptions) -> Result<ArrayRef> {
251    let variant_array = VariantArray::try_new(input)?;
252
253    let GetOptions {
254        as_type,
255        path,
256        cast_options,
257    } = options;
258
259    shredded_get_path(&variant_array, &path, as_type.as_deref(), &cast_options)
260}
261
262#[derive(Debug, Clone, Default)]
264pub struct GetOptions<'a> {
265    pub path: VariantPath<'a>,
267    pub as_type: Option<FieldRef>,
271    pub cast_options: CastOptions<'a>,
273}
274
275impl<'a> GetOptions<'a> {
276    pub fn new() -> Self {
278        Default::default()
279    }
280
281    pub fn new_with_path(path: VariantPath<'a>) -> Self {
283        Self {
284            path,
285            as_type: None,
286            cast_options: Default::default(),
287        }
288    }
289
290    pub fn with_as_type(mut self, as_type: Option<FieldRef>) -> Self {
292        self.as_type = as_type;
293        self
294    }
295
296    pub fn with_cast_options(mut self, cast_options: CastOptions<'a>) -> Self {
298        self.cast_options = cast_options;
299        self
300    }
301}
302
303#[cfg(test)]
304mod test {
305    use std::str::FromStr;
306    use std::sync::Arc;
307
308    use super::{GetOptions, variant_get};
309    use crate::variant_array::{ShreddedVariantFieldArray, StructArrayBuilder};
310    use crate::{VariantArray, VariantArrayBuilder, json_to_variant};
311    use arrow::array::{
312        Array, ArrayRef, AsArray, BinaryViewArray, BooleanArray, Date32Array, Decimal32Array,
313        Decimal64Array, Decimal128Array, Decimal256Array, Float32Array, Float64Array, Int8Array,
314        Int16Array, Int32Array, Int64Array, NullBuilder, StringArray, StructArray,
315        Time64MicrosecondArray,
316    };
317    use arrow::buffer::NullBuffer;
318    use arrow::compute::CastOptions;
319    use arrow::datatypes::DataType::{Int16, Int32, Int64};
320    use arrow::datatypes::i256;
321    use arrow_schema::DataType::{Boolean, Float32, Float64, Int8};
322    use arrow_schema::{DataType, Field, FieldRef, Fields, TimeUnit};
323    use chrono::DateTime;
324    use parquet_variant::{
325        EMPTY_VARIANT_METADATA_BYTES, Variant, VariantDecimal4, VariantDecimal8, VariantDecimal16,
326        VariantDecimalType, VariantPath,
327    };
328
329    fn single_variant_get_test(input_json: &str, path: VariantPath, expected_json: &str) {
330        let input_array_ref: ArrayRef = Arc::new(StringArray::from(vec![Some(input_json)]));
332        let input_variant_array_ref = ArrayRef::from(json_to_variant(&input_array_ref).unwrap());
333
334        let result =
335            variant_get(&input_variant_array_ref, GetOptions::new_with_path(path)).unwrap();
336
337        let expected_array_ref: ArrayRef = Arc::new(StringArray::from(vec![Some(expected_json)]));
339        let expected_variant_array = json_to_variant(&expected_array_ref).unwrap();
340
341        let result_array = VariantArray::try_new(&result).unwrap();
342        assert_eq!(
343            result_array.len(),
344            1,
345            "Expected result array to have length 1"
346        );
347        assert!(
348            result_array.nulls().is_none(),
349            "Expected no nulls in result array"
350        );
351        let result_variant = result_array.value(0);
352        let expected_variant = expected_variant_array.value(0);
353        assert_eq!(
354            result_variant, expected_variant,
355            "Result variant does not match expected variant"
356        );
357    }
358
359    #[test]
360    fn get_primitive_variant_field() {
361        single_variant_get_test(
362            r#"{"some_field": 1234}"#,
363            VariantPath::from("some_field"),
364            "1234",
365        );
366    }
367
368    #[test]
369    fn get_primitive_variant_list_index() {
370        single_variant_get_test("[1234, 5678]", VariantPath::from(0), "1234");
371    }
372
373    #[test]
374    fn get_primitive_variant_inside_object_of_object() {
375        single_variant_get_test(
376            r#"{"top_level_field": {"inner_field": 1234}}"#,
377            VariantPath::from("top_level_field").join("inner_field"),
378            "1234",
379        );
380    }
381
382    #[test]
383    fn get_primitive_variant_inside_list_of_object() {
384        single_variant_get_test(
385            r#"[{"some_field": 1234}]"#,
386            VariantPath::from(0).join("some_field"),
387            "1234",
388        );
389    }
390
391    #[test]
392    fn get_primitive_variant_inside_object_of_list() {
393        single_variant_get_test(
394            r#"{"some_field": [1234]}"#,
395            VariantPath::from("some_field").join(0),
396            "1234",
397        );
398    }
399
400    #[test]
401    fn get_complex_variant() {
402        single_variant_get_test(
403            r#"{"top_level_field": {"inner_field": 1234}}"#,
404            VariantPath::from("top_level_field"),
405            r#"{"inner_field": 1234}"#,
406        );
407    }
408
409    macro_rules! numeric_partially_shredded_test {
411        ($primitive_type:ty, $data_fn:ident) => {
412            let array = $data_fn();
413            let options = GetOptions::new();
414            let result = variant_get(&array, options).unwrap();
415
416            let result = VariantArray::try_new(&result).unwrap();
418            assert_eq!(result.len(), 4);
419
420            assert_eq!(
422                result.value(0),
423                Variant::from(<$primitive_type>::try_from(34u8).unwrap())
424            );
425            assert!(!result.is_valid(1));
426            assert_eq!(result.value(2), Variant::from("n/a"));
427            assert_eq!(
428                result.value(3),
429                Variant::from(<$primitive_type>::try_from(100u8).unwrap())
430            );
431        };
432    }
433
434    macro_rules! partially_shredded_variant_array_gen {
435        ($func_name:ident,  $typed_value_array_gen: expr) => {
436            fn $func_name() -> ArrayRef {
437                let (metadata, string_value) = {
438                    let mut builder = parquet_variant::VariantBuilder::new();
439                    builder.append_value("n/a");
440                    builder.finish()
441                };
442
443                let nulls = NullBuffer::from(vec![
444                    true,  false, true,  true,  ]);
449
450                let metadata = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 4));
452
453                let values = BinaryViewArray::from(vec![
456                    None,                Some(b"" as &[u8]),  Some(&string_value), None,                ]);
461
462                let typed_value = $typed_value_array_gen();
463
464                let struct_array = StructArrayBuilder::new()
465                    .with_field("metadata", Arc::new(metadata), false)
466                    .with_field("typed_value", Arc::new(typed_value), true)
467                    .with_field("value", Arc::new(values), true)
468                    .with_nulls(nulls)
469                    .build();
470                ArrayRef::from(
471                    VariantArray::try_new(&struct_array).expect("should create variant array"),
472                )
473            }
474        };
475    }
476
477    #[test]
478    fn get_variant_partially_shredded_int8_as_variant() {
479        numeric_partially_shredded_test!(i8, partially_shredded_int8_variant_array);
480    }
481
482    #[test]
483    fn get_variant_partially_shredded_int16_as_variant() {
484        numeric_partially_shredded_test!(i16, partially_shredded_int16_variant_array);
485    }
486
487    #[test]
488    fn get_variant_partially_shredded_int32_as_variant() {
489        numeric_partially_shredded_test!(i32, partially_shredded_int32_variant_array);
490    }
491
492    #[test]
493    fn get_variant_partially_shredded_int64_as_variant() {
494        numeric_partially_shredded_test!(i64, partially_shredded_int64_variant_array);
495    }
496
497    #[test]
498    fn get_variant_partially_shredded_float32_as_variant() {
499        numeric_partially_shredded_test!(f32, partially_shredded_float32_variant_array);
500    }
501
502    #[test]
503    fn get_variant_partially_shredded_float64_as_variant() {
504        numeric_partially_shredded_test!(f64, partially_shredded_float64_variant_array);
505    }
506
507    #[test]
508    fn get_variant_partially_shredded_bool_as_variant() {
509        let array = partially_shredded_bool_variant_array();
510        let options = GetOptions::new();
511        let result = variant_get(&array, options).unwrap();
512
513        let result = VariantArray::try_new(&result).unwrap();
515        assert_eq!(result.len(), 4);
516
517        assert_eq!(result.value(0), Variant::from(true));
519        assert!(!result.is_valid(1));
520        assert_eq!(result.value(2), Variant::from("n/a"));
521        assert_eq!(result.value(3), Variant::from(false));
522    }
523
524    #[test]
525    fn get_variant_partially_shredded_utf8_as_variant() {
526        let array = partially_shredded_utf8_variant_array();
527        let options = GetOptions::new();
528        let result = variant_get(&array, options).unwrap();
529
530        let result = VariantArray::try_new(&result).unwrap();
532        assert_eq!(result.len(), 4);
533
534        assert_eq!(result.value(0), Variant::from("hello"));
536        assert!(!result.is_valid(1));
537        assert_eq!(result.value(2), Variant::from("n/a"));
538        assert_eq!(result.value(3), Variant::from("world"));
539    }
540
541    partially_shredded_variant_array_gen!(partially_shredded_binary_view_variant_array, || {
542        BinaryViewArray::from(vec![
543            Some(&[1u8, 2u8, 3u8][..]), None,                       None,                       Some(&[4u8, 5u8, 6u8][..]), ])
548    });
549
550    #[test]
551    fn get_variant_partially_shredded_date32_as_variant() {
552        let array = partially_shredded_date32_variant_array();
553        let options = GetOptions::new();
554        let result = variant_get(&array, options).unwrap();
555
556        let result = VariantArray::try_new(&result).unwrap();
558        assert_eq!(result.len(), 4);
559
560        use chrono::NaiveDate;
562        let date1 = NaiveDate::from_ymd_opt(2025, 9, 17).unwrap();
563        let date2 = NaiveDate::from_ymd_opt(2025, 9, 9).unwrap();
564        assert_eq!(result.value(0), Variant::from(date1));
565        assert!(!result.is_valid(1));
566        assert_eq!(result.value(2), Variant::from("n/a"));
567        assert_eq!(result.value(3), Variant::from(date2));
568    }
569
570    #[test]
571    fn get_variant_partially_shredded_binary_view_as_variant() {
572        let array = partially_shredded_binary_view_variant_array();
573        let options = GetOptions::new();
574        let result = variant_get(&array, options).unwrap();
575
576        let result = VariantArray::try_new(&result).unwrap();
578        assert_eq!(result.len(), 4);
579
580        assert_eq!(result.value(0), Variant::from(&[1u8, 2u8, 3u8][..]));
582        assert!(!result.is_valid(1));
583        assert_eq!(result.value(2), Variant::from("n/a"));
584        assert_eq!(result.value(3), Variant::from(&[4u8, 5u8, 6u8][..]));
585    }
586
587    #[test]
589    fn get_variant_shredded_int32_as_int32_safe_cast() {
590        let array = partially_shredded_int32_variant_array();
592        let field = Field::new("typed_value", DataType::Int32, true);
594        let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
595        let result = variant_get(&array, options).unwrap();
596        let expected: ArrayRef = Arc::new(Int32Array::from(vec![
597            Some(34),
598            None,
599            None, Some(100),
601        ]));
602        assert_eq!(&result, &expected)
603    }
604
605    #[test]
607    fn get_variant_shredded_int32_as_int32_unsafe_cast() {
608        let array = partially_shredded_int32_variant_array();
610        let field = Field::new("typed_value", DataType::Int32, true);
611        let cast_options = CastOptions {
612            safe: false, ..Default::default()
614        };
615        let options = GetOptions::new()
616            .with_as_type(Some(FieldRef::from(field)))
617            .with_cast_options(cast_options);
618
619        let err = variant_get(&array, options).unwrap_err();
620        assert_eq!(
622            err.to_string(),
623            "Cast error: Failed to extract primitive of type Int32 from variant ShortString(ShortString(\"n/a\")) at path VariantPath([])"
624        );
625    }
626
627    macro_rules! numeric_perfectly_shredded_test {
629        ($primitive_type:ty, $data_fn:ident) => {
630            let array = $data_fn();
631            let options = GetOptions::new();
632            let result = variant_get(&array, options).unwrap();
633
634            let result = VariantArray::try_new(&result).unwrap();
636            assert_eq!(result.len(), 3);
637
638            assert_eq!(
640                result.value(0),
641                Variant::from(<$primitive_type>::try_from(1u8).unwrap())
642            );
643            assert_eq!(
644                result.value(1),
645                Variant::from(<$primitive_type>::try_from(2u8).unwrap())
646            );
647            assert_eq!(
648                result.value(2),
649                Variant::from(<$primitive_type>::try_from(3u8).unwrap())
650            );
651        };
652    }
653
654    #[test]
655    fn get_variant_perfectly_shredded_int8_as_variant() {
656        numeric_perfectly_shredded_test!(i8, perfectly_shredded_int8_variant_array);
657    }
658
659    #[test]
660    fn get_variant_perfectly_shredded_int16_as_variant() {
661        numeric_perfectly_shredded_test!(i16, perfectly_shredded_int16_variant_array);
662    }
663
664    #[test]
665    fn get_variant_perfectly_shredded_int32_as_variant() {
666        numeric_perfectly_shredded_test!(i32, perfectly_shredded_int32_variant_array);
667    }
668
669    #[test]
670    fn get_variant_perfectly_shredded_int64_as_variant() {
671        numeric_perfectly_shredded_test!(i64, perfectly_shredded_int64_variant_array);
672    }
673
674    #[test]
675    fn get_variant_perfectly_shredded_float32_as_variant() {
676        numeric_perfectly_shredded_test!(f32, perfectly_shredded_float32_variant_array);
677    }
678
679    #[test]
680    fn get_variant_perfectly_shredded_float64_as_variant() {
681        numeric_perfectly_shredded_test!(f64, perfectly_shredded_float64_variant_array);
682    }
683
684    #[test]
686    fn get_variant_all_null_as_variant() {
687        let array = all_null_variant_array();
688        let options = GetOptions::new();
689        let result = variant_get(&array, options).unwrap();
690
691        let result = VariantArray::try_new(&result).unwrap();
693        assert_eq!(result.len(), 3);
694
695        assert!(!result.is_valid(0));
697        assert!(!result.is_valid(1));
698        assert!(!result.is_valid(2));
699    }
700
701    #[test]
703    fn get_variant_all_null_as_int32() {
704        let array = all_null_variant_array();
705        let field = Field::new("typed_value", DataType::Int32, true);
707        let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
708        let result = variant_get(&array, options).unwrap();
709
710        let expected: ArrayRef = Arc::new(Int32Array::from(vec![
711            Option::<i32>::None,
712            Option::<i32>::None,
713            Option::<i32>::None,
714        ]));
715        assert_eq!(&result, &expected)
716    }
717
718    macro_rules! perfectly_shredded_to_arrow_primitive_test {
719        ($name:ident, $primitive_type:expr, $perfectly_shredded_array_gen_fun:ident, $expected_array:expr) => {
720            #[test]
721            fn $name() {
722                let array = $perfectly_shredded_array_gen_fun();
723                let field = Field::new("typed_value", $primitive_type, true);
724                let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
725                let result = variant_get(&array, options).unwrap();
726                let expected_array: ArrayRef = Arc::new($expected_array);
727                assert_eq!(&result, &expected_array);
728            }
729        };
730    }
731
732    perfectly_shredded_to_arrow_primitive_test!(
733        get_variant_perfectly_shredded_int18_as_int8,
734        Int8,
735        perfectly_shredded_int8_variant_array,
736        Int8Array::from(vec![Some(1), Some(2), Some(3)])
737    );
738
739    perfectly_shredded_to_arrow_primitive_test!(
740        get_variant_perfectly_shredded_int16_as_int16,
741        Int16,
742        perfectly_shredded_int16_variant_array,
743        Int16Array::from(vec![Some(1), Some(2), Some(3)])
744    );
745
746    perfectly_shredded_to_arrow_primitive_test!(
747        get_variant_perfectly_shredded_int32_as_int32,
748        Int32,
749        perfectly_shredded_int32_variant_array,
750        Int32Array::from(vec![Some(1), Some(2), Some(3)])
751    );
752
753    perfectly_shredded_to_arrow_primitive_test!(
754        get_variant_perfectly_shredded_int64_as_int64,
755        Int64,
756        perfectly_shredded_int64_variant_array,
757        Int64Array::from(vec![Some(1), Some(2), Some(3)])
758    );
759
760    perfectly_shredded_to_arrow_primitive_test!(
761        get_variant_perfectly_shredded_float32_as_float32,
762        Float32,
763        perfectly_shredded_float32_variant_array,
764        Float32Array::from(vec![Some(1.0), Some(2.0), Some(3.0)])
765    );
766
767    perfectly_shredded_to_arrow_primitive_test!(
768        get_variant_perfectly_shredded_float64_as_float64,
769        Float64,
770        perfectly_shredded_float64_variant_array,
771        Float64Array::from(vec![Some(1.0), Some(2.0), Some(3.0)])
772    );
773
774    perfectly_shredded_to_arrow_primitive_test!(
775        get_variant_perfectly_shredded_boolean_as_boolean,
776        Boolean,
777        perfectly_shredded_bool_variant_array,
778        BooleanArray::from(vec![Some(true), Some(false), Some(true)])
779    );
780
781    macro_rules! perfectly_shredded_variant_array_fn {
782        ($func:ident, $typed_value_gen:expr) => {
783            fn $func() -> ArrayRef {
784                let metadata = BinaryViewArray::from_iter_values(std::iter::repeat_n(
787                    EMPTY_VARIANT_METADATA_BYTES,
788                    3,
789                ));
790                let typed_value = $typed_value_gen();
791
792                let struct_array = StructArrayBuilder::new()
793                    .with_field("metadata", Arc::new(metadata), false)
794                    .with_field("typed_value", Arc::new(typed_value), true)
795                    .build();
796
797                VariantArray::try_new(&struct_array)
798                    .expect("should create variant array")
799                    .into()
800            }
801        };
802    }
803
804    perfectly_shredded_variant_array_fn!(perfectly_shredded_bool_variant_array, || {
805        BooleanArray::from(vec![Some(true), Some(false), Some(true)])
806    });
807
808    macro_rules! numeric_perfectly_shredded_variant_array_fn {
820        ($func:ident, $array_type:ident, $primitive_type:ty) => {
821            perfectly_shredded_variant_array_fn!($func, || {
822                $array_type::from(vec![
823                    Some(<$primitive_type>::try_from(1u8).unwrap()),
824                    Some(<$primitive_type>::try_from(2u8).unwrap()),
825                    Some(<$primitive_type>::try_from(3u8).unwrap()),
826                ])
827            });
828        };
829    }
830
831    numeric_perfectly_shredded_variant_array_fn!(
832        perfectly_shredded_int8_variant_array,
833        Int8Array,
834        i8
835    );
836    numeric_perfectly_shredded_variant_array_fn!(
837        perfectly_shredded_int16_variant_array,
838        Int16Array,
839        i16
840    );
841    numeric_perfectly_shredded_variant_array_fn!(
842        perfectly_shredded_int32_variant_array,
843        Int32Array,
844        i32
845    );
846    numeric_perfectly_shredded_variant_array_fn!(
847        perfectly_shredded_int64_variant_array,
848        Int64Array,
849        i64
850    );
851    numeric_perfectly_shredded_variant_array_fn!(
852        perfectly_shredded_float32_variant_array,
853        Float32Array,
854        f32
855    );
856    numeric_perfectly_shredded_variant_array_fn!(
857        perfectly_shredded_float64_variant_array,
858        Float64Array,
859        f64
860    );
861
862    perfectly_shredded_variant_array_fn!(
863        perfectly_shredded_timestamp_micro_ntz_variant_array,
864        || {
865            arrow::array::TimestampMicrosecondArray::from(vec![
866                Some(-456000),
867                Some(1758602096000001),
868                Some(1758602096000002),
869            ])
870        }
871    );
872
873    perfectly_shredded_to_arrow_primitive_test!(
874        get_variant_perfectly_shredded_timestamp_micro_ntz_as_timestamp_micro_ntz,
875        DataType::Timestamp(TimeUnit::Microsecond, None),
876        perfectly_shredded_timestamp_micro_ntz_variant_array,
877        arrow::array::TimestampMicrosecondArray::from(vec![
878            Some(-456000),
879            Some(1758602096000001),
880            Some(1758602096000002),
881        ])
882    );
883
884    perfectly_shredded_to_arrow_primitive_test!(
886        get_variant_perfectly_shredded_timestamp_micro_ntz_as_nano_ntz,
887        DataType::Timestamp(TimeUnit::Nanosecond, None),
888        perfectly_shredded_timestamp_micro_ntz_variant_array,
889        arrow::array::TimestampNanosecondArray::from(vec![
890            Some(-456000000),
891            Some(1758602096000001000),
892            Some(1758602096000002000)
893        ])
894    );
895
896    perfectly_shredded_variant_array_fn!(perfectly_shredded_timestamp_micro_variant_array, || {
897        arrow::array::TimestampMicrosecondArray::from(vec![
898            Some(-456000),
899            Some(1758602096000001),
900            Some(1758602096000002),
901        ])
902        .with_timezone("+00:00")
903    });
904
905    perfectly_shredded_to_arrow_primitive_test!(
906        get_variant_perfectly_shredded_timestamp_micro_as_timestamp_micro,
907        DataType::Timestamp(TimeUnit::Microsecond, Some(Arc::from("+00:00"))),
908        perfectly_shredded_timestamp_micro_variant_array,
909        arrow::array::TimestampMicrosecondArray::from(vec![
910            Some(-456000),
911            Some(1758602096000001),
912            Some(1758602096000002),
913        ])
914        .with_timezone("+00:00")
915    );
916
917    perfectly_shredded_to_arrow_primitive_test!(
919        get_variant_perfectly_shredded_timestamp_micro_as_nano,
920        DataType::Timestamp(TimeUnit::Nanosecond, Some(Arc::from("+00:00"))),
921        perfectly_shredded_timestamp_micro_variant_array,
922        arrow::array::TimestampNanosecondArray::from(vec![
923            Some(-456000000),
924            Some(1758602096000001000),
925            Some(1758602096000002000)
926        ])
927        .with_timezone("+00:00")
928    );
929
930    perfectly_shredded_variant_array_fn!(
931        perfectly_shredded_timestamp_nano_ntz_variant_array,
932        || {
933            arrow::array::TimestampNanosecondArray::from(vec![
934                Some(-4999999561),
935                Some(1758602096000000001),
936                Some(1758602096000000002),
937            ])
938        }
939    );
940
941    perfectly_shredded_to_arrow_primitive_test!(
942        get_variant_perfectly_shredded_timestamp_nano_ntz_as_timestamp_nano_ntz,
943        DataType::Timestamp(TimeUnit::Nanosecond, None),
944        perfectly_shredded_timestamp_nano_ntz_variant_array,
945        arrow::array::TimestampNanosecondArray::from(vec![
946            Some(-4999999561),
947            Some(1758602096000000001),
948            Some(1758602096000000002),
949        ])
950    );
951
952    perfectly_shredded_variant_array_fn!(perfectly_shredded_timestamp_nano_variant_array, || {
953        arrow::array::TimestampNanosecondArray::from(vec![
954            Some(-4999999561),
955            Some(1758602096000000001),
956            Some(1758602096000000002),
957        ])
958        .with_timezone("+00:00")
959    });
960
961    perfectly_shredded_to_arrow_primitive_test!(
962        get_variant_perfectly_shredded_timestamp_nano_as_timestamp_nano,
963        DataType::Timestamp(TimeUnit::Nanosecond, Some(Arc::from("+00:00"))),
964        perfectly_shredded_timestamp_nano_variant_array,
965        arrow::array::TimestampNanosecondArray::from(vec![
966            Some(-4999999561),
967            Some(1758602096000000001),
968            Some(1758602096000000002),
969        ])
970        .with_timezone("+00:00")
971    );
972
973    perfectly_shredded_variant_array_fn!(perfectly_shredded_date_variant_array, || {
974        Date32Array::from(vec![Some(-12345), Some(17586), Some(20000)])
975    });
976
977    perfectly_shredded_to_arrow_primitive_test!(
978        get_variant_perfectly_shredded_date_as_date,
979        DataType::Date32,
980        perfectly_shredded_date_variant_array,
981        Date32Array::from(vec![Some(-12345), Some(17586), Some(20000)])
982    );
983
984    perfectly_shredded_variant_array_fn!(perfectly_shredded_time_variant_array, || {
985        Time64MicrosecondArray::from(vec![Some(12345000), Some(87654000), Some(135792000)])
986    });
987
988    perfectly_shredded_to_arrow_primitive_test!(
989        get_variant_perfectly_shredded_time_as_time,
990        DataType::Time64(TimeUnit::Microsecond),
991        perfectly_shredded_time_variant_array,
992        Time64MicrosecondArray::from(vec![Some(12345000), Some(87654000), Some(135792000)])
993    );
994
995    perfectly_shredded_variant_array_fn!(perfectly_shredded_null_variant_array, || {
996        let mut builder = NullBuilder::new();
997        builder.append_nulls(3);
998        builder.finish()
999    });
1000
1001    perfectly_shredded_to_arrow_primitive_test!(
1002        get_variant_perfectly_shredded_null_as_null,
1003        DataType::Null,
1004        perfectly_shredded_null_variant_array,
1005        arrow::array::NullArray::new(3)
1006    );
1007
1008    perfectly_shredded_variant_array_fn!(perfectly_shredded_decimal4_variant_array, || {
1009        Decimal32Array::from(vec![Some(12345), Some(23400), Some(-12342)])
1010            .with_precision_and_scale(5, 2)
1011            .unwrap()
1012    });
1013
1014    perfectly_shredded_to_arrow_primitive_test!(
1015        get_variant_perfectly_shredded_decimal4_as_decimal4,
1016        DataType::Decimal32(5, 2),
1017        perfectly_shredded_decimal4_variant_array,
1018        Decimal32Array::from(vec![Some(12345), Some(23400), Some(-12342)])
1019            .with_precision_and_scale(5, 2)
1020            .unwrap()
1021    );
1022
1023    perfectly_shredded_variant_array_fn!(
1024        perfectly_shredded_decimal8_variant_array_cast2decimal32,
1025        || {
1026            Decimal64Array::from(vec![Some(123456), Some(145678), Some(-123456)])
1027                .with_precision_and_scale(6, 1)
1028                .unwrap()
1029        }
1030    );
1031
1032    perfectly_shredded_to_arrow_primitive_test!(
1036        get_variant_perfectly_shredded_decimal8_through_decimal32_as_decimal8,
1037        DataType::Decimal64(6, 1),
1038        perfectly_shredded_decimal8_variant_array_cast2decimal32,
1039        Decimal64Array::from(vec![Some(123456), Some(145678), Some(-123456)])
1040            .with_precision_and_scale(6, 1)
1041            .unwrap()
1042    );
1043
1044    perfectly_shredded_variant_array_fn!(perfectly_shredded_decimal8_variant_array, || {
1047        Decimal64Array::from(vec![Some(1234567809), Some(1456787000), Some(-1234561203)])
1048            .with_precision_and_scale(10, 1)
1049            .unwrap()
1050    });
1051
1052    perfectly_shredded_to_arrow_primitive_test!(
1053        get_variant_perfectly_shredded_decimal8_as_decimal8,
1054        DataType::Decimal64(10, 1),
1055        perfectly_shredded_decimal8_variant_array,
1056        Decimal64Array::from(vec![Some(1234567809), Some(1456787000), Some(-1234561203)])
1057            .with_precision_and_scale(10, 1)
1058            .unwrap()
1059    );
1060
1061    perfectly_shredded_variant_array_fn!(
1064        perfectly_shredded_decimal16_within_decimal4_variant_array,
1065        || {
1066            Decimal128Array::from(vec![
1067                Some(i128::from(1234589)),
1068                Some(i128::from(2344444)),
1069                Some(i128::from(-1234789)),
1070            ])
1071            .with_precision_and_scale(7, 3)
1072            .unwrap()
1073        }
1074    );
1075
1076    perfectly_shredded_to_arrow_primitive_test!(
1079        get_variant_perfectly_shredded_decimal16_within_decimal4_as_decimal16,
1080        DataType::Decimal128(7, 3),
1081        perfectly_shredded_decimal16_within_decimal4_variant_array,
1082        Decimal128Array::from(vec![
1083            Some(i128::from(1234589)),
1084            Some(i128::from(2344444)),
1085            Some(i128::from(-1234789)),
1086        ])
1087        .with_precision_and_scale(7, 3)
1088        .unwrap()
1089    );
1090
1091    perfectly_shredded_variant_array_fn!(
1092        perfectly_shredded_decimal16_within_decimal8_variant_array,
1093        || {
1094            Decimal128Array::from(vec![Some(1234567809), Some(1456787000), Some(-1234561203)])
1095                .with_precision_and_scale(10, 1)
1096                .unwrap()
1097        }
1098    );
1099
1100    perfectly_shredded_to_arrow_primitive_test!(
1103        get_variant_perfectly_shredded_decimal16_within8_as_decimal16,
1104        DataType::Decimal128(10, 1),
1105        perfectly_shredded_decimal16_within_decimal8_variant_array,
1106        Decimal128Array::from(vec![Some(1234567809), Some(1456787000), Some(-1234561203)])
1107            .with_precision_and_scale(10, 1)
1108            .unwrap()
1109    );
1110
1111    perfectly_shredded_variant_array_fn!(perfectly_shredded_decimal16_variant_array, || {
1112        Decimal128Array::from(vec![
1113            Some(i128::from_str("12345678901234567899").unwrap()),
1114            Some(i128::from_str("23445677483748324300").unwrap()),
1115            Some(i128::from_str("-12345678901234567899").unwrap()),
1116        ])
1117        .with_precision_and_scale(20, 3)
1118        .unwrap()
1119    });
1120
1121    perfectly_shredded_to_arrow_primitive_test!(
1124        get_variant_perfectly_shredded_decimal16_as_decimal16,
1125        DataType::Decimal128(20, 3),
1126        perfectly_shredded_decimal16_variant_array,
1127        Decimal128Array::from(vec![
1128            Some(i128::from_str("12345678901234567899").unwrap()),
1129            Some(i128::from_str("23445677483748324300").unwrap()),
1130            Some(i128::from_str("-12345678901234567899").unwrap())
1131        ])
1132        .with_precision_and_scale(20, 3)
1133        .unwrap()
1134    );
1135
1136    macro_rules! assert_variant_get_as_variant_array_with_default_option {
1137        ($variant_array: expr, $array_expected: expr) => {{
1138            let options = GetOptions::new();
1139            let array = $variant_array;
1140            let result = variant_get(&array, options).unwrap();
1141
1142            let result = VariantArray::try_new(&result).unwrap();
1144
1145            assert_eq!(result.len(), $array_expected.len());
1146
1147            for (idx, item) in $array_expected.into_iter().enumerate() {
1148                match item {
1149                    Some(item) => assert_eq!(result.value(idx), item),
1150                    None => assert!(result.is_null(idx)),
1151                }
1152            }
1153        }};
1154    }
1155
1156    partially_shredded_variant_array_gen!(
1157        partially_shredded_timestamp_micro_ntz_variant_array,
1158        || {
1159            arrow::array::TimestampMicrosecondArray::from(vec![
1160                Some(-456000),
1161                None,
1162                None,
1163                Some(1758602096000000),
1164            ])
1165        }
1166    );
1167
1168    #[test]
1169    fn get_variant_partial_shredded_timestamp_micro_ntz_as_variant() {
1170        let array = partially_shredded_timestamp_micro_ntz_variant_array();
1171        assert_variant_get_as_variant_array_with_default_option!(
1172            array,
1173            vec![
1174                Some(Variant::from(
1175                    DateTime::from_timestamp_micros(-456000i64)
1176                        .unwrap()
1177                        .naive_utc(),
1178                )),
1179                None,
1180                Some(Variant::from("n/a")),
1181                Some(Variant::from(
1182                    DateTime::parse_from_rfc3339("2025-09-23T12:34:56+08:00")
1183                        .unwrap()
1184                        .naive_utc(),
1185                )),
1186            ]
1187        )
1188    }
1189
1190    partially_shredded_variant_array_gen!(partially_shredded_timestamp_micro_variant_array, || {
1191        arrow::array::TimestampMicrosecondArray::from(vec![
1192            Some(-456000),
1193            None,
1194            None,
1195            Some(1758602096000000),
1196        ])
1197        .with_timezone("+00:00")
1198    });
1199
1200    #[test]
1201    fn get_variant_partial_shredded_timestamp_micro_as_variant() {
1202        let array = partially_shredded_timestamp_micro_variant_array();
1203        assert_variant_get_as_variant_array_with_default_option!(
1204            array,
1205            vec![
1206                Some(Variant::from(
1207                    DateTime::from_timestamp_micros(-456000i64)
1208                        .unwrap()
1209                        .to_utc(),
1210                )),
1211                None,
1212                Some(Variant::from("n/a")),
1213                Some(Variant::from(
1214                    DateTime::parse_from_rfc3339("2025-09-23T12:34:56+08:00")
1215                        .unwrap()
1216                        .to_utc(),
1217                )),
1218            ]
1219        )
1220    }
1221
1222    partially_shredded_variant_array_gen!(
1223        partially_shredded_timestamp_nano_ntz_variant_array,
1224        || {
1225            arrow::array::TimestampNanosecondArray::from(vec![
1226                Some(-4999999561),
1227                None,
1228                None,
1229                Some(1758602096000000000),
1230            ])
1231        }
1232    );
1233
1234    #[test]
1235    fn get_variant_partial_shredded_timestamp_nano_ntz_as_variant() {
1236        let array = partially_shredded_timestamp_nano_ntz_variant_array();
1237
1238        assert_variant_get_as_variant_array_with_default_option!(
1239            array,
1240            vec![
1241                Some(Variant::from(
1242                    DateTime::from_timestamp(-5, 439).unwrap().naive_utc()
1243                )),
1244                None,
1245                Some(Variant::from("n/a")),
1246                Some(Variant::from(
1247                    DateTime::parse_from_rfc3339("2025-09-23T12:34:56+08:00")
1248                        .unwrap()
1249                        .naive_utc()
1250                )),
1251            ]
1252        )
1253    }
1254
1255    partially_shredded_variant_array_gen!(partially_shredded_timestamp_nano_variant_array, || {
1256        arrow::array::TimestampNanosecondArray::from(vec![
1257            Some(-4999999561),
1258            None,
1259            None,
1260            Some(1758602096000000000),
1261        ])
1262        .with_timezone("+00:00")
1263    });
1264
1265    #[test]
1266    fn get_variant_partial_shredded_timestamp_nano_as_variant() {
1267        let array = partially_shredded_timestamp_nano_variant_array();
1268
1269        assert_variant_get_as_variant_array_with_default_option!(
1270            array,
1271            vec![
1272                Some(Variant::from(
1273                    DateTime::from_timestamp(-5, 439).unwrap().to_utc()
1274                )),
1275                None,
1276                Some(Variant::from("n/a")),
1277                Some(Variant::from(
1278                    DateTime::parse_from_rfc3339("2025-09-23T12:34:56+08:00")
1279                        .unwrap()
1280                        .to_utc()
1281                )),
1282            ]
1283        )
1284    }
1285
1286    macro_rules! numeric_partially_shredded_variant_array_fn {
1310        ($func:ident, $array_type:ident, $primitive_type:ty) => {
1311            partially_shredded_variant_array_gen!($func, || $array_type::from(vec![
1312                Some(<$primitive_type>::try_from(34u8).unwrap()), None,                                             None, Some(<$primitive_type>::try_from(100u8).unwrap()), ]));
1317        };
1318    }
1319
1320    macro_rules! partially_shredded_variant_array_gen {
1321        ($func:ident, $typed_array_gen: expr) => {
1322            fn $func() -> ArrayRef {
1323                let (metadata, string_value) = {
1326                    let mut builder = parquet_variant::VariantBuilder::new();
1327                    builder.append_value("n/a");
1328                    builder.finish()
1329                };
1330
1331                let nulls = NullBuffer::from(vec![
1332                    true,  false, true,  true,  ]);
1337
1338                let metadata = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 4));
1340
1341                let values = BinaryViewArray::from(vec![
1344                    None,                Some(b"" as &[u8]),  Some(&string_value), None,                ]);
1349
1350                let typed_value = $typed_array_gen();
1351
1352                let struct_array = StructArrayBuilder::new()
1353                    .with_field("metadata", Arc::new(metadata), false)
1354                    .with_field("typed_value", Arc::new(typed_value), true)
1355                    .with_field("value", Arc::new(values), true)
1356                    .with_nulls(nulls)
1357                    .build();
1358
1359                ArrayRef::from(
1360                    VariantArray::try_new(&struct_array).expect("should create variant array"),
1361                )
1362            }
1363        };
1364    }
1365
1366    numeric_partially_shredded_variant_array_fn!(
1367        partially_shredded_int8_variant_array,
1368        Int8Array,
1369        i8
1370    );
1371    numeric_partially_shredded_variant_array_fn!(
1372        partially_shredded_int16_variant_array,
1373        Int16Array,
1374        i16
1375    );
1376    numeric_partially_shredded_variant_array_fn!(
1377        partially_shredded_int32_variant_array,
1378        Int32Array,
1379        i32
1380    );
1381    numeric_partially_shredded_variant_array_fn!(
1382        partially_shredded_int64_variant_array,
1383        Int64Array,
1384        i64
1385    );
1386    numeric_partially_shredded_variant_array_fn!(
1387        partially_shredded_float32_variant_array,
1388        Float32Array,
1389        f32
1390    );
1391    numeric_partially_shredded_variant_array_fn!(
1392        partially_shredded_float64_variant_array,
1393        Float64Array,
1394        f64
1395    );
1396
1397    partially_shredded_variant_array_gen!(partially_shredded_bool_variant_array, || {
1398        arrow::array::BooleanArray::from(vec![
1399            Some(true),  None,        None,        Some(false), ])
1404    });
1405
1406    partially_shredded_variant_array_gen!(partially_shredded_utf8_variant_array, || {
1407        StringArray::from(vec![
1408            Some("hello"), None,          None,          Some("world"), ])
1413    });
1414
1415    partially_shredded_variant_array_gen!(partially_shredded_date32_variant_array, || {
1416        Date32Array::from(vec![
1417            Some(20348), None,        None,        Some(20340), ])
1422    });
1423
1424    fn all_null_variant_array() -> ArrayRef {
1441        let nulls = NullBuffer::from(vec![
1442            false, false, false, ]);
1446
1447        let metadata =
1449            BinaryViewArray::from_iter_values(std::iter::repeat_n(EMPTY_VARIANT_METADATA_BYTES, 3));
1450
1451        let struct_array = StructArrayBuilder::new()
1452            .with_field("metadata", Arc::new(metadata), false)
1453            .with_nulls(nulls)
1454            .build();
1455
1456        Arc::new(struct_array)
1457    }
1458    #[test]
1462    fn test_shredded_object_field_access() {
1463        let array = shredded_object_with_x_field_variant_array();
1464
1465        let options = GetOptions::new_with_path(VariantPath::from("x"));
1467        let result = variant_get(&array, options).unwrap();
1468
1469        let result_variant = VariantArray::try_new(&result).unwrap();
1470        assert_eq!(result_variant.len(), 2);
1471
1472        assert_eq!(result_variant.value(0), Variant::Int32(1));
1474        assert_eq!(result_variant.value(1), Variant::Int32(42));
1476    }
1477
1478    #[test]
1480    fn test_shredded_object_field_as_int32() {
1481        let array = shredded_object_with_x_field_variant_array();
1482
1483        let field = Field::new("x", DataType::Int32, false);
1485        let options = GetOptions::new_with_path(VariantPath::from("x"))
1486            .with_as_type(Some(FieldRef::from(field)));
1487        let result = variant_get(&array, options).unwrap();
1488
1489        let expected: ArrayRef = Arc::new(Int32Array::from(vec![Some(1), Some(42)]));
1491        assert_eq!(&result, &expected);
1492    }
1493
1494    fn shredded_object_with_x_field_variant_array() -> ArrayRef {
1506        let (metadata, y_field_value) = {
1508            let mut builder = parquet_variant::VariantBuilder::new();
1509            let mut obj = builder.new_object();
1510            obj.insert("x", Variant::Int32(42));
1511            obj.insert("y", Variant::from("foo"));
1512            obj.finish();
1513            builder.finish()
1514        };
1515
1516        let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 2));
1518
1519        let empty_object_value = {
1524            let mut builder = parquet_variant::VariantBuilder::new();
1525            let obj = builder.new_object();
1526            obj.finish();
1527            let (_, value) = builder.finish();
1528            value
1529        };
1530
1531        let value_array = BinaryViewArray::from(vec![
1532            Some(y_field_value.as_slice()),      Some(empty_object_value.as_slice()), ]);
1535
1536        let x_field_typed_value = Int32Array::from(vec![Some(1), Some(42)]);
1539
1540        let x_field_struct = StructArrayBuilder::new()
1542            .with_field("typed_value", Arc::new(x_field_typed_value), true)
1543            .build();
1544
1545        let x_field_shredded = ShreddedVariantFieldArray::try_new(&x_field_struct)
1547            .expect("should create ShreddedVariantFieldArray");
1548
1549        let typed_value_fields = Fields::from(vec![Field::new(
1551            "x",
1552            x_field_shredded.data_type().clone(),
1553            true,
1554        )]);
1555        let typed_value_struct = StructArray::try_new(
1556            typed_value_fields,
1557            vec![ArrayRef::from(x_field_shredded)],
1558            None, )
1560        .unwrap();
1561
1562        let main_struct = StructArrayBuilder::new()
1564            .with_field("metadata", Arc::new(metadata_array), false)
1565            .with_field("value", Arc::new(value_array), true)
1566            .with_field("typed_value", Arc::new(typed_value_struct), true)
1567            .build();
1568
1569        Arc::new(main_struct)
1570    }
1571
1572    #[test]
1574    fn test_simple_nested_path_support() {
1575        println!("Testing path parsing:");
1577
1578        let path_x = VariantPath::from("x");
1579        let elements_x: Vec<_> = path_x.iter().collect();
1580        println!("  'x' -> {} elements: {:?}", elements_x.len(), elements_x);
1581
1582        let path_ax = VariantPath::from("a.x");
1583        let elements_ax: Vec<_> = path_ax.iter().collect();
1584        println!(
1585            "  'a.x' -> {} elements: {:?}",
1586            elements_ax.len(),
1587            elements_ax
1588        );
1589
1590        let path_ax_alt = VariantPath::from("$.a.x");
1591        let elements_ax_alt: Vec<_> = path_ax_alt.iter().collect();
1592        println!(
1593            "  '$.a.x' -> {} elements: {:?}",
1594            elements_ax_alt.len(),
1595            elements_ax_alt
1596        );
1597
1598        let path_nested = VariantPath::from("a").join("x");
1599        let elements_nested: Vec<_> = path_nested.iter().collect();
1600        println!(
1601            "  VariantPath::from('a').join('x') -> {} elements: {:?}",
1602            elements_nested.len(),
1603            elements_nested
1604        );
1605
1606        let array = shredded_object_with_x_field_variant_array();
1608
1609        let real_nested_path = VariantPath::from("a").join("x");
1611        let options = GetOptions::new_with_path(real_nested_path);
1612        let result = variant_get(&array, options);
1613
1614        match result {
1615            Ok(_) => {
1616                println!("Nested path 'a.x' works unexpectedly!");
1617            }
1618            Err(e) => {
1619                println!("Nested path 'a.x' error: {}", e);
1620                if e.to_string().contains("Not yet implemented")
1621                    || e.to_string().contains("NotYetImplemented")
1622                {
1623                    println!("This is expected - nested paths are not implemented");
1624                    return;
1625                }
1626                println!("This shows nested paths need implementation");
1628            }
1629        }
1630    }
1631
1632    #[test]
1636    fn test_depth_0_int32_conversion() {
1637        println!("=== Testing Depth 0: Direct field access ===");
1638
1639        let unshredded_array = create_depth_0_test_data();
1641
1642        let field = Field::new("result", DataType::Int32, true);
1643        let path = VariantPath::from("x");
1644        let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
1645        let result = variant_get(&unshredded_array, options).unwrap();
1646
1647        let expected: ArrayRef = Arc::new(Int32Array::from(vec![
1648            Some(42), None,     None,     ]));
1652        assert_eq!(&result, &expected);
1653        println!("Depth 0 (unshredded) passed");
1654
1655        let shredded_array = create_depth_0_shredded_test_data_simple();
1657
1658        let field = Field::new("result", DataType::Int32, true);
1659        let path = VariantPath::from("x");
1660        let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
1661        let result = variant_get(&shredded_array, options).unwrap();
1662
1663        let expected: ArrayRef = Arc::new(Int32Array::from(vec![
1664            Some(42), None,     ]));
1667        assert_eq!(&result, &expected);
1668        println!("Depth 0 (shredded) passed");
1669    }
1670
1671    #[test]
1674    fn test_depth_1_int32_conversion() {
1675        println!("=== Testing Depth 1: Single nested field access ===");
1676
1677        let unshredded_array = create_nested_path_test_data();
1679
1680        let field = Field::new("result", DataType::Int32, true);
1681        let path = VariantPath::from("a.x"); let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
1683        let result = variant_get(&unshredded_array, options).unwrap();
1684
1685        let expected: ArrayRef = Arc::new(Int32Array::from(vec![
1686            Some(55), None,     ]));
1689        assert_eq!(&result, &expected);
1690        println!("Depth 1 (unshredded) passed");
1691
1692        let shredded_array = create_depth_1_shredded_test_data_working();
1694
1695        let field = Field::new("result", DataType::Int32, true);
1696        let path = VariantPath::from("a.x"); let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
1698        let result = variant_get(&shredded_array, options).unwrap();
1699
1700        let expected: ArrayRef = Arc::new(Int32Array::from(vec![
1701            Some(55), None,     ]));
1704        assert_eq!(&result, &expected);
1705        println!("Depth 1 (shredded) passed");
1706    }
1707
1708    #[test]
1711    fn test_depth_2_int32_conversion() {
1712        println!("=== Testing Depth 2: Double nested field access ===");
1713
1714        let unshredded_array = create_depth_2_test_data();
1716
1717        let field = Field::new("result", DataType::Int32, true);
1718        let path = VariantPath::from("a.b.x"); let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
1720        let result = variant_get(&unshredded_array, options).unwrap();
1721
1722        let expected: ArrayRef = Arc::new(Int32Array::from(vec![
1723            Some(100), None,      None,      ]));
1727        assert_eq!(&result, &expected);
1728        println!("Depth 2 (unshredded) passed");
1729
1730        let shredded_array = create_depth_2_shredded_test_data_working();
1732
1733        let field = Field::new("result", DataType::Int32, true);
1734        let path = VariantPath::from("a.b.x"); let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
1736        let result = variant_get(&shredded_array, options).unwrap();
1737
1738        let expected: ArrayRef = Arc::new(Int32Array::from(vec![
1739            Some(100), None,      None,      ]));
1743        assert_eq!(&result, &expected);
1744        println!("Depth 2 (shredded) passed");
1745    }
1746
1747    #[test]
1752    fn test_current_nested_path_functionality() {
1753        let array = shredded_object_with_x_field_variant_array();
1754
1755        let single_path = VariantPath::from("x");
1757        let field = Field::new("result", DataType::Int32, true);
1758        let options =
1759            GetOptions::new_with_path(single_path).with_as_type(Some(FieldRef::from(field)));
1760        let result = variant_get(&array, options).unwrap();
1761
1762        println!("Single path 'x' works - result: {:?}", result);
1763
1764        let nested_path = VariantPath::from("a").join("x");
1766        let field = Field::new("result", DataType::Int32, true);
1767        let options =
1768            GetOptions::new_with_path(nested_path).with_as_type(Some(FieldRef::from(field)));
1769        let result = variant_get(&array, options).unwrap();
1770
1771        println!("Nested path 'a.x' result: {:?}", result);
1772    }
1773
1774    fn create_depth_0_test_data() -> ArrayRef {
1777        let mut builder = crate::VariantArrayBuilder::new(3);
1778
1779        {
1781            let json_str = r#"{"x": 42}"#;
1782            let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
1783            if let Ok(variant_array) = json_to_variant(&string_array) {
1784                builder.append_variant(variant_array.value(0));
1785            } else {
1786                builder.append_null();
1787            }
1788        }
1789
1790        {
1792            let json_str = r#"{"x": "foo"}"#;
1793            let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
1794            if let Ok(variant_array) = json_to_variant(&string_array) {
1795                builder.append_variant(variant_array.value(0));
1796            } else {
1797                builder.append_null();
1798            }
1799        }
1800
1801        {
1803            let json_str = r#"{"y": 10}"#;
1804            let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
1805            if let Ok(variant_array) = json_to_variant(&string_array) {
1806                builder.append_variant(variant_array.value(0));
1807            } else {
1808                builder.append_null();
1809            }
1810        }
1811
1812        ArrayRef::from(builder.build())
1813    }
1814
1815    fn create_nested_path_test_data() -> ArrayRef {
1818        let mut builder = crate::VariantArrayBuilder::new(2);
1819
1820        {
1822            let json_str = r#"{"a": {"x": 55}, "b": 42}"#;
1823            let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
1824            if let Ok(variant_array) = json_to_variant(&string_array) {
1825                builder.append_variant(variant_array.value(0));
1826            } else {
1827                builder.append_null();
1828            }
1829        }
1830
1831        {
1833            let json_str = r#"{"a": {"x": "foo"}, "b": 42}"#;
1834            let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
1835            if let Ok(variant_array) = json_to_variant(&string_array) {
1836                builder.append_variant(variant_array.value(0));
1837            } else {
1838                builder.append_null();
1839            }
1840        }
1841
1842        ArrayRef::from(builder.build())
1843    }
1844
1845    fn create_depth_2_test_data() -> ArrayRef {
1848        let mut builder = crate::VariantArrayBuilder::new(3);
1849
1850        {
1852            let json_str = r#"{"a": {"b": {"x": 100}}}"#;
1853            let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
1854            if let Ok(variant_array) = json_to_variant(&string_array) {
1855                builder.append_variant(variant_array.value(0));
1856            } else {
1857                builder.append_null();
1858            }
1859        }
1860
1861        {
1863            let json_str = r#"{"a": {"b": {"x": "bar"}}}"#;
1864            let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
1865            if let Ok(variant_array) = json_to_variant(&string_array) {
1866                builder.append_variant(variant_array.value(0));
1867            } else {
1868                builder.append_null();
1869            }
1870        }
1871
1872        {
1874            let json_str = r#"{"a": {"b": {"y": 200}}}"#;
1875            let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
1876            if let Ok(variant_array) = json_to_variant(&string_array) {
1877                builder.append_variant(variant_array.value(0));
1878            } else {
1879                builder.append_null();
1880            }
1881        }
1882
1883        ArrayRef::from(builder.build())
1884    }
1885
1886    fn create_depth_0_shredded_test_data_simple() -> ArrayRef {
1889        let (metadata, string_x_value) = {
1891            let mut builder = parquet_variant::VariantBuilder::new();
1892            let mut obj = builder.new_object();
1893            obj.insert("x", Variant::from("foo"));
1894            obj.finish();
1895            builder.finish()
1896        };
1897
1898        let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 2));
1900
1901        let empty_object_value = {
1905            let mut builder = parquet_variant::VariantBuilder::new();
1906            let obj = builder.new_object();
1907            obj.finish();
1908            let (_, value) = builder.finish();
1909            value
1910        };
1911
1912        let value_array = BinaryViewArray::from(vec![
1913            Some(empty_object_value.as_slice()), Some(string_x_value.as_slice()),     ]);
1916
1917        let x_field_typed_value = Int32Array::from(vec![Some(42), None]);
1919
1920        let x_field_struct = StructArrayBuilder::new()
1922            .with_field("typed_value", Arc::new(x_field_typed_value), true)
1923            .build();
1924
1925        let x_field_shredded = ShreddedVariantFieldArray::try_new(&x_field_struct)
1926            .expect("should create ShreddedVariantFieldArray");
1927
1928        let typed_value_fields = Fields::from(vec![Field::new(
1930            "x",
1931            x_field_shredded.data_type().clone(),
1932            true,
1933        )]);
1934        let typed_value_struct = StructArray::try_new(
1935            typed_value_fields,
1936            vec![ArrayRef::from(x_field_shredded)],
1937            None,
1938        )
1939        .unwrap();
1940
1941        let struct_array = StructArrayBuilder::new()
1943            .with_field("metadata", Arc::new(metadata_array), false)
1944            .with_field("value", Arc::new(value_array), true)
1945            .with_field("typed_value", Arc::new(typed_value_struct), true)
1946            .build();
1947
1948        Arc::new(struct_array)
1949    }
1950
1951    fn create_depth_1_shredded_test_data_working() -> ArrayRef {
1956        let (metadata, _) = {
1958            let mut builder = parquet_variant::VariantBuilder::new();
1960            let mut obj = builder.new_object();
1961
1962            let mut a_obj = obj.new_object("a");
1964            a_obj.insert("x", Variant::Int32(55));
1965            a_obj.finish();
1966
1967            obj.insert("b", Variant::Int32(42));
1968            obj.finish();
1969            builder.finish()
1970        };
1971
1972        let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 2));
1973
1974        let empty_object_value = {
1977            let mut builder = parquet_variant::VariantBuilder::new();
1978            let obj = builder.new_object();
1979            obj.finish();
1980            let (_, value) = builder.finish();
1981            value
1982        };
1983
1984        let row1_fallback = {
1987            let mut builder = parquet_variant::VariantBuilder::new();
1988            let mut obj = builder.new_object();
1989            obj.insert("fallback", Variant::from("data"));
1990            obj.finish();
1991            let (_, value) = builder.finish();
1992            value
1993        };
1994
1995        let value_array = BinaryViewArray::from(vec![
1996            Some(empty_object_value.as_slice()), Some(row1_fallback.as_slice()), ]);
1999
2000        let x_typed_value = Int32Array::from(vec![Some(55), None]);
2003        let x_field_struct = StructArrayBuilder::new()
2004            .with_field("typed_value", Arc::new(x_typed_value), true)
2005            .build();
2006        let x_field_shredded = ShreddedVariantFieldArray::try_new(&x_field_struct)
2007            .expect("should create ShreddedVariantFieldArray for x");
2008
2009        let a_value_data = {
2014            let mut builder = parquet_variant::VariantBuilder::new();
2015            let obj = builder.new_object();
2016            obj.finish();
2017            let (_, value) = builder.finish();
2018            value
2019        };
2020        let a_value_array = BinaryViewArray::from(vec![
2021            None,                          Some(a_value_data.as_slice()), ]);
2024
2025        let a_inner_fields = Fields::from(vec![Field::new(
2026            "x",
2027            x_field_shredded.data_type().clone(),
2028            true,
2029        )]);
2030        let a_inner_struct = StructArrayBuilder::new()
2031            .with_field(
2032                "typed_value",
2033                Arc::new(
2034                    StructArray::try_new(
2035                        a_inner_fields,
2036                        vec![ArrayRef::from(x_field_shredded)],
2037                        None,
2038                    )
2039                    .unwrap(),
2040                ),
2041                true,
2042            )
2043            .with_field("value", Arc::new(a_value_array), true)
2044            .build();
2045        let a_field_shredded = ShreddedVariantFieldArray::try_new(&a_inner_struct)
2046            .expect("should create ShreddedVariantFieldArray for a");
2047
2048        let typed_value_fields = Fields::from(vec![Field::new(
2050            "a",
2051            a_field_shredded.data_type().clone(),
2052            true,
2053        )]);
2054        let typed_value_struct = StructArray::try_new(
2055            typed_value_fields,
2056            vec![ArrayRef::from(a_field_shredded)],
2057            None,
2058        )
2059        .unwrap();
2060
2061        let struct_array = StructArrayBuilder::new()
2063            .with_field("metadata", Arc::new(metadata_array), false)
2064            .with_field("value", Arc::new(value_array), true)
2065            .with_field("typed_value", Arc::new(typed_value_struct), true)
2066            .build();
2067
2068        Arc::new(struct_array)
2069    }
2070
2071    fn create_depth_2_shredded_test_data_working() -> ArrayRef {
2077        let (metadata, _) = {
2079            let mut builder = parquet_variant::VariantBuilder::new();
2081            let mut obj = builder.new_object();
2082
2083            let mut a_obj = obj.new_object("a");
2085            let mut b_obj = a_obj.new_object("b");
2086            b_obj.insert("x", Variant::Int32(100));
2087            b_obj.finish();
2088            a_obj.finish();
2089
2090            obj.finish();
2091            builder.finish()
2092        };
2093
2094        let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 3));
2095
2096        let empty_object_value = {
2098            let mut builder = parquet_variant::VariantBuilder::new();
2099            let obj = builder.new_object();
2100            obj.finish();
2101            let (_, value) = builder.finish();
2102            value
2103        };
2104
2105        let value_array = BinaryViewArray::from(vec![
2107            Some(empty_object_value.as_slice()), Some(empty_object_value.as_slice()), Some(empty_object_value.as_slice()), ]);
2111
2112        let x_typed_value = Int32Array::from(vec![Some(100), None, None]);
2116        let x_field_struct = StructArrayBuilder::new()
2117            .with_field("typed_value", Arc::new(x_typed_value), true)
2118            .build();
2119        let x_field_shredded = ShreddedVariantFieldArray::try_new(&x_field_struct)
2120            .expect("should create ShreddedVariantFieldArray for x");
2121
2122        let b_value_data = {
2124            let mut builder = parquet_variant::VariantBuilder::new();
2125            let obj = builder.new_object();
2126            obj.finish();
2127            let (_, value) = builder.finish();
2128            value
2129        };
2130        let b_value_array = BinaryViewArray::from(vec![
2131            None,                          Some(b_value_data.as_slice()), Some(b_value_data.as_slice()), ]);
2135
2136        let b_inner_fields = Fields::from(vec![Field::new(
2137            "x",
2138            x_field_shredded.data_type().clone(),
2139            true,
2140        )]);
2141        let b_inner_struct = StructArrayBuilder::new()
2142            .with_field(
2143                "typed_value",
2144                Arc::new(
2145                    StructArray::try_new(
2146                        b_inner_fields,
2147                        vec![ArrayRef::from(x_field_shredded)],
2148                        None,
2149                    )
2150                    .unwrap(),
2151                ),
2152                true,
2153            )
2154            .with_field("value", Arc::new(b_value_array), true)
2155            .build();
2156        let b_field_shredded = ShreddedVariantFieldArray::try_new(&b_inner_struct)
2157            .expect("should create ShreddedVariantFieldArray for b");
2158
2159        let a_value_data = {
2161            let mut builder = parquet_variant::VariantBuilder::new();
2162            let obj = builder.new_object();
2163            obj.finish();
2164            let (_, value) = builder.finish();
2165            value
2166        };
2167        let a_value_array = BinaryViewArray::from(vec![
2168            None,                          Some(a_value_data.as_slice()), Some(a_value_data.as_slice()), ]);
2172
2173        let a_inner_fields = Fields::from(vec![Field::new(
2174            "b",
2175            b_field_shredded.data_type().clone(),
2176            true,
2177        )]);
2178        let a_inner_struct = StructArrayBuilder::new()
2179            .with_field(
2180                "typed_value",
2181                Arc::new(
2182                    StructArray::try_new(
2183                        a_inner_fields,
2184                        vec![ArrayRef::from(b_field_shredded)],
2185                        None,
2186                    )
2187                    .unwrap(),
2188                ),
2189                true,
2190            )
2191            .with_field("value", Arc::new(a_value_array), true)
2192            .build();
2193        let a_field_shredded = ShreddedVariantFieldArray::try_new(&a_inner_struct)
2194            .expect("should create ShreddedVariantFieldArray for a");
2195
2196        let typed_value_fields = Fields::from(vec![Field::new(
2198            "a",
2199            a_field_shredded.data_type().clone(),
2200            true,
2201        )]);
2202        let typed_value_struct = StructArray::try_new(
2203            typed_value_fields,
2204            vec![ArrayRef::from(a_field_shredded)],
2205            None,
2206        )
2207        .unwrap();
2208
2209        let struct_array = StructArrayBuilder::new()
2211            .with_field("metadata", Arc::new(metadata_array), false)
2212            .with_field("value", Arc::new(value_array), true)
2213            .with_field("typed_value", Arc::new(typed_value_struct), true)
2214            .build();
2215
2216        Arc::new(struct_array)
2217    }
2218
2219    #[test]
2220    fn test_strict_cast_options_downcast_failure() {
2221        use arrow::compute::CastOptions;
2222        use arrow::datatypes::{DataType, Field};
2223        use arrow::error::ArrowError;
2224        use parquet_variant::VariantPath;
2225        use std::sync::Arc;
2226
2227        let variant_array = perfectly_shredded_int32_variant_array();
2229
2230        let safe_options = GetOptions {
2232            path: VariantPath::from("nonexistent_field"),
2233            as_type: Some(Arc::new(Field::new("result", DataType::Int32, true))),
2234            cast_options: CastOptions::default(), };
2236
2237        let variant_array_ref: Arc<dyn Array> = variant_array.clone();
2238        let result = variant_get(&variant_array_ref, safe_options);
2239        assert!(result.is_ok());
2241        let result_array = result.unwrap();
2242        assert_eq!(result_array.len(), 3);
2243        assert!(result_array.is_null(0));
2244        assert!(result_array.is_null(1));
2245        assert!(result_array.is_null(2));
2246
2247        let strict_options = GetOptions {
2249            path: VariantPath::from("nonexistent_field"),
2250            as_type: Some(Arc::new(Field::new("result", DataType::Int32, true))),
2251            cast_options: CastOptions {
2252                safe: false,
2253                ..Default::default()
2254            },
2255        };
2256
2257        let result = variant_get(&variant_array_ref, strict_options);
2258        assert!(result.is_err());
2260        let error = result.unwrap_err();
2261        assert!(matches!(error, ArrowError::CastError(_)));
2262        assert!(
2263            error
2264                .to_string()
2265                .contains("Cannot access field 'nonexistent_field' on non-struct type")
2266        );
2267    }
2268
2269    #[test]
2270    fn test_error_message_boolean_type_display() {
2271        let mut builder = VariantArrayBuilder::new(1);
2272        builder.append_variant(Variant::Int32(123));
2273        let variant_array: ArrayRef = ArrayRef::from(builder.build());
2274
2275        let options = GetOptions {
2277            path: VariantPath::default(),
2278            as_type: Some(Arc::new(Field::new("result", DataType::Boolean, true))),
2279            cast_options: CastOptions {
2280                safe: false,
2281                ..Default::default()
2282            },
2283        };
2284
2285        let err = variant_get(&variant_array, options).unwrap_err();
2286        let msg = err.to_string();
2287        assert!(msg.contains("Failed to extract primitive of type Boolean"));
2288    }
2289
2290    #[test]
2291    fn test_error_message_numeric_type_display() {
2292        let mut builder = VariantArrayBuilder::new(1);
2293        builder.append_variant(Variant::BooleanTrue);
2294        let variant_array: ArrayRef = ArrayRef::from(builder.build());
2295
2296        let options = GetOptions {
2298            path: VariantPath::default(),
2299            as_type: Some(Arc::new(Field::new("result", DataType::Float32, true))),
2300            cast_options: CastOptions {
2301                safe: false,
2302                ..Default::default()
2303            },
2304        };
2305
2306        let err = variant_get(&variant_array, options).unwrap_err();
2307        let msg = err.to_string();
2308        assert!(msg.contains("Failed to extract primitive of type Float32"));
2309    }
2310
2311    #[test]
2312    fn test_error_message_temporal_type_display() {
2313        let mut builder = VariantArrayBuilder::new(1);
2314        builder.append_variant(Variant::BooleanFalse);
2315        let variant_array: ArrayRef = ArrayRef::from(builder.build());
2316
2317        let options = GetOptions {
2319            path: VariantPath::default(),
2320            as_type: Some(Arc::new(Field::new(
2321                "result",
2322                DataType::Timestamp(TimeUnit::Nanosecond, None),
2323                true,
2324            ))),
2325            cast_options: CastOptions {
2326                safe: false,
2327                ..Default::default()
2328            },
2329        };
2330
2331        let err = variant_get(&variant_array, options).unwrap_err();
2332        let msg = err.to_string();
2333        assert!(msg.contains("Failed to extract primitive of type Timestamp(ns)"));
2334    }
2335
2336    #[test]
2337    fn test_null_buffer_union_for_shredded_paths() {
2338        use arrow::compute::CastOptions;
2339        use arrow::datatypes::{DataType, Field};
2340        use parquet_variant::VariantPath;
2341        use std::sync::Arc;
2342
2343        let variant_array = create_depth_1_shredded_test_data_working();
2352
2353        let options = GetOptions {
2358            path: VariantPath::from("a.x"),
2359            as_type: Some(Arc::new(Field::new("result", DataType::Int32, true))),
2360            cast_options: CastOptions::default(),
2361        };
2362
2363        let variant_array_ref: Arc<dyn Array> = variant_array.clone();
2364        let result = variant_get(&variant_array_ref, options).unwrap();
2365
2366        assert_eq!(result.len(), variant_array.len());
2368
2369        assert!(!result.is_null(0), "Row 0 should have valid Int32 data");
2373        assert!(
2374            result.is_null(1),
2375            "Row 1 should be null due to type casting failure"
2376        );
2377
2378        let int32_result = result.as_any().downcast_ref::<Int32Array>().unwrap();
2380        assert_eq!(int32_result.value(0), 55); }
2382
2383    #[test]
2384    fn test_struct_null_mask_union_from_children() {
2385        use arrow::compute::CastOptions;
2386        use arrow::datatypes::{DataType, Field, Fields};
2387        use parquet_variant::VariantPath;
2388        use std::sync::Arc;
2389
2390        use arrow::array::StringArray;
2391
2392        let json_strings = vec![
2397            r#"{"a": 42, "b": "hello"}"#, r#"{"a": "world", "b": 100}"#, r#"{"a": 55, "b": 77}"#,       ];
2401
2402        let string_array: Arc<dyn arrow::array::Array> = Arc::new(StringArray::from(json_strings));
2403        let variant_array = json_to_variant(&string_array).unwrap();
2404
2405        let struct_fields = Fields::from(vec![
2408            Field::new("a", DataType::Int32, true),
2409            Field::new("b", DataType::Int32, true),
2410        ]);
2411        let struct_type = DataType::Struct(struct_fields);
2412
2413        let options = GetOptions {
2414            path: VariantPath::default(), as_type: Some(Arc::new(Field::new("result", struct_type, true))),
2416            cast_options: CastOptions::default(),
2417        };
2418
2419        let variant_array_ref = ArrayRef::from(variant_array);
2420        let result = variant_get(&variant_array_ref, options).unwrap();
2421
2422        let struct_result = result.as_struct();
2424        assert_eq!(struct_result.len(), 3);
2425
2426        let field_a = struct_result
2428            .column(0)
2429            .as_any()
2430            .downcast_ref::<Int32Array>()
2431            .unwrap();
2432        let field_b = struct_result
2433            .column(1)
2434            .as_any()
2435            .downcast_ref::<Int32Array>()
2436            .unwrap();
2437
2438        assert!(!field_a.is_null(0));
2441        assert_eq!(field_a.value(0), 42);
2442        assert!(field_b.is_null(0)); assert!(field_a.is_null(1)); assert!(!field_b.is_null(1));
2447        assert_eq!(field_b.value(1), 100);
2448
2449        assert!(!field_a.is_null(2));
2451        assert_eq!(field_a.value(2), 55);
2452        assert!(!field_b.is_null(2));
2453        assert_eq!(field_b.value(2), 77);
2454
2455        assert!(!struct_result.is_null(0)); assert!(!struct_result.is_null(1)); assert!(!struct_result.is_null(2)); }
2462
2463    #[test]
2464    fn test_field_nullability_preservation() {
2465        use arrow::compute::CastOptions;
2466        use arrow::datatypes::{DataType, Field};
2467        use parquet_variant::VariantPath;
2468        use std::sync::Arc;
2469
2470        use arrow::array::StringArray;
2471
2472        let json_strings = vec![
2475            r#"{"x": 42}"#,                  r#"{"x": "not_a_number"}"#,      r#"{"x": null}"#,                r#"{"x": "hello"}"#,             r#"{"y": 100}"#,                 r#"{"x": 127}"#, r#"{"x": 32767}"#, r#"{"x": 2147483647}"#, r#"{"x": 9223372036854775807}"#, ];
2485
2486        let string_array: Arc<dyn arrow::array::Array> = Arc::new(StringArray::from(json_strings));
2487        let variant_array = json_to_variant(&string_array).unwrap();
2488
2489        let nullable_field = Arc::new(Field::new("result", DataType::Int32, true));
2491        let options_nullable = GetOptions {
2492            path: VariantPath::from("x"),
2493            as_type: Some(nullable_field.clone()),
2494            cast_options: CastOptions::default(),
2495        };
2496
2497        let variant_array_ref = ArrayRef::from(variant_array);
2498        let result_nullable = variant_get(&variant_array_ref, options_nullable).unwrap();
2499
2500        let int32_result = result_nullable
2502            .as_any()
2503            .downcast_ref::<Int32Array>()
2504            .unwrap();
2505        assert_eq!(int32_result.len(), 9);
2506
2507        assert!(!int32_result.is_null(0));
2509        assert_eq!(int32_result.value(0), 42);
2510
2511        assert!(int32_result.is_null(1));
2513
2514        assert!(int32_result.is_null(2));
2516
2517        assert!(int32_result.is_null(3));
2519
2520        assert!(int32_result.is_null(4));
2522
2523        assert!(!int32_result.is_null(5));
2526        assert_eq!(int32_result.value(5), 127);
2527
2528        assert!(!int32_result.is_null(6));
2531        assert_eq!(int32_result.value(6), 32767);
2532
2533        assert!(!int32_result.is_null(7));
2536        assert_eq!(int32_result.value(7), 2147483647);
2537
2538        assert!(int32_result.is_null(8));
2541
2542        let non_nullable_field = Arc::new(Field::new("result", DataType::Int32, false));
2544        let options_non_nullable = GetOptions {
2545            path: VariantPath::from("x"),
2546            as_type: Some(non_nullable_field.clone()),
2547            cast_options: CastOptions::default(), };
2549
2550        let variant_array_2 = json_to_variant(&string_array).unwrap();
2552        let variant_array_ref_2 = ArrayRef::from(variant_array_2);
2553        let result_non_nullable = variant_get(&variant_array_ref_2, options_non_nullable).unwrap();
2554        let int32_result_2 = result_non_nullable
2555            .as_any()
2556            .downcast_ref::<Int32Array>()
2557            .unwrap();
2558
2559        assert_eq!(int32_result_2.len(), 9);
2561
2562        assert!(!int32_result_2.is_null(0));
2564        assert_eq!(int32_result_2.value(0), 42);
2565
2566        assert!(int32_result_2.is_null(1)); assert!(int32_result_2.is_null(2)); assert!(int32_result_2.is_null(3)); assert!(int32_result_2.is_null(4)); assert!(!int32_result_2.is_null(5)); assert_eq!(int32_result_2.value(5), 127);
2576        assert!(!int32_result_2.is_null(6)); assert_eq!(int32_result_2.value(6), 32767);
2578        assert!(!int32_result_2.is_null(7)); assert_eq!(int32_result_2.value(7), 2147483647);
2580
2581        assert!(int32_result_2.is_null(8)); }
2584
2585    #[test]
2586    fn test_struct_extraction_subset_superset_schema_perfectly_shredded() {
2587        let variant_array = create_comprehensive_shredded_variant();
2589
2590        let struct_fields = Fields::from(vec![
2592            Field::new("a", DataType::Int32, true),
2593            Field::new("b", DataType::Int32, true),
2594            Field::new("d", DataType::Int32, true),
2595        ]);
2596        let struct_type = DataType::Struct(struct_fields);
2597
2598        let options = GetOptions {
2599            path: VariantPath::default(),
2600            as_type: Some(Arc::new(Field::new("result", struct_type, true))),
2601            cast_options: CastOptions::default(),
2602        };
2603
2604        let result = variant_get(&variant_array, options).unwrap();
2605
2606        let struct_result = result.as_any().downcast_ref::<StructArray>().unwrap();
2608        assert_eq!(struct_result.len(), 5);
2609        assert_eq!(struct_result.num_columns(), 3);
2610
2611        let field_a = struct_result
2612            .column(0)
2613            .as_any()
2614            .downcast_ref::<Int32Array>()
2615            .unwrap();
2616        let field_b = struct_result
2617            .column(1)
2618            .as_any()
2619            .downcast_ref::<Int32Array>()
2620            .unwrap();
2621        let field_d = struct_result
2622            .column(2)
2623            .as_any()
2624            .downcast_ref::<Int32Array>()
2625            .unwrap();
2626
2627        assert!(!struct_result.is_null(0));
2629        assert_eq!(field_a.value(0), 1);
2630        assert_eq!(field_b.value(0), 2);
2631        assert!(field_d.is_null(0)); assert!(struct_result.is_null(1));
2635
2636        assert!(!struct_result.is_null(2));
2638        assert!(field_a.is_null(2)); assert_eq!(field_b.value(2), 2);
2640        assert!(field_d.is_null(2)); assert!(!struct_result.is_null(3));
2644        assert_eq!(field_a.value(3), 1);
2645        assert!(field_b.is_null(3)); assert!(field_d.is_null(3)); assert!(!struct_result.is_null(4));
2650        assert!(field_a.is_null(4)); assert!(field_b.is_null(4)); assert!(field_d.is_null(4)); }
2654
2655    #[test]
2656    fn test_nested_struct_extraction_perfectly_shredded() {
2657        let variant_array = create_comprehensive_nested_shredded_variant();
2659        println!("variant_array: {variant_array:?}");
2660
2661        let inner_field = Field::new("inner", DataType::Int32, true);
2663        let inner_type = DataType::Struct(Fields::from(vec![inner_field]));
2664        let outer_field = Field::new("outer", inner_type, true);
2665        let result_type = DataType::Struct(Fields::from(vec![outer_field]));
2666
2667        let options = GetOptions {
2668            path: VariantPath::default(),
2669            as_type: Some(Arc::new(Field::new("result", result_type, true))),
2670            cast_options: CastOptions::default(),
2671        };
2672
2673        let result = variant_get(&variant_array, options).unwrap();
2674        println!("result: {result:?}");
2675
2676        let outer_struct = result.as_any().downcast_ref::<StructArray>().unwrap();
2678        assert_eq!(outer_struct.len(), 4);
2679        assert_eq!(outer_struct.num_columns(), 1);
2680
2681        let inner_struct = outer_struct
2683            .column(0)
2684            .as_any()
2685            .downcast_ref::<StructArray>()
2686            .unwrap();
2687        assert_eq!(inner_struct.num_columns(), 1);
2688
2689        let leaf_field = inner_struct
2691            .column(0)
2692            .as_any()
2693            .downcast_ref::<Int32Array>()
2694            .unwrap();
2695
2696        assert!(!outer_struct.is_null(0));
2698        assert!(!inner_struct.is_null(0));
2699        assert_eq!(leaf_field.value(0), 42);
2700
2701        assert!(!outer_struct.is_null(1));
2703        assert!(!inner_struct.is_null(1)); assert!(leaf_field.is_null(1)); assert!(!outer_struct.is_null(2));
2708        assert!(inner_struct.is_null(2)); assert!(outer_struct.is_null(3));
2712    }
2713
2714    #[test]
2715    fn test_path_based_null_masks_one_step() {
2716        let variant_array = create_comprehensive_nested_shredded_variant();
2718
2719        let path = VariantPath::from("outer");
2721        let inner_field = Field::new("inner", DataType::Int32, true);
2722        let result_type = DataType::Struct(Fields::from(vec![inner_field]));
2723
2724        let options = GetOptions {
2725            path,
2726            as_type: Some(Arc::new(Field::new("result", result_type, true))),
2727            cast_options: CastOptions::default(),
2728        };
2729
2730        let result = variant_get(&variant_array, options).unwrap();
2731
2732        let outer_result = result.as_any().downcast_ref::<StructArray>().unwrap();
2734        assert_eq!(outer_result.len(), 4);
2735        assert_eq!(outer_result.num_columns(), 1);
2736
2737        let inner_field = outer_result
2739            .column(0)
2740            .as_any()
2741            .downcast_ref::<Int32Array>()
2742            .unwrap();
2743
2744        assert!(!outer_result.is_null(0));
2746        assert_eq!(inner_field.value(0), 42);
2747
2748        assert!(!outer_result.is_null(1));
2750        assert!(inner_field.is_null(1));
2751
2752        assert!(outer_result.is_null(2));
2754
2755        assert!(outer_result.is_null(3));
2757    }
2758
2759    #[test]
2760    fn test_path_based_null_masks_two_steps() {
2761        let variant_array = create_comprehensive_nested_shredded_variant();
2763
2764        let path = VariantPath::from("outer").join("inner");
2766
2767        let options = GetOptions {
2768            path,
2769            as_type: Some(Arc::new(Field::new("result", DataType::Int32, true))),
2770            cast_options: CastOptions::default(),
2771        };
2772
2773        let result = variant_get(&variant_array, options).unwrap();
2774
2775        let int_result = result.as_any().downcast_ref::<Int32Array>().unwrap();
2777        assert_eq!(int_result.len(), 4);
2778
2779        assert!(!int_result.is_null(0));
2781        assert_eq!(int_result.value(0), 42);
2782
2783        assert!(int_result.is_null(1));
2785
2786        assert!(int_result.is_null(2));
2788
2789        assert!(int_result.is_null(3));
2791    }
2792
2793    #[test]
2794    fn test_struct_extraction_mixed_and_unshredded() {
2795        let variant_array = create_mixed_and_unshredded_variant();
2797
2798        let struct_fields = Fields::from(vec![
2800            Field::new("x", DataType::Int32, true),
2801            Field::new("y", DataType::Int32, true),
2802        ]);
2803        let struct_type = DataType::Struct(struct_fields);
2804
2805        let options = GetOptions {
2806            path: VariantPath::default(),
2807            as_type: Some(Arc::new(Field::new("result", struct_type, true))),
2808            cast_options: CastOptions::default(),
2809        };
2810
2811        let result = variant_get(&variant_array, options).unwrap();
2812
2813        let struct_result = result.as_any().downcast_ref::<StructArray>().unwrap();
2815        assert_eq!(struct_result.len(), 4);
2816        assert_eq!(struct_result.num_columns(), 2);
2817
2818        let field_x = struct_result
2819            .column(0)
2820            .as_any()
2821            .downcast_ref::<Int32Array>()
2822            .unwrap();
2823        let field_y = struct_result
2824            .column(1)
2825            .as_any()
2826            .downcast_ref::<Int32Array>()
2827            .unwrap();
2828
2829        assert_eq!(field_x.value(0), 1);
2831        assert_eq!(field_y.value(0), 42);
2832
2833        assert_eq!(field_x.value(1), 2);
2835        assert!(field_y.is_null(1));
2836
2837        assert_eq!(field_x.value(2), 3);
2839        assert!(field_y.is_null(2));
2840
2841        assert!(struct_result.is_null(3));
2843    }
2844
2845    #[test]
2848    fn test_struct_row_builder_gap_demonstration() {
2849        let json_strings = vec![
2851            r#"{"outer": {"inner": 42}}"#,
2852            r#"{"outer": {"inner": 100}}"#,
2853        ];
2854        let string_array: Arc<dyn Array> = Arc::new(StringArray::from(json_strings));
2855        let variant_array = json_to_variant(&string_array).unwrap();
2856
2857        let inner_fields = Fields::from(vec![Field::new("inner", DataType::Int32, true)]);
2859        let inner_struct_type = DataType::Struct(inner_fields);
2860        let outer_fields = Fields::from(vec![Field::new("outer", inner_struct_type, true)]);
2861        let outer_struct_type = DataType::Struct(outer_fields);
2862
2863        let options = GetOptions {
2864            path: VariantPath::default(),
2865            as_type: Some(Arc::new(Field::new("result", outer_struct_type, true))),
2866            cast_options: CastOptions::default(),
2867        };
2868
2869        let variant_array_ref = ArrayRef::from(variant_array);
2870        let result = variant_get(&variant_array_ref, options);
2871
2872        assert!(result.is_err());
2874        let error = result.unwrap_err();
2875        assert!(error.to_string().contains("Not yet implemented"));
2876    }
2877
2878    fn create_comprehensive_shredded_variant() -> ArrayRef {
2881        let (metadata, _) = {
2882            let mut builder = parquet_variant::VariantBuilder::new();
2883            let obj = builder.new_object();
2884            obj.finish();
2885            builder.finish()
2886        };
2887
2888        let nulls = NullBuffer::from(vec![
2890            true,  false, true,  true,  true,  ]);
2896
2897        let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 5));
2898
2899        let a_field_typed_value = Int32Array::from(vec![Some(1), None, None, Some(1), None]);
2902        let a_field_struct = StructArrayBuilder::new()
2903            .with_field("typed_value", Arc::new(a_field_typed_value), true)
2904            .build();
2905        let a_field_shredded = ShreddedVariantFieldArray::try_new(&a_field_struct)
2906            .expect("should create ShreddedVariantFieldArray for a");
2907
2908        let b_field_typed_value = Int32Array::from(vec![Some(2), None, Some(2), None, None]);
2910        let b_field_struct = StructArrayBuilder::new()
2911            .with_field("typed_value", Arc::new(b_field_typed_value), true)
2912            .build();
2913        let b_field_shredded = ShreddedVariantFieldArray::try_new(&b_field_struct)
2914            .expect("should create ShreddedVariantFieldArray for b");
2915
2916        let c_field_typed_value = Int32Array::from(vec![Some(3), None, None, None, None]);
2918        let c_field_struct = StructArrayBuilder::new()
2919            .with_field("typed_value", Arc::new(c_field_typed_value), true)
2920            .build();
2921        let c_field_shredded = ShreddedVariantFieldArray::try_new(&c_field_struct)
2922            .expect("should create ShreddedVariantFieldArray for c");
2923
2924        let typed_value_fields = Fields::from(vec![
2926            Field::new("a", a_field_shredded.data_type().clone(), true),
2927            Field::new("b", b_field_shredded.data_type().clone(), true),
2928            Field::new("c", c_field_shredded.data_type().clone(), true),
2929        ]);
2930        let typed_value_struct = StructArray::try_new(
2931            typed_value_fields,
2932            vec![
2933                ArrayRef::from(a_field_shredded),
2934                ArrayRef::from(b_field_shredded),
2935                ArrayRef::from(c_field_shredded),
2936            ],
2937            None,
2938        )
2939        .unwrap();
2940
2941        let struct_array = StructArrayBuilder::new()
2943            .with_field("metadata", Arc::new(metadata_array), false)
2944            .with_field("typed_value", Arc::new(typed_value_struct), true)
2945            .with_nulls(nulls)
2946            .build();
2947
2948        Arc::new(struct_array)
2949    }
2950
2951    fn create_comprehensive_nested_shredded_variant() -> ArrayRef {
2956        let inner_typed_value = Int32Array::from(vec![Some(42), None, None, None]); let inner = StructArrayBuilder::new()
2960            .with_field("typed_value", Arc::new(inner_typed_value), true)
2961            .build();
2962        let inner = ShreddedVariantFieldArray::try_new(&inner).unwrap();
2963
2964        let outer_typed_value_nulls = NullBuffer::from(vec![
2965            true,  false, false, false, ]);
2970        let outer_typed_value = StructArrayBuilder::new()
2971            .with_field("inner", ArrayRef::from(inner), false)
2972            .with_nulls(outer_typed_value_nulls)
2973            .build();
2974
2975        let outer = StructArrayBuilder::new()
2976            .with_field("typed_value", Arc::new(outer_typed_value), true)
2977            .build();
2978        let outer = ShreddedVariantFieldArray::try_new(&outer).unwrap();
2979
2980        let typed_value_nulls = NullBuffer::from(vec![
2981            true,  true,  false, false, ]);
2986        let typed_value = StructArrayBuilder::new()
2987            .with_field("outer", ArrayRef::from(outer), false)
2988            .with_nulls(typed_value_nulls)
2989            .build();
2990
2991        let metadata_array =
2993            BinaryViewArray::from_iter_values(std::iter::repeat_n(EMPTY_VARIANT_METADATA_BYTES, 4));
2994        let nulls = NullBuffer::from(vec![
2995            true,  true,  true,  false, ]);
3000        let struct_array = StructArrayBuilder::new()
3001            .with_field("metadata", Arc::new(metadata_array), false)
3002            .with_field("typed_value", Arc::new(typed_value), true)
3003            .with_nulls(nulls)
3004            .build();
3005
3006        Arc::new(struct_array)
3007    }
3008
3009    fn create_mixed_and_unshredded_variant() -> ArrayRef {
3012        let (metadata, y_field_value) = {
3017            let mut builder = parquet_variant::VariantBuilder::new();
3018            let mut obj = builder.new_object();
3019            obj.insert("y", Variant::from(42));
3020            obj.finish();
3021            builder.finish()
3022        };
3023
3024        let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 4));
3025
3026        let empty_object_value = {
3033            let mut builder = parquet_variant::VariantBuilder::new();
3034            builder.new_object().finish();
3035            let (_, value) = builder.finish();
3036            value
3037        };
3038
3039        let y_null_value = {
3040            let mut builder = parquet_variant::VariantBuilder::new();
3041            builder.new_object().with_field("y", Variant::Null).finish();
3042            let (_, value) = builder.finish();
3043            value
3044        };
3045
3046        let value_array = BinaryViewArray::from(vec![
3047            Some(y_field_value.as_slice()),      Some(empty_object_value.as_slice()), Some(y_null_value.as_slice()),       Some(empty_object_value.as_slice()), ]);
3052
3053        let x_field_typed_value = Int32Array::from(vec![Some(1), Some(2), Some(3), Some(0)]);
3056        let x_field_struct = StructArrayBuilder::new()
3057            .with_field("typed_value", Arc::new(x_field_typed_value), true)
3058            .build();
3059        let x_field_shredded = ShreddedVariantFieldArray::try_new(&x_field_struct)
3060            .expect("should create ShreddedVariantFieldArray for x");
3061
3062        let typed_value_struct = StructArrayBuilder::new()
3064            .with_field("x", ArrayRef::from(x_field_shredded), false)
3065            .build();
3066
3067        let variant_nulls = NullBuffer::from(vec![true, true, true, false]); let struct_array = StructArrayBuilder::new()
3071            .with_field("metadata", Arc::new(metadata_array), false)
3072            .with_field("value", Arc::new(value_array), true)
3073            .with_field("typed_value", Arc::new(typed_value_struct), true)
3074            .with_nulls(variant_nulls)
3075            .build();
3076
3077        Arc::new(struct_array)
3078    }
3079
3080    #[test]
3081    fn get_decimal32_rescaled_to_scale2() {
3082        let mut builder = crate::VariantArrayBuilder::new(5);
3084        builder.append_variant(VariantDecimal4::try_new(1234, 2).unwrap().into()); builder.append_variant(VariantDecimal4::try_new(1234, 3).unwrap().into()); builder.append_variant(VariantDecimal4::try_new(1234, 0).unwrap().into()); builder.append_null();
3088        builder.append_variant(
3089            VariantDecimal8::try_new((VariantDecimal4::MAX_UNSCALED_VALUE as i64) + 1, 3)
3090                .unwrap()
3091                .into(),
3092        ); let variant_array: ArrayRef = ArrayRef::from(builder.build());
3094
3095        let field = Field::new("result", DataType::Decimal32(9, 2), true);
3096        let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3097        let result = variant_get(&variant_array, options).unwrap();
3098        let result = result.as_any().downcast_ref::<Decimal32Array>().unwrap();
3099
3100        assert_eq!(result.precision(), 9);
3101        assert_eq!(result.scale(), 2);
3102        assert_eq!(result.value(0), 1234);
3103        assert_eq!(result.value(1), 123);
3104        assert_eq!(result.value(2), 123400);
3105        assert!(result.is_null(3));
3106        assert_eq!(
3107            result.value(4),
3108            VariantDecimal4::MAX_UNSCALED_VALUE / 10 + 1
3109        ); }
3111
3112    #[test]
3113    fn get_decimal32_scale_down_rounding() {
3114        let mut builder = crate::VariantArrayBuilder::new(7);
3115        builder.append_variant(VariantDecimal4::try_new(1235, 0).unwrap().into());
3116        builder.append_variant(VariantDecimal4::try_new(1245, 0).unwrap().into());
3117        builder.append_variant(VariantDecimal4::try_new(-1235, 0).unwrap().into());
3118        builder.append_variant(VariantDecimal4::try_new(-1245, 0).unwrap().into());
3119        builder.append_variant(VariantDecimal4::try_new(1235, 2).unwrap().into()); builder.append_variant(VariantDecimal4::try_new(1235, 3).unwrap().into()); builder.append_variant(VariantDecimal4::try_new(5235, 3).unwrap().into()); let variant_array: ArrayRef = ArrayRef::from(builder.build());
3123
3124        let field = Field::new("result", DataType::Decimal32(9, -1), true);
3125        let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3126        let result = variant_get(&variant_array, options).unwrap();
3127        let result = result.as_any().downcast_ref::<Decimal32Array>().unwrap();
3128
3129        assert_eq!(result.precision(), 9);
3130        assert_eq!(result.scale(), -1);
3131        assert_eq!(result.value(0), 124);
3132        assert_eq!(result.value(1), 125);
3133        assert_eq!(result.value(2), -124);
3134        assert_eq!(result.value(3), -125);
3135        assert_eq!(result.value(4), 1);
3136        assert!(result.is_valid(5));
3137        assert_eq!(result.value(5), 0);
3138        assert_eq!(result.value(6), 1);
3139    }
3140
3141    #[test]
3142    fn get_decimal32_large_scale_reduction() {
3143        let mut builder = crate::VariantArrayBuilder::new(2);
3144        builder.append_variant(
3145            VariantDecimal4::try_new(-VariantDecimal4::MAX_UNSCALED_VALUE, 0)
3146                .unwrap()
3147                .into(),
3148        );
3149        builder.append_variant(
3150            VariantDecimal4::try_new(VariantDecimal4::MAX_UNSCALED_VALUE, 0)
3151                .unwrap()
3152                .into(),
3153        );
3154        let variant_array: ArrayRef = ArrayRef::from(builder.build());
3155
3156        let field = Field::new("result", DataType::Decimal32(9, -9), true);
3157        let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3158        let result = variant_get(&variant_array, options).unwrap();
3159        let result = result.as_any().downcast_ref::<Decimal32Array>().unwrap();
3160
3161        assert_eq!(result.precision(), 9);
3162        assert_eq!(result.scale(), -9);
3163        assert_eq!(result.value(0), -1);
3164        assert_eq!(result.value(1), 1);
3165
3166        let field = Field::new("result", DataType::Decimal32(9, -10), true);
3167        let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3168        let result = variant_get(&variant_array, options).unwrap();
3169        let result = result.as_any().downcast_ref::<Decimal32Array>().unwrap();
3170
3171        assert_eq!(result.precision(), 9);
3172        assert_eq!(result.scale(), -10);
3173        assert!(result.is_valid(0));
3174        assert_eq!(result.value(0), 0);
3175        assert!(result.is_valid(1));
3176        assert_eq!(result.value(1), 0);
3177    }
3178
3179    #[test]
3180    fn get_decimal32_precision_overflow_safe() {
3181        let mut builder = crate::VariantArrayBuilder::new(2);
3183        builder.append_variant(
3184            VariantDecimal4::try_new(VariantDecimal4::MAX_UNSCALED_VALUE, 0)
3185                .unwrap()
3186                .into(),
3187        );
3188        builder.append_variant(
3189            VariantDecimal4::try_new(VariantDecimal4::MAX_UNSCALED_VALUE, 9)
3190                .unwrap()
3191                .into(),
3192        ); let variant_array: ArrayRef = ArrayRef::from(builder.build());
3194
3195        let field = Field::new("result", DataType::Decimal32(2, 2), true);
3196        let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3197        let result = variant_get(&variant_array, options).unwrap();
3198        let result = result.as_any().downcast_ref::<Decimal32Array>().unwrap();
3199
3200        assert!(result.is_null(0));
3201        assert!(result.is_null(1)); }
3203
3204    #[test]
3205    fn get_decimal32_precision_overflow_unsafe_errors() {
3206        let mut builder = crate::VariantArrayBuilder::new(1);
3207        builder.append_variant(
3208            VariantDecimal4::try_new(VariantDecimal4::MAX_UNSCALED_VALUE, 0)
3209                .unwrap()
3210                .into(),
3211        );
3212        let variant_array: ArrayRef = ArrayRef::from(builder.build());
3213
3214        let field = Field::new("result", DataType::Decimal32(9, 2), true);
3215        let cast_options = CastOptions {
3216            safe: false,
3217            ..Default::default()
3218        };
3219        let options = GetOptions::new()
3220            .with_as_type(Some(FieldRef::from(field)))
3221            .with_cast_options(cast_options);
3222        let err = variant_get(&variant_array, options).unwrap_err();
3223
3224        assert!(
3225            err.to_string().contains(
3226                "Failed to cast to Decimal32(precision=9, scale=2) from variant Decimal4"
3227            )
3228        );
3229    }
3230
3231    #[test]
3232    fn get_decimal64_rescaled_to_scale2() {
3233        let mut builder = crate::VariantArrayBuilder::new(5);
3234        builder.append_variant(VariantDecimal8::try_new(1234, 2).unwrap().into()); builder.append_variant(VariantDecimal8::try_new(1234, 3).unwrap().into()); builder.append_variant(VariantDecimal8::try_new(1234, 0).unwrap().into()); builder.append_null();
3238        builder.append_variant(
3239            VariantDecimal16::try_new((VariantDecimal8::MAX_UNSCALED_VALUE as i128) + 1, 3)
3240                .unwrap()
3241                .into(),
3242        ); let variant_array: ArrayRef = ArrayRef::from(builder.build());
3244
3245        let field = Field::new("result", DataType::Decimal64(18, 2), true);
3246        let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3247        let result = variant_get(&variant_array, options).unwrap();
3248        let result = result.as_any().downcast_ref::<Decimal64Array>().unwrap();
3249
3250        assert_eq!(result.precision(), 18);
3251        assert_eq!(result.scale(), 2);
3252        assert_eq!(result.value(0), 1234);
3253        assert_eq!(result.value(1), 123);
3254        assert_eq!(result.value(2), 123400);
3255        assert!(result.is_null(3));
3256        assert_eq!(
3257            result.value(4),
3258            VariantDecimal8::MAX_UNSCALED_VALUE / 10 + 1
3259        ); }
3261
3262    #[test]
3263    fn get_decimal64_scale_down_rounding() {
3264        let mut builder = crate::VariantArrayBuilder::new(7);
3265        builder.append_variant(VariantDecimal8::try_new(1235, 0).unwrap().into());
3266        builder.append_variant(VariantDecimal8::try_new(1245, 0).unwrap().into());
3267        builder.append_variant(VariantDecimal8::try_new(-1235, 0).unwrap().into());
3268        builder.append_variant(VariantDecimal8::try_new(-1245, 0).unwrap().into());
3269        builder.append_variant(VariantDecimal8::try_new(1235, 2).unwrap().into()); builder.append_variant(VariantDecimal8::try_new(1235, 3).unwrap().into()); builder.append_variant(VariantDecimal8::try_new(5235, 3).unwrap().into()); let variant_array: ArrayRef = ArrayRef::from(builder.build());
3273
3274        let field = Field::new("result", DataType::Decimal64(18, -1), true);
3275        let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3276        let result = variant_get(&variant_array, options).unwrap();
3277        let result = result.as_any().downcast_ref::<Decimal64Array>().unwrap();
3278
3279        assert_eq!(result.precision(), 18);
3280        assert_eq!(result.scale(), -1);
3281        assert_eq!(result.value(0), 124);
3282        assert_eq!(result.value(1), 125);
3283        assert_eq!(result.value(2), -124);
3284        assert_eq!(result.value(3), -125);
3285        assert_eq!(result.value(4), 1);
3286        assert!(result.is_valid(5));
3287        assert_eq!(result.value(5), 0);
3288        assert_eq!(result.value(6), 1);
3289    }
3290
3291    #[test]
3292    fn get_decimal64_large_scale_reduction() {
3293        let mut builder = crate::VariantArrayBuilder::new(2);
3294        builder.append_variant(
3295            VariantDecimal8::try_new(-VariantDecimal8::MAX_UNSCALED_VALUE, 0)
3296                .unwrap()
3297                .into(),
3298        );
3299        builder.append_variant(
3300            VariantDecimal8::try_new(VariantDecimal8::MAX_UNSCALED_VALUE, 0)
3301                .unwrap()
3302                .into(),
3303        );
3304        let variant_array: ArrayRef = ArrayRef::from(builder.build());
3305
3306        let field = Field::new("result", DataType::Decimal64(18, -18), true);
3307        let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3308        let result = variant_get(&variant_array, options).unwrap();
3309        let result = result.as_any().downcast_ref::<Decimal64Array>().unwrap();
3310
3311        assert_eq!(result.precision(), 18);
3312        assert_eq!(result.scale(), -18);
3313        assert_eq!(result.value(0), -1);
3314        assert_eq!(result.value(1), 1);
3315
3316        let field = Field::new("result", DataType::Decimal64(18, -19), true);
3317        let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3318        let result = variant_get(&variant_array, options).unwrap();
3319        let result = result.as_any().downcast_ref::<Decimal64Array>().unwrap();
3320
3321        assert_eq!(result.precision(), 18);
3322        assert_eq!(result.scale(), -19);
3323        assert!(result.is_valid(0));
3324        assert_eq!(result.value(0), 0);
3325        assert!(result.is_valid(1));
3326        assert_eq!(result.value(1), 0);
3327    }
3328
3329    #[test]
3330    fn get_decimal64_precision_overflow_safe() {
3331        let mut builder = crate::VariantArrayBuilder::new(2);
3333        builder.append_variant(
3334            VariantDecimal8::try_new(VariantDecimal8::MAX_UNSCALED_VALUE, 0)
3335                .unwrap()
3336                .into(),
3337        );
3338        builder.append_variant(
3339            VariantDecimal8::try_new(VariantDecimal8::MAX_UNSCALED_VALUE, 18)
3340                .unwrap()
3341                .into(),
3342        ); let variant_array: ArrayRef = ArrayRef::from(builder.build());
3344
3345        let field = Field::new("result", DataType::Decimal64(2, 2), true);
3346        let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3347        let result = variant_get(&variant_array, options).unwrap();
3348        let result = result.as_any().downcast_ref::<Decimal64Array>().unwrap();
3349
3350        assert!(result.is_null(0));
3351        assert!(result.is_null(1));
3352    }
3353
3354    #[test]
3355    fn get_decimal64_precision_overflow_unsafe_errors() {
3356        let mut builder = crate::VariantArrayBuilder::new(1);
3357        builder.append_variant(
3358            VariantDecimal8::try_new(VariantDecimal8::MAX_UNSCALED_VALUE, 0)
3359                .unwrap()
3360                .into(),
3361        );
3362        let variant_array: ArrayRef = ArrayRef::from(builder.build());
3363
3364        let field = Field::new("result", DataType::Decimal64(18, 2), true);
3365        let cast_options = CastOptions {
3366            safe: false,
3367            ..Default::default()
3368        };
3369        let options = GetOptions::new()
3370            .with_as_type(Some(FieldRef::from(field)))
3371            .with_cast_options(cast_options);
3372        let err = variant_get(&variant_array, options).unwrap_err();
3373
3374        assert!(
3375            err.to_string().contains(
3376                "Failed to cast to Decimal64(precision=18, scale=2) from variant Decimal8"
3377            )
3378        );
3379    }
3380
3381    #[test]
3382    fn get_decimal128_rescaled_to_scale2() {
3383        let mut builder = crate::VariantArrayBuilder::new(4);
3384        builder.append_variant(VariantDecimal16::try_new(1234, 2).unwrap().into());
3385        builder.append_variant(VariantDecimal16::try_new(1234, 3).unwrap().into());
3386        builder.append_variant(VariantDecimal16::try_new(1234, 0).unwrap().into());
3387        builder.append_null();
3388        let variant_array: ArrayRef = ArrayRef::from(builder.build());
3389
3390        let field = Field::new("result", DataType::Decimal128(38, 2), true);
3391        let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3392        let result = variant_get(&variant_array, options).unwrap();
3393        let result = result.as_any().downcast_ref::<Decimal128Array>().unwrap();
3394
3395        assert_eq!(result.precision(), 38);
3396        assert_eq!(result.scale(), 2);
3397        assert_eq!(result.value(0), 1234);
3398        assert_eq!(result.value(1), 123);
3399        assert_eq!(result.value(2), 123400);
3400        assert!(result.is_null(3));
3401    }
3402
3403    #[test]
3404    fn get_decimal128_scale_down_rounding() {
3405        let mut builder = crate::VariantArrayBuilder::new(7);
3406        builder.append_variant(VariantDecimal16::try_new(1235, 0).unwrap().into());
3407        builder.append_variant(VariantDecimal16::try_new(1245, 0).unwrap().into());
3408        builder.append_variant(VariantDecimal16::try_new(-1235, 0).unwrap().into());
3409        builder.append_variant(VariantDecimal16::try_new(-1245, 0).unwrap().into());
3410        builder.append_variant(VariantDecimal16::try_new(1235, 2).unwrap().into()); builder.append_variant(VariantDecimal16::try_new(1235, 3).unwrap().into()); builder.append_variant(VariantDecimal16::try_new(5235, 3).unwrap().into()); let variant_array: ArrayRef = ArrayRef::from(builder.build());
3414
3415        let field = Field::new("result", DataType::Decimal128(38, -1), true);
3416        let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3417        let result = variant_get(&variant_array, options).unwrap();
3418        let result = result.as_any().downcast_ref::<Decimal128Array>().unwrap();
3419
3420        assert_eq!(result.precision(), 38);
3421        assert_eq!(result.scale(), -1);
3422        assert_eq!(result.value(0), 124);
3423        assert_eq!(result.value(1), 125);
3424        assert_eq!(result.value(2), -124);
3425        assert_eq!(result.value(3), -125);
3426        assert_eq!(result.value(4), 1);
3427        assert!(result.is_valid(5));
3428        assert_eq!(result.value(5), 0);
3429        assert_eq!(result.value(6), 1);
3430    }
3431
3432    #[test]
3433    fn get_decimal128_precision_overflow_safe() {
3434        let mut builder = crate::VariantArrayBuilder::new(2);
3436        builder.append_variant(
3437            VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 0)
3438                .unwrap()
3439                .into(),
3440        );
3441        builder.append_variant(
3442            VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 38)
3443                .unwrap()
3444                .into(),
3445        ); let variant_array: ArrayRef = ArrayRef::from(builder.build());
3447
3448        let field = Field::new("result", DataType::Decimal128(2, 2), true);
3449        let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3450        let result = variant_get(&variant_array, options).unwrap();
3451        let result = result.as_any().downcast_ref::<Decimal128Array>().unwrap();
3452
3453        assert!(result.is_null(0));
3454        assert!(result.is_null(1)); }
3456
3457    #[test]
3458    fn get_decimal128_precision_overflow_unsafe_errors() {
3459        let mut builder = crate::VariantArrayBuilder::new(1);
3460        builder.append_variant(
3461            VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 0)
3462                .unwrap()
3463                .into(),
3464        );
3465        let variant_array: ArrayRef = ArrayRef::from(builder.build());
3466
3467        let field = Field::new("result", DataType::Decimal128(38, 2), true);
3468        let cast_options = CastOptions {
3469            safe: false,
3470            ..Default::default()
3471        };
3472        let options = GetOptions::new()
3473            .with_as_type(Some(FieldRef::from(field)))
3474            .with_cast_options(cast_options);
3475        let err = variant_get(&variant_array, options).unwrap_err();
3476
3477        assert!(err.to_string().contains(
3478            "Failed to cast to Decimal128(precision=38, scale=2) from variant Decimal16"
3479        ));
3480    }
3481
3482    #[test]
3483    fn get_decimal256_rescaled_to_scale2() {
3484        let mut builder = crate::VariantArrayBuilder::new(4);
3486        builder.append_variant(VariantDecimal16::try_new(1234, 2).unwrap().into()); builder.append_variant(VariantDecimal16::try_new(1234, 3).unwrap().into()); builder.append_variant(VariantDecimal16::try_new(1234, 0).unwrap().into()); builder.append_null();
3490        let variant_array: ArrayRef = ArrayRef::from(builder.build());
3491
3492        let field = Field::new("result", DataType::Decimal256(76, 2), true);
3493        let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3494        let result = variant_get(&variant_array, options).unwrap();
3495        let result = result.as_any().downcast_ref::<Decimal256Array>().unwrap();
3496
3497        assert_eq!(result.precision(), 76);
3498        assert_eq!(result.scale(), 2);
3499        assert_eq!(result.value(0), i256::from_i128(1234));
3500        assert_eq!(result.value(1), i256::from_i128(123));
3501        assert_eq!(result.value(2), i256::from_i128(123400));
3502        assert!(result.is_null(3));
3503    }
3504
3505    #[test]
3506    fn get_decimal256_scale_down_rounding() {
3507        let mut builder = crate::VariantArrayBuilder::new(7);
3508        builder.append_variant(VariantDecimal16::try_new(1235, 0).unwrap().into());
3509        builder.append_variant(VariantDecimal16::try_new(1245, 0).unwrap().into());
3510        builder.append_variant(VariantDecimal16::try_new(-1235, 0).unwrap().into());
3511        builder.append_variant(VariantDecimal16::try_new(-1245, 0).unwrap().into());
3512        builder.append_variant(VariantDecimal16::try_new(1235, 2).unwrap().into()); builder.append_variant(VariantDecimal16::try_new(1235, 3).unwrap().into()); builder.append_variant(VariantDecimal16::try_new(5235, 3).unwrap().into()); let variant_array: ArrayRef = ArrayRef::from(builder.build());
3516
3517        let field = Field::new("result", DataType::Decimal256(76, -1), true);
3518        let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3519        let result = variant_get(&variant_array, options).unwrap();
3520        let result = result.as_any().downcast_ref::<Decimal256Array>().unwrap();
3521
3522        assert_eq!(result.precision(), 76);
3523        assert_eq!(result.scale(), -1);
3524        assert_eq!(result.value(0), i256::from_i128(124));
3525        assert_eq!(result.value(1), i256::from_i128(125));
3526        assert_eq!(result.value(2), i256::from_i128(-124));
3527        assert_eq!(result.value(3), i256::from_i128(-125));
3528        assert_eq!(result.value(4), i256::from_i128(1));
3529        assert!(result.is_valid(5));
3530        assert_eq!(result.value(5), i256::from_i128(0));
3531        assert_eq!(result.value(6), i256::from_i128(1));
3532    }
3533
3534    #[test]
3535    fn get_decimal256_precision_overflow_safe() {
3536        let mut builder = crate::VariantArrayBuilder::new(2);
3538        builder.append_variant(
3539            VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 1)
3540                .unwrap()
3541                .into(),
3542        );
3543        builder.append_variant(
3544            VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 0)
3545                .unwrap()
3546                .into(),
3547        );
3548        let variant_array: ArrayRef = ArrayRef::from(builder.build());
3549
3550        let field = Field::new("result", DataType::Decimal256(76, 39), true);
3551        let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3552        let result = variant_get(&variant_array, options).unwrap();
3553        let result = result.as_any().downcast_ref::<Decimal256Array>().unwrap();
3554
3555        let base = i256::from_i128(10);
3558        let factor = base.checked_pow(38).unwrap();
3559        let expected = i256::from_i128(VariantDecimal16::MAX_UNSCALED_VALUE)
3560            .checked_mul(factor)
3561            .unwrap();
3562        assert_eq!(result.value(0), expected);
3563        assert!(result.is_null(1));
3564    }
3565
3566    #[test]
3567    fn get_decimal256_precision_overflow_unsafe_errors() {
3568        let mut builder = crate::VariantArrayBuilder::new(2);
3570        builder.append_variant(
3571            VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 1)
3572                .unwrap()
3573                .into(),
3574        );
3575        builder.append_variant(
3576            VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 0)
3577                .unwrap()
3578                .into(),
3579        );
3580        let variant_array: ArrayRef = ArrayRef::from(builder.build());
3581
3582        let field = Field::new("result", DataType::Decimal256(76, 39), true);
3583        let cast_options = CastOptions {
3584            safe: false,
3585            ..Default::default()
3586        };
3587        let options = GetOptions::new()
3588            .with_as_type(Some(FieldRef::from(field)))
3589            .with_cast_options(cast_options);
3590        let err = variant_get(&variant_array, options).unwrap_err();
3591
3592        assert!(err.to_string().contains(
3593            "Failed to cast to Decimal256(precision=76, scale=39) from variant Decimal16"
3594        ));
3595    }
3596
3597    perfectly_shredded_variant_array_fn!(perfectly_shredded_invalid_time_variant_array, || {
3598        Time64MicrosecondArray::from(vec![
3600            Some(86401000000),
3601            Some(86401000000),
3602            Some(86401000000),
3603        ])
3604    });
3605
3606    #[test]
3607    fn test_variant_get_error_when_cast_failure_and_safe_false() {
3608        let variant_array = perfectly_shredded_invalid_time_variant_array();
3609
3610        let field = Field::new("result", DataType::Time64(TimeUnit::Microsecond), true);
3611        let cast_options = CastOptions {
3612            safe: false, ..Default::default()
3614        };
3615        let options = GetOptions::new()
3616            .with_as_type(Some(FieldRef::from(field)))
3617            .with_cast_options(cast_options);
3618        let err = variant_get(&variant_array, options).unwrap_err();
3619        assert!(
3620            err.to_string().contains(
3621                "Cast error: Cast failed at index 0 (array type: Time64(µs)): Invalid microsecond from midnight: 86401000000"
3622            )
3623        );
3624    }
3625
3626    #[test]
3627    fn test_variant_get_return_null_when_cast_failure_and_safe_true() {
3628        let variant_array = perfectly_shredded_invalid_time_variant_array();
3629
3630        let field = Field::new("result", DataType::Time64(TimeUnit::Microsecond), true);
3631        let cast_options = CastOptions {
3632            safe: true, ..Default::default()
3634        };
3635        let options = GetOptions::new()
3636            .with_as_type(Some(FieldRef::from(field)))
3637            .with_cast_options(cast_options);
3638        let result = variant_get(&variant_array, options).unwrap();
3639        assert_eq!(3, result.len());
3640
3641        for i in 0..3 {
3642            assert!(result.is_null(i));
3643        }
3644    }
3645}