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 Some(shredded) = try_perfect_shredding(&target, as_field) {
213 return Ok(shredded);
214 }
215
216 if let DataType::Struct(fields) = as_field.data_type() {
219 let children = fields
220 .iter()
221 .map(|field| {
222 shredded_get_path(
223 &target,
224 &[VariantPathElement::from(field.name().as_str())],
225 Some(field),
226 cast_options,
227 )
228 })
229 .collect::<Result<Vec<_>>>()?;
230
231 let struct_nulls = target.nulls().cloned();
232
233 return Ok(Arc::new(StructArray::try_new(
234 fields.clone(),
235 children,
236 struct_nulls,
237 )?));
238 }
239
240 shred_basic_variant(target, VariantPath::default(), Some(as_field))
242}
243
244fn try_perfect_shredding(variant_array: &VariantArray, as_field: &Field) -> Option<ArrayRef> {
245 if matches!(as_field.data_type(), DataType::Struct(_)) {
247 return None;
248 }
249 let typed_value = variant_array.typed_value_field()?;
250 if typed_value.data_type() == as_field.data_type()
251 && variant_array
252 .value_field()
253 .is_none_or(|v| v.null_count() == v.len())
254 {
255 return Some(typed_value.clone());
262 }
263 None
264}
265
266pub fn variant_get(input: &ArrayRef, options: GetOptions) -> Result<ArrayRef> {
278 let variant_array = VariantArray::try_new(input)?;
279
280 let GetOptions {
281 as_type,
282 path,
283 cast_options,
284 } = options;
285
286 shredded_get_path(&variant_array, &path, as_type.as_deref(), &cast_options)
287}
288
289#[derive(Debug, Clone, Default)]
291pub struct GetOptions<'a> {
292 pub path: VariantPath<'a>,
294 pub as_type: Option<FieldRef>,
298 pub cast_options: CastOptions<'a>,
300}
301
302impl<'a> GetOptions<'a> {
303 pub fn new() -> Self {
305 Default::default()
306 }
307
308 pub fn new_with_path(path: VariantPath<'a>) -> Self {
310 Self {
311 path,
312 as_type: None,
313 cast_options: Default::default(),
314 }
315 }
316
317 pub fn with_as_type(mut self, as_type: Option<FieldRef>) -> Self {
319 self.as_type = as_type;
320 self
321 }
322
323 pub fn with_cast_options(mut self, cast_options: CastOptions<'a>) -> Self {
325 self.cast_options = cast_options;
326 self
327 }
328}
329
330#[cfg(test)]
331mod test {
332 use std::str::FromStr;
333 use std::sync::Arc;
334
335 use super::{GetOptions, variant_get};
336 use crate::variant_array::{ShreddedVariantFieldArray, StructArrayBuilder};
337 use crate::{VariantArray, VariantArrayBuilder, json_to_variant};
338 use arrow::array::{
339 Array, ArrayRef, AsArray, BinaryArray, BinaryViewArray, BooleanArray, Date32Array,
340 Date64Array, Decimal32Array, Decimal64Array, Decimal128Array, Decimal256Array,
341 Float32Array, Float64Array, Int8Array, Int16Array, Int32Array, Int64Array,
342 LargeBinaryArray, LargeStringArray, NullBuilder, StringArray, StringViewArray, StructArray,
343 Time32MillisecondArray, Time32SecondArray, Time64MicrosecondArray, Time64NanosecondArray,
344 };
345 use arrow::buffer::NullBuffer;
346 use arrow::compute::CastOptions;
347 use arrow::datatypes::DataType::{Int16, Int32, Int64};
348 use arrow::datatypes::i256;
349 use arrow::util::display::FormatOptions;
350 use arrow_schema::DataType::{Boolean, Float32, Float64, Int8};
351 use arrow_schema::{DataType, Field, FieldRef, Fields, IntervalUnit, TimeUnit};
352 use chrono::DateTime;
353 use parquet_variant::{
354 EMPTY_VARIANT_METADATA_BYTES, Variant, VariantDecimal4, VariantDecimal8, VariantDecimal16,
355 VariantDecimalType, VariantPath,
356 };
357
358 fn single_variant_get_test(input_json: &str, path: VariantPath, expected_json: &str) {
359 let input_array_ref: ArrayRef = Arc::new(StringArray::from(vec![Some(input_json)]));
361 let input_variant_array_ref = ArrayRef::from(json_to_variant(&input_array_ref).unwrap());
362
363 let result =
364 variant_get(&input_variant_array_ref, GetOptions::new_with_path(path)).unwrap();
365
366 let expected_array_ref: ArrayRef = Arc::new(StringArray::from(vec![Some(expected_json)]));
368 let expected_variant_array = json_to_variant(&expected_array_ref).unwrap();
369
370 let result_array = VariantArray::try_new(&result).unwrap();
371 assert_eq!(
372 result_array.len(),
373 1,
374 "Expected result array to have length 1"
375 );
376 assert!(
377 result_array.nulls().is_none(),
378 "Expected no nulls in result array"
379 );
380 let result_variant = result_array.value(0);
381 let expected_variant = expected_variant_array.value(0);
382 assert_eq!(
383 result_variant, expected_variant,
384 "Result variant does not match expected variant"
385 );
386 }
387
388 #[test]
389 fn get_primitive_variant_field() {
390 single_variant_get_test(
391 r#"{"some_field": 1234}"#,
392 VariantPath::from("some_field"),
393 "1234",
394 );
395 }
396
397 #[test]
398 fn get_primitive_variant_list_index() {
399 single_variant_get_test("[1234, 5678]", VariantPath::from(0), "1234");
400 }
401
402 #[test]
403 fn get_primitive_variant_inside_object_of_object() {
404 single_variant_get_test(
405 r#"{"top_level_field": {"inner_field": 1234}}"#,
406 VariantPath::from("top_level_field").join("inner_field"),
407 "1234",
408 );
409 }
410
411 #[test]
412 fn get_primitive_variant_inside_list_of_object() {
413 single_variant_get_test(
414 r#"[{"some_field": 1234}]"#,
415 VariantPath::from(0).join("some_field"),
416 "1234",
417 );
418 }
419
420 #[test]
421 fn get_primitive_variant_inside_object_of_list() {
422 single_variant_get_test(
423 r#"{"some_field": [1234]}"#,
424 VariantPath::from("some_field").join(0),
425 "1234",
426 );
427 }
428
429 #[test]
430 fn get_complex_variant() {
431 single_variant_get_test(
432 r#"{"top_level_field": {"inner_field": 1234}}"#,
433 VariantPath::from("top_level_field"),
434 r#"{"inner_field": 1234}"#,
435 );
436 }
437
438 macro_rules! numeric_partially_shredded_test {
440 ($primitive_type:ty, $data_fn:ident) => {
441 let array = $data_fn();
442 let options = GetOptions::new();
443 let result = variant_get(&array, options).unwrap();
444
445 let result = VariantArray::try_new(&result).unwrap();
447 assert_eq!(result.len(), 4);
448
449 assert_eq!(
451 result.value(0),
452 Variant::from(<$primitive_type>::try_from(34u8).unwrap())
453 );
454 assert!(!result.is_valid(1));
455 assert_eq!(result.value(2), Variant::from("n/a"));
456 assert_eq!(
457 result.value(3),
458 Variant::from(<$primitive_type>::try_from(100u8).unwrap())
459 );
460 };
461 }
462
463 macro_rules! partially_shredded_variant_array_gen {
464 ($func_name:ident, $typed_value_array_gen: expr) => {
465 fn $func_name() -> ArrayRef {
466 let (metadata, string_value) = {
467 let mut builder = parquet_variant::VariantBuilder::new();
468 builder.append_value("n/a");
469 builder.finish()
470 };
471
472 let nulls = NullBuffer::from(vec![
473 true, false, true, true, ]);
478
479 let metadata = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 4));
481
482 let values = BinaryViewArray::from(vec![
485 None, Some(b"" as &[u8]), Some(&string_value), None, ]);
490
491 let typed_value = $typed_value_array_gen();
492
493 let struct_array = StructArrayBuilder::new()
494 .with_field("metadata", Arc::new(metadata), false)
495 .with_field("typed_value", Arc::new(typed_value), true)
496 .with_field("value", Arc::new(values), true)
497 .with_nulls(nulls)
498 .build();
499 ArrayRef::from(
500 VariantArray::try_new(&struct_array).expect("should create variant array"),
501 )
502 }
503 };
504 }
505
506 #[test]
507 fn get_variant_partially_shredded_int8_as_variant() {
508 numeric_partially_shredded_test!(i8, partially_shredded_int8_variant_array);
509 }
510
511 #[test]
512 fn get_variant_partially_shredded_int16_as_variant() {
513 numeric_partially_shredded_test!(i16, partially_shredded_int16_variant_array);
514 }
515
516 #[test]
517 fn get_variant_partially_shredded_int32_as_variant() {
518 numeric_partially_shredded_test!(i32, partially_shredded_int32_variant_array);
519 }
520
521 #[test]
522 fn get_variant_partially_shredded_int64_as_variant() {
523 numeric_partially_shredded_test!(i64, partially_shredded_int64_variant_array);
524 }
525
526 #[test]
527 fn get_variant_partially_shredded_float32_as_variant() {
528 numeric_partially_shredded_test!(f32, partially_shredded_float32_variant_array);
529 }
530
531 #[test]
532 fn get_variant_partially_shredded_float64_as_variant() {
533 numeric_partially_shredded_test!(f64, partially_shredded_float64_variant_array);
534 }
535
536 #[test]
537 fn get_variant_partially_shredded_bool_as_variant() {
538 let array = partially_shredded_bool_variant_array();
539 let options = GetOptions::new();
540 let result = variant_get(&array, options).unwrap();
541
542 let result = VariantArray::try_new(&result).unwrap();
544 assert_eq!(result.len(), 4);
545
546 assert_eq!(result.value(0), Variant::from(true));
548 assert!(!result.is_valid(1));
549 assert_eq!(result.value(2), Variant::from("n/a"));
550 assert_eq!(result.value(3), Variant::from(false));
551 }
552
553 #[test]
554 fn get_variant_partially_shredded_utf8_as_variant() {
555 let array = partially_shredded_utf8_variant_array();
556 let options = GetOptions::new();
557 let result = variant_get(&array, options).unwrap();
558
559 let result = VariantArray::try_new(&result).unwrap();
561 assert_eq!(result.len(), 4);
562
563 assert_eq!(result.value(0), Variant::from("hello"));
565 assert!(!result.is_valid(1));
566 assert_eq!(result.value(2), Variant::from("n/a"));
567 assert_eq!(result.value(3), Variant::from("world"));
568 }
569
570 partially_shredded_variant_array_gen!(partially_shredded_binary_view_variant_array, || {
571 BinaryViewArray::from(vec![
572 Some(&[1u8, 2u8, 3u8][..]), None, None, Some(&[4u8, 5u8, 6u8][..]), ])
577 });
578
579 #[test]
580 fn get_variant_partially_shredded_date32_as_variant() {
581 let array = partially_shredded_date32_variant_array();
582 let options = GetOptions::new();
583 let result = variant_get(&array, options).unwrap();
584
585 let result = VariantArray::try_new(&result).unwrap();
587 assert_eq!(result.len(), 4);
588
589 use chrono::NaiveDate;
591 let date1 = NaiveDate::from_ymd_opt(2025, 9, 17).unwrap();
592 let date2 = NaiveDate::from_ymd_opt(2025, 9, 9).unwrap();
593 assert_eq!(result.value(0), Variant::from(date1));
594 assert!(!result.is_valid(1));
595 assert_eq!(result.value(2), Variant::from("n/a"));
596 assert_eq!(result.value(3), Variant::from(date2));
597 }
598
599 #[test]
600 fn get_variant_partially_shredded_binary_view_as_variant() {
601 let array = partially_shredded_binary_view_variant_array();
602 let options = GetOptions::new();
603 let result = variant_get(&array, options).unwrap();
604
605 let result = VariantArray::try_new(&result).unwrap();
607 assert_eq!(result.len(), 4);
608
609 assert_eq!(result.value(0), Variant::from(&[1u8, 2u8, 3u8][..]));
611 assert!(!result.is_valid(1));
612 assert_eq!(result.value(2), Variant::from("n/a"));
613 assert_eq!(result.value(3), Variant::from(&[4u8, 5u8, 6u8][..]));
614 }
615
616 #[test]
618 fn get_variant_shredded_int32_as_int32_safe_cast() {
619 let array = partially_shredded_int32_variant_array();
621 let field = Field::new("typed_value", DataType::Int32, true);
623 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
624 let result = variant_get(&array, options).unwrap();
625 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
626 Some(34),
627 None,
628 None, Some(100),
630 ]));
631 assert_eq!(&result, &expected)
632 }
633
634 #[test]
636 fn get_variant_shredded_int32_as_int32_unsafe_cast() {
637 let array = partially_shredded_int32_variant_array();
639 let field = Field::new("typed_value", DataType::Int32, true);
640 let cast_options = CastOptions {
641 safe: false, ..Default::default()
643 };
644 let options = GetOptions::new()
645 .with_as_type(Some(FieldRef::from(field)))
646 .with_cast_options(cast_options);
647
648 let err = variant_get(&array, options).unwrap_err();
649 assert_eq!(
651 err.to_string(),
652 "Cast error: Failed to extract primitive of type Int32 from variant ShortString(ShortString(\"n/a\")) at path VariantPath([])"
653 );
654 }
655
656 macro_rules! numeric_perfectly_shredded_test {
658 ($primitive_type:ty, $data_fn:ident) => {
659 let array = $data_fn();
660 let options = GetOptions::new();
661 let result = variant_get(&array, options).unwrap();
662
663 let result = VariantArray::try_new(&result).unwrap();
665 assert_eq!(result.len(), 3);
666
667 assert_eq!(
669 result.value(0),
670 Variant::from(<$primitive_type>::try_from(1u8).unwrap())
671 );
672 assert_eq!(
673 result.value(1),
674 Variant::from(<$primitive_type>::try_from(2u8).unwrap())
675 );
676 assert_eq!(
677 result.value(2),
678 Variant::from(<$primitive_type>::try_from(3u8).unwrap())
679 );
680 };
681 }
682
683 #[test]
684 fn get_variant_perfectly_shredded_int8_as_variant() {
685 numeric_perfectly_shredded_test!(i8, perfectly_shredded_int8_variant_array);
686 }
687
688 #[test]
689 fn get_variant_perfectly_shredded_int16_as_variant() {
690 numeric_perfectly_shredded_test!(i16, perfectly_shredded_int16_variant_array);
691 }
692
693 #[test]
694 fn get_variant_perfectly_shredded_int32_as_variant() {
695 numeric_perfectly_shredded_test!(i32, perfectly_shredded_int32_variant_array);
696 }
697
698 #[test]
699 fn get_variant_perfectly_shredded_int64_as_variant() {
700 numeric_perfectly_shredded_test!(i64, perfectly_shredded_int64_variant_array);
701 }
702
703 #[test]
704 fn get_variant_perfectly_shredded_float32_as_variant() {
705 numeric_perfectly_shredded_test!(f32, perfectly_shredded_float32_variant_array);
706 }
707
708 #[test]
709 fn get_variant_perfectly_shredded_float64_as_variant() {
710 numeric_perfectly_shredded_test!(f64, perfectly_shredded_float64_variant_array);
711 }
712
713 #[test]
715 fn get_variant_all_null_as_variant() {
716 let array = all_null_variant_array();
717 let options = GetOptions::new();
718 let result = variant_get(&array, options).unwrap();
719
720 let result = VariantArray::try_new(&result).unwrap();
722 assert_eq!(result.len(), 3);
723
724 assert!(!result.is_valid(0));
726 assert!(!result.is_valid(1));
727 assert!(!result.is_valid(2));
728 }
729
730 #[test]
732 fn get_variant_all_null_as_int32() {
733 let array = all_null_variant_array();
734 let field = Field::new("typed_value", DataType::Int32, true);
736 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
737 let result = variant_get(&array, options).unwrap();
738
739 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
740 Option::<i32>::None,
741 Option::<i32>::None,
742 Option::<i32>::None,
743 ]));
744 assert_eq!(&result, &expected)
745 }
746
747 macro_rules! perfectly_shredded_to_arrow_primitive_test {
748 ($name:ident, $primitive_type:expr, $perfectly_shredded_array_gen_fun:ident, $expected_array:expr) => {
749 #[test]
750 fn $name() {
751 let array = $perfectly_shredded_array_gen_fun();
752 let field = Field::new("typed_value", $primitive_type, true);
753 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
754 let result = variant_get(&array, options).unwrap();
755 let expected_array: ArrayRef = Arc::new($expected_array);
756 assert_eq!(&result, &expected_array);
757 }
758 };
759 }
760
761 perfectly_shredded_to_arrow_primitive_test!(
762 get_variant_perfectly_shredded_int18_as_int8,
763 Int8,
764 perfectly_shredded_int8_variant_array,
765 Int8Array::from(vec![Some(1), Some(2), Some(3)])
766 );
767
768 perfectly_shredded_to_arrow_primitive_test!(
769 get_variant_perfectly_shredded_int16_as_int16,
770 Int16,
771 perfectly_shredded_int16_variant_array,
772 Int16Array::from(vec![Some(1), Some(2), Some(3)])
773 );
774
775 perfectly_shredded_to_arrow_primitive_test!(
776 get_variant_perfectly_shredded_int32_as_int32,
777 Int32,
778 perfectly_shredded_int32_variant_array,
779 Int32Array::from(vec![Some(1), Some(2), Some(3)])
780 );
781
782 perfectly_shredded_to_arrow_primitive_test!(
783 get_variant_perfectly_shredded_int64_as_int64,
784 Int64,
785 perfectly_shredded_int64_variant_array,
786 Int64Array::from(vec![Some(1), Some(2), Some(3)])
787 );
788
789 perfectly_shredded_to_arrow_primitive_test!(
790 get_variant_perfectly_shredded_float32_as_float32,
791 Float32,
792 perfectly_shredded_float32_variant_array,
793 Float32Array::from(vec![Some(1.0), Some(2.0), Some(3.0)])
794 );
795
796 perfectly_shredded_to_arrow_primitive_test!(
797 get_variant_perfectly_shredded_float64_as_float64,
798 Float64,
799 perfectly_shredded_float64_variant_array,
800 Float64Array::from(vec![Some(1.0), Some(2.0), Some(3.0)])
801 );
802
803 perfectly_shredded_to_arrow_primitive_test!(
804 get_variant_perfectly_shredded_boolean_as_boolean,
805 Boolean,
806 perfectly_shredded_bool_variant_array,
807 BooleanArray::from(vec![Some(true), Some(false), Some(true)])
808 );
809
810 perfectly_shredded_to_arrow_primitive_test!(
811 get_variant_perfectly_shredded_utf8_as_utf8,
812 DataType::Utf8,
813 perfectly_shredded_utf8_variant_array,
814 StringArray::from(vec![Some("foo"), Some("bar"), Some("baz")])
815 );
816
817 perfectly_shredded_to_arrow_primitive_test!(
818 get_variant_perfectly_shredded_large_utf8_as_utf8,
819 DataType::Utf8,
820 perfectly_shredded_large_utf8_variant_array,
821 StringArray::from(vec![Some("foo"), Some("bar"), Some("baz")])
822 );
823
824 perfectly_shredded_to_arrow_primitive_test!(
825 get_variant_perfectly_shredded_utf8_view_as_utf8,
826 DataType::Utf8,
827 perfectly_shredded_utf8_view_variant_array,
828 StringArray::from(vec![Some("foo"), Some("bar"), Some("baz")])
829 );
830
831 macro_rules! perfectly_shredded_variant_array_fn {
832 ($func:ident, $typed_value_gen:expr) => {
833 fn $func() -> ArrayRef {
834 let metadata = BinaryViewArray::from_iter_values(std::iter::repeat_n(
837 EMPTY_VARIANT_METADATA_BYTES,
838 3,
839 ));
840 let typed_value = $typed_value_gen();
841
842 let struct_array = StructArrayBuilder::new()
843 .with_field("metadata", Arc::new(metadata), false)
844 .with_field("typed_value", Arc::new(typed_value), true)
845 .build();
846
847 VariantArray::try_new(&struct_array)
848 .expect("should create variant array")
849 .into()
850 }
851 };
852 }
853
854 perfectly_shredded_variant_array_fn!(perfectly_shredded_utf8_variant_array, || {
855 StringArray::from(vec![Some("foo"), Some("bar"), Some("baz")])
856 });
857
858 perfectly_shredded_variant_array_fn!(perfectly_shredded_large_utf8_variant_array, || {
859 LargeStringArray::from(vec![Some("foo"), Some("bar"), Some("baz")])
860 });
861
862 perfectly_shredded_variant_array_fn!(perfectly_shredded_utf8_view_variant_array, || {
863 StringViewArray::from(vec![Some("foo"), Some("bar"), Some("baz")])
864 });
865
866 perfectly_shredded_variant_array_fn!(perfectly_shredded_bool_variant_array, || {
867 BooleanArray::from(vec![Some(true), Some(false), Some(true)])
868 });
869
870 macro_rules! numeric_perfectly_shredded_variant_array_fn {
882 ($func:ident, $array_type:ident, $primitive_type:ty) => {
883 perfectly_shredded_variant_array_fn!($func, || {
884 $array_type::from(vec![
885 Some(<$primitive_type>::try_from(1u8).unwrap()),
886 Some(<$primitive_type>::try_from(2u8).unwrap()),
887 Some(<$primitive_type>::try_from(3u8).unwrap()),
888 ])
889 });
890 };
891 }
892
893 numeric_perfectly_shredded_variant_array_fn!(
894 perfectly_shredded_int8_variant_array,
895 Int8Array,
896 i8
897 );
898 numeric_perfectly_shredded_variant_array_fn!(
899 perfectly_shredded_int16_variant_array,
900 Int16Array,
901 i16
902 );
903 numeric_perfectly_shredded_variant_array_fn!(
904 perfectly_shredded_int32_variant_array,
905 Int32Array,
906 i32
907 );
908 numeric_perfectly_shredded_variant_array_fn!(
909 perfectly_shredded_int64_variant_array,
910 Int64Array,
911 i64
912 );
913 numeric_perfectly_shredded_variant_array_fn!(
914 perfectly_shredded_float32_variant_array,
915 Float32Array,
916 f32
917 );
918 numeric_perfectly_shredded_variant_array_fn!(
919 perfectly_shredded_float64_variant_array,
920 Float64Array,
921 f64
922 );
923
924 perfectly_shredded_variant_array_fn!(
925 perfectly_shredded_timestamp_micro_ntz_variant_array,
926 || {
927 arrow::array::TimestampMicrosecondArray::from(vec![
928 Some(-456000),
929 Some(1758602096000001),
930 Some(1758602096000002),
931 ])
932 }
933 );
934
935 perfectly_shredded_to_arrow_primitive_test!(
936 get_variant_perfectly_shredded_timestamp_micro_ntz_as_timestamp_micro_ntz,
937 DataType::Timestamp(TimeUnit::Microsecond, None),
938 perfectly_shredded_timestamp_micro_ntz_variant_array,
939 arrow::array::TimestampMicrosecondArray::from(vec![
940 Some(-456000),
941 Some(1758602096000001),
942 Some(1758602096000002),
943 ])
944 );
945
946 perfectly_shredded_to_arrow_primitive_test!(
948 get_variant_perfectly_shredded_timestamp_micro_ntz_as_nano_ntz,
949 DataType::Timestamp(TimeUnit::Nanosecond, None),
950 perfectly_shredded_timestamp_micro_ntz_variant_array,
951 arrow::array::TimestampNanosecondArray::from(vec![
952 Some(-456000000),
953 Some(1758602096000001000),
954 Some(1758602096000002000)
955 ])
956 );
957
958 perfectly_shredded_variant_array_fn!(perfectly_shredded_timestamp_micro_variant_array, || {
959 arrow::array::TimestampMicrosecondArray::from(vec![
960 Some(-456000),
961 Some(1758602096000001),
962 Some(1758602096000002),
963 ])
964 .with_timezone("+00:00")
965 });
966
967 perfectly_shredded_to_arrow_primitive_test!(
968 get_variant_perfectly_shredded_timestamp_micro_as_timestamp_micro,
969 DataType::Timestamp(TimeUnit::Microsecond, Some(Arc::from("+00:00"))),
970 perfectly_shredded_timestamp_micro_variant_array,
971 arrow::array::TimestampMicrosecondArray::from(vec![
972 Some(-456000),
973 Some(1758602096000001),
974 Some(1758602096000002),
975 ])
976 .with_timezone("+00:00")
977 );
978
979 perfectly_shredded_to_arrow_primitive_test!(
981 get_variant_perfectly_shredded_timestamp_micro_as_nano,
982 DataType::Timestamp(TimeUnit::Nanosecond, Some(Arc::from("+00:00"))),
983 perfectly_shredded_timestamp_micro_variant_array,
984 arrow::array::TimestampNanosecondArray::from(vec![
985 Some(-456000000),
986 Some(1758602096000001000),
987 Some(1758602096000002000)
988 ])
989 .with_timezone("+00:00")
990 );
991
992 perfectly_shredded_variant_array_fn!(
993 perfectly_shredded_timestamp_nano_ntz_variant_array,
994 || {
995 arrow::array::TimestampNanosecondArray::from(vec![
996 Some(-4999999561),
997 Some(1758602096000000001),
998 Some(1758602096000000002),
999 ])
1000 }
1001 );
1002
1003 perfectly_shredded_variant_array_fn!(
1004 perfectly_shredded_timestamp_micro_variant_array_for_second_and_milli_second,
1005 || {
1006 arrow::array::TimestampMicrosecondArray::from(vec![
1007 Some(1234), Some(1234000), Some(1234000000), ])
1011 .with_timezone("+00:00")
1012 }
1013 );
1014
1015 perfectly_shredded_to_arrow_primitive_test!(
1018 get_variant_perfectly_shredded_timestamp_micro_as_timestamp_second,
1019 DataType::Timestamp(TimeUnit::Second, Some(Arc::from("+00:00"))),
1020 perfectly_shredded_timestamp_micro_variant_array_for_second_and_milli_second,
1021 arrow::array::TimestampSecondArray::from(vec![
1022 None,
1023 None, Some(1234)
1025 ])
1026 .with_timezone("+00:00")
1027 );
1028
1029 perfectly_shredded_to_arrow_primitive_test!(
1030 get_variant_perfectly_shredded_timestamp_micro_as_timestamp_milli,
1031 DataType::Timestamp(TimeUnit::Millisecond, Some(Arc::from("+00:00"))),
1032 perfectly_shredded_timestamp_micro_variant_array_for_second_and_milli_second,
1033 arrow::array::TimestampMillisecondArray::from(vec![
1034 None, Some(1234),
1036 Some(1234000)
1037 ])
1038 .with_timezone("+00:00")
1039 );
1040
1041 perfectly_shredded_variant_array_fn!(
1042 perfectly_shredded_timestamp_micro_ntz_variant_array_for_second_and_milli_second,
1043 || {
1044 arrow::array::TimestampMicrosecondArray::from(vec![
1045 Some(1234), Some(1234000), Some(1234000000), ])
1049 }
1050 );
1051
1052 perfectly_shredded_to_arrow_primitive_test!(
1055 get_variant_perfectly_shredded_timestamp_micro_ntz_as_timestamp_second,
1056 DataType::Timestamp(TimeUnit::Second, None),
1057 perfectly_shredded_timestamp_micro_ntz_variant_array_for_second_and_milli_second,
1058 arrow::array::TimestampSecondArray::from(vec![
1059 None,
1060 None, Some(1234)
1062 ])
1063 );
1064
1065 perfectly_shredded_to_arrow_primitive_test!(
1066 get_variant_perfectly_shredded_timestamp_micro_ntz_as_timestamp_milli,
1067 DataType::Timestamp(TimeUnit::Millisecond, None),
1068 perfectly_shredded_timestamp_micro_ntz_variant_array_for_second_and_milli_second,
1069 arrow::array::TimestampMillisecondArray::from(vec![
1070 None, Some(1234),
1072 Some(1234000)
1073 ])
1074 );
1075
1076 perfectly_shredded_variant_array_fn!(
1077 perfectly_shredded_timestamp_nano_variant_array_for_second_and_milli_second,
1078 || {
1079 arrow::array::TimestampNanosecondArray::from(vec![
1080 Some(1234000), Some(1234000000), Some(1234000000000), ])
1084 .with_timezone("+00:00")
1085 }
1086 );
1087
1088 perfectly_shredded_to_arrow_primitive_test!(
1091 get_variant_perfectly_shredded_timestamp_nano_as_timestamp_second,
1092 DataType::Timestamp(TimeUnit::Second, Some(Arc::from("+00:00"))),
1093 perfectly_shredded_timestamp_nano_variant_array_for_second_and_milli_second,
1094 arrow::array::TimestampSecondArray::from(vec![
1095 None,
1096 None, Some(1234)
1098 ])
1099 .with_timezone("+00:00")
1100 );
1101
1102 perfectly_shredded_to_arrow_primitive_test!(
1103 get_variant_perfectly_shredded_timestamp_nano_as_timestamp_milli,
1104 DataType::Timestamp(TimeUnit::Millisecond, Some(Arc::from("+00:00"))),
1105 perfectly_shredded_timestamp_nano_variant_array_for_second_and_milli_second,
1106 arrow::array::TimestampMillisecondArray::from(vec![
1107 None, Some(1234),
1109 Some(1234000)
1110 ])
1111 .with_timezone("+00:00")
1112 );
1113
1114 perfectly_shredded_variant_array_fn!(
1115 perfectly_shredded_timestamp_nano_ntz_variant_array_for_second_and_milli_second,
1116 || {
1117 arrow::array::TimestampNanosecondArray::from(vec![
1118 Some(1234000), Some(1234000000), Some(1234000000000), ])
1122 }
1123 );
1124
1125 perfectly_shredded_to_arrow_primitive_test!(
1128 get_variant_perfectly_shredded_timestamp_nano_ntz_as_timestamp_second,
1129 DataType::Timestamp(TimeUnit::Second, None),
1130 perfectly_shredded_timestamp_nano_ntz_variant_array_for_second_and_milli_second,
1131 arrow::array::TimestampSecondArray::from(vec![
1132 None,
1133 None, Some(1234)
1135 ])
1136 );
1137
1138 perfectly_shredded_to_arrow_primitive_test!(
1139 get_variant_perfectly_shredded_timestamp_nano_ntz_as_timestamp_milli,
1140 DataType::Timestamp(TimeUnit::Millisecond, None),
1141 perfectly_shredded_timestamp_nano_ntz_variant_array_for_second_and_milli_second,
1142 arrow::array::TimestampMillisecondArray::from(vec![
1143 None, Some(1234),
1145 Some(1234000)
1146 ])
1147 );
1148
1149 perfectly_shredded_to_arrow_primitive_test!(
1150 get_variant_perfectly_shredded_timestamp_nano_ntz_as_timestamp_nano_ntz,
1151 DataType::Timestamp(TimeUnit::Nanosecond, None),
1152 perfectly_shredded_timestamp_nano_ntz_variant_array,
1153 arrow::array::TimestampNanosecondArray::from(vec![
1154 Some(-4999999561),
1155 Some(1758602096000000001),
1156 Some(1758602096000000002),
1157 ])
1158 );
1159
1160 perfectly_shredded_variant_array_fn!(perfectly_shredded_timestamp_nano_variant_array, || {
1161 arrow::array::TimestampNanosecondArray::from(vec![
1162 Some(-4999999561),
1163 Some(1758602096000000001),
1164 Some(1758602096000000002),
1165 ])
1166 .with_timezone("+00:00")
1167 });
1168
1169 perfectly_shredded_to_arrow_primitive_test!(
1170 get_variant_perfectly_shredded_timestamp_nano_as_timestamp_nano,
1171 DataType::Timestamp(TimeUnit::Nanosecond, Some(Arc::from("+00:00"))),
1172 perfectly_shredded_timestamp_nano_variant_array,
1173 arrow::array::TimestampNanosecondArray::from(vec![
1174 Some(-4999999561),
1175 Some(1758602096000000001),
1176 Some(1758602096000000002),
1177 ])
1178 .with_timezone("+00:00")
1179 );
1180
1181 perfectly_shredded_variant_array_fn!(perfectly_shredded_date_variant_array, || {
1182 Date32Array::from(vec![Some(-12345), Some(17586), Some(20000)])
1183 });
1184
1185 perfectly_shredded_to_arrow_primitive_test!(
1186 get_variant_perfectly_shredded_date_as_date,
1187 DataType::Date32,
1188 perfectly_shredded_date_variant_array,
1189 Date32Array::from(vec![Some(-12345), Some(17586), Some(20000)])
1190 );
1191
1192 perfectly_shredded_to_arrow_primitive_test!(
1193 get_variant_perfectly_shredded_date_as_date64,
1194 DataType::Date64,
1195 perfectly_shredded_date_variant_array,
1196 Date64Array::from(vec![
1197 Some(-1066608000000),
1198 Some(1519430400000),
1199 Some(1728000000000)
1200 ])
1201 );
1202
1203 perfectly_shredded_variant_array_fn!(perfectly_shredded_time_variant_array, || {
1204 Time64MicrosecondArray::from(vec![Some(12345000), Some(87654000), Some(135792000)])
1205 });
1206
1207 perfectly_shredded_to_arrow_primitive_test!(
1208 get_variant_perfectly_shredded_time_as_time,
1209 DataType::Time64(TimeUnit::Microsecond),
1210 perfectly_shredded_time_variant_array,
1211 Time64MicrosecondArray::from(vec![Some(12345000), Some(87654000), Some(135792000)])
1212 );
1213
1214 perfectly_shredded_to_arrow_primitive_test!(
1215 get_variant_perfectly_shredded_time_as_time64_nano,
1216 DataType::Time64(TimeUnit::Nanosecond),
1217 perfectly_shredded_time_variant_array,
1218 Time64NanosecondArray::from(vec![
1219 Some(12345000000),
1220 Some(87654000000),
1221 Some(135792000000)
1222 ])
1223 );
1224
1225 perfectly_shredded_variant_array_fn!(perfectly_shredded_time_variant_array_for_time32, || {
1226 Time64MicrosecondArray::from(vec![
1227 Some(1234), Some(7654000), Some(35792000000), ])
1231 });
1232
1233 perfectly_shredded_to_arrow_primitive_test!(
1234 get_variant_perfectly_shredded_time_as_time32_second,
1235 DataType::Time32(TimeUnit::Second),
1236 perfectly_shredded_time_variant_array_for_time32,
1237 Time32SecondArray::from(vec![
1238 None,
1239 None, Some(35792)
1241 ])
1242 );
1243
1244 perfectly_shredded_to_arrow_primitive_test!(
1245 get_variant_perfectly_shredded_time_as_time32_milli,
1246 DataType::Time32(TimeUnit::Millisecond),
1247 perfectly_shredded_time_variant_array_for_time32,
1248 Time32MillisecondArray::from(vec![
1249 None, Some(7654),
1251 Some(35792000)
1252 ])
1253 );
1254
1255 perfectly_shredded_variant_array_fn!(perfectly_shredded_null_variant_array, || {
1256 let mut builder = NullBuilder::new();
1257 builder.append_nulls(3);
1258 builder.finish()
1259 });
1260
1261 perfectly_shredded_to_arrow_primitive_test!(
1262 get_variant_perfectly_shredded_null_as_null,
1263 DataType::Null,
1264 perfectly_shredded_null_variant_array,
1265 arrow::array::NullArray::new(3)
1266 );
1267
1268 perfectly_shredded_variant_array_fn!(perfectly_shredded_null_variant_array_with_int, || {
1269 Int32Array::from(vec![Some(32), Some(64), Some(48)])
1270 });
1271
1272 perfectly_shredded_to_arrow_primitive_test!(
1274 get_variant_perfectly_shredded_null_with_type_missmatch_in_safe_mode,
1275 DataType::Null,
1276 perfectly_shredded_null_variant_array_with_int,
1277 arrow::array::NullArray::new(3)
1278 );
1279
1280 #[test]
1282 fn get_variant_perfectly_shredded_null_as_null_with_type_missmatch_in_strict_mode() {
1283 let array = perfectly_shredded_null_variant_array_with_int();
1284 let field = Field::new("typed_value", DataType::Null, true);
1285 let options = GetOptions::new()
1286 .with_as_type(Some(FieldRef::from(field)))
1287 .with_cast_options(CastOptions {
1288 safe: false,
1289 format_options: FormatOptions::default(),
1290 });
1291
1292 let result = variant_get(&array, options);
1293
1294 assert!(result.is_err());
1295 let error_msg = format!("{}", result.unwrap_err());
1296 assert!(
1297 error_msg
1298 .contains("Cast error: Failed to extract primitive of type Null from variant Int32(32) at path VariantPath([])"),
1299 "Expected=[Cast error: Failed to extract primitive of type Null from variant Int32(32) at path VariantPath([])],\
1300 Got error message=[{}]",
1301 error_msg
1302 );
1303 }
1304
1305 perfectly_shredded_variant_array_fn!(perfectly_shredded_decimal4_variant_array, || {
1306 Decimal32Array::from(vec![Some(12345), Some(23400), Some(-12342)])
1307 .with_precision_and_scale(5, 2)
1308 .unwrap()
1309 });
1310
1311 perfectly_shredded_to_arrow_primitive_test!(
1312 get_variant_perfectly_shredded_decimal4_as_decimal4,
1313 DataType::Decimal32(5, 2),
1314 perfectly_shredded_decimal4_variant_array,
1315 Decimal32Array::from(vec![Some(12345), Some(23400), Some(-12342)])
1316 .with_precision_and_scale(5, 2)
1317 .unwrap()
1318 );
1319
1320 perfectly_shredded_variant_array_fn!(
1321 perfectly_shredded_decimal8_variant_array_cast2decimal32,
1322 || {
1323 Decimal64Array::from(vec![Some(123456), Some(145678), Some(-123456)])
1324 .with_precision_and_scale(6, 1)
1325 .unwrap()
1326 }
1327 );
1328
1329 perfectly_shredded_to_arrow_primitive_test!(
1333 get_variant_perfectly_shredded_decimal8_through_decimal32_as_decimal8,
1334 DataType::Decimal64(6, 1),
1335 perfectly_shredded_decimal8_variant_array_cast2decimal32,
1336 Decimal64Array::from(vec![Some(123456), Some(145678), Some(-123456)])
1337 .with_precision_and_scale(6, 1)
1338 .unwrap()
1339 );
1340
1341 perfectly_shredded_variant_array_fn!(perfectly_shredded_decimal8_variant_array, || {
1344 Decimal64Array::from(vec![Some(1234567809), Some(1456787000), Some(-1234561203)])
1345 .with_precision_and_scale(10, 1)
1346 .unwrap()
1347 });
1348
1349 perfectly_shredded_to_arrow_primitive_test!(
1350 get_variant_perfectly_shredded_decimal8_as_decimal8,
1351 DataType::Decimal64(10, 1),
1352 perfectly_shredded_decimal8_variant_array,
1353 Decimal64Array::from(vec![Some(1234567809), Some(1456787000), Some(-1234561203)])
1354 .with_precision_and_scale(10, 1)
1355 .unwrap()
1356 );
1357
1358 perfectly_shredded_variant_array_fn!(
1361 perfectly_shredded_decimal16_within_decimal4_variant_array,
1362 || {
1363 Decimal128Array::from(vec![
1364 Some(i128::from(1234589)),
1365 Some(i128::from(2344444)),
1366 Some(i128::from(-1234789)),
1367 ])
1368 .with_precision_and_scale(7, 3)
1369 .unwrap()
1370 }
1371 );
1372
1373 perfectly_shredded_to_arrow_primitive_test!(
1376 get_variant_perfectly_shredded_decimal16_within_decimal4_as_decimal16,
1377 DataType::Decimal128(7, 3),
1378 perfectly_shredded_decimal16_within_decimal4_variant_array,
1379 Decimal128Array::from(vec![
1380 Some(i128::from(1234589)),
1381 Some(i128::from(2344444)),
1382 Some(i128::from(-1234789)),
1383 ])
1384 .with_precision_and_scale(7, 3)
1385 .unwrap()
1386 );
1387
1388 perfectly_shredded_variant_array_fn!(
1389 perfectly_shredded_decimal16_within_decimal8_variant_array,
1390 || {
1391 Decimal128Array::from(vec![Some(1234567809), Some(1456787000), Some(-1234561203)])
1392 .with_precision_and_scale(10, 1)
1393 .unwrap()
1394 }
1395 );
1396
1397 perfectly_shredded_to_arrow_primitive_test!(
1400 get_variant_perfectly_shredded_decimal16_within8_as_decimal16,
1401 DataType::Decimal128(10, 1),
1402 perfectly_shredded_decimal16_within_decimal8_variant_array,
1403 Decimal128Array::from(vec![Some(1234567809), Some(1456787000), Some(-1234561203)])
1404 .with_precision_and_scale(10, 1)
1405 .unwrap()
1406 );
1407
1408 perfectly_shredded_variant_array_fn!(perfectly_shredded_decimal16_variant_array, || {
1409 Decimal128Array::from(vec![
1410 Some(i128::from_str("12345678901234567899").unwrap()),
1411 Some(i128::from_str("23445677483748324300").unwrap()),
1412 Some(i128::from_str("-12345678901234567899").unwrap()),
1413 ])
1414 .with_precision_and_scale(20, 3)
1415 .unwrap()
1416 });
1417
1418 perfectly_shredded_to_arrow_primitive_test!(
1421 get_variant_perfectly_shredded_decimal16_as_decimal16,
1422 DataType::Decimal128(20, 3),
1423 perfectly_shredded_decimal16_variant_array,
1424 Decimal128Array::from(vec![
1425 Some(i128::from_str("12345678901234567899").unwrap()),
1426 Some(i128::from_str("23445677483748324300").unwrap()),
1427 Some(i128::from_str("-12345678901234567899").unwrap())
1428 ])
1429 .with_precision_and_scale(20, 3)
1430 .unwrap()
1431 );
1432
1433 macro_rules! assert_variant_get_as_variant_array_with_default_option {
1434 ($variant_array: expr, $array_expected: expr) => {{
1435 let options = GetOptions::new();
1436 let array = $variant_array;
1437 let result = variant_get(&array, options).unwrap();
1438
1439 let result = VariantArray::try_new(&result).unwrap();
1441
1442 assert_eq!(result.len(), $array_expected.len());
1443
1444 for (idx, item) in $array_expected.into_iter().enumerate() {
1445 match item {
1446 Some(item) => assert_eq!(result.value(idx), item),
1447 None => assert!(result.is_null(idx)),
1448 }
1449 }
1450 }};
1451 }
1452
1453 partially_shredded_variant_array_gen!(
1454 partially_shredded_timestamp_micro_ntz_variant_array,
1455 || {
1456 arrow::array::TimestampMicrosecondArray::from(vec![
1457 Some(-456000),
1458 None,
1459 None,
1460 Some(1758602096000000),
1461 ])
1462 }
1463 );
1464
1465 #[test]
1466 fn get_variant_partial_shredded_timestamp_micro_ntz_as_variant() {
1467 let array = partially_shredded_timestamp_micro_ntz_variant_array();
1468 assert_variant_get_as_variant_array_with_default_option!(
1469 array,
1470 vec![
1471 Some(Variant::from(
1472 DateTime::from_timestamp_micros(-456000i64)
1473 .unwrap()
1474 .naive_utc(),
1475 )),
1476 None,
1477 Some(Variant::from("n/a")),
1478 Some(Variant::from(
1479 DateTime::parse_from_rfc3339("2025-09-23T12:34:56+08:00")
1480 .unwrap()
1481 .naive_utc(),
1482 )),
1483 ]
1484 )
1485 }
1486
1487 partially_shredded_variant_array_gen!(partially_shredded_timestamp_micro_variant_array, || {
1488 arrow::array::TimestampMicrosecondArray::from(vec![
1489 Some(-456000),
1490 None,
1491 None,
1492 Some(1758602096000000),
1493 ])
1494 .with_timezone("+00:00")
1495 });
1496
1497 #[test]
1498 fn get_variant_partial_shredded_timestamp_micro_as_variant() {
1499 let array = partially_shredded_timestamp_micro_variant_array();
1500 assert_variant_get_as_variant_array_with_default_option!(
1501 array,
1502 vec![
1503 Some(Variant::from(
1504 DateTime::from_timestamp_micros(-456000i64)
1505 .unwrap()
1506 .to_utc(),
1507 )),
1508 None,
1509 Some(Variant::from("n/a")),
1510 Some(Variant::from(
1511 DateTime::parse_from_rfc3339("2025-09-23T12:34:56+08:00")
1512 .unwrap()
1513 .to_utc(),
1514 )),
1515 ]
1516 )
1517 }
1518
1519 partially_shredded_variant_array_gen!(
1520 partially_shredded_timestamp_nano_ntz_variant_array,
1521 || {
1522 arrow::array::TimestampNanosecondArray::from(vec![
1523 Some(-4999999561),
1524 None,
1525 None,
1526 Some(1758602096000000000),
1527 ])
1528 }
1529 );
1530
1531 #[test]
1532 fn get_variant_partial_shredded_timestamp_nano_ntz_as_variant() {
1533 let array = partially_shredded_timestamp_nano_ntz_variant_array();
1534
1535 assert_variant_get_as_variant_array_with_default_option!(
1536 array,
1537 vec![
1538 Some(Variant::from(
1539 DateTime::from_timestamp(-5, 439).unwrap().naive_utc()
1540 )),
1541 None,
1542 Some(Variant::from("n/a")),
1543 Some(Variant::from(
1544 DateTime::parse_from_rfc3339("2025-09-23T12:34:56+08:00")
1545 .unwrap()
1546 .naive_utc()
1547 )),
1548 ]
1549 )
1550 }
1551
1552 partially_shredded_variant_array_gen!(partially_shredded_timestamp_nano_variant_array, || {
1553 arrow::array::TimestampNanosecondArray::from(vec![
1554 Some(-4999999561),
1555 None,
1556 None,
1557 Some(1758602096000000000),
1558 ])
1559 .with_timezone("+00:00")
1560 });
1561
1562 #[test]
1563 fn get_variant_partial_shredded_timestamp_nano_as_variant() {
1564 let array = partially_shredded_timestamp_nano_variant_array();
1565
1566 assert_variant_get_as_variant_array_with_default_option!(
1567 array,
1568 vec![
1569 Some(Variant::from(
1570 DateTime::from_timestamp(-5, 439).unwrap().to_utc()
1571 )),
1572 None,
1573 Some(Variant::from("n/a")),
1574 Some(Variant::from(
1575 DateTime::parse_from_rfc3339("2025-09-23T12:34:56+08:00")
1576 .unwrap()
1577 .to_utc()
1578 )),
1579 ]
1580 )
1581 }
1582
1583 perfectly_shredded_variant_array_fn!(perfectly_shredded_binary_variant_array, || {
1584 BinaryArray::from(vec![
1585 Some(b"Apache" as &[u8]),
1586 Some(b"Arrow-rs" as &[u8]),
1587 Some(b"Parquet-variant" as &[u8]),
1588 ])
1589 });
1590
1591 perfectly_shredded_to_arrow_primitive_test!(
1592 get_variant_perfectly_shredded_binary_as_binary,
1593 DataType::Binary,
1594 perfectly_shredded_binary_variant_array,
1595 BinaryArray::from(vec![
1596 Some(b"Apache" as &[u8]),
1597 Some(b"Arrow-rs" as &[u8]),
1598 Some(b"Parquet-variant" as &[u8]),
1599 ])
1600 );
1601
1602 perfectly_shredded_variant_array_fn!(perfectly_shredded_large_binary_variant_array, || {
1603 LargeBinaryArray::from(vec![
1604 Some(b"Apache" as &[u8]),
1605 Some(b"Arrow-rs" as &[u8]),
1606 Some(b"Parquet-variant" as &[u8]),
1607 ])
1608 });
1609
1610 perfectly_shredded_to_arrow_primitive_test!(
1611 get_variant_perfectly_shredded_large_binary_as_large_binary,
1612 DataType::LargeBinary,
1613 perfectly_shredded_large_binary_variant_array,
1614 LargeBinaryArray::from(vec![
1615 Some(b"Apache" as &[u8]),
1616 Some(b"Arrow-rs" as &[u8]),
1617 Some(b"Parquet-variant" as &[u8]),
1618 ])
1619 );
1620
1621 perfectly_shredded_variant_array_fn!(perfectly_shredded_binary_view_variant_array, || {
1622 BinaryViewArray::from(vec![
1623 Some(b"Apache" as &[u8]),
1624 Some(b"Arrow-rs" as &[u8]),
1625 Some(b"Parquet-variant" as &[u8]),
1626 ])
1627 });
1628
1629 perfectly_shredded_to_arrow_primitive_test!(
1630 get_variant_perfectly_shredded_binary_view_as_binary_view,
1631 DataType::BinaryView,
1632 perfectly_shredded_binary_view_variant_array,
1633 BinaryViewArray::from(vec![
1634 Some(b"Apache" as &[u8]),
1635 Some(b"Arrow-rs" as &[u8]),
1636 Some(b"Parquet-variant" as &[u8]),
1637 ])
1638 );
1639
1640 macro_rules! numeric_partially_shredded_variant_array_fn {
1664 ($func:ident, $array_type:ident, $primitive_type:ty) => {
1665 partially_shredded_variant_array_gen!($func, || $array_type::from(vec![
1666 Some(<$primitive_type>::try_from(34u8).unwrap()), None, None, Some(<$primitive_type>::try_from(100u8).unwrap()), ]));
1671 };
1672 }
1673
1674 macro_rules! partially_shredded_variant_array_gen {
1675 ($func:ident, $typed_array_gen: expr) => {
1676 fn $func() -> ArrayRef {
1677 let (metadata, string_value) = {
1680 let mut builder = parquet_variant::VariantBuilder::new();
1681 builder.append_value("n/a");
1682 builder.finish()
1683 };
1684
1685 let nulls = NullBuffer::from(vec![
1686 true, false, true, true, ]);
1691
1692 let metadata = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 4));
1694
1695 let values = BinaryViewArray::from(vec![
1698 None, Some(b"" as &[u8]), Some(&string_value), None, ]);
1703
1704 let typed_value = $typed_array_gen();
1705
1706 let struct_array = StructArrayBuilder::new()
1707 .with_field("metadata", Arc::new(metadata), false)
1708 .with_field("typed_value", Arc::new(typed_value), true)
1709 .with_field("value", Arc::new(values), true)
1710 .with_nulls(nulls)
1711 .build();
1712
1713 ArrayRef::from(
1714 VariantArray::try_new(&struct_array).expect("should create variant array"),
1715 )
1716 }
1717 };
1718 }
1719
1720 numeric_partially_shredded_variant_array_fn!(
1721 partially_shredded_int8_variant_array,
1722 Int8Array,
1723 i8
1724 );
1725 numeric_partially_shredded_variant_array_fn!(
1726 partially_shredded_int16_variant_array,
1727 Int16Array,
1728 i16
1729 );
1730 numeric_partially_shredded_variant_array_fn!(
1731 partially_shredded_int32_variant_array,
1732 Int32Array,
1733 i32
1734 );
1735 numeric_partially_shredded_variant_array_fn!(
1736 partially_shredded_int64_variant_array,
1737 Int64Array,
1738 i64
1739 );
1740 numeric_partially_shredded_variant_array_fn!(
1741 partially_shredded_float32_variant_array,
1742 Float32Array,
1743 f32
1744 );
1745 numeric_partially_shredded_variant_array_fn!(
1746 partially_shredded_float64_variant_array,
1747 Float64Array,
1748 f64
1749 );
1750
1751 partially_shredded_variant_array_gen!(partially_shredded_bool_variant_array, || {
1752 arrow::array::BooleanArray::from(vec![
1753 Some(true), None, None, Some(false), ])
1758 });
1759
1760 partially_shredded_variant_array_gen!(partially_shredded_utf8_variant_array, || {
1761 StringArray::from(vec![
1762 Some("hello"), None, None, Some("world"), ])
1767 });
1768
1769 partially_shredded_variant_array_gen!(partially_shredded_date32_variant_array, || {
1770 Date32Array::from(vec![
1771 Some(20348), None, None, Some(20340), ])
1776 });
1777
1778 fn all_null_variant_array() -> ArrayRef {
1795 let nulls = NullBuffer::from(vec![
1796 false, false, false, ]);
1800
1801 let metadata =
1803 BinaryViewArray::from_iter_values(std::iter::repeat_n(EMPTY_VARIANT_METADATA_BYTES, 3));
1804
1805 let struct_array = StructArrayBuilder::new()
1806 .with_field("metadata", Arc::new(metadata), false)
1807 .with_nulls(nulls)
1808 .build();
1809
1810 Arc::new(struct_array)
1811 }
1812 #[test]
1816 fn test_shredded_object_field_access() {
1817 let array = shredded_object_with_x_field_variant_array();
1818
1819 let options = GetOptions::new_with_path(VariantPath::from("x"));
1821 let result = variant_get(&array, options).unwrap();
1822
1823 let result_variant = VariantArray::try_new(&result).unwrap();
1824 assert_eq!(result_variant.len(), 2);
1825
1826 assert_eq!(result_variant.value(0), Variant::Int32(1));
1828 assert_eq!(result_variant.value(1), Variant::Int32(42));
1830 }
1831
1832 #[test]
1834 fn test_shredded_object_field_as_int32() {
1835 let array = shredded_object_with_x_field_variant_array();
1836
1837 let field = Field::new("x", DataType::Int32, false);
1839 let options = GetOptions::new_with_path(VariantPath::from("x"))
1840 .with_as_type(Some(FieldRef::from(field)));
1841 let result = variant_get(&array, options).unwrap();
1842
1843 let expected: ArrayRef = Arc::new(Int32Array::from(vec![Some(1), Some(42)]));
1845 assert_eq!(&result, &expected);
1846 }
1847
1848 fn shredded_object_with_x_field_variant_array() -> ArrayRef {
1860 let (metadata, y_field_value) = {
1862 let mut builder = parquet_variant::VariantBuilder::new();
1863 let mut obj = builder.new_object();
1864 obj.insert("x", Variant::Int32(42));
1865 obj.insert("y", Variant::from("foo"));
1866 obj.finish();
1867 builder.finish()
1868 };
1869
1870 let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 2));
1872
1873 let empty_object_value = {
1878 let mut builder = parquet_variant::VariantBuilder::new();
1879 let obj = builder.new_object();
1880 obj.finish();
1881 let (_, value) = builder.finish();
1882 value
1883 };
1884
1885 let value_array = BinaryViewArray::from(vec![
1886 Some(y_field_value.as_slice()), Some(empty_object_value.as_slice()), ]);
1889
1890 let x_field_typed_value = Int32Array::from(vec![Some(1), Some(42)]);
1893
1894 let x_field_struct = StructArrayBuilder::new()
1896 .with_field("typed_value", Arc::new(x_field_typed_value), true)
1897 .build();
1898
1899 let x_field_shredded = ShreddedVariantFieldArray::try_new(&x_field_struct)
1901 .expect("should create ShreddedVariantFieldArray");
1902
1903 let typed_value_fields = Fields::from(vec![Field::new(
1905 "x",
1906 x_field_shredded.data_type().clone(),
1907 true,
1908 )]);
1909 let typed_value_struct = StructArray::try_new(
1910 typed_value_fields,
1911 vec![ArrayRef::from(x_field_shredded)],
1912 None, )
1914 .unwrap();
1915
1916 let main_struct = StructArrayBuilder::new()
1918 .with_field("metadata", Arc::new(metadata_array), false)
1919 .with_field("value", Arc::new(value_array), true)
1920 .with_field("typed_value", Arc::new(typed_value_struct), true)
1921 .build();
1922
1923 Arc::new(main_struct)
1924 }
1925
1926 #[test]
1928 fn test_simple_nested_path_support() {
1929 println!("Testing path parsing:");
1931
1932 let path_x = VariantPath::from("x");
1933 let elements_x: Vec<_> = path_x.iter().collect();
1934 println!(" 'x' -> {} elements: {:?}", elements_x.len(), elements_x);
1935
1936 let path_ax = VariantPath::from("a.x");
1937 let elements_ax: Vec<_> = path_ax.iter().collect();
1938 println!(
1939 " 'a.x' -> {} elements: {:?}",
1940 elements_ax.len(),
1941 elements_ax
1942 );
1943
1944 let path_ax_alt = VariantPath::from("$.a.x");
1945 let elements_ax_alt: Vec<_> = path_ax_alt.iter().collect();
1946 println!(
1947 " '$.a.x' -> {} elements: {:?}",
1948 elements_ax_alt.len(),
1949 elements_ax_alt
1950 );
1951
1952 let path_nested = VariantPath::from("a").join("x");
1953 let elements_nested: Vec<_> = path_nested.iter().collect();
1954 println!(
1955 " VariantPath::from('a').join('x') -> {} elements: {:?}",
1956 elements_nested.len(),
1957 elements_nested
1958 );
1959
1960 let array = shredded_object_with_x_field_variant_array();
1962
1963 let real_nested_path = VariantPath::from("a").join("x");
1965 let options = GetOptions::new_with_path(real_nested_path);
1966 let result = variant_get(&array, options);
1967
1968 match result {
1969 Ok(_) => {
1970 println!("Nested path 'a.x' works unexpectedly!");
1971 }
1972 Err(e) => {
1973 println!("Nested path 'a.x' error: {}", e);
1974 if e.to_string().contains("Not yet implemented")
1975 || e.to_string().contains("NotYetImplemented")
1976 {
1977 println!("This is expected - nested paths are not implemented");
1978 return;
1979 }
1980 println!("This shows nested paths need implementation");
1982 }
1983 }
1984 }
1985
1986 #[test]
1990 fn test_depth_0_int32_conversion() {
1991 println!("=== Testing Depth 0: Direct field access ===");
1992
1993 let unshredded_array = create_depth_0_test_data();
1995
1996 let field = Field::new("result", DataType::Int32, true);
1997 let path = VariantPath::from("x");
1998 let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
1999 let result = variant_get(&unshredded_array, options).unwrap();
2000
2001 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
2002 Some(42), None, None, ]));
2006 assert_eq!(&result, &expected);
2007 println!("Depth 0 (unshredded) passed");
2008
2009 let shredded_array = create_depth_0_shredded_test_data_simple();
2011
2012 let field = Field::new("result", DataType::Int32, true);
2013 let path = VariantPath::from("x");
2014 let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
2015 let result = variant_get(&shredded_array, options).unwrap();
2016
2017 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
2018 Some(42), None, ]));
2021 assert_eq!(&result, &expected);
2022 println!("Depth 0 (shredded) passed");
2023 }
2024
2025 #[test]
2028 fn test_depth_1_int32_conversion() {
2029 println!("=== Testing Depth 1: Single nested field access ===");
2030
2031 let unshredded_array = create_nested_path_test_data();
2033
2034 let field = Field::new("result", DataType::Int32, true);
2035 let path = VariantPath::from("a.x"); let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
2037 let result = variant_get(&unshredded_array, options).unwrap();
2038
2039 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
2040 Some(55), None, ]));
2043 assert_eq!(&result, &expected);
2044 println!("Depth 1 (unshredded) passed");
2045
2046 let shredded_array = create_depth_1_shredded_test_data_working();
2048
2049 let field = Field::new("result", DataType::Int32, true);
2050 let path = VariantPath::from("a.x"); let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
2052 let result = variant_get(&shredded_array, options).unwrap();
2053
2054 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
2055 Some(55), None, ]));
2058 assert_eq!(&result, &expected);
2059 println!("Depth 1 (shredded) passed");
2060 }
2061
2062 #[test]
2065 fn test_depth_2_int32_conversion() {
2066 println!("=== Testing Depth 2: Double nested field access ===");
2067
2068 let unshredded_array = create_depth_2_test_data();
2070
2071 let field = Field::new("result", DataType::Int32, true);
2072 let path = VariantPath::from("a.b.x"); let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
2074 let result = variant_get(&unshredded_array, options).unwrap();
2075
2076 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
2077 Some(100), None, None, ]));
2081 assert_eq!(&result, &expected);
2082 println!("Depth 2 (unshredded) passed");
2083
2084 let shredded_array = create_depth_2_shredded_test_data_working();
2086
2087 let field = Field::new("result", DataType::Int32, true);
2088 let path = VariantPath::from("a.b.x"); let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
2090 let result = variant_get(&shredded_array, options).unwrap();
2091
2092 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
2093 Some(100), None, None, ]));
2097 assert_eq!(&result, &expected);
2098 println!("Depth 2 (shredded) passed");
2099 }
2100
2101 #[test]
2106 fn test_current_nested_path_functionality() {
2107 let array = shredded_object_with_x_field_variant_array();
2108
2109 let single_path = VariantPath::from("x");
2111 let field = Field::new("result", DataType::Int32, true);
2112 let options =
2113 GetOptions::new_with_path(single_path).with_as_type(Some(FieldRef::from(field)));
2114 let result = variant_get(&array, options).unwrap();
2115
2116 println!("Single path 'x' works - result: {:?}", result);
2117
2118 let nested_path = VariantPath::from("a").join("x");
2120 let field = Field::new("result", DataType::Int32, true);
2121 let options =
2122 GetOptions::new_with_path(nested_path).with_as_type(Some(FieldRef::from(field)));
2123 let result = variant_get(&array, options).unwrap();
2124
2125 println!("Nested path 'a.x' result: {:?}", result);
2126 }
2127
2128 fn create_depth_0_test_data() -> ArrayRef {
2131 let mut builder = crate::VariantArrayBuilder::new(3);
2132
2133 {
2135 let json_str = r#"{"x": 42}"#;
2136 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2137 if let Ok(variant_array) = json_to_variant(&string_array) {
2138 builder.append_variant(variant_array.value(0));
2139 } else {
2140 builder.append_null();
2141 }
2142 }
2143
2144 {
2146 let json_str = r#"{"x": "foo"}"#;
2147 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2148 if let Ok(variant_array) = json_to_variant(&string_array) {
2149 builder.append_variant(variant_array.value(0));
2150 } else {
2151 builder.append_null();
2152 }
2153 }
2154
2155 {
2157 let json_str = r#"{"y": 10}"#;
2158 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2159 if let Ok(variant_array) = json_to_variant(&string_array) {
2160 builder.append_variant(variant_array.value(0));
2161 } else {
2162 builder.append_null();
2163 }
2164 }
2165
2166 ArrayRef::from(builder.build())
2167 }
2168
2169 fn create_nested_path_test_data() -> ArrayRef {
2172 let mut builder = crate::VariantArrayBuilder::new(2);
2173
2174 {
2176 let json_str = r#"{"a": {"x": 55}, "b": 42}"#;
2177 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2178 if let Ok(variant_array) = json_to_variant(&string_array) {
2179 builder.append_variant(variant_array.value(0));
2180 } else {
2181 builder.append_null();
2182 }
2183 }
2184
2185 {
2187 let json_str = r#"{"a": {"x": "foo"}, "b": 42}"#;
2188 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2189 if let Ok(variant_array) = json_to_variant(&string_array) {
2190 builder.append_variant(variant_array.value(0));
2191 } else {
2192 builder.append_null();
2193 }
2194 }
2195
2196 ArrayRef::from(builder.build())
2197 }
2198
2199 fn create_depth_2_test_data() -> ArrayRef {
2202 let mut builder = crate::VariantArrayBuilder::new(3);
2203
2204 {
2206 let json_str = r#"{"a": {"b": {"x": 100}}}"#;
2207 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2208 if let Ok(variant_array) = json_to_variant(&string_array) {
2209 builder.append_variant(variant_array.value(0));
2210 } else {
2211 builder.append_null();
2212 }
2213 }
2214
2215 {
2217 let json_str = r#"{"a": {"b": {"x": "bar"}}}"#;
2218 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2219 if let Ok(variant_array) = json_to_variant(&string_array) {
2220 builder.append_variant(variant_array.value(0));
2221 } else {
2222 builder.append_null();
2223 }
2224 }
2225
2226 {
2228 let json_str = r#"{"a": {"b": {"y": 200}}}"#;
2229 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2230 if let Ok(variant_array) = json_to_variant(&string_array) {
2231 builder.append_variant(variant_array.value(0));
2232 } else {
2233 builder.append_null();
2234 }
2235 }
2236
2237 ArrayRef::from(builder.build())
2238 }
2239
2240 fn create_depth_0_shredded_test_data_simple() -> ArrayRef {
2243 let (metadata, string_x_value) = {
2245 let mut builder = parquet_variant::VariantBuilder::new();
2246 let mut obj = builder.new_object();
2247 obj.insert("x", Variant::from("foo"));
2248 obj.finish();
2249 builder.finish()
2250 };
2251
2252 let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 2));
2254
2255 let empty_object_value = {
2259 let mut builder = parquet_variant::VariantBuilder::new();
2260 let obj = builder.new_object();
2261 obj.finish();
2262 let (_, value) = builder.finish();
2263 value
2264 };
2265
2266 let value_array = BinaryViewArray::from(vec![
2267 Some(empty_object_value.as_slice()), Some(string_x_value.as_slice()), ]);
2270
2271 let x_field_typed_value = Int32Array::from(vec![Some(42), None]);
2273
2274 let x_field_struct = StructArrayBuilder::new()
2276 .with_field("typed_value", Arc::new(x_field_typed_value), true)
2277 .build();
2278
2279 let x_field_shredded = ShreddedVariantFieldArray::try_new(&x_field_struct)
2280 .expect("should create ShreddedVariantFieldArray");
2281
2282 let typed_value_fields = Fields::from(vec![Field::new(
2284 "x",
2285 x_field_shredded.data_type().clone(),
2286 true,
2287 )]);
2288 let typed_value_struct = StructArray::try_new(
2289 typed_value_fields,
2290 vec![ArrayRef::from(x_field_shredded)],
2291 None,
2292 )
2293 .unwrap();
2294
2295 let struct_array = StructArrayBuilder::new()
2297 .with_field("metadata", Arc::new(metadata_array), false)
2298 .with_field("value", Arc::new(value_array), true)
2299 .with_field("typed_value", Arc::new(typed_value_struct), true)
2300 .build();
2301
2302 Arc::new(struct_array)
2303 }
2304
2305 fn create_depth_1_shredded_test_data_working() -> ArrayRef {
2310 let (metadata, _) = {
2312 let mut builder = parquet_variant::VariantBuilder::new();
2314 let mut obj = builder.new_object();
2315
2316 let mut a_obj = obj.new_object("a");
2318 a_obj.insert("x", Variant::Int32(55));
2319 a_obj.finish();
2320
2321 obj.insert("b", Variant::Int32(42));
2322 obj.finish();
2323 builder.finish()
2324 };
2325
2326 let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 2));
2327
2328 let empty_object_value = {
2331 let mut builder = parquet_variant::VariantBuilder::new();
2332 let obj = builder.new_object();
2333 obj.finish();
2334 let (_, value) = builder.finish();
2335 value
2336 };
2337
2338 let row1_fallback = {
2341 let mut builder = parquet_variant::VariantBuilder::new();
2342 let mut obj = builder.new_object();
2343 obj.insert("fallback", Variant::from("data"));
2344 obj.finish();
2345 let (_, value) = builder.finish();
2346 value
2347 };
2348
2349 let value_array = BinaryViewArray::from(vec![
2350 Some(empty_object_value.as_slice()), Some(row1_fallback.as_slice()), ]);
2353
2354 let x_typed_value = Int32Array::from(vec![Some(55), None]);
2357 let x_field_struct = StructArrayBuilder::new()
2358 .with_field("typed_value", Arc::new(x_typed_value), true)
2359 .build();
2360 let x_field_shredded = ShreddedVariantFieldArray::try_new(&x_field_struct)
2361 .expect("should create ShreddedVariantFieldArray for x");
2362
2363 let a_value_data = {
2368 let mut builder = parquet_variant::VariantBuilder::new();
2369 let obj = builder.new_object();
2370 obj.finish();
2371 let (_, value) = builder.finish();
2372 value
2373 };
2374 let a_value_array = BinaryViewArray::from(vec![
2375 None, Some(a_value_data.as_slice()), ]);
2378
2379 let a_inner_fields = Fields::from(vec![Field::new(
2380 "x",
2381 x_field_shredded.data_type().clone(),
2382 true,
2383 )]);
2384 let a_inner_struct = StructArrayBuilder::new()
2385 .with_field(
2386 "typed_value",
2387 Arc::new(
2388 StructArray::try_new(
2389 a_inner_fields,
2390 vec![ArrayRef::from(x_field_shredded)],
2391 None,
2392 )
2393 .unwrap(),
2394 ),
2395 true,
2396 )
2397 .with_field("value", Arc::new(a_value_array), true)
2398 .build();
2399 let a_field_shredded = ShreddedVariantFieldArray::try_new(&a_inner_struct)
2400 .expect("should create ShreddedVariantFieldArray for a");
2401
2402 let typed_value_fields = Fields::from(vec![Field::new(
2404 "a",
2405 a_field_shredded.data_type().clone(),
2406 true,
2407 )]);
2408 let typed_value_struct = StructArray::try_new(
2409 typed_value_fields,
2410 vec![ArrayRef::from(a_field_shredded)],
2411 None,
2412 )
2413 .unwrap();
2414
2415 let struct_array = StructArrayBuilder::new()
2417 .with_field("metadata", Arc::new(metadata_array), false)
2418 .with_field("value", Arc::new(value_array), true)
2419 .with_field("typed_value", Arc::new(typed_value_struct), true)
2420 .build();
2421
2422 Arc::new(struct_array)
2423 }
2424
2425 fn create_depth_2_shredded_test_data_working() -> ArrayRef {
2431 let (metadata, _) = {
2433 let mut builder = parquet_variant::VariantBuilder::new();
2435 let mut obj = builder.new_object();
2436
2437 let mut a_obj = obj.new_object("a");
2439 let mut b_obj = a_obj.new_object("b");
2440 b_obj.insert("x", Variant::Int32(100));
2441 b_obj.finish();
2442 a_obj.finish();
2443
2444 obj.finish();
2445 builder.finish()
2446 };
2447
2448 let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 3));
2449
2450 let empty_object_value = {
2452 let mut builder = parquet_variant::VariantBuilder::new();
2453 let obj = builder.new_object();
2454 obj.finish();
2455 let (_, value) = builder.finish();
2456 value
2457 };
2458
2459 let value_array = BinaryViewArray::from(vec![
2461 Some(empty_object_value.as_slice()), Some(empty_object_value.as_slice()), Some(empty_object_value.as_slice()), ]);
2465
2466 let x_typed_value = Int32Array::from(vec![Some(100), None, None]);
2470 let x_field_struct = StructArrayBuilder::new()
2471 .with_field("typed_value", Arc::new(x_typed_value), true)
2472 .build();
2473 let x_field_shredded = ShreddedVariantFieldArray::try_new(&x_field_struct)
2474 .expect("should create ShreddedVariantFieldArray for x");
2475
2476 let b_value_data = {
2478 let mut builder = parquet_variant::VariantBuilder::new();
2479 let obj = builder.new_object();
2480 obj.finish();
2481 let (_, value) = builder.finish();
2482 value
2483 };
2484 let b_value_array = BinaryViewArray::from(vec![
2485 None, Some(b_value_data.as_slice()), Some(b_value_data.as_slice()), ]);
2489
2490 let b_inner_fields = Fields::from(vec![Field::new(
2491 "x",
2492 x_field_shredded.data_type().clone(),
2493 true,
2494 )]);
2495 let b_inner_struct = StructArrayBuilder::new()
2496 .with_field(
2497 "typed_value",
2498 Arc::new(
2499 StructArray::try_new(
2500 b_inner_fields,
2501 vec![ArrayRef::from(x_field_shredded)],
2502 None,
2503 )
2504 .unwrap(),
2505 ),
2506 true,
2507 )
2508 .with_field("value", Arc::new(b_value_array), true)
2509 .build();
2510 let b_field_shredded = ShreddedVariantFieldArray::try_new(&b_inner_struct)
2511 .expect("should create ShreddedVariantFieldArray for b");
2512
2513 let a_value_data = {
2515 let mut builder = parquet_variant::VariantBuilder::new();
2516 let obj = builder.new_object();
2517 obj.finish();
2518 let (_, value) = builder.finish();
2519 value
2520 };
2521 let a_value_array = BinaryViewArray::from(vec![
2522 None, Some(a_value_data.as_slice()), Some(a_value_data.as_slice()), ]);
2526
2527 let a_inner_fields = Fields::from(vec![Field::new(
2528 "b",
2529 b_field_shredded.data_type().clone(),
2530 true,
2531 )]);
2532 let a_inner_struct = StructArrayBuilder::new()
2533 .with_field(
2534 "typed_value",
2535 Arc::new(
2536 StructArray::try_new(
2537 a_inner_fields,
2538 vec![ArrayRef::from(b_field_shredded)],
2539 None,
2540 )
2541 .unwrap(),
2542 ),
2543 true,
2544 )
2545 .with_field("value", Arc::new(a_value_array), true)
2546 .build();
2547 let a_field_shredded = ShreddedVariantFieldArray::try_new(&a_inner_struct)
2548 .expect("should create ShreddedVariantFieldArray for a");
2549
2550 let typed_value_fields = Fields::from(vec![Field::new(
2552 "a",
2553 a_field_shredded.data_type().clone(),
2554 true,
2555 )]);
2556 let typed_value_struct = StructArray::try_new(
2557 typed_value_fields,
2558 vec![ArrayRef::from(a_field_shredded)],
2559 None,
2560 )
2561 .unwrap();
2562
2563 let struct_array = StructArrayBuilder::new()
2565 .with_field("metadata", Arc::new(metadata_array), false)
2566 .with_field("value", Arc::new(value_array), true)
2567 .with_field("typed_value", Arc::new(typed_value_struct), true)
2568 .build();
2569
2570 Arc::new(struct_array)
2571 }
2572
2573 #[test]
2574 fn test_strict_cast_options_downcast_failure() {
2575 use arrow::compute::CastOptions;
2576 use arrow::datatypes::{DataType, Field};
2577 use arrow::error::ArrowError;
2578 use parquet_variant::VariantPath;
2579 use std::sync::Arc;
2580
2581 let variant_array = perfectly_shredded_int32_variant_array();
2583
2584 let safe_options = GetOptions {
2586 path: VariantPath::from("nonexistent_field"),
2587 as_type: Some(Arc::new(Field::new("result", DataType::Int32, true))),
2588 cast_options: CastOptions::default(), };
2590
2591 let variant_array_ref: Arc<dyn Array> = variant_array.clone();
2592 let result = variant_get(&variant_array_ref, safe_options);
2593 assert!(result.is_ok());
2595 let result_array = result.unwrap();
2596 assert_eq!(result_array.len(), 3);
2597 assert!(result_array.is_null(0));
2598 assert!(result_array.is_null(1));
2599 assert!(result_array.is_null(2));
2600
2601 let strict_options = GetOptions {
2603 path: VariantPath::from("nonexistent_field"),
2604 as_type: Some(Arc::new(Field::new("result", DataType::Int32, true))),
2605 cast_options: CastOptions {
2606 safe: false,
2607 ..Default::default()
2608 },
2609 };
2610
2611 let result = variant_get(&variant_array_ref, strict_options);
2612 assert!(result.is_err());
2614 let error = result.unwrap_err();
2615 assert!(matches!(error, ArrowError::CastError(_)));
2616 assert!(
2617 error
2618 .to_string()
2619 .contains("Cannot access field 'nonexistent_field' on non-struct type")
2620 );
2621 }
2622
2623 #[test]
2624 fn test_error_message_boolean_type_display() {
2625 let mut builder = VariantArrayBuilder::new(1);
2626 builder.append_variant(Variant::Int32(123));
2627 let variant_array: ArrayRef = ArrayRef::from(builder.build());
2628
2629 let options = GetOptions {
2631 path: VariantPath::default(),
2632 as_type: Some(Arc::new(Field::new("result", DataType::Boolean, true))),
2633 cast_options: CastOptions {
2634 safe: false,
2635 ..Default::default()
2636 },
2637 };
2638
2639 let err = variant_get(&variant_array, options).unwrap_err();
2640 let msg = err.to_string();
2641 assert!(msg.contains("Failed to extract primitive of type Boolean"));
2642 }
2643
2644 #[test]
2645 fn test_error_message_numeric_type_display() {
2646 let mut builder = VariantArrayBuilder::new(1);
2647 builder.append_variant(Variant::BooleanTrue);
2648 let variant_array: ArrayRef = ArrayRef::from(builder.build());
2649
2650 let options = GetOptions {
2652 path: VariantPath::default(),
2653 as_type: Some(Arc::new(Field::new("result", DataType::Float32, true))),
2654 cast_options: CastOptions {
2655 safe: false,
2656 ..Default::default()
2657 },
2658 };
2659
2660 let err = variant_get(&variant_array, options).unwrap_err();
2661 let msg = err.to_string();
2662 assert!(msg.contains("Failed to extract primitive of type Float32"));
2663 }
2664
2665 #[test]
2666 fn test_error_message_temporal_type_display() {
2667 let mut builder = VariantArrayBuilder::new(1);
2668 builder.append_variant(Variant::BooleanFalse);
2669 let variant_array: ArrayRef = ArrayRef::from(builder.build());
2670
2671 let options = GetOptions {
2673 path: VariantPath::default(),
2674 as_type: Some(Arc::new(Field::new(
2675 "result",
2676 DataType::Timestamp(TimeUnit::Nanosecond, None),
2677 true,
2678 ))),
2679 cast_options: CastOptions {
2680 safe: false,
2681 ..Default::default()
2682 },
2683 };
2684
2685 let err = variant_get(&variant_array, options).unwrap_err();
2686 let msg = err.to_string();
2687 assert!(msg.contains("Failed to extract primitive of type Timestamp(ns)"));
2688 }
2689
2690 #[test]
2691 fn test_null_buffer_union_for_shredded_paths() {
2692 use arrow::compute::CastOptions;
2693 use arrow::datatypes::{DataType, Field};
2694 use parquet_variant::VariantPath;
2695 use std::sync::Arc;
2696
2697 let variant_array = create_depth_1_shredded_test_data_working();
2706
2707 let options = GetOptions {
2712 path: VariantPath::from("a.x"),
2713 as_type: Some(Arc::new(Field::new("result", DataType::Int32, true))),
2714 cast_options: CastOptions::default(),
2715 };
2716
2717 let variant_array_ref: Arc<dyn Array> = variant_array.clone();
2718 let result = variant_get(&variant_array_ref, options).unwrap();
2719
2720 assert_eq!(result.len(), variant_array.len());
2722
2723 assert!(!result.is_null(0), "Row 0 should have valid Int32 data");
2727 assert!(
2728 result.is_null(1),
2729 "Row 1 should be null due to type casting failure"
2730 );
2731
2732 let int32_result = result.as_any().downcast_ref::<Int32Array>().unwrap();
2734 assert_eq!(int32_result.value(0), 55); }
2736
2737 #[test]
2738 fn test_struct_null_mask_union_from_children() {
2739 use arrow::compute::CastOptions;
2740 use arrow::datatypes::{DataType, Field, Fields};
2741 use parquet_variant::VariantPath;
2742 use std::sync::Arc;
2743
2744 use arrow::array::StringArray;
2745
2746 let json_strings = vec![
2751 r#"{"a": 42, "b": "hello"}"#, r#"{"a": "world", "b": 100}"#, r#"{"a": 55, "b": 77}"#, ];
2755
2756 let string_array: Arc<dyn arrow::array::Array> = Arc::new(StringArray::from(json_strings));
2757 let variant_array = json_to_variant(&string_array).unwrap();
2758
2759 let struct_fields = Fields::from(vec![
2762 Field::new("a", DataType::Int32, true),
2763 Field::new("b", DataType::Int32, true),
2764 ]);
2765 let struct_type = DataType::Struct(struct_fields);
2766
2767 let options = GetOptions {
2768 path: VariantPath::default(), as_type: Some(Arc::new(Field::new("result", struct_type, true))),
2770 cast_options: CastOptions::default(),
2771 };
2772
2773 let variant_array_ref = ArrayRef::from(variant_array);
2774 let result = variant_get(&variant_array_ref, options).unwrap();
2775
2776 let struct_result = result.as_struct();
2778 assert_eq!(struct_result.len(), 3);
2779
2780 let field_a = struct_result
2782 .column(0)
2783 .as_any()
2784 .downcast_ref::<Int32Array>()
2785 .unwrap();
2786 let field_b = struct_result
2787 .column(1)
2788 .as_any()
2789 .downcast_ref::<Int32Array>()
2790 .unwrap();
2791
2792 assert!(!field_a.is_null(0));
2795 assert_eq!(field_a.value(0), 42);
2796 assert!(field_b.is_null(0)); assert!(field_a.is_null(1)); assert!(!field_b.is_null(1));
2801 assert_eq!(field_b.value(1), 100);
2802
2803 assert!(!field_a.is_null(2));
2805 assert_eq!(field_a.value(2), 55);
2806 assert!(!field_b.is_null(2));
2807 assert_eq!(field_b.value(2), 77);
2808
2809 assert!(!struct_result.is_null(0)); assert!(!struct_result.is_null(1)); assert!(!struct_result.is_null(2)); }
2816
2817 #[test]
2818 fn test_field_nullability_preservation() {
2819 use arrow::compute::CastOptions;
2820 use arrow::datatypes::{DataType, Field};
2821 use parquet_variant::VariantPath;
2822 use std::sync::Arc;
2823
2824 use arrow::array::StringArray;
2825
2826 let json_strings = vec![
2829 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}"#, ];
2839
2840 let string_array: Arc<dyn arrow::array::Array> = Arc::new(StringArray::from(json_strings));
2841 let variant_array = json_to_variant(&string_array).unwrap();
2842
2843 let nullable_field = Arc::new(Field::new("result", DataType::Int32, true));
2845 let options_nullable = GetOptions {
2846 path: VariantPath::from("x"),
2847 as_type: Some(nullable_field.clone()),
2848 cast_options: CastOptions::default(),
2849 };
2850
2851 let variant_array_ref = ArrayRef::from(variant_array);
2852 let result_nullable = variant_get(&variant_array_ref, options_nullable).unwrap();
2853
2854 let int32_result = result_nullable
2856 .as_any()
2857 .downcast_ref::<Int32Array>()
2858 .unwrap();
2859 assert_eq!(int32_result.len(), 9);
2860
2861 assert!(!int32_result.is_null(0));
2863 assert_eq!(int32_result.value(0), 42);
2864
2865 assert!(int32_result.is_null(1));
2867
2868 assert!(int32_result.is_null(2));
2870
2871 assert!(int32_result.is_null(3));
2873
2874 assert!(int32_result.is_null(4));
2876
2877 assert!(!int32_result.is_null(5));
2880 assert_eq!(int32_result.value(5), 127);
2881
2882 assert!(!int32_result.is_null(6));
2885 assert_eq!(int32_result.value(6), 32767);
2886
2887 assert!(!int32_result.is_null(7));
2890 assert_eq!(int32_result.value(7), 2147483647);
2891
2892 assert!(int32_result.is_null(8));
2895
2896 let non_nullable_field = Arc::new(Field::new("result", DataType::Int32, false));
2898 let options_non_nullable = GetOptions {
2899 path: VariantPath::from("x"),
2900 as_type: Some(non_nullable_field.clone()),
2901 cast_options: CastOptions::default(), };
2903
2904 let variant_array_2 = json_to_variant(&string_array).unwrap();
2906 let variant_array_ref_2 = ArrayRef::from(variant_array_2);
2907 let result_non_nullable = variant_get(&variant_array_ref_2, options_non_nullable).unwrap();
2908 let int32_result_2 = result_non_nullable
2909 .as_any()
2910 .downcast_ref::<Int32Array>()
2911 .unwrap();
2912
2913 assert_eq!(int32_result_2.len(), 9);
2915
2916 assert!(!int32_result_2.is_null(0));
2918 assert_eq!(int32_result_2.value(0), 42);
2919
2920 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);
2930 assert!(!int32_result_2.is_null(6)); assert_eq!(int32_result_2.value(6), 32767);
2932 assert!(!int32_result_2.is_null(7)); assert_eq!(int32_result_2.value(7), 2147483647);
2934
2935 assert!(int32_result_2.is_null(8)); }
2938
2939 #[test]
2940 fn test_struct_extraction_subset_superset_schema_perfectly_shredded() {
2941 let variant_array = create_comprehensive_shredded_variant();
2943
2944 let struct_fields = Fields::from(vec![
2946 Field::new("a", DataType::Int32, true),
2947 Field::new("b", DataType::Int32, true),
2948 Field::new("d", DataType::Int32, true),
2949 ]);
2950 let struct_type = DataType::Struct(struct_fields);
2951
2952 let options = GetOptions {
2953 path: VariantPath::default(),
2954 as_type: Some(Arc::new(Field::new("result", struct_type, true))),
2955 cast_options: CastOptions::default(),
2956 };
2957
2958 let result = variant_get(&variant_array, options).unwrap();
2959
2960 let struct_result = result.as_any().downcast_ref::<StructArray>().unwrap();
2962 assert_eq!(struct_result.len(), 5);
2963 assert_eq!(struct_result.num_columns(), 3);
2964
2965 let field_a = struct_result
2966 .column(0)
2967 .as_any()
2968 .downcast_ref::<Int32Array>()
2969 .unwrap();
2970 let field_b = struct_result
2971 .column(1)
2972 .as_any()
2973 .downcast_ref::<Int32Array>()
2974 .unwrap();
2975 let field_d = struct_result
2976 .column(2)
2977 .as_any()
2978 .downcast_ref::<Int32Array>()
2979 .unwrap();
2980
2981 assert!(!struct_result.is_null(0));
2983 assert_eq!(field_a.value(0), 1);
2984 assert_eq!(field_b.value(0), 2);
2985 assert!(field_d.is_null(0)); assert!(struct_result.is_null(1));
2989
2990 assert!(!struct_result.is_null(2));
2992 assert!(field_a.is_null(2)); assert_eq!(field_b.value(2), 2);
2994 assert!(field_d.is_null(2)); assert!(!struct_result.is_null(3));
2998 assert_eq!(field_a.value(3), 1);
2999 assert!(field_b.is_null(3)); assert!(field_d.is_null(3)); assert!(!struct_result.is_null(4));
3004 assert!(field_a.is_null(4)); assert!(field_b.is_null(4)); assert!(field_d.is_null(4)); }
3008
3009 #[test]
3010 fn test_nested_struct_extraction_perfectly_shredded() {
3011 let variant_array = create_comprehensive_nested_shredded_variant();
3013 println!("variant_array: {variant_array:?}");
3014
3015 let inner_field = Field::new("inner", DataType::Int32, true);
3017 let inner_type = DataType::Struct(Fields::from(vec![inner_field]));
3018 let outer_field = Field::new("outer", inner_type, true);
3019 let result_type = DataType::Struct(Fields::from(vec![outer_field]));
3020
3021 let options = GetOptions {
3022 path: VariantPath::default(),
3023 as_type: Some(Arc::new(Field::new("result", result_type, true))),
3024 cast_options: CastOptions::default(),
3025 };
3026
3027 let result = variant_get(&variant_array, options).unwrap();
3028 println!("result: {result:?}");
3029
3030 let outer_struct = result.as_any().downcast_ref::<StructArray>().unwrap();
3032 assert_eq!(outer_struct.len(), 4);
3033 assert_eq!(outer_struct.num_columns(), 1);
3034
3035 let inner_struct = outer_struct
3037 .column(0)
3038 .as_any()
3039 .downcast_ref::<StructArray>()
3040 .unwrap();
3041 assert_eq!(inner_struct.num_columns(), 1);
3042
3043 let leaf_field = inner_struct
3045 .column(0)
3046 .as_any()
3047 .downcast_ref::<Int32Array>()
3048 .unwrap();
3049
3050 assert!(!outer_struct.is_null(0));
3052 assert!(!inner_struct.is_null(0));
3053 assert_eq!(leaf_field.value(0), 42);
3054
3055 assert!(!outer_struct.is_null(1));
3057 assert!(!inner_struct.is_null(1)); assert!(leaf_field.is_null(1)); assert!(!outer_struct.is_null(2));
3062 assert!(inner_struct.is_null(2)); assert!(outer_struct.is_null(3));
3066 }
3067
3068 #[test]
3069 fn test_path_based_null_masks_one_step() {
3070 let variant_array = create_comprehensive_nested_shredded_variant();
3072
3073 let path = VariantPath::from("outer");
3075 let inner_field = Field::new("inner", DataType::Int32, true);
3076 let result_type = DataType::Struct(Fields::from(vec![inner_field]));
3077
3078 let options = GetOptions {
3079 path,
3080 as_type: Some(Arc::new(Field::new("result", result_type, true))),
3081 cast_options: CastOptions::default(),
3082 };
3083
3084 let result = variant_get(&variant_array, options).unwrap();
3085
3086 let outer_result = result.as_any().downcast_ref::<StructArray>().unwrap();
3088 assert_eq!(outer_result.len(), 4);
3089 assert_eq!(outer_result.num_columns(), 1);
3090
3091 let inner_field = outer_result
3093 .column(0)
3094 .as_any()
3095 .downcast_ref::<Int32Array>()
3096 .unwrap();
3097
3098 assert!(!outer_result.is_null(0));
3100 assert_eq!(inner_field.value(0), 42);
3101
3102 assert!(!outer_result.is_null(1));
3104 assert!(inner_field.is_null(1));
3105
3106 assert!(outer_result.is_null(2));
3108
3109 assert!(outer_result.is_null(3));
3111 }
3112
3113 #[test]
3114 fn test_path_based_null_masks_two_steps() {
3115 let variant_array = create_comprehensive_nested_shredded_variant();
3117
3118 let path = VariantPath::from("outer").join("inner");
3120
3121 let options = GetOptions {
3122 path,
3123 as_type: Some(Arc::new(Field::new("result", DataType::Int32, true))),
3124 cast_options: CastOptions::default(),
3125 };
3126
3127 let result = variant_get(&variant_array, options).unwrap();
3128
3129 let int_result = result.as_any().downcast_ref::<Int32Array>().unwrap();
3131 assert_eq!(int_result.len(), 4);
3132
3133 assert!(!int_result.is_null(0));
3135 assert_eq!(int_result.value(0), 42);
3136
3137 assert!(int_result.is_null(1));
3139
3140 assert!(int_result.is_null(2));
3142
3143 assert!(int_result.is_null(3));
3145 }
3146
3147 #[test]
3148 fn test_struct_extraction_mixed_and_unshredded() {
3149 let variant_array = create_mixed_and_unshredded_variant();
3151
3152 let struct_fields = Fields::from(vec![
3154 Field::new("x", DataType::Int32, true),
3155 Field::new("y", DataType::Int32, true),
3156 ]);
3157 let struct_type = DataType::Struct(struct_fields);
3158
3159 let options = GetOptions {
3160 path: VariantPath::default(),
3161 as_type: Some(Arc::new(Field::new("result", struct_type, true))),
3162 cast_options: CastOptions::default(),
3163 };
3164
3165 let result = variant_get(&variant_array, options).unwrap();
3166
3167 let struct_result = result.as_any().downcast_ref::<StructArray>().unwrap();
3169 assert_eq!(struct_result.len(), 4);
3170 assert_eq!(struct_result.num_columns(), 2);
3171
3172 let field_x = struct_result
3173 .column(0)
3174 .as_any()
3175 .downcast_ref::<Int32Array>()
3176 .unwrap();
3177 let field_y = struct_result
3178 .column(1)
3179 .as_any()
3180 .downcast_ref::<Int32Array>()
3181 .unwrap();
3182
3183 assert_eq!(field_x.value(0), 1);
3185 assert_eq!(field_y.value(0), 42);
3186
3187 assert_eq!(field_x.value(1), 2);
3189 assert!(field_y.is_null(1));
3190
3191 assert_eq!(field_x.value(2), 3);
3193 assert!(field_y.is_null(2));
3194
3195 assert!(struct_result.is_null(3));
3197 }
3198
3199 #[test]
3202 fn test_struct_row_builder_gap_demonstration() {
3203 let json_strings = vec![
3205 r#"{"outer": {"inner": 42}}"#,
3206 r#"{"outer": {"inner": 100}}"#,
3207 ];
3208 let string_array: Arc<dyn Array> = Arc::new(StringArray::from(json_strings));
3209 let variant_array = json_to_variant(&string_array).unwrap();
3210
3211 let inner_fields = Fields::from(vec![Field::new("inner", DataType::Int32, true)]);
3213 let inner_struct_type = DataType::Struct(inner_fields);
3214 let outer_fields = Fields::from(vec![Field::new("outer", inner_struct_type, true)]);
3215 let outer_struct_type = DataType::Struct(outer_fields);
3216
3217 let options = GetOptions {
3218 path: VariantPath::default(),
3219 as_type: Some(Arc::new(Field::new("result", outer_struct_type, true))),
3220 cast_options: CastOptions::default(),
3221 };
3222
3223 let variant_array_ref = ArrayRef::from(variant_array);
3224 let result = variant_get(&variant_array_ref, options);
3225
3226 assert!(result.is_err());
3228 let error = result.unwrap_err();
3229 assert!(error.to_string().contains("Not yet implemented"));
3230 }
3231
3232 fn create_comprehensive_shredded_variant() -> ArrayRef {
3235 let (metadata, _) = {
3236 let mut builder = parquet_variant::VariantBuilder::new();
3237 let obj = builder.new_object();
3238 obj.finish();
3239 builder.finish()
3240 };
3241
3242 let nulls = NullBuffer::from(vec![
3244 true, false, true, true, true, ]);
3250
3251 let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 5));
3252
3253 let a_field_typed_value = Int32Array::from(vec![Some(1), None, None, Some(1), None]);
3256 let a_field_struct = StructArrayBuilder::new()
3257 .with_field("typed_value", Arc::new(a_field_typed_value), true)
3258 .build();
3259 let a_field_shredded = ShreddedVariantFieldArray::try_new(&a_field_struct)
3260 .expect("should create ShreddedVariantFieldArray for a");
3261
3262 let b_field_typed_value = Int32Array::from(vec![Some(2), None, Some(2), None, None]);
3264 let b_field_struct = StructArrayBuilder::new()
3265 .with_field("typed_value", Arc::new(b_field_typed_value), true)
3266 .build();
3267 let b_field_shredded = ShreddedVariantFieldArray::try_new(&b_field_struct)
3268 .expect("should create ShreddedVariantFieldArray for b");
3269
3270 let c_field_typed_value = Int32Array::from(vec![Some(3), None, None, None, None]);
3272 let c_field_struct = StructArrayBuilder::new()
3273 .with_field("typed_value", Arc::new(c_field_typed_value), true)
3274 .build();
3275 let c_field_shredded = ShreddedVariantFieldArray::try_new(&c_field_struct)
3276 .expect("should create ShreddedVariantFieldArray for c");
3277
3278 let typed_value_fields = Fields::from(vec![
3280 Field::new("a", a_field_shredded.data_type().clone(), true),
3281 Field::new("b", b_field_shredded.data_type().clone(), true),
3282 Field::new("c", c_field_shredded.data_type().clone(), true),
3283 ]);
3284 let typed_value_struct = StructArray::try_new(
3285 typed_value_fields,
3286 vec![
3287 ArrayRef::from(a_field_shredded),
3288 ArrayRef::from(b_field_shredded),
3289 ArrayRef::from(c_field_shredded),
3290 ],
3291 None,
3292 )
3293 .unwrap();
3294
3295 let struct_array = StructArrayBuilder::new()
3297 .with_field("metadata", Arc::new(metadata_array), false)
3298 .with_field("typed_value", Arc::new(typed_value_struct), true)
3299 .with_nulls(nulls)
3300 .build();
3301
3302 Arc::new(struct_array)
3303 }
3304
3305 fn create_comprehensive_nested_shredded_variant() -> ArrayRef {
3310 let inner_typed_value = Int32Array::from(vec![Some(42), None, None, None]); let inner = StructArrayBuilder::new()
3314 .with_field("typed_value", Arc::new(inner_typed_value), true)
3315 .build();
3316 let inner = ShreddedVariantFieldArray::try_new(&inner).unwrap();
3317
3318 let outer_typed_value_nulls = NullBuffer::from(vec![
3319 true, false, false, false, ]);
3324 let outer_typed_value = StructArrayBuilder::new()
3325 .with_field("inner", ArrayRef::from(inner), false)
3326 .with_nulls(outer_typed_value_nulls)
3327 .build();
3328
3329 let outer = StructArrayBuilder::new()
3330 .with_field("typed_value", Arc::new(outer_typed_value), true)
3331 .build();
3332 let outer = ShreddedVariantFieldArray::try_new(&outer).unwrap();
3333
3334 let typed_value_nulls = NullBuffer::from(vec![
3335 true, true, false, false, ]);
3340 let typed_value = StructArrayBuilder::new()
3341 .with_field("outer", ArrayRef::from(outer), false)
3342 .with_nulls(typed_value_nulls)
3343 .build();
3344
3345 let metadata_array =
3347 BinaryViewArray::from_iter_values(std::iter::repeat_n(EMPTY_VARIANT_METADATA_BYTES, 4));
3348 let nulls = NullBuffer::from(vec![
3349 true, true, true, false, ]);
3354 let struct_array = StructArrayBuilder::new()
3355 .with_field("metadata", Arc::new(metadata_array), false)
3356 .with_field("typed_value", Arc::new(typed_value), true)
3357 .with_nulls(nulls)
3358 .build();
3359
3360 Arc::new(struct_array)
3361 }
3362
3363 fn create_mixed_and_unshredded_variant() -> ArrayRef {
3366 let (metadata, y_field_value) = {
3371 let mut builder = parquet_variant::VariantBuilder::new();
3372 let mut obj = builder.new_object();
3373 obj.insert("y", Variant::from(42));
3374 obj.finish();
3375 builder.finish()
3376 };
3377
3378 let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 4));
3379
3380 let empty_object_value = {
3387 let mut builder = parquet_variant::VariantBuilder::new();
3388 builder.new_object().finish();
3389 let (_, value) = builder.finish();
3390 value
3391 };
3392
3393 let y_null_value = {
3394 let mut builder = parquet_variant::VariantBuilder::new();
3395 builder.new_object().with_field("y", Variant::Null).finish();
3396 let (_, value) = builder.finish();
3397 value
3398 };
3399
3400 let value_array = BinaryViewArray::from(vec![
3401 Some(y_field_value.as_slice()), Some(empty_object_value.as_slice()), Some(y_null_value.as_slice()), Some(empty_object_value.as_slice()), ]);
3406
3407 let x_field_typed_value = Int32Array::from(vec![Some(1), Some(2), Some(3), Some(0)]);
3410 let x_field_struct = StructArrayBuilder::new()
3411 .with_field("typed_value", Arc::new(x_field_typed_value), true)
3412 .build();
3413 let x_field_shredded = ShreddedVariantFieldArray::try_new(&x_field_struct)
3414 .expect("should create ShreddedVariantFieldArray for x");
3415
3416 let typed_value_struct = StructArrayBuilder::new()
3418 .with_field("x", ArrayRef::from(x_field_shredded), false)
3419 .build();
3420
3421 let variant_nulls = NullBuffer::from(vec![true, true, true, false]); let struct_array = StructArrayBuilder::new()
3425 .with_field("metadata", Arc::new(metadata_array), false)
3426 .with_field("value", Arc::new(value_array), true)
3427 .with_field("typed_value", Arc::new(typed_value_struct), true)
3428 .with_nulls(variant_nulls)
3429 .build();
3430
3431 Arc::new(struct_array)
3432 }
3433
3434 #[test]
3435 fn get_decimal32_rescaled_to_scale2() {
3436 let mut builder = crate::VariantArrayBuilder::new(5);
3438 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();
3442 builder.append_variant(
3443 VariantDecimal8::try_new((VariantDecimal4::MAX_UNSCALED_VALUE as i64) + 1, 3)
3444 .unwrap()
3445 .into(),
3446 ); let variant_array: ArrayRef = ArrayRef::from(builder.build());
3448
3449 let field = Field::new("result", DataType::Decimal32(9, 2), true);
3450 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3451 let result = variant_get(&variant_array, options).unwrap();
3452 let result = result.as_any().downcast_ref::<Decimal32Array>().unwrap();
3453
3454 assert_eq!(result.precision(), 9);
3455 assert_eq!(result.scale(), 2);
3456 assert_eq!(result.value(0), 1234);
3457 assert_eq!(result.value(1), 123);
3458 assert_eq!(result.value(2), 123400);
3459 assert!(result.is_null(3));
3460 assert_eq!(
3461 result.value(4),
3462 VariantDecimal4::MAX_UNSCALED_VALUE / 10 + 1
3463 ); }
3465
3466 #[test]
3467 fn get_decimal32_scale_down_rounding() {
3468 let mut builder = crate::VariantArrayBuilder::new(7);
3469 builder.append_variant(VariantDecimal4::try_new(1235, 0).unwrap().into());
3470 builder.append_variant(VariantDecimal4::try_new(1245, 0).unwrap().into());
3471 builder.append_variant(VariantDecimal4::try_new(-1235, 0).unwrap().into());
3472 builder.append_variant(VariantDecimal4::try_new(-1245, 0).unwrap().into());
3473 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());
3477
3478 let field = Field::new("result", DataType::Decimal32(9, -1), true);
3479 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3480 let result = variant_get(&variant_array, options).unwrap();
3481 let result = result.as_any().downcast_ref::<Decimal32Array>().unwrap();
3482
3483 assert_eq!(result.precision(), 9);
3484 assert_eq!(result.scale(), -1);
3485 assert_eq!(result.value(0), 124);
3486 assert_eq!(result.value(1), 125);
3487 assert_eq!(result.value(2), -124);
3488 assert_eq!(result.value(3), -125);
3489 assert_eq!(result.value(4), 1);
3490 assert!(result.is_valid(5));
3491 assert_eq!(result.value(5), 0);
3492 assert_eq!(result.value(6), 1);
3493 }
3494
3495 #[test]
3496 fn get_decimal32_large_scale_reduction() {
3497 let mut builder = crate::VariantArrayBuilder::new(2);
3498 builder.append_variant(
3499 VariantDecimal4::try_new(-VariantDecimal4::MAX_UNSCALED_VALUE, 0)
3500 .unwrap()
3501 .into(),
3502 );
3503 builder.append_variant(
3504 VariantDecimal4::try_new(VariantDecimal4::MAX_UNSCALED_VALUE, 0)
3505 .unwrap()
3506 .into(),
3507 );
3508 let variant_array: ArrayRef = ArrayRef::from(builder.build());
3509
3510 let field = Field::new("result", DataType::Decimal32(9, -9), true);
3511 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3512 let result = variant_get(&variant_array, options).unwrap();
3513 let result = result.as_any().downcast_ref::<Decimal32Array>().unwrap();
3514
3515 assert_eq!(result.precision(), 9);
3516 assert_eq!(result.scale(), -9);
3517 assert_eq!(result.value(0), -1);
3518 assert_eq!(result.value(1), 1);
3519
3520 let field = Field::new("result", DataType::Decimal32(9, -10), true);
3521 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3522 let result = variant_get(&variant_array, options).unwrap();
3523 let result = result.as_any().downcast_ref::<Decimal32Array>().unwrap();
3524
3525 assert_eq!(result.precision(), 9);
3526 assert_eq!(result.scale(), -10);
3527 assert!(result.is_valid(0));
3528 assert_eq!(result.value(0), 0);
3529 assert!(result.is_valid(1));
3530 assert_eq!(result.value(1), 0);
3531 }
3532
3533 #[test]
3534 fn get_decimal32_precision_overflow_safe() {
3535 let mut builder = crate::VariantArrayBuilder::new(2);
3537 builder.append_variant(
3538 VariantDecimal4::try_new(VariantDecimal4::MAX_UNSCALED_VALUE, 0)
3539 .unwrap()
3540 .into(),
3541 );
3542 builder.append_variant(
3543 VariantDecimal4::try_new(VariantDecimal4::MAX_UNSCALED_VALUE, 9)
3544 .unwrap()
3545 .into(),
3546 ); let variant_array: ArrayRef = ArrayRef::from(builder.build());
3548
3549 let field = Field::new("result", DataType::Decimal32(2, 2), true);
3550 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3551 let result = variant_get(&variant_array, options).unwrap();
3552 let result = result.as_any().downcast_ref::<Decimal32Array>().unwrap();
3553
3554 assert!(result.is_null(0));
3555 assert!(result.is_null(1)); }
3557
3558 #[test]
3559 fn get_decimal32_precision_overflow_unsafe_errors() {
3560 let mut builder = crate::VariantArrayBuilder::new(1);
3561 builder.append_variant(
3562 VariantDecimal4::try_new(VariantDecimal4::MAX_UNSCALED_VALUE, 0)
3563 .unwrap()
3564 .into(),
3565 );
3566 let variant_array: ArrayRef = ArrayRef::from(builder.build());
3567
3568 let field = Field::new("result", DataType::Decimal32(9, 2), true);
3569 let cast_options = CastOptions {
3570 safe: false,
3571 ..Default::default()
3572 };
3573 let options = GetOptions::new()
3574 .with_as_type(Some(FieldRef::from(field)))
3575 .with_cast_options(cast_options);
3576 let err = variant_get(&variant_array, options).unwrap_err();
3577
3578 assert!(
3579 err.to_string().contains(
3580 "Failed to cast to Decimal32(precision=9, scale=2) from variant Decimal4"
3581 )
3582 );
3583 }
3584
3585 #[test]
3586 fn get_decimal64_rescaled_to_scale2() {
3587 let mut builder = crate::VariantArrayBuilder::new(5);
3588 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();
3592 builder.append_variant(
3593 VariantDecimal16::try_new((VariantDecimal8::MAX_UNSCALED_VALUE as i128) + 1, 3)
3594 .unwrap()
3595 .into(),
3596 ); let variant_array: ArrayRef = ArrayRef::from(builder.build());
3598
3599 let field = Field::new("result", DataType::Decimal64(18, 2), true);
3600 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3601 let result = variant_get(&variant_array, options).unwrap();
3602 let result = result.as_any().downcast_ref::<Decimal64Array>().unwrap();
3603
3604 assert_eq!(result.precision(), 18);
3605 assert_eq!(result.scale(), 2);
3606 assert_eq!(result.value(0), 1234);
3607 assert_eq!(result.value(1), 123);
3608 assert_eq!(result.value(2), 123400);
3609 assert!(result.is_null(3));
3610 assert_eq!(
3611 result.value(4),
3612 VariantDecimal8::MAX_UNSCALED_VALUE / 10 + 1
3613 ); }
3615
3616 #[test]
3617 fn get_decimal64_scale_down_rounding() {
3618 let mut builder = crate::VariantArrayBuilder::new(7);
3619 builder.append_variant(VariantDecimal8::try_new(1235, 0).unwrap().into());
3620 builder.append_variant(VariantDecimal8::try_new(1245, 0).unwrap().into());
3621 builder.append_variant(VariantDecimal8::try_new(-1235, 0).unwrap().into());
3622 builder.append_variant(VariantDecimal8::try_new(-1245, 0).unwrap().into());
3623 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());
3627
3628 let field = Field::new("result", DataType::Decimal64(18, -1), true);
3629 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3630 let result = variant_get(&variant_array, options).unwrap();
3631 let result = result.as_any().downcast_ref::<Decimal64Array>().unwrap();
3632
3633 assert_eq!(result.precision(), 18);
3634 assert_eq!(result.scale(), -1);
3635 assert_eq!(result.value(0), 124);
3636 assert_eq!(result.value(1), 125);
3637 assert_eq!(result.value(2), -124);
3638 assert_eq!(result.value(3), -125);
3639 assert_eq!(result.value(4), 1);
3640 assert!(result.is_valid(5));
3641 assert_eq!(result.value(5), 0);
3642 assert_eq!(result.value(6), 1);
3643 }
3644
3645 #[test]
3646 fn get_decimal64_large_scale_reduction() {
3647 let mut builder = crate::VariantArrayBuilder::new(2);
3648 builder.append_variant(
3649 VariantDecimal8::try_new(-VariantDecimal8::MAX_UNSCALED_VALUE, 0)
3650 .unwrap()
3651 .into(),
3652 );
3653 builder.append_variant(
3654 VariantDecimal8::try_new(VariantDecimal8::MAX_UNSCALED_VALUE, 0)
3655 .unwrap()
3656 .into(),
3657 );
3658 let variant_array: ArrayRef = ArrayRef::from(builder.build());
3659
3660 let field = Field::new("result", DataType::Decimal64(18, -18), true);
3661 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3662 let result = variant_get(&variant_array, options).unwrap();
3663 let result = result.as_any().downcast_ref::<Decimal64Array>().unwrap();
3664
3665 assert_eq!(result.precision(), 18);
3666 assert_eq!(result.scale(), -18);
3667 assert_eq!(result.value(0), -1);
3668 assert_eq!(result.value(1), 1);
3669
3670 let field = Field::new("result", DataType::Decimal64(18, -19), true);
3671 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3672 let result = variant_get(&variant_array, options).unwrap();
3673 let result = result.as_any().downcast_ref::<Decimal64Array>().unwrap();
3674
3675 assert_eq!(result.precision(), 18);
3676 assert_eq!(result.scale(), -19);
3677 assert!(result.is_valid(0));
3678 assert_eq!(result.value(0), 0);
3679 assert!(result.is_valid(1));
3680 assert_eq!(result.value(1), 0);
3681 }
3682
3683 #[test]
3684 fn get_decimal64_precision_overflow_safe() {
3685 let mut builder = crate::VariantArrayBuilder::new(2);
3687 builder.append_variant(
3688 VariantDecimal8::try_new(VariantDecimal8::MAX_UNSCALED_VALUE, 0)
3689 .unwrap()
3690 .into(),
3691 );
3692 builder.append_variant(
3693 VariantDecimal8::try_new(VariantDecimal8::MAX_UNSCALED_VALUE, 18)
3694 .unwrap()
3695 .into(),
3696 ); let variant_array: ArrayRef = ArrayRef::from(builder.build());
3698
3699 let field = Field::new("result", DataType::Decimal64(2, 2), true);
3700 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3701 let result = variant_get(&variant_array, options).unwrap();
3702 let result = result.as_any().downcast_ref::<Decimal64Array>().unwrap();
3703
3704 assert!(result.is_null(0));
3705 assert!(result.is_null(1));
3706 }
3707
3708 #[test]
3709 fn get_decimal64_precision_overflow_unsafe_errors() {
3710 let mut builder = crate::VariantArrayBuilder::new(1);
3711 builder.append_variant(
3712 VariantDecimal8::try_new(VariantDecimal8::MAX_UNSCALED_VALUE, 0)
3713 .unwrap()
3714 .into(),
3715 );
3716 let variant_array: ArrayRef = ArrayRef::from(builder.build());
3717
3718 let field = Field::new("result", DataType::Decimal64(18, 2), true);
3719 let cast_options = CastOptions {
3720 safe: false,
3721 ..Default::default()
3722 };
3723 let options = GetOptions::new()
3724 .with_as_type(Some(FieldRef::from(field)))
3725 .with_cast_options(cast_options);
3726 let err = variant_get(&variant_array, options).unwrap_err();
3727
3728 assert!(
3729 err.to_string().contains(
3730 "Failed to cast to Decimal64(precision=18, scale=2) from variant Decimal8"
3731 )
3732 );
3733 }
3734
3735 #[test]
3736 fn get_decimal128_rescaled_to_scale2() {
3737 let mut builder = crate::VariantArrayBuilder::new(4);
3738 builder.append_variant(VariantDecimal16::try_new(1234, 2).unwrap().into());
3739 builder.append_variant(VariantDecimal16::try_new(1234, 3).unwrap().into());
3740 builder.append_variant(VariantDecimal16::try_new(1234, 0).unwrap().into());
3741 builder.append_null();
3742 let variant_array: ArrayRef = ArrayRef::from(builder.build());
3743
3744 let field = Field::new("result", DataType::Decimal128(38, 2), true);
3745 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3746 let result = variant_get(&variant_array, options).unwrap();
3747 let result = result.as_any().downcast_ref::<Decimal128Array>().unwrap();
3748
3749 assert_eq!(result.precision(), 38);
3750 assert_eq!(result.scale(), 2);
3751 assert_eq!(result.value(0), 1234);
3752 assert_eq!(result.value(1), 123);
3753 assert_eq!(result.value(2), 123400);
3754 assert!(result.is_null(3));
3755 }
3756
3757 #[test]
3758 fn get_decimal128_scale_down_rounding() {
3759 let mut builder = crate::VariantArrayBuilder::new(7);
3760 builder.append_variant(VariantDecimal16::try_new(1235, 0).unwrap().into());
3761 builder.append_variant(VariantDecimal16::try_new(1245, 0).unwrap().into());
3762 builder.append_variant(VariantDecimal16::try_new(-1235, 0).unwrap().into());
3763 builder.append_variant(VariantDecimal16::try_new(-1245, 0).unwrap().into());
3764 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());
3768
3769 let field = Field::new("result", DataType::Decimal128(38, -1), true);
3770 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3771 let result = variant_get(&variant_array, options).unwrap();
3772 let result = result.as_any().downcast_ref::<Decimal128Array>().unwrap();
3773
3774 assert_eq!(result.precision(), 38);
3775 assert_eq!(result.scale(), -1);
3776 assert_eq!(result.value(0), 124);
3777 assert_eq!(result.value(1), 125);
3778 assert_eq!(result.value(2), -124);
3779 assert_eq!(result.value(3), -125);
3780 assert_eq!(result.value(4), 1);
3781 assert!(result.is_valid(5));
3782 assert_eq!(result.value(5), 0);
3783 assert_eq!(result.value(6), 1);
3784 }
3785
3786 #[test]
3787 fn get_decimal128_precision_overflow_safe() {
3788 let mut builder = crate::VariantArrayBuilder::new(2);
3790 builder.append_variant(
3791 VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 0)
3792 .unwrap()
3793 .into(),
3794 );
3795 builder.append_variant(
3796 VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 38)
3797 .unwrap()
3798 .into(),
3799 ); let variant_array: ArrayRef = ArrayRef::from(builder.build());
3801
3802 let field = Field::new("result", DataType::Decimal128(2, 2), true);
3803 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3804 let result = variant_get(&variant_array, options).unwrap();
3805 let result = result.as_any().downcast_ref::<Decimal128Array>().unwrap();
3806
3807 assert!(result.is_null(0));
3808 assert!(result.is_null(1)); }
3810
3811 #[test]
3812 fn get_decimal128_precision_overflow_unsafe_errors() {
3813 let mut builder = crate::VariantArrayBuilder::new(1);
3814 builder.append_variant(
3815 VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 0)
3816 .unwrap()
3817 .into(),
3818 );
3819 let variant_array: ArrayRef = ArrayRef::from(builder.build());
3820
3821 let field = Field::new("result", DataType::Decimal128(38, 2), true);
3822 let cast_options = CastOptions {
3823 safe: false,
3824 ..Default::default()
3825 };
3826 let options = GetOptions::new()
3827 .with_as_type(Some(FieldRef::from(field)))
3828 .with_cast_options(cast_options);
3829 let err = variant_get(&variant_array, options).unwrap_err();
3830
3831 assert!(err.to_string().contains(
3832 "Failed to cast to Decimal128(precision=38, scale=2) from variant Decimal16"
3833 ));
3834 }
3835
3836 #[test]
3837 fn get_decimal256_rescaled_to_scale2() {
3838 let mut builder = crate::VariantArrayBuilder::new(4);
3840 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();
3844 let variant_array: ArrayRef = ArrayRef::from(builder.build());
3845
3846 let field = Field::new("result", DataType::Decimal256(76, 2), true);
3847 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3848 let result = variant_get(&variant_array, options).unwrap();
3849 let result = result.as_any().downcast_ref::<Decimal256Array>().unwrap();
3850
3851 assert_eq!(result.precision(), 76);
3852 assert_eq!(result.scale(), 2);
3853 assert_eq!(result.value(0), i256::from_i128(1234));
3854 assert_eq!(result.value(1), i256::from_i128(123));
3855 assert_eq!(result.value(2), i256::from_i128(123400));
3856 assert!(result.is_null(3));
3857 }
3858
3859 #[test]
3860 fn get_decimal256_scale_down_rounding() {
3861 let mut builder = crate::VariantArrayBuilder::new(7);
3862 builder.append_variant(VariantDecimal16::try_new(1235, 0).unwrap().into());
3863 builder.append_variant(VariantDecimal16::try_new(1245, 0).unwrap().into());
3864 builder.append_variant(VariantDecimal16::try_new(-1235, 0).unwrap().into());
3865 builder.append_variant(VariantDecimal16::try_new(-1245, 0).unwrap().into());
3866 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());
3870
3871 let field = Field::new("result", DataType::Decimal256(76, -1), true);
3872 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3873 let result = variant_get(&variant_array, options).unwrap();
3874 let result = result.as_any().downcast_ref::<Decimal256Array>().unwrap();
3875
3876 assert_eq!(result.precision(), 76);
3877 assert_eq!(result.scale(), -1);
3878 assert_eq!(result.value(0), i256::from_i128(124));
3879 assert_eq!(result.value(1), i256::from_i128(125));
3880 assert_eq!(result.value(2), i256::from_i128(-124));
3881 assert_eq!(result.value(3), i256::from_i128(-125));
3882 assert_eq!(result.value(4), i256::from_i128(1));
3883 assert!(result.is_valid(5));
3884 assert_eq!(result.value(5), i256::from_i128(0));
3885 assert_eq!(result.value(6), i256::from_i128(1));
3886 }
3887
3888 #[test]
3889 fn get_decimal256_precision_overflow_safe() {
3890 let mut builder = crate::VariantArrayBuilder::new(2);
3892 builder.append_variant(
3893 VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 1)
3894 .unwrap()
3895 .into(),
3896 );
3897 builder.append_variant(
3898 VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 0)
3899 .unwrap()
3900 .into(),
3901 );
3902 let variant_array: ArrayRef = ArrayRef::from(builder.build());
3903
3904 let field = Field::new("result", DataType::Decimal256(76, 39), true);
3905 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3906 let result = variant_get(&variant_array, options).unwrap();
3907 let result = result.as_any().downcast_ref::<Decimal256Array>().unwrap();
3908
3909 let base = i256::from_i128(10);
3912 let factor = base.checked_pow(38).unwrap();
3913 let expected = i256::from_i128(VariantDecimal16::MAX_UNSCALED_VALUE)
3914 .checked_mul(factor)
3915 .unwrap();
3916 assert_eq!(result.value(0), expected);
3917 assert!(result.is_null(1));
3918 }
3919
3920 #[test]
3921 fn get_decimal256_precision_overflow_unsafe_errors() {
3922 let mut builder = crate::VariantArrayBuilder::new(2);
3924 builder.append_variant(
3925 VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 1)
3926 .unwrap()
3927 .into(),
3928 );
3929 builder.append_variant(
3930 VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 0)
3931 .unwrap()
3932 .into(),
3933 );
3934 let variant_array: ArrayRef = ArrayRef::from(builder.build());
3935
3936 let field = Field::new("result", DataType::Decimal256(76, 39), true);
3937 let cast_options = CastOptions {
3938 safe: false,
3939 ..Default::default()
3940 };
3941 let options = GetOptions::new()
3942 .with_as_type(Some(FieldRef::from(field)))
3943 .with_cast_options(cast_options);
3944 let err = variant_get(&variant_array, options).unwrap_err();
3945
3946 assert!(err.to_string().contains(
3947 "Failed to cast to Decimal256(precision=76, scale=39) from variant Decimal16"
3948 ));
3949 }
3950
3951 #[test]
3952 fn get_non_supported_temporal_types_error() {
3953 let values = vec![None, Some(Variant::Null), Some(Variant::BooleanFalse)];
3954 let variant_array: ArrayRef = ArrayRef::from(VariantArray::from_iter(values));
3955
3956 let test_cases = vec![
3957 FieldRef::from(Field::new(
3958 "result",
3959 DataType::Duration(TimeUnit::Microsecond),
3960 true,
3961 )),
3962 FieldRef::from(Field::new(
3963 "result",
3964 DataType::Interval(IntervalUnit::YearMonth),
3965 true,
3966 )),
3967 ];
3968
3969 for field in test_cases {
3970 let options = GetOptions::new().with_as_type(Some(field));
3971 let err = variant_get(&variant_array, options).unwrap_err();
3972 assert!(
3973 err.to_string()
3974 .contains("Casting Variant to duration/interval types is not supported")
3975 );
3976 }
3977 }
3978
3979 fn invalid_time_variant_array() -> ArrayRef {
3980 let mut builder = VariantArrayBuilder::new(3);
3981 builder.append_variant(Variant::Int64(86401000000));
3983 builder.append_variant(Variant::Int64(86401000000));
3984 builder.append_variant(Variant::Int64(86401000000));
3985 Arc::new(builder.build().into_inner())
3986 }
3987
3988 #[test]
3989 fn test_variant_get_error_when_cast_failure_and_safe_false() {
3990 let variant_array = invalid_time_variant_array();
3991
3992 let field = Field::new("result", DataType::Time64(TimeUnit::Microsecond), true);
3993 let cast_options = CastOptions {
3994 safe: false, ..Default::default()
3996 };
3997 let options = GetOptions::new()
3998 .with_as_type(Some(FieldRef::from(field)))
3999 .with_cast_options(cast_options);
4000 let err = variant_get(&variant_array, options).unwrap_err();
4001 assert!(
4002 err.to_string().contains(
4003 "Cast error: Failed to extract primitive of type Time64(µs) from variant Int64(86401000000) at path VariantPath([])"
4004 ),
4005 "actual: {err}",
4006 );
4007 }
4008
4009 #[test]
4010 fn test_variant_get_return_null_when_cast_failure_and_safe_true() {
4011 let variant_array = invalid_time_variant_array();
4012
4013 let field = Field::new("result", DataType::Time64(TimeUnit::Microsecond), true);
4014 let cast_options = CastOptions {
4015 safe: true, ..Default::default()
4017 };
4018 let options = GetOptions::new()
4019 .with_as_type(Some(FieldRef::from(field)))
4020 .with_cast_options(cast_options);
4021 let result = variant_get(&variant_array, options).unwrap();
4022 assert_eq!(3, result.len());
4023
4024 for i in 0..3 {
4025 assert!(result.is_null(i));
4026 }
4027 }
4028
4029 #[test]
4030 fn test_perfect_shredding_returns_same_arc_ptr() {
4031 let variant_array = perfectly_shredded_int32_variant_array();
4032
4033 let variant_array_ref = VariantArray::try_new(&variant_array).unwrap();
4034 let typed_value_arc = variant_array_ref.typed_value_field().unwrap().clone();
4035
4036 let field = Field::new("result", DataType::Int32, true);
4037 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
4038 let result = variant_get(&variant_array, options).unwrap();
4039
4040 assert!(Arc::ptr_eq(&typed_value_arc, &result));
4041 }
4042
4043 #[test]
4044 fn test_perfect_shredding_three_typed_value_columns() {
4045 let all_nulls_values: Arc<Int32Array> = Arc::new(Int32Array::from(vec![
4047 Option::<i32>::None,
4048 Option::<i32>::None,
4049 Option::<i32>::None,
4050 ]));
4051 let all_nulls_erased: ArrayRef = all_nulls_values.clone();
4052 let all_nulls_field =
4053 ShreddedVariantFieldArray::from_parts(None, Some(all_nulls_erased.clone()), None);
4054 let all_nulls_type = all_nulls_field.data_type().clone();
4055 let all_nulls_struct: ArrayRef = ArrayRef::from(all_nulls_field);
4056
4057 let some_nulls_values: Arc<Int32Array> =
4059 Arc::new(Int32Array::from(vec![Some(10), None, Some(30)]));
4060 let some_nulls_erased: ArrayRef = some_nulls_values.clone();
4061 let some_nulls_field =
4062 ShreddedVariantFieldArray::from_parts(None, Some(some_nulls_erased.clone()), None);
4063 let some_nulls_type = some_nulls_field.data_type().clone();
4064 let some_nulls_struct: ArrayRef = ArrayRef::from(some_nulls_field);
4065
4066 let inner_values: Arc<Int32Array> =
4068 Arc::new(Int32Array::from(vec![Some(111), None, Some(333)]));
4069 let inner_erased: ArrayRef = inner_values.clone();
4070 let inner_field =
4071 ShreddedVariantFieldArray::from_parts(None, Some(inner_erased.clone()), None);
4072 let inner_field_type = inner_field.data_type().clone();
4073 let inner_struct_array: ArrayRef = ArrayRef::from(inner_field);
4074
4075 let nested_struct = Arc::new(
4076 StructArray::try_new(
4077 Fields::from(vec![Field::new("inner", inner_field_type, true)]),
4078 vec![inner_struct_array],
4079 None,
4080 )
4081 .unwrap(),
4082 );
4083 let nested_struct_erased: ArrayRef = nested_struct.clone();
4084 let struct_field =
4085 ShreddedVariantFieldArray::from_parts(None, Some(nested_struct_erased.clone()), None);
4086 let struct_field_type = struct_field.data_type().clone();
4087 let struct_field_struct: ArrayRef = ArrayRef::from(struct_field);
4088
4089 let typed_value_struct = StructArray::try_new(
4091 Fields::from(vec![
4092 Field::new("all_nulls", all_nulls_type, true),
4093 Field::new("some_nulls", some_nulls_type, true),
4094 Field::new("struct_field", struct_field_type, true),
4095 ]),
4096 vec![all_nulls_struct, some_nulls_struct, struct_field_struct],
4097 None,
4098 )
4099 .unwrap();
4100
4101 let metadata = BinaryViewArray::from_iter_values(std::iter::repeat_n(
4102 EMPTY_VARIANT_METADATA_BYTES,
4103 all_nulls_values.len(),
4104 ));
4105 let variant_struct = StructArrayBuilder::new()
4106 .with_field("metadata", Arc::new(metadata), false)
4107 .with_field("typed_value", Arc::new(typed_value_struct), true)
4108 .build();
4109 let variant_array: ArrayRef = VariantArray::try_new(&variant_struct).unwrap().into();
4110
4111 let all_nulls_field_ref = FieldRef::from(Field::new("result", DataType::Int32, true));
4113 let all_nulls_result = variant_get(
4114 &variant_array,
4115 GetOptions::new_with_path(VariantPath::from("all_nulls"))
4116 .with_as_type(Some(all_nulls_field_ref)),
4117 )
4118 .unwrap();
4119 assert!(Arc::ptr_eq(&all_nulls_result, &all_nulls_erased));
4120
4121 let some_nulls_field_ref = FieldRef::from(Field::new("result", DataType::Int32, true));
4123 let some_nulls_result = variant_get(
4124 &variant_array,
4125 GetOptions::new_with_path(VariantPath::from("some_nulls"))
4126 .with_as_type(Some(some_nulls_field_ref)),
4127 )
4128 .unwrap();
4129 assert!(Arc::ptr_eq(&some_nulls_result, &some_nulls_erased));
4130
4131 let struct_child_fields = Fields::from(vec![Field::new("inner", DataType::Int32, true)]);
4133 let struct_field_ref = FieldRef::from(Field::new(
4134 "result",
4135 DataType::Struct(struct_child_fields.clone()),
4136 true,
4137 ));
4138 let struct_result = variant_get(
4139 &variant_array,
4140 GetOptions::new_with_path(VariantPath::from("struct_field"))
4141 .with_as_type(Some(struct_field_ref)),
4142 )
4143 .unwrap();
4144 let struct_array = struct_result
4145 .as_any()
4146 .downcast_ref::<StructArray>()
4147 .unwrap();
4148 assert_eq!(struct_array.len(), 3);
4149 assert_eq!(struct_array.null_count(), 0);
4150
4151 let inner_values_result = struct_array
4152 .column(0)
4153 .as_any()
4154 .downcast_ref::<Int32Array>()
4155 .unwrap();
4156 assert_eq!(inner_values_result.len(), 3);
4157 assert_eq!(inner_values_result.value(0), 111);
4158 assert!(inner_values_result.is_null(1));
4159 assert_eq!(inner_values_result.value(2), 333);
4160 }
4161}