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) => array::new_null_array(data_type, num_rows),
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() {
226 if target.typed_value_field().is_none() {
227 return shred_basic_variant(target, VariantPath::default(), Some(as_field));
228 }
229
230 let children = fields
231 .iter()
232 .map(|field| {
233 shredded_get_path(
234 &target,
235 &[VariantPathElement::from(field.name().as_str())],
236 Some(field),
237 cast_options,
238 )
239 })
240 .collect::<Result<Vec<_>>>()?;
241
242 let struct_nulls = target.nulls().cloned();
243
244 return Ok(Arc::new(StructArray::try_new(
245 fields.clone(),
246 children,
247 struct_nulls,
248 )?));
249 }
250
251 shred_basic_variant(target, VariantPath::default(), Some(as_field))
253}
254
255fn try_perfect_shredding(variant_array: &VariantArray, as_field: &Field) -> Option<ArrayRef> {
256 if matches!(as_field.data_type(), DataType::Struct(_)) {
258 return None;
259 }
260 let typed_value = variant_array.typed_value_field()?;
261 if typed_value.data_type() == as_field.data_type()
262 && variant_array
263 .value_field()
264 .is_none_or(|v| v.null_count() == v.len())
265 {
266 return Some(typed_value.clone());
273 }
274 None
275}
276
277pub fn variant_get(input: &ArrayRef, options: GetOptions) -> Result<ArrayRef> {
289 let variant_array = VariantArray::try_new(input)?;
290
291 let GetOptions {
292 as_type,
293 path,
294 cast_options,
295 } = options;
296
297 shredded_get_path(&variant_array, &path, as_type.as_deref(), &cast_options)
298}
299
300#[derive(Debug, Clone, Default)]
302pub struct GetOptions<'a> {
303 pub path: VariantPath<'a>,
305 pub as_type: Option<FieldRef>,
309 pub cast_options: CastOptions<'a>,
311}
312
313impl<'a> GetOptions<'a> {
314 pub fn new() -> Self {
316 Default::default()
317 }
318
319 pub fn new_with_path(path: VariantPath<'a>) -> Self {
321 Self {
322 path,
323 as_type: None,
324 cast_options: Default::default(),
325 }
326 }
327
328 pub fn with_as_type(mut self, as_type: Option<FieldRef>) -> Self {
330 self.as_type = as_type;
331 self
332 }
333
334 pub fn with_cast_options(mut self, cast_options: CastOptions<'a>) -> Self {
336 self.cast_options = cast_options;
337 self
338 }
339}
340
341#[cfg(test)]
342mod test {
343 use std::str::FromStr;
344 use std::sync::Arc;
345
346 use super::{GetOptions, variant_get};
347 use crate::variant_array::{ShreddedVariantFieldArray, StructArrayBuilder};
348 use crate::{
349 VariantArray, VariantArrayBuilder, cast_to_variant, json_to_variant, shred_variant,
350 };
351 use arrow::array::{
352 Array, ArrayRef, AsArray, BinaryArray, BinaryViewArray, BooleanArray, Date32Array,
353 Date64Array, Decimal32Array, Decimal64Array, Decimal128Array, Decimal256Array,
354 Float32Array, Float64Array, Int8Array, Int16Array, Int32Array, Int64Array,
355 LargeBinaryArray, LargeListArray, LargeListViewArray, LargeStringArray, ListArray,
356 ListViewArray, NullBuilder, StringArray, StringViewArray, StructArray,
357 Time32MillisecondArray, Time32SecondArray, Time64MicrosecondArray, Time64NanosecondArray,
358 };
359 use arrow::buffer::{NullBuffer, OffsetBuffer, ScalarBuffer};
360 use arrow::compute::CastOptions;
361 use arrow::datatypes::DataType::{Int16, Int32, Int64};
362 use arrow::datatypes::i256;
363 use arrow::util::display::FormatOptions;
364 use arrow_schema::DataType::{Boolean, Float32, Float64, Int8};
365 use arrow_schema::{DataType, Field, FieldRef, Fields, IntervalUnit, TimeUnit};
366 use chrono::DateTime;
367 use parquet_variant::{
368 EMPTY_VARIANT_METADATA_BYTES, Variant, VariantDecimal4, VariantDecimal8, VariantDecimal16,
369 VariantDecimalType, VariantPath,
370 };
371
372 fn single_variant_get_test(input_json: &str, path: VariantPath, expected_json: &str) {
373 let input_array_ref: ArrayRef = Arc::new(StringArray::from(vec![Some(input_json)]));
375 let input_variant_array_ref = ArrayRef::from(json_to_variant(&input_array_ref).unwrap());
376
377 let result =
378 variant_get(&input_variant_array_ref, GetOptions::new_with_path(path)).unwrap();
379
380 let expected_array_ref: ArrayRef = Arc::new(StringArray::from(vec![Some(expected_json)]));
382 let expected_variant_array = json_to_variant(&expected_array_ref).unwrap();
383
384 let result_array = VariantArray::try_new(&result).unwrap();
385 assert_eq!(
386 result_array.len(),
387 1,
388 "Expected result array to have length 1"
389 );
390 assert!(
391 result_array.nulls().is_none(),
392 "Expected no nulls in result array"
393 );
394 let result_variant = result_array.value(0);
395 let expected_variant = expected_variant_array.value(0);
396 assert_eq!(
397 result_variant, expected_variant,
398 "Result variant does not match expected variant"
399 );
400 }
401
402 #[test]
403 fn get_primitive_variant_field() {
404 single_variant_get_test(
405 r#"{"some_field": 1234}"#,
406 VariantPath::try_from("some_field").unwrap(),
407 "1234",
408 );
409 }
410
411 #[test]
412 fn get_primitive_variant_list_index() {
413 single_variant_get_test("[1234, 5678]", VariantPath::from(0), "1234");
414 }
415
416 #[test]
417 fn get_primitive_variant_inside_object_of_object() {
418 single_variant_get_test(
419 r#"{"top_level_field": {"inner_field": 1234}}"#,
420 VariantPath::try_from("top_level_field")
421 .unwrap()
422 .join("inner_field"),
423 "1234",
424 );
425 }
426
427 #[test]
428 fn get_primitive_variant_inside_list_of_object() {
429 single_variant_get_test(
430 r#"[{"some_field": 1234}]"#,
431 VariantPath::from(0).join("some_field"),
432 "1234",
433 );
434 }
435
436 #[test]
437 fn get_primitive_variant_inside_object_of_list() {
438 single_variant_get_test(
439 r#"{"some_field": [1234]}"#,
440 VariantPath::try_from("some_field").unwrap().join(0),
441 "1234",
442 );
443 }
444
445 #[test]
446 fn get_complex_variant() {
447 single_variant_get_test(
448 r#"{"top_level_field": {"inner_field": 1234}}"#,
449 VariantPath::try_from("top_level_field").unwrap(),
450 r#"{"inner_field": 1234}"#,
451 );
452 }
453
454 macro_rules! numeric_partially_shredded_test {
456 ($primitive_type:ty, $data_fn:ident) => {
457 let array = $data_fn();
458 let options = GetOptions::new();
459 let result = variant_get(&array, options).unwrap();
460
461 let result = VariantArray::try_new(&result).unwrap();
463 assert_eq!(result.len(), 4);
464
465 assert_eq!(
467 result.value(0),
468 Variant::from(<$primitive_type>::try_from(34u8).unwrap())
469 );
470 assert!(!result.is_valid(1));
471 assert_eq!(result.value(2), Variant::from("n/a"));
472 assert_eq!(
473 result.value(3),
474 Variant::from(<$primitive_type>::try_from(100u8).unwrap())
475 );
476 };
477 }
478
479 macro_rules! partially_shredded_variant_array_gen {
482 ($func_name:ident, $typed_value_array_gen: expr) => {
483 partially_shredded_variant_array_gen!(
484 $func_name,
485 $typed_value_array_gen,
486 Variant::from("n/a")
487 );
488 };
489 ($func_name:ident, $typed_value_array_gen: expr, $fallback_variant:expr) => {
490 fn $func_name() -> ArrayRef {
491 let typed_value: ArrayRef = Arc::new($typed_value_array_gen());
492 let typed_as_variant = cast_to_variant(typed_value.as_ref())
493 .expect("should cast typed array to variant");
494 let mut input_builder = VariantArrayBuilder::new(typed_as_variant.len());
495 input_builder.append_variant(typed_as_variant.value(0));
496 input_builder.append_null();
497 input_builder.append_variant($fallback_variant);
498 input_builder.append_variant(typed_as_variant.value(3));
499
500 let variant_array = shred_variant(&input_builder.build(), typed_value.data_type())
501 .expect("should shred variant array");
502 ArrayRef::from(variant_array)
503 }
504 };
505 }
506
507 macro_rules! numeric_partially_shredded_variant_array_fn {
509 ($func:ident, $array_type:ident, $primitive_type:ty) => {
510 partially_shredded_variant_array_gen!($func, || $array_type::from(vec![
511 Some(<$primitive_type>::try_from(34u8).unwrap()),
512 None,
513 None,
514 Some(<$primitive_type>::try_from(100u8).unwrap()),
515 ]));
516 };
517 }
518
519 numeric_partially_shredded_variant_array_fn!(
520 partially_shredded_int8_variant_array,
521 Int8Array,
522 i8
523 );
524 numeric_partially_shredded_variant_array_fn!(
525 partially_shredded_int16_variant_array,
526 Int16Array,
527 i16
528 );
529 numeric_partially_shredded_variant_array_fn!(
530 partially_shredded_int32_variant_array,
531 Int32Array,
532 i32
533 );
534 numeric_partially_shredded_variant_array_fn!(
535 partially_shredded_int64_variant_array,
536 Int64Array,
537 i64
538 );
539 numeric_partially_shredded_variant_array_fn!(
540 partially_shredded_float32_variant_array,
541 Float32Array,
542 f32
543 );
544 numeric_partially_shredded_variant_array_fn!(
545 partially_shredded_float64_variant_array,
546 Float64Array,
547 f64
548 );
549
550 partially_shredded_variant_array_gen!(partially_shredded_bool_variant_array, || {
551 arrow::array::BooleanArray::from(vec![Some(true), None, None, Some(false)])
552 });
553
554 partially_shredded_variant_array_gen!(
555 partially_shredded_utf8_variant_array,
556 || { StringArray::from(vec![Some("hello"), None, None, Some("world")]) },
557 Variant::from(42i32)
558 );
559
560 partially_shredded_variant_array_gen!(partially_shredded_date32_variant_array, || {
561 Date32Array::from(vec![
562 Some(20348), None,
564 None,
565 Some(20340), ])
567 });
568
569 #[test]
570 fn get_variant_partially_shredded_int8_as_variant() {
571 numeric_partially_shredded_test!(i8, partially_shredded_int8_variant_array);
572 }
573
574 #[test]
575 fn get_variant_partially_shredded_int16_as_variant() {
576 numeric_partially_shredded_test!(i16, partially_shredded_int16_variant_array);
577 }
578
579 #[test]
580 fn get_variant_partially_shredded_int32_as_variant() {
581 numeric_partially_shredded_test!(i32, partially_shredded_int32_variant_array);
582 }
583
584 #[test]
585 fn get_variant_partially_shredded_int64_as_variant() {
586 numeric_partially_shredded_test!(i64, partially_shredded_int64_variant_array);
587 }
588
589 #[test]
590 fn get_variant_partially_shredded_float32_as_variant() {
591 numeric_partially_shredded_test!(f32, partially_shredded_float32_variant_array);
592 }
593
594 #[test]
595 fn get_variant_partially_shredded_float64_as_variant() {
596 numeric_partially_shredded_test!(f64, partially_shredded_float64_variant_array);
597 }
598
599 #[test]
600 fn get_variant_partially_shredded_bool_as_variant() {
601 let array = partially_shredded_bool_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(true));
611 assert!(!result.is_valid(1));
612 assert_eq!(result.value(2), Variant::from("n/a"));
613 assert_eq!(result.value(3), Variant::from(false));
614 }
615
616 #[test]
617 fn get_variant_partially_shredded_utf8_as_variant() {
618 let array = partially_shredded_utf8_variant_array();
619 let options = GetOptions::new();
620 let result = variant_get(&array, options).unwrap();
621
622 let result = VariantArray::try_new(&result).unwrap();
624 assert_eq!(result.len(), 4);
625
626 assert_eq!(result.value(0), Variant::from("hello"));
628 assert!(!result.is_valid(1));
629 assert_eq!(result.value(2), Variant::from(42i32));
630 assert_eq!(result.value(3), Variant::from("world"));
631 }
632
633 partially_shredded_variant_array_gen!(partially_shredded_binary_view_variant_array, || {
634 BinaryViewArray::from(vec![
635 Some(&[1u8, 2u8, 3u8][..]), None, None, Some(&[4u8, 5u8, 6u8][..]), ])
640 });
641
642 #[test]
643 fn get_variant_partially_shredded_date32_as_variant() {
644 let array = partially_shredded_date32_variant_array();
645 let options = GetOptions::new();
646 let result = variant_get(&array, options).unwrap();
647
648 let result = VariantArray::try_new(&result).unwrap();
650 assert_eq!(result.len(), 4);
651
652 use chrono::NaiveDate;
654 let date1 = NaiveDate::from_ymd_opt(2025, 9, 17).unwrap();
655 let date2 = NaiveDate::from_ymd_opt(2025, 9, 9).unwrap();
656 assert_eq!(result.value(0), Variant::from(date1));
657 assert!(!result.is_valid(1));
658 assert_eq!(result.value(2), Variant::from("n/a"));
659 assert_eq!(result.value(3), Variant::from(date2));
660 }
661
662 #[test]
663 fn get_variant_partially_shredded_binary_view_as_variant() {
664 let array = partially_shredded_binary_view_variant_array();
665 let options = GetOptions::new();
666 let result = variant_get(&array, options).unwrap();
667
668 let result = VariantArray::try_new(&result).unwrap();
670 assert_eq!(result.len(), 4);
671
672 assert_eq!(result.value(0), Variant::from(&[1u8, 2u8, 3u8][..]));
674 assert!(!result.is_valid(1));
675 assert_eq!(result.value(2), Variant::from("n/a"));
676 assert_eq!(result.value(3), Variant::from(&[4u8, 5u8, 6u8][..]));
677 }
678
679 macro_rules! assert_variant_get_as_variant_array_with_default_option {
681 ($variant_array: expr, $array_expected: expr) => {{
682 let options = GetOptions::new();
683 let array = $variant_array;
684 let result = variant_get(&array, options).unwrap();
685 let result = VariantArray::try_new(&result).unwrap();
686
687 assert_eq!(result.len(), $array_expected.len());
688
689 for (idx, item) in $array_expected.into_iter().enumerate() {
690 match item {
691 Some(item) => assert_eq!(result.value(idx), item),
692 None => assert!(result.is_null(idx)),
693 }
694 }
695 }};
696 }
697
698 partially_shredded_variant_array_gen!(
699 partially_shredded_timestamp_micro_ntz_variant_array,
700 || {
701 arrow::array::TimestampMicrosecondArray::from(vec![
702 Some(-456000),
703 None,
704 None,
705 Some(1758602096000000),
706 ])
707 }
708 );
709
710 #[test]
711 fn get_variant_partial_shredded_timestamp_micro_ntz_as_variant() {
712 let array = partially_shredded_timestamp_micro_ntz_variant_array();
713 assert_variant_get_as_variant_array_with_default_option!(
714 array,
715 vec![
716 Some(Variant::from(
717 DateTime::from_timestamp_micros(-456000i64)
718 .unwrap()
719 .naive_utc(),
720 )),
721 None,
722 Some(Variant::from("n/a")),
723 Some(Variant::from(
724 DateTime::parse_from_rfc3339("2025-09-23T12:34:56+08:00")
725 .unwrap()
726 .naive_utc(),
727 )),
728 ]
729 )
730 }
731
732 partially_shredded_variant_array_gen!(partially_shredded_timestamp_micro_variant_array, || {
733 arrow::array::TimestampMicrosecondArray::from(vec![
734 Some(-456000),
735 None,
736 None,
737 Some(1758602096000000),
738 ])
739 .with_timezone("+00:00")
740 });
741
742 #[test]
743 fn get_variant_partial_shredded_timestamp_micro_as_variant() {
744 let array = partially_shredded_timestamp_micro_variant_array();
745 assert_variant_get_as_variant_array_with_default_option!(
746 array,
747 vec![
748 Some(Variant::from(
749 DateTime::from_timestamp_micros(-456000i64)
750 .unwrap()
751 .to_utc(),
752 )),
753 None,
754 Some(Variant::from("n/a")),
755 Some(Variant::from(
756 DateTime::parse_from_rfc3339("2025-09-23T12:34:56+08:00")
757 .unwrap()
758 .to_utc(),
759 )),
760 ]
761 )
762 }
763
764 partially_shredded_variant_array_gen!(
765 partially_shredded_timestamp_nano_ntz_variant_array,
766 || {
767 arrow::array::TimestampNanosecondArray::from(vec![
768 Some(-4999999561),
769 None,
770 None,
771 Some(1758602096000000000),
772 ])
773 }
774 );
775
776 #[test]
777 fn get_variant_partial_shredded_timestamp_nano_ntz_as_variant() {
778 let array = partially_shredded_timestamp_nano_ntz_variant_array();
779 assert_variant_get_as_variant_array_with_default_option!(
780 array,
781 vec![
782 Some(Variant::from(
783 DateTime::from_timestamp(-5, 439).unwrap().naive_utc()
784 )),
785 None,
786 Some(Variant::from("n/a")),
787 Some(Variant::from(
788 DateTime::parse_from_rfc3339("2025-09-23T12:34:56+08:00")
789 .unwrap()
790 .naive_utc()
791 )),
792 ]
793 )
794 }
795
796 partially_shredded_variant_array_gen!(partially_shredded_timestamp_nano_variant_array, || {
797 arrow::array::TimestampNanosecondArray::from(vec![
798 Some(-4999999561),
799 None,
800 None,
801 Some(1758602096000000000),
802 ])
803 .with_timezone("+00:00")
804 });
805
806 #[test]
807 fn get_variant_partial_shredded_timestamp_nano_as_variant() {
808 let array = partially_shredded_timestamp_nano_variant_array();
809 assert_variant_get_as_variant_array_with_default_option!(
810 array,
811 vec![
812 Some(Variant::from(
813 DateTime::from_timestamp(-5, 439).unwrap().to_utc()
814 )),
815 None,
816 Some(Variant::from("n/a")),
817 Some(Variant::from(
818 DateTime::parse_from_rfc3339("2025-09-23T12:34:56+08:00")
819 .unwrap()
820 .to_utc()
821 )),
822 ]
823 )
824 }
825
826 #[test]
828 fn get_variant_shredded_int32_as_int32_safe_cast() {
829 let array = partially_shredded_int32_variant_array();
831 let field = Field::new("typed_value", DataType::Int32, true);
833 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
834 let result = variant_get(&array, options).unwrap();
835 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
836 Some(34),
837 None,
838 None, Some(100),
840 ]));
841 assert_eq!(&result, &expected)
842 }
843
844 #[test]
846 fn get_variant_shredded_int32_as_int32_unsafe_cast() {
847 let array = partially_shredded_int32_variant_array();
849 let field = Field::new("typed_value", DataType::Int32, true);
850 let cast_options = CastOptions {
851 safe: false, ..Default::default()
853 };
854 let options = GetOptions::new()
855 .with_as_type(Some(FieldRef::from(field)))
856 .with_cast_options(cast_options);
857
858 let err = variant_get(&array, options).unwrap_err();
859 assert_eq!(
861 err.to_string(),
862 "Cast error: Failed to extract primitive of type Int32 from variant ShortString(ShortString(\"n/a\")) at path VariantPath([])"
863 );
864 }
865
866 macro_rules! numeric_perfectly_shredded_test {
868 ($primitive_type:ty, $data_fn:ident) => {
869 let array = $data_fn();
870 let options = GetOptions::new();
871 let result = variant_get(&array, options).unwrap();
872
873 let result = VariantArray::try_new(&result).unwrap();
875 assert_eq!(result.len(), 3);
876
877 assert_eq!(
879 result.value(0),
880 Variant::from(<$primitive_type>::try_from(1u8).unwrap())
881 );
882 assert_eq!(
883 result.value(1),
884 Variant::from(<$primitive_type>::try_from(2u8).unwrap())
885 );
886 assert_eq!(
887 result.value(2),
888 Variant::from(<$primitive_type>::try_from(3u8).unwrap())
889 );
890 };
891 }
892
893 #[test]
894 fn get_variant_perfectly_shredded_int8_as_variant() {
895 numeric_perfectly_shredded_test!(i8, perfectly_shredded_int8_variant_array);
896 }
897
898 #[test]
899 fn get_variant_perfectly_shredded_int16_as_variant() {
900 numeric_perfectly_shredded_test!(i16, perfectly_shredded_int16_variant_array);
901 }
902
903 #[test]
904 fn get_variant_perfectly_shredded_int32_as_variant() {
905 numeric_perfectly_shredded_test!(i32, perfectly_shredded_int32_variant_array);
906 }
907
908 #[test]
909 fn get_variant_perfectly_shredded_int64_as_variant() {
910 numeric_perfectly_shredded_test!(i64, perfectly_shredded_int64_variant_array);
911 }
912
913 #[test]
914 fn get_variant_perfectly_shredded_float32_as_variant() {
915 numeric_perfectly_shredded_test!(f32, perfectly_shredded_float32_variant_array);
916 }
917
918 #[test]
919 fn get_variant_perfectly_shredded_float64_as_variant() {
920 numeric_perfectly_shredded_test!(f64, perfectly_shredded_float64_variant_array);
921 }
922
923 #[test]
925 fn get_variant_all_null_as_variant() {
926 let array = all_null_variant_array();
927 let options = GetOptions::new();
928 let result = variant_get(&array, options).unwrap();
929
930 let result = VariantArray::try_new(&result).unwrap();
932 assert_eq!(result.len(), 3);
933
934 assert!(!result.is_valid(0));
936 assert!(!result.is_valid(1));
937 assert!(!result.is_valid(2));
938 }
939
940 #[test]
942 fn get_variant_all_null_as_int32() {
943 let array = all_null_variant_array();
944 let field = Field::new("typed_value", DataType::Int32, true);
946 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
947 let result = variant_get(&array, options).unwrap();
948
949 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
950 Option::<i32>::None,
951 Option::<i32>::None,
952 Option::<i32>::None,
953 ]));
954 assert_eq!(&result, &expected)
955 }
956
957 macro_rules! perfectly_shredded_to_arrow_primitive_test {
958 ($name:ident, $primitive_type:expr, $perfectly_shredded_array_gen_fun:ident, $expected_array:expr) => {
959 #[test]
960 fn $name() {
961 let array = $perfectly_shredded_array_gen_fun();
962 let field = Field::new("typed_value", $primitive_type, true);
963 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
964 let result = variant_get(&array, options).unwrap();
965 let expected_array: ArrayRef = Arc::new($expected_array);
966 assert_eq!(&result, &expected_array);
967 }
968 };
969 }
970
971 perfectly_shredded_to_arrow_primitive_test!(
972 get_variant_perfectly_shredded_int18_as_int8,
973 Int8,
974 perfectly_shredded_int8_variant_array,
975 Int8Array::from(vec![Some(1), Some(2), Some(3)])
976 );
977
978 perfectly_shredded_to_arrow_primitive_test!(
979 get_variant_perfectly_shredded_int16_as_int16,
980 Int16,
981 perfectly_shredded_int16_variant_array,
982 Int16Array::from(vec![Some(1), Some(2), Some(3)])
983 );
984
985 perfectly_shredded_to_arrow_primitive_test!(
986 get_variant_perfectly_shredded_int32_as_int32,
987 Int32,
988 perfectly_shredded_int32_variant_array,
989 Int32Array::from(vec![Some(1), Some(2), Some(3)])
990 );
991
992 perfectly_shredded_to_arrow_primitive_test!(
993 get_variant_perfectly_shredded_int64_as_int64,
994 Int64,
995 perfectly_shredded_int64_variant_array,
996 Int64Array::from(vec![Some(1), Some(2), Some(3)])
997 );
998
999 perfectly_shredded_to_arrow_primitive_test!(
1000 get_variant_perfectly_shredded_float32_as_float32,
1001 Float32,
1002 perfectly_shredded_float32_variant_array,
1003 Float32Array::from(vec![Some(1.0), Some(2.0), Some(3.0)])
1004 );
1005
1006 perfectly_shredded_to_arrow_primitive_test!(
1007 get_variant_perfectly_shredded_float64_as_float64,
1008 Float64,
1009 perfectly_shredded_float64_variant_array,
1010 Float64Array::from(vec![Some(1.0), Some(2.0), Some(3.0)])
1011 );
1012
1013 perfectly_shredded_to_arrow_primitive_test!(
1014 get_variant_perfectly_shredded_boolean_as_boolean,
1015 Boolean,
1016 perfectly_shredded_bool_variant_array,
1017 BooleanArray::from(vec![Some(true), Some(false), Some(true)])
1018 );
1019
1020 perfectly_shredded_to_arrow_primitive_test!(
1021 get_variant_perfectly_shredded_utf8_as_utf8,
1022 DataType::Utf8,
1023 perfectly_shredded_utf8_variant_array,
1024 StringArray::from(vec![Some("foo"), Some("bar"), Some("baz")])
1025 );
1026
1027 perfectly_shredded_to_arrow_primitive_test!(
1028 get_variant_perfectly_shredded_large_utf8_as_utf8,
1029 DataType::Utf8,
1030 perfectly_shredded_large_utf8_variant_array,
1031 StringArray::from(vec![Some("foo"), Some("bar"), Some("baz")])
1032 );
1033
1034 perfectly_shredded_to_arrow_primitive_test!(
1035 get_variant_perfectly_shredded_utf8_view_as_utf8,
1036 DataType::Utf8,
1037 perfectly_shredded_utf8_view_variant_array,
1038 StringArray::from(vec![Some("foo"), Some("bar"), Some("baz")])
1039 );
1040
1041 macro_rules! perfectly_shredded_variant_array_fn {
1042 ($func:ident, $typed_value_gen:expr) => {
1043 fn $func() -> ArrayRef {
1044 let typed_value: ArrayRef = Arc::new($typed_value_gen());
1047 if let Some(shredded) = cast_to_variant(typed_value.as_ref())
1048 .ok()
1049 .and_then(|unshredded| shred_variant(&unshredded, typed_value.data_type()).ok())
1050 {
1051 return shredded.into();
1052 }
1053
1054 let metadata = BinaryViewArray::from_iter_values(std::iter::repeat_n(
1055 EMPTY_VARIANT_METADATA_BYTES,
1056 typed_value.len(),
1057 ));
1058 VariantArray::from_parts(metadata, None, Some(typed_value), None).into()
1059 }
1060 };
1061 }
1062
1063 perfectly_shredded_variant_array_fn!(perfectly_shredded_utf8_variant_array, || {
1064 StringArray::from(vec![Some("foo"), Some("bar"), Some("baz")])
1065 });
1066
1067 perfectly_shredded_variant_array_fn!(perfectly_shredded_large_utf8_variant_array, || {
1068 LargeStringArray::from(vec![Some("foo"), Some("bar"), Some("baz")])
1069 });
1070
1071 perfectly_shredded_variant_array_fn!(perfectly_shredded_utf8_view_variant_array, || {
1072 StringViewArray::from(vec![Some("foo"), Some("bar"), Some("baz")])
1073 });
1074
1075 perfectly_shredded_variant_array_fn!(perfectly_shredded_bool_variant_array, || {
1076 BooleanArray::from(vec![Some(true), Some(false), Some(true)])
1077 });
1078
1079 macro_rules! numeric_perfectly_shredded_variant_array_fn {
1091 ($func:ident, $array_type:ident, $primitive_type:ty) => {
1092 perfectly_shredded_variant_array_fn!($func, || {
1093 $array_type::from(vec![
1094 Some(<$primitive_type>::try_from(1u8).unwrap()),
1095 Some(<$primitive_type>::try_from(2u8).unwrap()),
1096 Some(<$primitive_type>::try_from(3u8).unwrap()),
1097 ])
1098 });
1099 };
1100 }
1101
1102 numeric_perfectly_shredded_variant_array_fn!(
1103 perfectly_shredded_int8_variant_array,
1104 Int8Array,
1105 i8
1106 );
1107 numeric_perfectly_shredded_variant_array_fn!(
1108 perfectly_shredded_int16_variant_array,
1109 Int16Array,
1110 i16
1111 );
1112 numeric_perfectly_shredded_variant_array_fn!(
1113 perfectly_shredded_int32_variant_array,
1114 Int32Array,
1115 i32
1116 );
1117 numeric_perfectly_shredded_variant_array_fn!(
1118 perfectly_shredded_int64_variant_array,
1119 Int64Array,
1120 i64
1121 );
1122 numeric_perfectly_shredded_variant_array_fn!(
1123 perfectly_shredded_float32_variant_array,
1124 Float32Array,
1125 f32
1126 );
1127 numeric_perfectly_shredded_variant_array_fn!(
1128 perfectly_shredded_float64_variant_array,
1129 Float64Array,
1130 f64
1131 );
1132
1133 perfectly_shredded_variant_array_fn!(
1134 perfectly_shredded_timestamp_micro_ntz_variant_array,
1135 || {
1136 arrow::array::TimestampMicrosecondArray::from(vec![
1137 Some(-456000),
1138 Some(1758602096000001),
1139 Some(1758602096000002),
1140 ])
1141 }
1142 );
1143
1144 perfectly_shredded_to_arrow_primitive_test!(
1145 get_variant_perfectly_shredded_timestamp_micro_ntz_as_timestamp_micro_ntz,
1146 DataType::Timestamp(TimeUnit::Microsecond, None),
1147 perfectly_shredded_timestamp_micro_ntz_variant_array,
1148 arrow::array::TimestampMicrosecondArray::from(vec![
1149 Some(-456000),
1150 Some(1758602096000001),
1151 Some(1758602096000002),
1152 ])
1153 );
1154
1155 perfectly_shredded_to_arrow_primitive_test!(
1157 get_variant_perfectly_shredded_timestamp_micro_ntz_as_nano_ntz,
1158 DataType::Timestamp(TimeUnit::Nanosecond, None),
1159 perfectly_shredded_timestamp_micro_ntz_variant_array,
1160 arrow::array::TimestampNanosecondArray::from(vec![
1161 Some(-456000000),
1162 Some(1758602096000001000),
1163 Some(1758602096000002000)
1164 ])
1165 );
1166
1167 perfectly_shredded_variant_array_fn!(perfectly_shredded_timestamp_micro_variant_array, || {
1168 arrow::array::TimestampMicrosecondArray::from(vec![
1169 Some(-456000),
1170 Some(1758602096000001),
1171 Some(1758602096000002),
1172 ])
1173 .with_timezone("+00:00")
1174 });
1175
1176 perfectly_shredded_to_arrow_primitive_test!(
1177 get_variant_perfectly_shredded_timestamp_micro_as_timestamp_micro,
1178 DataType::Timestamp(TimeUnit::Microsecond, Some(Arc::from("+00:00"))),
1179 perfectly_shredded_timestamp_micro_variant_array,
1180 arrow::array::TimestampMicrosecondArray::from(vec![
1181 Some(-456000),
1182 Some(1758602096000001),
1183 Some(1758602096000002),
1184 ])
1185 .with_timezone("+00:00")
1186 );
1187
1188 perfectly_shredded_to_arrow_primitive_test!(
1190 get_variant_perfectly_shredded_timestamp_micro_as_nano,
1191 DataType::Timestamp(TimeUnit::Nanosecond, Some(Arc::from("+00:00"))),
1192 perfectly_shredded_timestamp_micro_variant_array,
1193 arrow::array::TimestampNanosecondArray::from(vec![
1194 Some(-456000000),
1195 Some(1758602096000001000),
1196 Some(1758602096000002000)
1197 ])
1198 .with_timezone("+00:00")
1199 );
1200
1201 perfectly_shredded_variant_array_fn!(
1202 perfectly_shredded_timestamp_nano_ntz_variant_array,
1203 || {
1204 arrow::array::TimestampNanosecondArray::from(vec![
1205 Some(-4999999561),
1206 Some(1758602096000000001),
1207 Some(1758602096000000002),
1208 ])
1209 }
1210 );
1211
1212 perfectly_shredded_variant_array_fn!(
1213 perfectly_shredded_timestamp_micro_variant_array_for_second_and_milli_second,
1214 || {
1215 arrow::array::TimestampMicrosecondArray::from(vec![
1216 Some(1234), Some(1234000), Some(1234000000), ])
1220 .with_timezone("+00:00")
1221 }
1222 );
1223
1224 perfectly_shredded_to_arrow_primitive_test!(
1227 get_variant_perfectly_shredded_timestamp_micro_as_timestamp_second,
1228 DataType::Timestamp(TimeUnit::Second, Some(Arc::from("+00:00"))),
1229 perfectly_shredded_timestamp_micro_variant_array_for_second_and_milli_second,
1230 arrow::array::TimestampSecondArray::from(vec![
1231 None,
1232 None, Some(1234)
1234 ])
1235 .with_timezone("+00:00")
1236 );
1237
1238 perfectly_shredded_to_arrow_primitive_test!(
1239 get_variant_perfectly_shredded_timestamp_micro_as_timestamp_milli,
1240 DataType::Timestamp(TimeUnit::Millisecond, Some(Arc::from("+00:00"))),
1241 perfectly_shredded_timestamp_micro_variant_array_for_second_and_milli_second,
1242 arrow::array::TimestampMillisecondArray::from(vec![
1243 None, Some(1234),
1245 Some(1234000)
1246 ])
1247 .with_timezone("+00:00")
1248 );
1249
1250 perfectly_shredded_variant_array_fn!(
1251 perfectly_shredded_timestamp_micro_ntz_variant_array_for_second_and_milli_second,
1252 || {
1253 arrow::array::TimestampMicrosecondArray::from(vec![
1254 Some(1234), Some(1234000), Some(1234000000), ])
1258 }
1259 );
1260
1261 perfectly_shredded_to_arrow_primitive_test!(
1264 get_variant_perfectly_shredded_timestamp_micro_ntz_as_timestamp_second,
1265 DataType::Timestamp(TimeUnit::Second, None),
1266 perfectly_shredded_timestamp_micro_ntz_variant_array_for_second_and_milli_second,
1267 arrow::array::TimestampSecondArray::from(vec![
1268 None,
1269 None, Some(1234)
1271 ])
1272 );
1273
1274 perfectly_shredded_to_arrow_primitive_test!(
1275 get_variant_perfectly_shredded_timestamp_micro_ntz_as_timestamp_milli,
1276 DataType::Timestamp(TimeUnit::Millisecond, None),
1277 perfectly_shredded_timestamp_micro_ntz_variant_array_for_second_and_milli_second,
1278 arrow::array::TimestampMillisecondArray::from(vec![
1279 None, Some(1234),
1281 Some(1234000)
1282 ])
1283 );
1284
1285 perfectly_shredded_variant_array_fn!(
1286 perfectly_shredded_timestamp_nano_variant_array_for_second_and_milli_second,
1287 || {
1288 arrow::array::TimestampNanosecondArray::from(vec![
1289 Some(1234000), Some(1234000000), Some(1234000000000), ])
1293 .with_timezone("+00:00")
1294 }
1295 );
1296
1297 perfectly_shredded_to_arrow_primitive_test!(
1300 get_variant_perfectly_shredded_timestamp_nano_as_timestamp_second,
1301 DataType::Timestamp(TimeUnit::Second, Some(Arc::from("+00:00"))),
1302 perfectly_shredded_timestamp_nano_variant_array_for_second_and_milli_second,
1303 arrow::array::TimestampSecondArray::from(vec![
1304 None,
1305 None, Some(1234)
1307 ])
1308 .with_timezone("+00:00")
1309 );
1310
1311 perfectly_shredded_to_arrow_primitive_test!(
1312 get_variant_perfectly_shredded_timestamp_nano_as_timestamp_milli,
1313 DataType::Timestamp(TimeUnit::Millisecond, Some(Arc::from("+00:00"))),
1314 perfectly_shredded_timestamp_nano_variant_array_for_second_and_milli_second,
1315 arrow::array::TimestampMillisecondArray::from(vec![
1316 None, Some(1234),
1318 Some(1234000)
1319 ])
1320 .with_timezone("+00:00")
1321 );
1322
1323 perfectly_shredded_variant_array_fn!(
1324 perfectly_shredded_timestamp_nano_ntz_variant_array_for_second_and_milli_second,
1325 || {
1326 arrow::array::TimestampNanosecondArray::from(vec![
1327 Some(1234000), Some(1234000000), Some(1234000000000), ])
1331 }
1332 );
1333
1334 perfectly_shredded_to_arrow_primitive_test!(
1337 get_variant_perfectly_shredded_timestamp_nano_ntz_as_timestamp_second,
1338 DataType::Timestamp(TimeUnit::Second, None),
1339 perfectly_shredded_timestamp_nano_ntz_variant_array_for_second_and_milli_second,
1340 arrow::array::TimestampSecondArray::from(vec![
1341 None,
1342 None, Some(1234)
1344 ])
1345 );
1346
1347 perfectly_shredded_to_arrow_primitive_test!(
1348 get_variant_perfectly_shredded_timestamp_nano_ntz_as_timestamp_milli,
1349 DataType::Timestamp(TimeUnit::Millisecond, None),
1350 perfectly_shredded_timestamp_nano_ntz_variant_array_for_second_and_milli_second,
1351 arrow::array::TimestampMillisecondArray::from(vec![
1352 None, Some(1234),
1354 Some(1234000)
1355 ])
1356 );
1357
1358 perfectly_shredded_to_arrow_primitive_test!(
1359 get_variant_perfectly_shredded_timestamp_nano_ntz_as_timestamp_nano_ntz,
1360 DataType::Timestamp(TimeUnit::Nanosecond, None),
1361 perfectly_shredded_timestamp_nano_ntz_variant_array,
1362 arrow::array::TimestampNanosecondArray::from(vec![
1363 Some(-4999999561),
1364 Some(1758602096000000001),
1365 Some(1758602096000000002),
1366 ])
1367 );
1368
1369 perfectly_shredded_variant_array_fn!(perfectly_shredded_timestamp_nano_variant_array, || {
1370 arrow::array::TimestampNanosecondArray::from(vec![
1371 Some(-4999999561),
1372 Some(1758602096000000001),
1373 Some(1758602096000000002),
1374 ])
1375 .with_timezone("+00:00")
1376 });
1377
1378 perfectly_shredded_to_arrow_primitive_test!(
1379 get_variant_perfectly_shredded_timestamp_nano_as_timestamp_nano,
1380 DataType::Timestamp(TimeUnit::Nanosecond, Some(Arc::from("+00:00"))),
1381 perfectly_shredded_timestamp_nano_variant_array,
1382 arrow::array::TimestampNanosecondArray::from(vec![
1383 Some(-4999999561),
1384 Some(1758602096000000001),
1385 Some(1758602096000000002),
1386 ])
1387 .with_timezone("+00:00")
1388 );
1389
1390 perfectly_shredded_variant_array_fn!(perfectly_shredded_date_variant_array, || {
1391 Date32Array::from(vec![Some(-12345), Some(17586), Some(20000)])
1392 });
1393
1394 perfectly_shredded_to_arrow_primitive_test!(
1395 get_variant_perfectly_shredded_date_as_date,
1396 DataType::Date32,
1397 perfectly_shredded_date_variant_array,
1398 Date32Array::from(vec![Some(-12345), Some(17586), Some(20000)])
1399 );
1400
1401 perfectly_shredded_to_arrow_primitive_test!(
1402 get_variant_perfectly_shredded_date_as_date64,
1403 DataType::Date64,
1404 perfectly_shredded_date_variant_array,
1405 Date64Array::from(vec![
1406 Some(-1066608000000),
1407 Some(1519430400000),
1408 Some(1728000000000)
1409 ])
1410 );
1411
1412 perfectly_shredded_variant_array_fn!(perfectly_shredded_time_variant_array, || {
1413 Time64MicrosecondArray::from(vec![Some(12345000), Some(87654000), Some(135792000)])
1414 });
1415
1416 perfectly_shredded_to_arrow_primitive_test!(
1417 get_variant_perfectly_shredded_time_as_time,
1418 DataType::Time64(TimeUnit::Microsecond),
1419 perfectly_shredded_time_variant_array,
1420 Time64MicrosecondArray::from(vec![Some(12345000), Some(87654000), Some(135792000)])
1421 );
1422
1423 perfectly_shredded_to_arrow_primitive_test!(
1424 get_variant_perfectly_shredded_time_as_time64_nano,
1425 DataType::Time64(TimeUnit::Nanosecond),
1426 perfectly_shredded_time_variant_array,
1427 Time64NanosecondArray::from(vec![
1428 Some(12345000000),
1429 Some(87654000000),
1430 Some(135792000000)
1431 ])
1432 );
1433
1434 perfectly_shredded_variant_array_fn!(perfectly_shredded_time_variant_array_for_time32, || {
1435 Time64MicrosecondArray::from(vec![
1436 Some(1234), Some(7654000), Some(35792000000), ])
1440 });
1441
1442 perfectly_shredded_to_arrow_primitive_test!(
1443 get_variant_perfectly_shredded_time_as_time32_second,
1444 DataType::Time32(TimeUnit::Second),
1445 perfectly_shredded_time_variant_array_for_time32,
1446 Time32SecondArray::from(vec![
1447 None,
1448 None, Some(35792)
1450 ])
1451 );
1452
1453 perfectly_shredded_to_arrow_primitive_test!(
1454 get_variant_perfectly_shredded_time_as_time32_milli,
1455 DataType::Time32(TimeUnit::Millisecond),
1456 perfectly_shredded_time_variant_array_for_time32,
1457 Time32MillisecondArray::from(vec![
1458 None, Some(7654),
1460 Some(35792000)
1461 ])
1462 );
1463
1464 perfectly_shredded_variant_array_fn!(perfectly_shredded_null_variant_array, || {
1465 let mut builder = NullBuilder::new();
1466 builder.append_nulls(3);
1467 builder.finish()
1468 });
1469
1470 perfectly_shredded_to_arrow_primitive_test!(
1471 get_variant_perfectly_shredded_null_as_null,
1472 DataType::Null,
1473 perfectly_shredded_null_variant_array,
1474 arrow::array::NullArray::new(3)
1475 );
1476
1477 perfectly_shredded_variant_array_fn!(perfectly_shredded_null_variant_array_with_int, || {
1478 Int32Array::from(vec![Some(32), Some(64), Some(48)])
1479 });
1480
1481 perfectly_shredded_to_arrow_primitive_test!(
1483 get_variant_perfectly_shredded_null_with_type_missmatch_in_safe_mode,
1484 DataType::Null,
1485 perfectly_shredded_null_variant_array_with_int,
1486 arrow::array::NullArray::new(3)
1487 );
1488
1489 #[test]
1491 fn get_variant_perfectly_shredded_null_as_null_with_type_missmatch_in_strict_mode() {
1492 let array = perfectly_shredded_null_variant_array_with_int();
1493 let field = Field::new("typed_value", DataType::Null, true);
1494 let options = GetOptions::new()
1495 .with_as_type(Some(FieldRef::from(field)))
1496 .with_cast_options(CastOptions {
1497 safe: false,
1498 format_options: FormatOptions::default(),
1499 });
1500
1501 let result = variant_get(&array, options);
1502
1503 assert!(result.is_err());
1504 let error_msg = format!("{}", result.unwrap_err());
1505 assert!(
1506 error_msg
1507 .contains("Cast error: Failed to extract primitive of type Null from variant Int32(32) at path VariantPath([])"),
1508 "Expected=[Cast error: Failed to extract primitive of type Null from variant Int32(32) at path VariantPath([])],\
1509 Got error message=[{}]",
1510 error_msg
1511 );
1512 }
1513
1514 perfectly_shredded_variant_array_fn!(perfectly_shredded_decimal4_variant_array, || {
1515 Decimal32Array::from(vec![Some(12345), Some(23400), Some(-12342)])
1516 .with_precision_and_scale(5, 2)
1517 .unwrap()
1518 });
1519
1520 perfectly_shredded_to_arrow_primitive_test!(
1521 get_variant_perfectly_shredded_decimal4_as_decimal4,
1522 DataType::Decimal32(5, 2),
1523 perfectly_shredded_decimal4_variant_array,
1524 Decimal32Array::from(vec![Some(12345), Some(23400), Some(-12342)])
1525 .with_precision_and_scale(5, 2)
1526 .unwrap()
1527 );
1528
1529 perfectly_shredded_variant_array_fn!(
1530 perfectly_shredded_decimal8_variant_array_cast2decimal32,
1531 || {
1532 Decimal64Array::from(vec![Some(123456), Some(145678), Some(-123456)])
1533 .with_precision_and_scale(6, 1)
1534 .unwrap()
1535 }
1536 );
1537
1538 perfectly_shredded_to_arrow_primitive_test!(
1542 get_variant_perfectly_shredded_decimal8_through_decimal32_as_decimal8,
1543 DataType::Decimal64(6, 1),
1544 perfectly_shredded_decimal8_variant_array_cast2decimal32,
1545 Decimal64Array::from(vec![Some(123456), Some(145678), Some(-123456)])
1546 .with_precision_and_scale(6, 1)
1547 .unwrap()
1548 );
1549
1550 perfectly_shredded_variant_array_fn!(perfectly_shredded_decimal8_variant_array, || {
1553 Decimal64Array::from(vec![Some(1234567809), Some(1456787000), Some(-1234561203)])
1554 .with_precision_and_scale(10, 1)
1555 .unwrap()
1556 });
1557
1558 perfectly_shredded_to_arrow_primitive_test!(
1559 get_variant_perfectly_shredded_decimal8_as_decimal8,
1560 DataType::Decimal64(10, 1),
1561 perfectly_shredded_decimal8_variant_array,
1562 Decimal64Array::from(vec![Some(1234567809), Some(1456787000), Some(-1234561203)])
1563 .with_precision_and_scale(10, 1)
1564 .unwrap()
1565 );
1566
1567 perfectly_shredded_variant_array_fn!(
1570 perfectly_shredded_decimal16_within_decimal4_variant_array,
1571 || {
1572 Decimal128Array::from(vec![
1573 Some(i128::from(1234589)),
1574 Some(i128::from(2344444)),
1575 Some(i128::from(-1234789)),
1576 ])
1577 .with_precision_and_scale(7, 3)
1578 .unwrap()
1579 }
1580 );
1581
1582 perfectly_shredded_to_arrow_primitive_test!(
1585 get_variant_perfectly_shredded_decimal16_within_decimal4_as_decimal16,
1586 DataType::Decimal128(7, 3),
1587 perfectly_shredded_decimal16_within_decimal4_variant_array,
1588 Decimal128Array::from(vec![
1589 Some(i128::from(1234589)),
1590 Some(i128::from(2344444)),
1591 Some(i128::from(-1234789)),
1592 ])
1593 .with_precision_and_scale(7, 3)
1594 .unwrap()
1595 );
1596
1597 perfectly_shredded_variant_array_fn!(
1598 perfectly_shredded_decimal16_within_decimal8_variant_array,
1599 || {
1600 Decimal128Array::from(vec![Some(1234567809), Some(1456787000), Some(-1234561203)])
1601 .with_precision_and_scale(10, 1)
1602 .unwrap()
1603 }
1604 );
1605
1606 perfectly_shredded_to_arrow_primitive_test!(
1609 get_variant_perfectly_shredded_decimal16_within8_as_decimal16,
1610 DataType::Decimal128(10, 1),
1611 perfectly_shredded_decimal16_within_decimal8_variant_array,
1612 Decimal128Array::from(vec![Some(1234567809), Some(1456787000), Some(-1234561203)])
1613 .with_precision_and_scale(10, 1)
1614 .unwrap()
1615 );
1616
1617 perfectly_shredded_variant_array_fn!(perfectly_shredded_decimal16_variant_array, || {
1618 Decimal128Array::from(vec![
1619 Some(i128::from_str("12345678901234567899").unwrap()),
1620 Some(i128::from_str("23445677483748324300").unwrap()),
1621 Some(i128::from_str("-12345678901234567899").unwrap()),
1622 ])
1623 .with_precision_and_scale(20, 3)
1624 .unwrap()
1625 });
1626
1627 perfectly_shredded_to_arrow_primitive_test!(
1630 get_variant_perfectly_shredded_decimal16_as_decimal16,
1631 DataType::Decimal128(20, 3),
1632 perfectly_shredded_decimal16_variant_array,
1633 Decimal128Array::from(vec![
1634 Some(i128::from_str("12345678901234567899").unwrap()),
1635 Some(i128::from_str("23445677483748324300").unwrap()),
1636 Some(i128::from_str("-12345678901234567899").unwrap())
1637 ])
1638 .with_precision_and_scale(20, 3)
1639 .unwrap()
1640 );
1641
1642 perfectly_shredded_variant_array_fn!(perfectly_shredded_binary_variant_array, || {
1643 BinaryArray::from(vec![
1644 Some(b"Apache" as &[u8]),
1645 Some(b"Arrow-rs" as &[u8]),
1646 Some(b"Parquet-variant" as &[u8]),
1647 ])
1648 });
1649
1650 perfectly_shredded_to_arrow_primitive_test!(
1651 get_variant_perfectly_shredded_binary_as_binary,
1652 DataType::Binary,
1653 perfectly_shredded_binary_variant_array,
1654 BinaryArray::from(vec![
1655 Some(b"Apache" as &[u8]),
1656 Some(b"Arrow-rs" as &[u8]),
1657 Some(b"Parquet-variant" as &[u8]),
1658 ])
1659 );
1660
1661 perfectly_shredded_variant_array_fn!(perfectly_shredded_large_binary_variant_array, || {
1662 LargeBinaryArray::from(vec![
1663 Some(b"Apache" as &[u8]),
1664 Some(b"Arrow-rs" as &[u8]),
1665 Some(b"Parquet-variant" as &[u8]),
1666 ])
1667 });
1668
1669 perfectly_shredded_to_arrow_primitive_test!(
1670 get_variant_perfectly_shredded_large_binary_as_large_binary,
1671 DataType::LargeBinary,
1672 perfectly_shredded_large_binary_variant_array,
1673 LargeBinaryArray::from(vec![
1674 Some(b"Apache" as &[u8]),
1675 Some(b"Arrow-rs" as &[u8]),
1676 Some(b"Parquet-variant" as &[u8]),
1677 ])
1678 );
1679
1680 perfectly_shredded_variant_array_fn!(perfectly_shredded_binary_view_variant_array, || {
1681 BinaryViewArray::from(vec![
1682 Some(b"Apache" as &[u8]),
1683 Some(b"Arrow-rs" as &[u8]),
1684 Some(b"Parquet-variant" as &[u8]),
1685 ])
1686 });
1687
1688 perfectly_shredded_to_arrow_primitive_test!(
1689 get_variant_perfectly_shredded_binary_view_as_binary_view,
1690 DataType::BinaryView,
1691 perfectly_shredded_binary_view_variant_array,
1692 BinaryViewArray::from(vec![
1693 Some(b"Apache" as &[u8]),
1694 Some(b"Arrow-rs" as &[u8]),
1695 Some(b"Parquet-variant" as &[u8]),
1696 ])
1697 );
1698
1699 fn all_null_variant_array() -> ArrayRef {
1716 let nulls = NullBuffer::from(vec![
1717 false, false, false, ]);
1721
1722 let metadata =
1724 BinaryViewArray::from_iter_values(std::iter::repeat_n(EMPTY_VARIANT_METADATA_BYTES, 3));
1725
1726 ArrayRef::from(VariantArray::from_parts(metadata, None, None, Some(nulls)))
1727 }
1728 #[test]
1732 fn test_shredded_object_field_access() {
1733 let array = shredded_object_with_x_field_variant_array();
1734
1735 let options = GetOptions::new_with_path(VariantPath::try_from("x").unwrap());
1737 let result = variant_get(&array, options).unwrap();
1738
1739 let result_variant = VariantArray::try_new(&result).unwrap();
1740 assert_eq!(result_variant.len(), 2);
1741
1742 assert_eq!(result_variant.value(0), Variant::Int32(1));
1744 assert_eq!(result_variant.value(1), Variant::Int32(42));
1746 }
1747
1748 #[test]
1750 fn test_shredded_object_field_as_int32() {
1751 let array = shredded_object_with_x_field_variant_array();
1752
1753 let field = Field::new("x", DataType::Int32, false);
1755 let options = GetOptions::new_with_path(VariantPath::try_from("x").unwrap())
1756 .with_as_type(Some(FieldRef::from(field)));
1757 let result = variant_get(&array, options).unwrap();
1758
1759 let expected: ArrayRef = Arc::new(Int32Array::from(vec![Some(1), Some(42)]));
1761 assert_eq!(&result, &expected);
1762 }
1763
1764 fn shredded_object_with_x_field_variant_array() -> ArrayRef {
1776 let (metadata, y_field_value) = {
1778 let mut builder = parquet_variant::VariantBuilder::new();
1779 let mut obj = builder.new_object();
1780 obj.insert("x", Variant::Int32(42));
1781 obj.insert("y", Variant::from("foo"));
1782 obj.finish();
1783 builder.finish()
1784 };
1785
1786 let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 2));
1788
1789 let empty_object_value = {
1794 let mut builder = parquet_variant::VariantBuilder::new();
1795 let obj = builder.new_object();
1796 obj.finish();
1797 let (_, value) = builder.finish();
1798 value
1799 };
1800
1801 let value_array = BinaryViewArray::from(vec![
1802 Some(y_field_value.as_slice()), Some(empty_object_value.as_slice()), ]);
1805
1806 let x_field_typed_value = Int32Array::from(vec![Some(1), Some(42)]);
1809
1810 let x_field_shredded = ShreddedVariantFieldArray::from_parts(
1812 None,
1813 Some(Arc::new(x_field_typed_value) as ArrayRef),
1814 None,
1815 );
1816
1817 let typed_value_fields = Fields::from(vec![Field::new(
1819 "x",
1820 x_field_shredded.data_type().clone(),
1821 true,
1822 )]);
1823 let typed_value_struct = StructArray::try_new(
1824 typed_value_fields,
1825 vec![ArrayRef::from(x_field_shredded)],
1826 None, )
1828 .unwrap();
1829
1830 ArrayRef::from(VariantArray::from_parts(
1832 metadata_array,
1833 Some(value_array),
1834 Some(Arc::new(typed_value_struct)),
1835 None,
1836 ))
1837 }
1838
1839 #[test]
1841 fn test_simple_nested_path_support() {
1842 println!("Testing path parsing:");
1844
1845 let path_x = VariantPath::try_from("x").unwrap();
1846 let elements_x: Vec<_> = path_x.iter().collect();
1847 println!(" 'x' -> {} elements: {:?}", elements_x.len(), elements_x);
1848
1849 let path_ax = VariantPath::try_from("a.x").unwrap();
1850 let elements_ax: Vec<_> = path_ax.iter().collect();
1851 println!(
1852 " 'a.x' -> {} elements: {:?}",
1853 elements_ax.len(),
1854 elements_ax
1855 );
1856
1857 let path_ax_alt = VariantPath::try_from("$.a.x").unwrap();
1858 let elements_ax_alt: Vec<_> = path_ax_alt.iter().collect();
1859 println!(
1860 " '$.a.x' -> {} elements: {:?}",
1861 elements_ax_alt.len(),
1862 elements_ax_alt
1863 );
1864
1865 let path_nested = VariantPath::try_from("a").unwrap().join("x");
1866 let elements_nested: Vec<_> = path_nested.iter().collect();
1867 println!(
1868 " VariantPath::try_from('a').unwrap().join('x') -> {} elements: {:?}",
1869 elements_nested.len(),
1870 elements_nested
1871 );
1872
1873 let array = shredded_object_with_x_field_variant_array();
1875
1876 let real_nested_path = VariantPath::try_from("a").unwrap().join("x");
1878 let options = GetOptions::new_with_path(real_nested_path);
1879 let result = variant_get(&array, options);
1880
1881 match result {
1882 Ok(_) => {
1883 println!("Nested path 'a.x' works unexpectedly!");
1884 }
1885 Err(e) => {
1886 println!("Nested path 'a.x' error: {}", e);
1887 if e.to_string().contains("Not yet implemented")
1888 || e.to_string().contains("NotYetImplemented")
1889 {
1890 println!("This is expected - nested paths are not implemented");
1891 return;
1892 }
1893 println!("This shows nested paths need implementation");
1895 }
1896 }
1897 }
1898
1899 #[test]
1903 fn test_depth_0_int32_conversion() {
1904 println!("=== Testing Depth 0: Direct field access ===");
1905
1906 let unshredded_array = create_depth_0_test_data();
1908
1909 let field = Field::new("result", DataType::Int32, true);
1910 let path = VariantPath::try_from("x").unwrap();
1911 let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
1912 let result = variant_get(&unshredded_array, options).unwrap();
1913
1914 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
1915 Some(42), None, None, ]));
1919 assert_eq!(&result, &expected);
1920 println!("Depth 0 (unshredded) passed");
1921
1922 let shredded_array = create_depth_0_shredded_test_data_simple();
1924
1925 let field = Field::new("result", DataType::Int32, true);
1926 let path = VariantPath::try_from("x").unwrap();
1927 let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
1928 let result = variant_get(&shredded_array, options).unwrap();
1929
1930 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
1931 Some(42), None, ]));
1934 assert_eq!(&result, &expected);
1935 println!("Depth 0 (shredded) passed");
1936 }
1937
1938 #[test]
1941 fn test_depth_1_int32_conversion() {
1942 println!("=== Testing Depth 1: Single nested field access ===");
1943
1944 let unshredded_array = create_nested_path_test_data();
1946
1947 let field = Field::new("result", DataType::Int32, true);
1948 let path = VariantPath::try_from("a.x").unwrap(); let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
1950 let result = variant_get(&unshredded_array, options).unwrap();
1951
1952 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
1953 Some(55), None, ]));
1956 assert_eq!(&result, &expected);
1957 println!("Depth 1 (unshredded) passed");
1958
1959 let shredded_array = create_depth_1_shredded_test_data_working();
1961
1962 let field = Field::new("result", DataType::Int32, true);
1963 let path = VariantPath::try_from("a.x").unwrap(); let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
1965 let result = variant_get(&shredded_array, options).unwrap();
1966
1967 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
1968 Some(55), None, ]));
1971 assert_eq!(&result, &expected);
1972 println!("Depth 1 (shredded) passed");
1973 }
1974
1975 #[test]
1978 fn test_depth_2_int32_conversion() {
1979 println!("=== Testing Depth 2: Double nested field access ===");
1980
1981 let unshredded_array = create_depth_2_test_data();
1983
1984 let field = Field::new("result", DataType::Int32, true);
1985 let path = VariantPath::try_from("a.b.x").unwrap(); let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
1987 let result = variant_get(&unshredded_array, options).unwrap();
1988
1989 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
1990 Some(100), None, None, ]));
1994 assert_eq!(&result, &expected);
1995 println!("Depth 2 (unshredded) passed");
1996
1997 let shredded_array = create_depth_2_shredded_test_data_working();
1999
2000 let field = Field::new("result", DataType::Int32, true);
2001 let path = VariantPath::try_from("a.b.x").unwrap(); let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
2003 let result = variant_get(&shredded_array, options).unwrap();
2004
2005 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
2006 Some(100), None, None, ]));
2010 assert_eq!(&result, &expected);
2011 println!("Depth 2 (shredded) passed");
2012 }
2013
2014 #[test]
2019 fn test_current_nested_path_functionality() {
2020 let array = shredded_object_with_x_field_variant_array();
2021
2022 let single_path = VariantPath::try_from("x").unwrap();
2024 let field = Field::new("result", DataType::Int32, true);
2025 let options =
2026 GetOptions::new_with_path(single_path).with_as_type(Some(FieldRef::from(field)));
2027 let result = variant_get(&array, options).unwrap();
2028
2029 println!("Single path 'x' works - result: {:?}", result);
2030
2031 let nested_path = VariantPath::try_from("a").unwrap().join("x");
2033 let field = Field::new("result", DataType::Int32, true);
2034 let options =
2035 GetOptions::new_with_path(nested_path).with_as_type(Some(FieldRef::from(field)));
2036 let result = variant_get(&array, options).unwrap();
2037
2038 println!("Nested path 'a.x' result: {:?}", result);
2039 }
2040
2041 fn create_depth_0_test_data() -> ArrayRef {
2044 let mut builder = crate::VariantArrayBuilder::new(3);
2045
2046 {
2048 let json_str = r#"{"x": 42}"#;
2049 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2050 if let Ok(variant_array) = json_to_variant(&string_array) {
2051 builder.append_variant(variant_array.value(0));
2052 } else {
2053 builder.append_null();
2054 }
2055 }
2056
2057 {
2059 let json_str = r#"{"x": "foo"}"#;
2060 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2061 if let Ok(variant_array) = json_to_variant(&string_array) {
2062 builder.append_variant(variant_array.value(0));
2063 } else {
2064 builder.append_null();
2065 }
2066 }
2067
2068 {
2070 let json_str = r#"{"y": 10}"#;
2071 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2072 if let Ok(variant_array) = json_to_variant(&string_array) {
2073 builder.append_variant(variant_array.value(0));
2074 } else {
2075 builder.append_null();
2076 }
2077 }
2078
2079 ArrayRef::from(builder.build())
2080 }
2081
2082 fn create_nested_path_test_data() -> ArrayRef {
2085 let mut builder = crate::VariantArrayBuilder::new(2);
2086
2087 {
2089 let json_str = r#"{"a": {"x": 55}, "b": 42}"#;
2090 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2091 if let Ok(variant_array) = json_to_variant(&string_array) {
2092 builder.append_variant(variant_array.value(0));
2093 } else {
2094 builder.append_null();
2095 }
2096 }
2097
2098 {
2100 let json_str = r#"{"a": {"x": "foo"}, "b": 42}"#;
2101 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2102 if let Ok(variant_array) = json_to_variant(&string_array) {
2103 builder.append_variant(variant_array.value(0));
2104 } else {
2105 builder.append_null();
2106 }
2107 }
2108
2109 ArrayRef::from(builder.build())
2110 }
2111
2112 fn create_depth_2_test_data() -> ArrayRef {
2115 let mut builder = crate::VariantArrayBuilder::new(3);
2116
2117 {
2119 let json_str = r#"{"a": {"b": {"x": 100}}}"#;
2120 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2121 if let Ok(variant_array) = json_to_variant(&string_array) {
2122 builder.append_variant(variant_array.value(0));
2123 } else {
2124 builder.append_null();
2125 }
2126 }
2127
2128 {
2130 let json_str = r#"{"a": {"b": {"x": "bar"}}}"#;
2131 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2132 if let Ok(variant_array) = json_to_variant(&string_array) {
2133 builder.append_variant(variant_array.value(0));
2134 } else {
2135 builder.append_null();
2136 }
2137 }
2138
2139 {
2141 let json_str = r#"{"a": {"b": {"y": 200}}}"#;
2142 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2143 if let Ok(variant_array) = json_to_variant(&string_array) {
2144 builder.append_variant(variant_array.value(0));
2145 } else {
2146 builder.append_null();
2147 }
2148 }
2149
2150 ArrayRef::from(builder.build())
2151 }
2152
2153 fn create_depth_0_shredded_test_data_simple() -> ArrayRef {
2156 let (metadata, string_x_value) = {
2158 let mut builder = parquet_variant::VariantBuilder::new();
2159 let mut obj = builder.new_object();
2160 obj.insert("x", Variant::from("foo"));
2161 obj.finish();
2162 builder.finish()
2163 };
2164
2165 let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 2));
2167
2168 let empty_object_value = {
2172 let mut builder = parquet_variant::VariantBuilder::new();
2173 let obj = builder.new_object();
2174 obj.finish();
2175 let (_, value) = builder.finish();
2176 value
2177 };
2178
2179 let value_array = BinaryViewArray::from(vec![
2180 Some(empty_object_value.as_slice()), Some(string_x_value.as_slice()), ]);
2183
2184 let x_field_typed_value = Int32Array::from(vec![Some(42), None]);
2186
2187 let x_field_shredded = ShreddedVariantFieldArray::from_parts(
2189 None,
2190 Some(Arc::new(x_field_typed_value) as ArrayRef),
2191 None,
2192 );
2193
2194 let typed_value_fields = Fields::from(vec![Field::new(
2196 "x",
2197 x_field_shredded.data_type().clone(),
2198 true,
2199 )]);
2200 let typed_value_struct = StructArray::try_new(
2201 typed_value_fields,
2202 vec![ArrayRef::from(x_field_shredded)],
2203 None,
2204 )
2205 .unwrap();
2206
2207 ArrayRef::from(VariantArray::from_parts(
2209 metadata_array,
2210 Some(value_array),
2211 Some(Arc::new(typed_value_struct)),
2212 None,
2213 ))
2214 }
2215
2216 fn create_depth_1_shredded_test_data_working() -> ArrayRef {
2221 let (metadata, _) = {
2223 let mut builder = parquet_variant::VariantBuilder::new();
2225 let mut obj = builder.new_object();
2226
2227 let mut a_obj = obj.new_object("a");
2229 a_obj.insert("x", Variant::Int32(55));
2230 a_obj.finish();
2231
2232 obj.insert("b", Variant::Int32(42));
2233 obj.finish();
2234 builder.finish()
2235 };
2236
2237 let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 2));
2238
2239 let empty_object_value = {
2242 let mut builder = parquet_variant::VariantBuilder::new();
2243 let obj = builder.new_object();
2244 obj.finish();
2245 let (_, value) = builder.finish();
2246 value
2247 };
2248
2249 let row1_fallback = {
2252 let mut builder = parquet_variant::VariantBuilder::new();
2253 let mut obj = builder.new_object();
2254 obj.insert("fallback", Variant::from("data"));
2255 obj.finish();
2256 let (_, value) = builder.finish();
2257 value
2258 };
2259
2260 let value_array = BinaryViewArray::from(vec![
2261 Some(empty_object_value.as_slice()), Some(row1_fallback.as_slice()), ]);
2264
2265 let x_typed_value = Int32Array::from(vec![Some(55), None]);
2268 let x_field_shredded = ShreddedVariantFieldArray::from_parts(
2269 None,
2270 Some(Arc::new(x_typed_value) as ArrayRef),
2271 None,
2272 );
2273
2274 let a_value_data = {
2279 let mut builder = parquet_variant::VariantBuilder::new();
2280 let obj = builder.new_object();
2281 obj.finish();
2282 let (_, value) = builder.finish();
2283 value
2284 };
2285 let a_value_array = BinaryViewArray::from(vec![
2286 None, Some(a_value_data.as_slice()), ]);
2289
2290 let a_inner_fields = Fields::from(vec![Field::new(
2291 "x",
2292 x_field_shredded.data_type().clone(),
2293 true,
2294 )]);
2295 let a_inner_typed_value = Arc::new(
2296 StructArray::try_new(a_inner_fields, vec![ArrayRef::from(x_field_shredded)], None)
2297 .unwrap(),
2298 ) as ArrayRef;
2299 let a_field_shredded = ShreddedVariantFieldArray::from_parts(
2300 Some(a_value_array),
2301 Some(a_inner_typed_value),
2302 None,
2303 );
2304
2305 let typed_value_fields = Fields::from(vec![Field::new(
2307 "a",
2308 a_field_shredded.data_type().clone(),
2309 true,
2310 )]);
2311 let typed_value_struct = StructArray::try_new(
2312 typed_value_fields,
2313 vec![ArrayRef::from(a_field_shredded)],
2314 None,
2315 )
2316 .unwrap();
2317
2318 ArrayRef::from(VariantArray::from_parts(
2320 metadata_array,
2321 Some(value_array),
2322 Some(Arc::new(typed_value_struct)),
2323 None,
2324 ))
2325 }
2326
2327 fn create_depth_2_shredded_test_data_working() -> ArrayRef {
2333 let (metadata, _) = {
2335 let mut builder = parquet_variant::VariantBuilder::new();
2337 let mut obj = builder.new_object();
2338
2339 let mut a_obj = obj.new_object("a");
2341 let mut b_obj = a_obj.new_object("b");
2342 b_obj.insert("x", Variant::Int32(100));
2343 b_obj.finish();
2344 a_obj.finish();
2345
2346 obj.finish();
2347 builder.finish()
2348 };
2349
2350 let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 3));
2351
2352 let empty_object_value = {
2354 let mut builder = parquet_variant::VariantBuilder::new();
2355 let obj = builder.new_object();
2356 obj.finish();
2357 let (_, value) = builder.finish();
2358 value
2359 };
2360
2361 let value_array = BinaryViewArray::from(vec![
2363 Some(empty_object_value.as_slice()), Some(empty_object_value.as_slice()), Some(empty_object_value.as_slice()), ]);
2367
2368 let x_typed_value = Int32Array::from(vec![Some(100), None, None]);
2372 let x_field_shredded = ShreddedVariantFieldArray::from_parts(
2373 None,
2374 Some(Arc::new(x_typed_value) as ArrayRef),
2375 None,
2376 );
2377
2378 let b_value_data = {
2380 let mut builder = parquet_variant::VariantBuilder::new();
2381 let obj = builder.new_object();
2382 obj.finish();
2383 let (_, value) = builder.finish();
2384 value
2385 };
2386 let b_value_array = BinaryViewArray::from(vec![
2387 None, Some(b_value_data.as_slice()), Some(b_value_data.as_slice()), ]);
2391
2392 let b_inner_fields = Fields::from(vec![Field::new(
2393 "x",
2394 x_field_shredded.data_type().clone(),
2395 true,
2396 )]);
2397 let b_inner_typed_value = Arc::new(
2398 StructArray::try_new(b_inner_fields, vec![ArrayRef::from(x_field_shredded)], None)
2399 .unwrap(),
2400 ) as ArrayRef;
2401 let b_field_shredded = ShreddedVariantFieldArray::from_parts(
2402 Some(b_value_array),
2403 Some(b_inner_typed_value),
2404 None,
2405 );
2406
2407 let a_value_data = {
2409 let mut builder = parquet_variant::VariantBuilder::new();
2410 let obj = builder.new_object();
2411 obj.finish();
2412 let (_, value) = builder.finish();
2413 value
2414 };
2415 let a_value_array = BinaryViewArray::from(vec![
2416 None, Some(a_value_data.as_slice()), Some(a_value_data.as_slice()), ]);
2420
2421 let a_inner_fields = Fields::from(vec![Field::new(
2422 "b",
2423 b_field_shredded.data_type().clone(),
2424 true,
2425 )]);
2426 let a_inner_typed_value = Arc::new(
2427 StructArray::try_new(a_inner_fields, vec![ArrayRef::from(b_field_shredded)], None)
2428 .unwrap(),
2429 ) as ArrayRef;
2430 let a_field_shredded = ShreddedVariantFieldArray::from_parts(
2431 Some(a_value_array),
2432 Some(a_inner_typed_value),
2433 None,
2434 );
2435
2436 let typed_value_fields = Fields::from(vec![Field::new(
2438 "a",
2439 a_field_shredded.data_type().clone(),
2440 true,
2441 )]);
2442 let typed_value_struct = StructArray::try_new(
2443 typed_value_fields,
2444 vec![ArrayRef::from(a_field_shredded)],
2445 None,
2446 )
2447 .unwrap();
2448
2449 ArrayRef::from(VariantArray::from_parts(
2451 metadata_array,
2452 Some(value_array),
2453 Some(Arc::new(typed_value_struct)),
2454 None,
2455 ))
2456 }
2457
2458 #[test]
2459 fn test_strict_cast_options_downcast_failure() {
2460 use arrow::compute::CastOptions;
2461 use arrow::datatypes::{DataType, Field};
2462 use arrow::error::ArrowError;
2463 use parquet_variant::VariantPath;
2464 use std::sync::Arc;
2465
2466 let variant_array = perfectly_shredded_int32_variant_array();
2468
2469 let safe_options = GetOptions {
2471 path: VariantPath::try_from("nonexistent_field").unwrap(),
2472 as_type: Some(Arc::new(Field::new("result", DataType::Int32, true))),
2473 cast_options: CastOptions::default(), };
2475
2476 let variant_array_ref: Arc<dyn Array> = variant_array.clone();
2477 let result = variant_get(&variant_array_ref, safe_options);
2478 assert!(result.is_ok());
2480 let result_array = result.unwrap();
2481 assert_eq!(result_array.len(), 3);
2482 assert!(result_array.is_null(0));
2483 assert!(result_array.is_null(1));
2484 assert!(result_array.is_null(2));
2485
2486 let strict_options = GetOptions {
2488 path: VariantPath::try_from("nonexistent_field").unwrap(),
2489 as_type: Some(Arc::new(Field::new("result", DataType::Int32, true))),
2490 cast_options: CastOptions {
2491 safe: false,
2492 ..Default::default()
2493 },
2494 };
2495
2496 let result = variant_get(&variant_array_ref, strict_options);
2497 assert!(result.is_err());
2499 let error = result.unwrap_err();
2500 assert!(matches!(error, ArrowError::CastError(_)));
2501 assert!(
2502 error
2503 .to_string()
2504 .contains("Cannot access field 'nonexistent_field' on non-struct type")
2505 );
2506 }
2507
2508 #[test]
2509 fn test_error_message_boolean_type_display() {
2510 let mut builder = VariantArrayBuilder::new(1);
2511 builder.append_variant(Variant::from("abcd"));
2512 let variant_array: ArrayRef = ArrayRef::from(builder.build());
2513
2514 let options = GetOptions {
2516 path: VariantPath::default(),
2517 as_type: Some(Arc::new(Field::new("result", DataType::Boolean, true))),
2518 cast_options: CastOptions {
2519 safe: false,
2520 ..Default::default()
2521 },
2522 };
2523
2524 let err = variant_get(&variant_array, options).unwrap_err();
2525 let msg = err.to_string();
2526 assert!(msg.contains("Failed to extract primitive of type Boolean"));
2527 }
2528
2529 #[test]
2530 fn test_error_message_numeric_type_display() {
2531 let mut builder = VariantArrayBuilder::new(1);
2532 builder.append_variant(Variant::from("abcd"));
2533 let variant_array: ArrayRef = ArrayRef::from(builder.build());
2534
2535 let options = GetOptions {
2537 path: VariantPath::default(),
2538 as_type: Some(Arc::new(Field::new("result", DataType::Float32, true))),
2539 cast_options: CastOptions {
2540 safe: false,
2541 ..Default::default()
2542 },
2543 };
2544
2545 let err = variant_get(&variant_array, options).unwrap_err();
2546 let msg = err.to_string();
2547 assert!(msg.contains("Failed to extract primitive of type Float32"));
2548 }
2549
2550 #[test]
2551 fn test_error_message_temporal_type_display() {
2552 let mut builder = VariantArrayBuilder::new(1);
2553 builder.append_variant(Variant::BooleanFalse);
2554 let variant_array: ArrayRef = ArrayRef::from(builder.build());
2555
2556 let options = GetOptions {
2558 path: VariantPath::default(),
2559 as_type: Some(Arc::new(Field::new(
2560 "result",
2561 DataType::Timestamp(TimeUnit::Nanosecond, None),
2562 true,
2563 ))),
2564 cast_options: CastOptions {
2565 safe: false,
2566 ..Default::default()
2567 },
2568 };
2569
2570 let err = variant_get(&variant_array, options).unwrap_err();
2571 let msg = err.to_string();
2572 assert!(msg.contains("Failed to extract primitive of type Timestamp(ns)"));
2573 }
2574
2575 #[test]
2576 fn test_null_buffer_union_for_shredded_paths() {
2577 use arrow::compute::CastOptions;
2578 use arrow::datatypes::{DataType, Field};
2579 use parquet_variant::VariantPath;
2580 use std::sync::Arc;
2581
2582 let variant_array = create_depth_1_shredded_test_data_working();
2591
2592 let options = GetOptions {
2597 path: VariantPath::try_from("a.x").unwrap(),
2598 as_type: Some(Arc::new(Field::new("result", DataType::Int32, true))),
2599 cast_options: CastOptions::default(),
2600 };
2601
2602 let variant_array_ref: Arc<dyn Array> = variant_array.clone();
2603 let result = variant_get(&variant_array_ref, options).unwrap();
2604
2605 assert_eq!(result.len(), variant_array.len());
2607
2608 assert!(!result.is_null(0), "Row 0 should have valid Int32 data");
2612 assert!(
2613 result.is_null(1),
2614 "Row 1 should be null due to type casting failure"
2615 );
2616
2617 let int32_result = result.as_any().downcast_ref::<Int32Array>().unwrap();
2619 assert_eq!(int32_result.value(0), 55); }
2621
2622 #[test]
2623 fn test_struct_null_mask_union_from_children() {
2624 use arrow::compute::CastOptions;
2625 use arrow::datatypes::{DataType, Field, Fields};
2626 use parquet_variant::VariantPath;
2627 use std::sync::Arc;
2628
2629 use arrow::array::StringArray;
2630
2631 let json_strings = vec![
2636 r#"{"a": 42, "b": "hello"}"#, r#"{"a": "world", "b": 100}"#, r#"{"a": 55, "b": 77}"#, ];
2640
2641 let string_array: Arc<dyn arrow::array::Array> = Arc::new(StringArray::from(json_strings));
2642 let variant_array = json_to_variant(&string_array).unwrap();
2643
2644 let struct_fields = Fields::from(vec![
2647 Field::new("a", DataType::Int32, true),
2648 Field::new("b", DataType::Int32, true),
2649 ]);
2650 let struct_type = DataType::Struct(struct_fields);
2651
2652 let options = GetOptions {
2653 path: VariantPath::default(), as_type: Some(Arc::new(Field::new("result", struct_type, true))),
2655 cast_options: CastOptions::default(),
2656 };
2657
2658 let variant_array_ref = ArrayRef::from(variant_array);
2659 let result = variant_get(&variant_array_ref, options).unwrap();
2660
2661 let struct_result = result.as_struct();
2663 assert_eq!(struct_result.len(), 3);
2664
2665 let field_a = struct_result
2667 .column(0)
2668 .as_any()
2669 .downcast_ref::<Int32Array>()
2670 .unwrap();
2671 let field_b = struct_result
2672 .column(1)
2673 .as_any()
2674 .downcast_ref::<Int32Array>()
2675 .unwrap();
2676
2677 assert!(!field_a.is_null(0));
2680 assert_eq!(field_a.value(0), 42);
2681 assert!(field_b.is_null(0)); assert!(field_a.is_null(1)); assert!(!field_b.is_null(1));
2686 assert_eq!(field_b.value(1), 100);
2687
2688 assert!(!field_a.is_null(2));
2690 assert_eq!(field_a.value(2), 55);
2691 assert!(!field_b.is_null(2));
2692 assert_eq!(field_b.value(2), 77);
2693
2694 assert!(!struct_result.is_null(0)); assert!(!struct_result.is_null(1)); assert!(!struct_result.is_null(2)); }
2701
2702 #[test]
2703 fn test_field_nullability_preservation() {
2704 use arrow::compute::CastOptions;
2705 use arrow::datatypes::{DataType, Field};
2706 use parquet_variant::VariantPath;
2707 use std::sync::Arc;
2708
2709 use arrow::array::StringArray;
2710
2711 let json_strings = vec![
2714 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}"#, ];
2724
2725 let string_array: Arc<dyn arrow::array::Array> = Arc::new(StringArray::from(json_strings));
2726 let variant_array = json_to_variant(&string_array).unwrap();
2727
2728 let nullable_field = Arc::new(Field::new("result", DataType::Int32, true));
2730 let options_nullable = GetOptions {
2731 path: VariantPath::try_from("x").unwrap(),
2732 as_type: Some(nullable_field.clone()),
2733 cast_options: CastOptions::default(),
2734 };
2735
2736 let variant_array_ref = ArrayRef::from(variant_array);
2737 let result_nullable = variant_get(&variant_array_ref, options_nullable).unwrap();
2738
2739 let int32_result = result_nullable
2741 .as_any()
2742 .downcast_ref::<Int32Array>()
2743 .unwrap();
2744 assert_eq!(int32_result.len(), 9);
2745
2746 assert!(!int32_result.is_null(0));
2748 assert_eq!(int32_result.value(0), 42);
2749
2750 assert!(int32_result.is_null(1));
2752
2753 assert!(int32_result.is_null(2));
2755
2756 assert!(int32_result.is_null(3));
2758
2759 assert!(int32_result.is_null(4));
2761
2762 assert!(!int32_result.is_null(5));
2765 assert_eq!(int32_result.value(5), 127);
2766
2767 assert!(!int32_result.is_null(6));
2770 assert_eq!(int32_result.value(6), 32767);
2771
2772 assert!(!int32_result.is_null(7));
2775 assert_eq!(int32_result.value(7), 2147483647);
2776
2777 assert!(int32_result.is_null(8));
2780
2781 let non_nullable_field = Arc::new(Field::new("result", DataType::Int32, false));
2783 let options_non_nullable = GetOptions {
2784 path: VariantPath::try_from("x").unwrap(),
2785 as_type: Some(non_nullable_field.clone()),
2786 cast_options: CastOptions::default(), };
2788
2789 let variant_array_2 = json_to_variant(&string_array).unwrap();
2791 let variant_array_ref_2 = ArrayRef::from(variant_array_2);
2792 let result_non_nullable = variant_get(&variant_array_ref_2, options_non_nullable).unwrap();
2793 let int32_result_2 = result_non_nullable
2794 .as_any()
2795 .downcast_ref::<Int32Array>()
2796 .unwrap();
2797
2798 assert_eq!(int32_result_2.len(), 9);
2800
2801 assert!(!int32_result_2.is_null(0));
2803 assert_eq!(int32_result_2.value(0), 42);
2804
2805 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);
2815 assert!(!int32_result_2.is_null(6)); assert_eq!(int32_result_2.value(6), 32767);
2817 assert!(!int32_result_2.is_null(7)); assert_eq!(int32_result_2.value(7), 2147483647);
2819
2820 assert!(int32_result_2.is_null(8)); }
2823
2824 #[test]
2825 fn test_struct_extraction_subset_superset_schema_perfectly_shredded() {
2826 let variant_array = create_comprehensive_shredded_variant();
2828
2829 let struct_fields = Fields::from(vec![
2831 Field::new("a", DataType::Int32, true),
2832 Field::new("b", DataType::Int32, true),
2833 Field::new("d", DataType::Int32, true),
2834 ]);
2835 let struct_type = DataType::Struct(struct_fields);
2836
2837 let options = GetOptions {
2838 path: VariantPath::default(),
2839 as_type: Some(Arc::new(Field::new("result", struct_type, true))),
2840 cast_options: CastOptions::default(),
2841 };
2842
2843 let result = variant_get(&variant_array, options).unwrap();
2844
2845 let struct_result = result.as_any().downcast_ref::<StructArray>().unwrap();
2847 assert_eq!(struct_result.len(), 5);
2848 assert_eq!(struct_result.num_columns(), 3);
2849
2850 let field_a = struct_result
2851 .column(0)
2852 .as_any()
2853 .downcast_ref::<Int32Array>()
2854 .unwrap();
2855 let field_b = struct_result
2856 .column(1)
2857 .as_any()
2858 .downcast_ref::<Int32Array>()
2859 .unwrap();
2860 let field_d = struct_result
2861 .column(2)
2862 .as_any()
2863 .downcast_ref::<Int32Array>()
2864 .unwrap();
2865
2866 assert!(!struct_result.is_null(0));
2868 assert_eq!(field_a.value(0), 1);
2869 assert_eq!(field_b.value(0), 2);
2870 assert!(field_d.is_null(0)); assert!(struct_result.is_null(1));
2874
2875 assert!(!struct_result.is_null(2));
2877 assert!(field_a.is_null(2)); assert_eq!(field_b.value(2), 2);
2879 assert!(field_d.is_null(2)); assert!(!struct_result.is_null(3));
2883 assert_eq!(field_a.value(3), 1);
2884 assert!(field_b.is_null(3)); assert!(field_d.is_null(3)); assert!(!struct_result.is_null(4));
2889 assert!(field_a.is_null(4)); assert!(field_b.is_null(4)); assert!(field_d.is_null(4)); }
2893
2894 #[test]
2895 fn test_nested_struct_extraction_perfectly_shredded() {
2896 let variant_array = create_comprehensive_nested_shredded_variant();
2898 println!("variant_array: {variant_array:?}");
2899
2900 let inner_field = Field::new("inner", DataType::Int32, true);
2902 let inner_type = DataType::Struct(Fields::from(vec![inner_field]));
2903 let outer_field = Field::new("outer", inner_type, true);
2904 let result_type = DataType::Struct(Fields::from(vec![outer_field]));
2905
2906 let options = GetOptions {
2907 path: VariantPath::default(),
2908 as_type: Some(Arc::new(Field::new("result", result_type, true))),
2909 cast_options: CastOptions::default(),
2910 };
2911
2912 let result = variant_get(&variant_array, options).unwrap();
2913 println!("result: {result:?}");
2914
2915 let outer_struct = result.as_any().downcast_ref::<StructArray>().unwrap();
2917 assert_eq!(outer_struct.len(), 4);
2918 assert_eq!(outer_struct.num_columns(), 1);
2919
2920 let inner_struct = outer_struct
2922 .column(0)
2923 .as_any()
2924 .downcast_ref::<StructArray>()
2925 .unwrap();
2926 assert_eq!(inner_struct.num_columns(), 1);
2927
2928 let leaf_field = inner_struct
2930 .column(0)
2931 .as_any()
2932 .downcast_ref::<Int32Array>()
2933 .unwrap();
2934
2935 assert!(!outer_struct.is_null(0));
2937 assert!(!inner_struct.is_null(0));
2938 assert_eq!(leaf_field.value(0), 42);
2939
2940 assert!(!outer_struct.is_null(1));
2942 assert!(!inner_struct.is_null(1)); assert!(leaf_field.is_null(1)); assert!(!outer_struct.is_null(2));
2947 assert!(inner_struct.is_null(2)); assert!(outer_struct.is_null(3));
2951 }
2952
2953 #[test]
2954 fn test_path_based_null_masks_one_step() {
2955 let variant_array = create_comprehensive_nested_shredded_variant();
2957
2958 let path = VariantPath::try_from("outer").unwrap();
2960 let inner_field = Field::new("inner", DataType::Int32, true);
2961 let result_type = DataType::Struct(Fields::from(vec![inner_field]));
2962
2963 let options = GetOptions {
2964 path,
2965 as_type: Some(Arc::new(Field::new("result", result_type, true))),
2966 cast_options: CastOptions::default(),
2967 };
2968
2969 let result = variant_get(&variant_array, options).unwrap();
2970
2971 let outer_result = result.as_any().downcast_ref::<StructArray>().unwrap();
2973 assert_eq!(outer_result.len(), 4);
2974 assert_eq!(outer_result.num_columns(), 1);
2975
2976 let inner_field = outer_result
2978 .column(0)
2979 .as_any()
2980 .downcast_ref::<Int32Array>()
2981 .unwrap();
2982
2983 assert!(!outer_result.is_null(0));
2985 assert_eq!(inner_field.value(0), 42);
2986
2987 assert!(!outer_result.is_null(1));
2989 assert!(inner_field.is_null(1));
2990
2991 assert!(outer_result.is_null(2));
2993
2994 assert!(outer_result.is_null(3));
2996 }
2997
2998 #[test]
2999 fn test_path_based_null_masks_two_steps() {
3000 let variant_array = create_comprehensive_nested_shredded_variant();
3002
3003 let path = VariantPath::try_from("outer").unwrap().join("inner");
3005
3006 let options = GetOptions {
3007 path,
3008 as_type: Some(Arc::new(Field::new("result", DataType::Int32, true))),
3009 cast_options: CastOptions::default(),
3010 };
3011
3012 let result = variant_get(&variant_array, options).unwrap();
3013
3014 let int_result = result.as_any().downcast_ref::<Int32Array>().unwrap();
3016 assert_eq!(int_result.len(), 4);
3017
3018 assert!(!int_result.is_null(0));
3020 assert_eq!(int_result.value(0), 42);
3021
3022 assert!(int_result.is_null(1));
3024
3025 assert!(int_result.is_null(2));
3027
3028 assert!(int_result.is_null(3));
3030 }
3031
3032 #[test]
3033 fn test_struct_extraction_mixed_and_unshredded() {
3034 let variant_array = create_mixed_and_unshredded_variant();
3036
3037 let struct_fields = Fields::from(vec![
3039 Field::new("x", DataType::Int32, true),
3040 Field::new("y", DataType::Int32, true),
3041 ]);
3042 let struct_type = DataType::Struct(struct_fields);
3043
3044 let options = GetOptions {
3045 path: VariantPath::default(),
3046 as_type: Some(Arc::new(Field::new("result", struct_type, true))),
3047 cast_options: CastOptions::default(),
3048 };
3049
3050 let result = variant_get(&variant_array, options).unwrap();
3051
3052 let struct_result = result.as_any().downcast_ref::<StructArray>().unwrap();
3054 assert_eq!(struct_result.len(), 4);
3055 assert_eq!(struct_result.num_columns(), 2);
3056
3057 let field_x = struct_result
3058 .column(0)
3059 .as_any()
3060 .downcast_ref::<Int32Array>()
3061 .unwrap();
3062 let field_y = struct_result
3063 .column(1)
3064 .as_any()
3065 .downcast_ref::<Int32Array>()
3066 .unwrap();
3067
3068 assert_eq!(field_x.value(0), 1);
3070 assert_eq!(field_y.value(0), 42);
3071
3072 assert_eq!(field_x.value(1), 2);
3074 assert!(field_y.is_null(1));
3075
3076 assert_eq!(field_x.value(2), 3);
3078 assert!(field_y.is_null(2));
3079
3080 assert!(struct_result.is_null(3));
3082 }
3083
3084 #[test]
3085 fn test_struct_row_builder_handles_unshredded_nested_structs() {
3086 let json_strings = vec![
3088 r#"{"outer": {"inner": 42}}"#,
3089 r#"{"outer": {"inner": 100}}"#,
3090 ];
3091 let string_array: Arc<dyn Array> = Arc::new(StringArray::from(json_strings));
3092 let variant_array = json_to_variant(&string_array).unwrap();
3093
3094 let inner_fields = Fields::from(vec![Field::new("inner", DataType::Int32, true)]);
3096 let inner_struct_type = DataType::Struct(inner_fields);
3097 let outer_fields = Fields::from(vec![Field::new("outer", inner_struct_type, true)]);
3098 let outer_struct_type = DataType::Struct(outer_fields);
3099
3100 let options = GetOptions {
3101 path: VariantPath::default(),
3102 as_type: Some(Arc::new(Field::new("result", outer_struct_type, true))),
3103 cast_options: CastOptions::default(),
3104 };
3105
3106 let variant_array_ref = ArrayRef::from(variant_array);
3107 let result = variant_get(&variant_array_ref, options).unwrap();
3108
3109 let outer_struct = result.as_struct();
3110 assert_eq!(outer_struct.len(), 2);
3111 assert_eq!(outer_struct.num_columns(), 1);
3112
3113 let inner_struct = outer_struct.column(0).as_struct();
3114 assert_eq!(inner_struct.num_columns(), 1);
3115
3116 let inner_values = inner_struct
3117 .column(0)
3118 .as_any()
3119 .downcast_ref::<Int32Array>()
3120 .unwrap();
3121 assert_eq!(inner_values.value(0), 42);
3122 assert_eq!(inner_values.value(1), 100);
3123 }
3124
3125 #[test]
3126 fn test_unshredded_struct_safe_cast_non_object_rows_are_null() {
3127 let json_strings = vec![r#"{"a": 1, "b": 2}"#, "123", "{}"];
3128 let string_array: Arc<dyn Array> = Arc::new(StringArray::from(json_strings));
3129 let variant_array_ref = ArrayRef::from(json_to_variant(&string_array).unwrap());
3130
3131 let struct_fields = Fields::from(vec![
3132 Field::new("a", DataType::Int32, true),
3133 Field::new("b", DataType::Int32, true),
3134 ]);
3135 let options = GetOptions {
3136 path: VariantPath::default(),
3137 as_type: Some(Arc::new(Field::new(
3138 "result",
3139 DataType::Struct(struct_fields),
3140 true,
3141 ))),
3142 cast_options: CastOptions::default(),
3143 };
3144
3145 let result = variant_get(&variant_array_ref, options).unwrap();
3146 let struct_result = result.as_struct();
3147 let field_a = struct_result
3148 .column(0)
3149 .as_primitive::<arrow::datatypes::Int32Type>();
3150 let field_b = struct_result
3151 .column(1)
3152 .as_primitive::<arrow::datatypes::Int32Type>();
3153
3154 assert!(!struct_result.is_null(0));
3156 assert_eq!(field_a.value(0), 1);
3157 assert_eq!(field_b.value(0), 2);
3158
3159 assert!(struct_result.is_null(1));
3161 assert!(field_a.is_null(1));
3162 assert!(field_b.is_null(1));
3163
3164 assert!(!struct_result.is_null(2));
3166 assert!(field_a.is_null(2));
3167 assert!(field_b.is_null(2));
3168 }
3169
3170 #[test]
3171 fn test_unshredded_struct_strict_cast_non_object_errors() {
3172 let json_strings = vec![r#"{"a": 1, "b": 2}"#, "123"];
3173 let string_array: Arc<dyn Array> = Arc::new(StringArray::from(json_strings));
3174 let variant_array_ref = ArrayRef::from(json_to_variant(&string_array).unwrap());
3175
3176 let struct_fields = Fields::from(vec![
3177 Field::new("a", DataType::Int32, true),
3178 Field::new("b", DataType::Int32, true),
3179 ]);
3180 let options = GetOptions {
3181 path: VariantPath::default(),
3182 as_type: Some(Arc::new(Field::new(
3183 "result",
3184 DataType::Struct(struct_fields),
3185 true,
3186 ))),
3187 cast_options: CastOptions {
3188 safe: false,
3189 ..Default::default()
3190 },
3191 };
3192
3193 let err = variant_get(&variant_array_ref, options).unwrap_err();
3194 assert!(
3195 err.to_string()
3196 .contains("Failed to extract struct from variant")
3197 );
3198 }
3199
3200 fn create_comprehensive_shredded_variant() -> ArrayRef {
3203 let (metadata, _) = {
3204 let mut builder = parquet_variant::VariantBuilder::new();
3205 let obj = builder.new_object();
3206 obj.finish();
3207 builder.finish()
3208 };
3209
3210 let nulls = NullBuffer::from(vec![
3212 true, false, true, true, true, ]);
3218
3219 let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 5));
3220
3221 let a_field_typed_value = Int32Array::from(vec![Some(1), None, None, Some(1), None]);
3224 let a_field_shredded = ShreddedVariantFieldArray::from_parts(
3225 None,
3226 Some(Arc::new(a_field_typed_value) as ArrayRef),
3227 None,
3228 );
3229
3230 let b_field_typed_value = Int32Array::from(vec![Some(2), None, Some(2), None, None]);
3232 let b_field_shredded = ShreddedVariantFieldArray::from_parts(
3233 None,
3234 Some(Arc::new(b_field_typed_value) as ArrayRef),
3235 None,
3236 );
3237
3238 let c_field_typed_value = Int32Array::from(vec![Some(3), None, None, None, None]);
3240 let c_field_shredded = ShreddedVariantFieldArray::from_parts(
3241 None,
3242 Some(Arc::new(c_field_typed_value) as ArrayRef),
3243 None,
3244 );
3245
3246 let typed_value_fields = Fields::from(vec![
3248 Field::new("a", a_field_shredded.data_type().clone(), true),
3249 Field::new("b", b_field_shredded.data_type().clone(), true),
3250 Field::new("c", c_field_shredded.data_type().clone(), true),
3251 ]);
3252 let typed_value_struct = StructArray::try_new(
3253 typed_value_fields,
3254 vec![
3255 ArrayRef::from(a_field_shredded),
3256 ArrayRef::from(b_field_shredded),
3257 ArrayRef::from(c_field_shredded),
3258 ],
3259 None,
3260 )
3261 .unwrap();
3262
3263 ArrayRef::from(VariantArray::from_parts(
3265 metadata_array,
3266 None,
3267 Some(Arc::new(typed_value_struct)),
3268 Some(nulls),
3269 ))
3270 }
3271
3272 fn create_comprehensive_nested_shredded_variant() -> ArrayRef {
3277 let inner_typed_value = Int32Array::from(vec![Some(42), None, None, None]); let inner = ShreddedVariantFieldArray::from_parts(
3281 None,
3282 Some(Arc::new(inner_typed_value) as ArrayRef),
3283 None,
3284 );
3285
3286 let outer_typed_value_nulls = NullBuffer::from(vec![
3287 true, false, false, false, ]);
3292 let outer_typed_value = StructArrayBuilder::new()
3293 .with_field("inner", ArrayRef::from(inner), false)
3294 .with_nulls(outer_typed_value_nulls)
3295 .build();
3296
3297 let outer = ShreddedVariantFieldArray::from_parts(
3298 None,
3299 Some(Arc::new(outer_typed_value) as ArrayRef),
3300 None,
3301 );
3302
3303 let typed_value_nulls = NullBuffer::from(vec![
3304 true, true, false, false, ]);
3309 let typed_value = StructArrayBuilder::new()
3310 .with_field("outer", ArrayRef::from(outer), false)
3311 .with_nulls(typed_value_nulls)
3312 .build();
3313
3314 let metadata_array =
3316 BinaryViewArray::from_iter_values(std::iter::repeat_n(EMPTY_VARIANT_METADATA_BYTES, 4));
3317 let nulls = NullBuffer::from(vec![
3318 true, true, true, false, ]);
3323 ArrayRef::from(VariantArray::from_parts(
3324 metadata_array,
3325 None,
3326 Some(Arc::new(typed_value)),
3327 Some(nulls),
3328 ))
3329 }
3330
3331 fn create_mixed_and_unshredded_variant() -> ArrayRef {
3334 let (metadata, y_field_value) = {
3339 let mut builder = parquet_variant::VariantBuilder::new();
3340 let mut obj = builder.new_object();
3341 obj.insert("y", Variant::from(42));
3342 obj.finish();
3343 builder.finish()
3344 };
3345
3346 let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 4));
3347
3348 let empty_object_value = {
3355 let mut builder = parquet_variant::VariantBuilder::new();
3356 builder.new_object().finish();
3357 let (_, value) = builder.finish();
3358 value
3359 };
3360
3361 let y_null_value = {
3362 let mut builder = parquet_variant::VariantBuilder::new();
3363 builder.new_object().with_field("y", Variant::Null).finish();
3364 let (_, value) = builder.finish();
3365 value
3366 };
3367
3368 let value_array = BinaryViewArray::from(vec![
3369 Some(y_field_value.as_slice()), Some(empty_object_value.as_slice()), Some(y_null_value.as_slice()), Some(empty_object_value.as_slice()), ]);
3374
3375 let x_field_typed_value = Int32Array::from(vec![Some(1), Some(2), Some(3), Some(0)]);
3378 let x_field_shredded = ShreddedVariantFieldArray::from_parts(
3379 None,
3380 Some(Arc::new(x_field_typed_value) as ArrayRef),
3381 None,
3382 );
3383
3384 let typed_value_struct = StructArrayBuilder::new()
3386 .with_field("x", ArrayRef::from(x_field_shredded), false)
3387 .build();
3388
3389 let variant_nulls = NullBuffer::from(vec![true, true, true, false]); ArrayRef::from(VariantArray::from_parts(
3393 metadata_array,
3394 Some(value_array),
3395 Some(Arc::new(typed_value_struct)),
3396 Some(variant_nulls),
3397 ))
3398 }
3399
3400 #[test]
3401 fn get_decimal32_rescaled_to_scale2() {
3402 let mut builder = crate::VariantArrayBuilder::new(5);
3404 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();
3408 builder.append_variant(
3409 VariantDecimal8::try_new((VariantDecimal4::MAX_UNSCALED_VALUE as i64) + 1, 3)
3410 .unwrap()
3411 .into(),
3412 ); let variant_array: ArrayRef = ArrayRef::from(builder.build());
3414
3415 let field = Field::new("result", DataType::Decimal32(9, 2), true);
3416 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3417 let result = variant_get(&variant_array, options).unwrap();
3418 let result = result.as_any().downcast_ref::<Decimal32Array>().unwrap();
3419
3420 assert_eq!(result.precision(), 9);
3421 assert_eq!(result.scale(), 2);
3422 assert_eq!(result.value(0), 1234);
3423 assert_eq!(result.value(1), 123);
3424 assert_eq!(result.value(2), 123400);
3425 assert!(result.is_null(3));
3426 assert_eq!(
3427 result.value(4),
3428 VariantDecimal4::MAX_UNSCALED_VALUE / 10 + 1
3429 ); }
3431
3432 #[test]
3433 fn get_decimal32_scale_down_rounding() {
3434 let mut builder = crate::VariantArrayBuilder::new(7);
3435 builder.append_variant(VariantDecimal4::try_new(1235, 0).unwrap().into());
3436 builder.append_variant(VariantDecimal4::try_new(1245, 0).unwrap().into());
3437 builder.append_variant(VariantDecimal4::try_new(-1235, 0).unwrap().into());
3438 builder.append_variant(VariantDecimal4::try_new(-1245, 0).unwrap().into());
3439 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());
3443
3444 let field = Field::new("result", DataType::Decimal32(9, -1), true);
3445 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3446 let result = variant_get(&variant_array, options).unwrap();
3447 let result = result.as_any().downcast_ref::<Decimal32Array>().unwrap();
3448
3449 assert_eq!(result.precision(), 9);
3450 assert_eq!(result.scale(), -1);
3451 assert_eq!(result.value(0), 124);
3452 assert_eq!(result.value(1), 125);
3453 assert_eq!(result.value(2), -124);
3454 assert_eq!(result.value(3), -125);
3455 assert_eq!(result.value(4), 1);
3456 assert!(result.is_valid(5));
3457 assert_eq!(result.value(5), 0);
3458 assert_eq!(result.value(6), 1);
3459 }
3460
3461 #[test]
3462 fn get_decimal32_large_scale_reduction() {
3463 let mut builder = crate::VariantArrayBuilder::new(2);
3464 builder.append_variant(
3465 VariantDecimal4::try_new(-VariantDecimal4::MAX_UNSCALED_VALUE, 0)
3466 .unwrap()
3467 .into(),
3468 );
3469 builder.append_variant(
3470 VariantDecimal4::try_new(VariantDecimal4::MAX_UNSCALED_VALUE, 0)
3471 .unwrap()
3472 .into(),
3473 );
3474 let variant_array: ArrayRef = ArrayRef::from(builder.build());
3475
3476 let field = Field::new("result", DataType::Decimal32(9, -9), true);
3477 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3478 let result = variant_get(&variant_array, options).unwrap();
3479 let result = result.as_any().downcast_ref::<Decimal32Array>().unwrap();
3480
3481 assert_eq!(result.precision(), 9);
3482 assert_eq!(result.scale(), -9);
3483 assert_eq!(result.value(0), -1);
3484 assert_eq!(result.value(1), 1);
3485
3486 let field = Field::new("result", DataType::Decimal32(9, -10), true);
3487 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3488 let result = variant_get(&variant_array, options).unwrap();
3489 let result = result.as_any().downcast_ref::<Decimal32Array>().unwrap();
3490
3491 assert_eq!(result.precision(), 9);
3492 assert_eq!(result.scale(), -10);
3493 assert!(result.is_valid(0));
3494 assert_eq!(result.value(0), 0);
3495 assert!(result.is_valid(1));
3496 assert_eq!(result.value(1), 0);
3497 }
3498
3499 #[test]
3500 fn get_decimal32_precision_overflow_safe() {
3501 let mut builder = crate::VariantArrayBuilder::new(2);
3503 builder.append_variant(
3504 VariantDecimal4::try_new(VariantDecimal4::MAX_UNSCALED_VALUE, 0)
3505 .unwrap()
3506 .into(),
3507 );
3508 builder.append_variant(
3509 VariantDecimal4::try_new(VariantDecimal4::MAX_UNSCALED_VALUE, 9)
3510 .unwrap()
3511 .into(),
3512 ); let variant_array: ArrayRef = ArrayRef::from(builder.build());
3514
3515 let field = Field::new("result", DataType::Decimal32(2, 2), true);
3516 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3517 let result = variant_get(&variant_array, options).unwrap();
3518 let result = result.as_any().downcast_ref::<Decimal32Array>().unwrap();
3519
3520 assert!(result.is_null(0));
3521 assert!(result.is_null(1)); }
3523
3524 #[test]
3525 fn get_decimal32_precision_overflow_unsafe_errors() {
3526 let mut builder = crate::VariantArrayBuilder::new(1);
3527 builder.append_variant(
3528 VariantDecimal4::try_new(VariantDecimal4::MAX_UNSCALED_VALUE, 0)
3529 .unwrap()
3530 .into(),
3531 );
3532 let variant_array: ArrayRef = ArrayRef::from(builder.build());
3533
3534 let field = Field::new("result", DataType::Decimal32(9, 2), true);
3535 let cast_options = CastOptions {
3536 safe: false,
3537 ..Default::default()
3538 };
3539 let options = GetOptions::new()
3540 .with_as_type(Some(FieldRef::from(field)))
3541 .with_cast_options(cast_options);
3542 let err = variant_get(&variant_array, options).unwrap_err();
3543
3544 assert!(
3545 err.to_string().contains(
3546 "Failed to cast to Decimal32(precision=9, scale=2) from variant Decimal4"
3547 )
3548 );
3549 }
3550
3551 #[test]
3552 fn get_decimal64_rescaled_to_scale2() {
3553 let mut builder = crate::VariantArrayBuilder::new(5);
3554 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();
3558 builder.append_variant(
3559 VariantDecimal16::try_new((VariantDecimal8::MAX_UNSCALED_VALUE as i128) + 1, 3)
3560 .unwrap()
3561 .into(),
3562 ); let variant_array: ArrayRef = ArrayRef::from(builder.build());
3564
3565 let field = Field::new("result", DataType::Decimal64(18, 2), true);
3566 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3567 let result = variant_get(&variant_array, options).unwrap();
3568 let result = result.as_any().downcast_ref::<Decimal64Array>().unwrap();
3569
3570 assert_eq!(result.precision(), 18);
3571 assert_eq!(result.scale(), 2);
3572 assert_eq!(result.value(0), 1234);
3573 assert_eq!(result.value(1), 123);
3574 assert_eq!(result.value(2), 123400);
3575 assert!(result.is_null(3));
3576 assert_eq!(
3577 result.value(4),
3578 VariantDecimal8::MAX_UNSCALED_VALUE / 10 + 1
3579 ); }
3581
3582 #[test]
3583 fn get_decimal64_scale_down_rounding() {
3584 let mut builder = crate::VariantArrayBuilder::new(7);
3585 builder.append_variant(VariantDecimal8::try_new(1235, 0).unwrap().into());
3586 builder.append_variant(VariantDecimal8::try_new(1245, 0).unwrap().into());
3587 builder.append_variant(VariantDecimal8::try_new(-1235, 0).unwrap().into());
3588 builder.append_variant(VariantDecimal8::try_new(-1245, 0).unwrap().into());
3589 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());
3593
3594 let field = Field::new("result", DataType::Decimal64(18, -1), true);
3595 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3596 let result = variant_get(&variant_array, options).unwrap();
3597 let result = result.as_any().downcast_ref::<Decimal64Array>().unwrap();
3598
3599 assert_eq!(result.precision(), 18);
3600 assert_eq!(result.scale(), -1);
3601 assert_eq!(result.value(0), 124);
3602 assert_eq!(result.value(1), 125);
3603 assert_eq!(result.value(2), -124);
3604 assert_eq!(result.value(3), -125);
3605 assert_eq!(result.value(4), 1);
3606 assert!(result.is_valid(5));
3607 assert_eq!(result.value(5), 0);
3608 assert_eq!(result.value(6), 1);
3609 }
3610
3611 #[test]
3612 fn get_decimal64_large_scale_reduction() {
3613 let mut builder = crate::VariantArrayBuilder::new(2);
3614 builder.append_variant(
3615 VariantDecimal8::try_new(-VariantDecimal8::MAX_UNSCALED_VALUE, 0)
3616 .unwrap()
3617 .into(),
3618 );
3619 builder.append_variant(
3620 VariantDecimal8::try_new(VariantDecimal8::MAX_UNSCALED_VALUE, 0)
3621 .unwrap()
3622 .into(),
3623 );
3624 let variant_array: ArrayRef = ArrayRef::from(builder.build());
3625
3626 let field = Field::new("result", DataType::Decimal64(18, -18), true);
3627 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3628 let result = variant_get(&variant_array, options).unwrap();
3629 let result = result.as_any().downcast_ref::<Decimal64Array>().unwrap();
3630
3631 assert_eq!(result.precision(), 18);
3632 assert_eq!(result.scale(), -18);
3633 assert_eq!(result.value(0), -1);
3634 assert_eq!(result.value(1), 1);
3635
3636 let field = Field::new("result", DataType::Decimal64(18, -19), true);
3637 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3638 let result = variant_get(&variant_array, options).unwrap();
3639 let result = result.as_any().downcast_ref::<Decimal64Array>().unwrap();
3640
3641 assert_eq!(result.precision(), 18);
3642 assert_eq!(result.scale(), -19);
3643 assert!(result.is_valid(0));
3644 assert_eq!(result.value(0), 0);
3645 assert!(result.is_valid(1));
3646 assert_eq!(result.value(1), 0);
3647 }
3648
3649 #[test]
3650 fn get_decimal64_precision_overflow_safe() {
3651 let mut builder = crate::VariantArrayBuilder::new(2);
3653 builder.append_variant(
3654 VariantDecimal8::try_new(VariantDecimal8::MAX_UNSCALED_VALUE, 0)
3655 .unwrap()
3656 .into(),
3657 );
3658 builder.append_variant(
3659 VariantDecimal8::try_new(VariantDecimal8::MAX_UNSCALED_VALUE, 18)
3660 .unwrap()
3661 .into(),
3662 ); let variant_array: ArrayRef = ArrayRef::from(builder.build());
3664
3665 let field = Field::new("result", DataType::Decimal64(2, 2), true);
3666 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3667 let result = variant_get(&variant_array, options).unwrap();
3668 let result = result.as_any().downcast_ref::<Decimal64Array>().unwrap();
3669
3670 assert!(result.is_null(0));
3671 assert!(result.is_null(1));
3672 }
3673
3674 #[test]
3675 fn get_decimal64_precision_overflow_unsafe_errors() {
3676 let mut builder = crate::VariantArrayBuilder::new(1);
3677 builder.append_variant(
3678 VariantDecimal8::try_new(VariantDecimal8::MAX_UNSCALED_VALUE, 0)
3679 .unwrap()
3680 .into(),
3681 );
3682 let variant_array: ArrayRef = ArrayRef::from(builder.build());
3683
3684 let field = Field::new("result", DataType::Decimal64(18, 2), true);
3685 let cast_options = CastOptions {
3686 safe: false,
3687 ..Default::default()
3688 };
3689 let options = GetOptions::new()
3690 .with_as_type(Some(FieldRef::from(field)))
3691 .with_cast_options(cast_options);
3692 let err = variant_get(&variant_array, options).unwrap_err();
3693
3694 assert!(
3695 err.to_string().contains(
3696 "Failed to cast to Decimal64(precision=18, scale=2) from variant Decimal8"
3697 )
3698 );
3699 }
3700
3701 #[test]
3702 fn get_decimal128_rescaled_to_scale2() {
3703 let mut builder = crate::VariantArrayBuilder::new(4);
3704 builder.append_variant(VariantDecimal16::try_new(1234, 2).unwrap().into());
3705 builder.append_variant(VariantDecimal16::try_new(1234, 3).unwrap().into());
3706 builder.append_variant(VariantDecimal16::try_new(1234, 0).unwrap().into());
3707 builder.append_null();
3708 let variant_array: ArrayRef = ArrayRef::from(builder.build());
3709
3710 let field = Field::new("result", DataType::Decimal128(38, 2), true);
3711 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3712 let result = variant_get(&variant_array, options).unwrap();
3713 let result = result.as_any().downcast_ref::<Decimal128Array>().unwrap();
3714
3715 assert_eq!(result.precision(), 38);
3716 assert_eq!(result.scale(), 2);
3717 assert_eq!(result.value(0), 1234);
3718 assert_eq!(result.value(1), 123);
3719 assert_eq!(result.value(2), 123400);
3720 assert!(result.is_null(3));
3721 }
3722
3723 #[test]
3724 fn get_decimal128_scale_down_rounding() {
3725 let mut builder = crate::VariantArrayBuilder::new(7);
3726 builder.append_variant(VariantDecimal16::try_new(1235, 0).unwrap().into());
3727 builder.append_variant(VariantDecimal16::try_new(1245, 0).unwrap().into());
3728 builder.append_variant(VariantDecimal16::try_new(-1235, 0).unwrap().into());
3729 builder.append_variant(VariantDecimal16::try_new(-1245, 0).unwrap().into());
3730 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());
3734
3735 let field = Field::new("result", DataType::Decimal128(38, -1), true);
3736 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3737 let result = variant_get(&variant_array, options).unwrap();
3738 let result = result.as_any().downcast_ref::<Decimal128Array>().unwrap();
3739
3740 assert_eq!(result.precision(), 38);
3741 assert_eq!(result.scale(), -1);
3742 assert_eq!(result.value(0), 124);
3743 assert_eq!(result.value(1), 125);
3744 assert_eq!(result.value(2), -124);
3745 assert_eq!(result.value(3), -125);
3746 assert_eq!(result.value(4), 1);
3747 assert!(result.is_valid(5));
3748 assert_eq!(result.value(5), 0);
3749 assert_eq!(result.value(6), 1);
3750 }
3751
3752 #[test]
3753 fn get_decimal128_precision_overflow_safe() {
3754 let mut builder = crate::VariantArrayBuilder::new(2);
3756 builder.append_variant(
3757 VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 0)
3758 .unwrap()
3759 .into(),
3760 );
3761 builder.append_variant(
3762 VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 38)
3763 .unwrap()
3764 .into(),
3765 ); let variant_array: ArrayRef = ArrayRef::from(builder.build());
3767
3768 let field = Field::new("result", DataType::Decimal128(2, 2), true);
3769 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3770 let result = variant_get(&variant_array, options).unwrap();
3771 let result = result.as_any().downcast_ref::<Decimal128Array>().unwrap();
3772
3773 assert!(result.is_null(0));
3774 assert!(result.is_null(1)); }
3776
3777 #[test]
3778 fn get_decimal128_precision_overflow_unsafe_errors() {
3779 let mut builder = crate::VariantArrayBuilder::new(1);
3780 builder.append_variant(
3781 VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 0)
3782 .unwrap()
3783 .into(),
3784 );
3785 let variant_array: ArrayRef = ArrayRef::from(builder.build());
3786
3787 let field = Field::new("result", DataType::Decimal128(38, 2), true);
3788 let cast_options = CastOptions {
3789 safe: false,
3790 ..Default::default()
3791 };
3792 let options = GetOptions::new()
3793 .with_as_type(Some(FieldRef::from(field)))
3794 .with_cast_options(cast_options);
3795 let err = variant_get(&variant_array, options).unwrap_err();
3796
3797 assert!(err.to_string().contains(
3798 "Failed to cast to Decimal128(precision=38, scale=2) from variant Decimal16"
3799 ));
3800 }
3801
3802 #[test]
3803 fn get_decimal256_rescaled_to_scale2() {
3804 let mut builder = crate::VariantArrayBuilder::new(4);
3806 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();
3810 let variant_array: ArrayRef = ArrayRef::from(builder.build());
3811
3812 let field = Field::new("result", DataType::Decimal256(76, 2), true);
3813 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3814 let result = variant_get(&variant_array, options).unwrap();
3815 let result = result.as_any().downcast_ref::<Decimal256Array>().unwrap();
3816
3817 assert_eq!(result.precision(), 76);
3818 assert_eq!(result.scale(), 2);
3819 assert_eq!(result.value(0), i256::from_i128(1234));
3820 assert_eq!(result.value(1), i256::from_i128(123));
3821 assert_eq!(result.value(2), i256::from_i128(123400));
3822 assert!(result.is_null(3));
3823 }
3824
3825 #[test]
3826 fn get_decimal256_scale_down_rounding() {
3827 let mut builder = crate::VariantArrayBuilder::new(7);
3828 builder.append_variant(VariantDecimal16::try_new(1235, 0).unwrap().into());
3829 builder.append_variant(VariantDecimal16::try_new(1245, 0).unwrap().into());
3830 builder.append_variant(VariantDecimal16::try_new(-1235, 0).unwrap().into());
3831 builder.append_variant(VariantDecimal16::try_new(-1245, 0).unwrap().into());
3832 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());
3836
3837 let field = Field::new("result", DataType::Decimal256(76, -1), true);
3838 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3839 let result = variant_get(&variant_array, options).unwrap();
3840 let result = result.as_any().downcast_ref::<Decimal256Array>().unwrap();
3841
3842 assert_eq!(result.precision(), 76);
3843 assert_eq!(result.scale(), -1);
3844 assert_eq!(result.value(0), i256::from_i128(124));
3845 assert_eq!(result.value(1), i256::from_i128(125));
3846 assert_eq!(result.value(2), i256::from_i128(-124));
3847 assert_eq!(result.value(3), i256::from_i128(-125));
3848 assert_eq!(result.value(4), i256::from_i128(1));
3849 assert!(result.is_valid(5));
3850 assert_eq!(result.value(5), i256::from_i128(0));
3851 assert_eq!(result.value(6), i256::from_i128(1));
3852 }
3853
3854 #[test]
3855 fn get_decimal256_precision_overflow_safe() {
3856 let mut builder = crate::VariantArrayBuilder::new(2);
3858 builder.append_variant(
3859 VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 1)
3860 .unwrap()
3861 .into(),
3862 );
3863 builder.append_variant(
3864 VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 0)
3865 .unwrap()
3866 .into(),
3867 );
3868 let variant_array: ArrayRef = ArrayRef::from(builder.build());
3869
3870 let field = Field::new("result", DataType::Decimal256(76, 39), true);
3871 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3872 let result = variant_get(&variant_array, options).unwrap();
3873 let result = result.as_any().downcast_ref::<Decimal256Array>().unwrap();
3874
3875 let base = i256::from_i128(10);
3878 let factor = base.checked_pow(38).unwrap();
3879 let expected = i256::from_i128(VariantDecimal16::MAX_UNSCALED_VALUE)
3880 .checked_mul(factor)
3881 .unwrap();
3882 assert_eq!(result.value(0), expected);
3883 assert!(result.is_null(1));
3884 }
3885
3886 #[test]
3887 fn get_decimal256_precision_overflow_unsafe_errors() {
3888 let mut builder = crate::VariantArrayBuilder::new(2);
3890 builder.append_variant(
3891 VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 1)
3892 .unwrap()
3893 .into(),
3894 );
3895 builder.append_variant(
3896 VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 0)
3897 .unwrap()
3898 .into(),
3899 );
3900 let variant_array: ArrayRef = ArrayRef::from(builder.build());
3901
3902 let field = Field::new("result", DataType::Decimal256(76, 39), true);
3903 let cast_options = CastOptions {
3904 safe: false,
3905 ..Default::default()
3906 };
3907 let options = GetOptions::new()
3908 .with_as_type(Some(FieldRef::from(field)))
3909 .with_cast_options(cast_options);
3910 let err = variant_get(&variant_array, options).unwrap_err();
3911
3912 assert!(err.to_string().contains(
3913 "Failed to cast to Decimal256(precision=76, scale=39) from variant Decimal16"
3914 ));
3915 }
3916
3917 #[test]
3918 fn get_non_supported_temporal_types_error() {
3919 let values = vec![None, Some(Variant::Null), Some(Variant::BooleanFalse)];
3920 let variant_array: ArrayRef = ArrayRef::from(VariantArray::from_iter(values));
3921
3922 let test_cases = vec![
3923 FieldRef::from(Field::new(
3924 "result",
3925 DataType::Duration(TimeUnit::Microsecond),
3926 true,
3927 )),
3928 FieldRef::from(Field::new(
3929 "result",
3930 DataType::Interval(IntervalUnit::YearMonth),
3931 true,
3932 )),
3933 ];
3934
3935 for field in test_cases {
3936 let options = GetOptions::new().with_as_type(Some(field));
3937 let err = variant_get(&variant_array, options).unwrap_err();
3938 assert!(
3939 err.to_string()
3940 .contains("Casting Variant to duration/interval types is not supported")
3941 );
3942 }
3943 }
3944
3945 fn invalid_time_variant_array() -> ArrayRef {
3946 let mut builder = VariantArrayBuilder::new(3);
3947 builder.append_variant(Variant::Int64(86401000000));
3949 builder.append_variant(Variant::Int64(86401000000));
3950 builder.append_variant(Variant::Int64(86401000000));
3951 Arc::new(builder.build().into_inner())
3952 }
3953
3954 #[test]
3955 fn test_variant_get_error_when_cast_failure_and_safe_false() {
3956 let variant_array = invalid_time_variant_array();
3957
3958 let field = Field::new("result", DataType::Time64(TimeUnit::Microsecond), true);
3959 let cast_options = CastOptions {
3960 safe: false, ..Default::default()
3962 };
3963 let options = GetOptions::new()
3964 .with_as_type(Some(FieldRef::from(field)))
3965 .with_cast_options(cast_options);
3966 let err = variant_get(&variant_array, options).unwrap_err();
3967 assert!(
3968 err.to_string().contains(
3969 "Cast error: Failed to extract primitive of type Time64(µs) from variant Int64(86401000000) at path VariantPath([])"
3970 ),
3971 "actual: {err}",
3972 );
3973 }
3974
3975 #[test]
3976 fn test_variant_get_return_null_when_cast_failure_and_safe_true() {
3977 let variant_array = invalid_time_variant_array();
3978
3979 let field = Field::new("result", DataType::Time64(TimeUnit::Microsecond), true);
3980 let cast_options = CastOptions {
3981 safe: true, ..Default::default()
3983 };
3984 let options = GetOptions::new()
3985 .with_as_type(Some(FieldRef::from(field)))
3986 .with_cast_options(cast_options);
3987 let result = variant_get(&variant_array, options).unwrap();
3988 assert_eq!(3, result.len());
3989
3990 for i in 0..3 {
3991 assert!(result.is_null(i));
3992 }
3993 }
3994
3995 #[test]
3996 fn test_perfect_shredding_returns_same_arc_ptr() {
3997 let variant_array = perfectly_shredded_int32_variant_array();
3998
3999 let variant_array_ref = VariantArray::try_new(&variant_array).unwrap();
4000 let typed_value_arc = variant_array_ref.typed_value_field().unwrap().clone();
4001
4002 let field = Field::new("result", DataType::Int32, true);
4003 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
4004 let result = variant_get(&variant_array, options).unwrap();
4005
4006 assert!(Arc::ptr_eq(&typed_value_arc, &result));
4007 }
4008
4009 #[test]
4010 fn test_perfect_shredding_three_typed_value_columns() {
4011 let all_nulls_values: Arc<Int32Array> = Arc::new(Int32Array::from(vec![
4013 Option::<i32>::None,
4014 Option::<i32>::None,
4015 Option::<i32>::None,
4016 ]));
4017 let all_nulls_erased: ArrayRef = all_nulls_values.clone();
4018 let all_nulls_field =
4019 ShreddedVariantFieldArray::from_parts(None, Some(all_nulls_erased.clone()), None);
4020 let all_nulls_type = all_nulls_field.data_type().clone();
4021 let all_nulls_struct: ArrayRef = ArrayRef::from(all_nulls_field);
4022
4023 let some_nulls_values: Arc<Int32Array> =
4025 Arc::new(Int32Array::from(vec![Some(10), None, Some(30)]));
4026 let some_nulls_erased: ArrayRef = some_nulls_values.clone();
4027 let some_nulls_field =
4028 ShreddedVariantFieldArray::from_parts(None, Some(some_nulls_erased.clone()), None);
4029 let some_nulls_type = some_nulls_field.data_type().clone();
4030 let some_nulls_struct: ArrayRef = ArrayRef::from(some_nulls_field);
4031
4032 let inner_values: Arc<Int32Array> =
4034 Arc::new(Int32Array::from(vec![Some(111), None, Some(333)]));
4035 let inner_erased: ArrayRef = inner_values.clone();
4036 let inner_field =
4037 ShreddedVariantFieldArray::from_parts(None, Some(inner_erased.clone()), None);
4038 let inner_field_type = inner_field.data_type().clone();
4039 let inner_struct_array: ArrayRef = ArrayRef::from(inner_field);
4040
4041 let nested_struct = Arc::new(
4042 StructArray::try_new(
4043 Fields::from(vec![Field::new("inner", inner_field_type, true)]),
4044 vec![inner_struct_array],
4045 None,
4046 )
4047 .unwrap(),
4048 );
4049 let nested_struct_erased: ArrayRef = nested_struct.clone();
4050 let struct_field =
4051 ShreddedVariantFieldArray::from_parts(None, Some(nested_struct_erased.clone()), None);
4052 let struct_field_type = struct_field.data_type().clone();
4053 let struct_field_struct: ArrayRef = ArrayRef::from(struct_field);
4054
4055 let typed_value_struct = StructArray::try_new(
4057 Fields::from(vec![
4058 Field::new("all_nulls", all_nulls_type, true),
4059 Field::new("some_nulls", some_nulls_type, true),
4060 Field::new("struct_field", struct_field_type, true),
4061 ]),
4062 vec![all_nulls_struct, some_nulls_struct, struct_field_struct],
4063 None,
4064 )
4065 .unwrap();
4066
4067 let metadata = BinaryViewArray::from_iter_values(std::iter::repeat_n(
4068 EMPTY_VARIANT_METADATA_BYTES,
4069 all_nulls_values.len(),
4070 ));
4071 let variant_array: ArrayRef =
4072 VariantArray::from_parts(metadata, None, Some(Arc::new(typed_value_struct)), None)
4073 .into();
4074
4075 let all_nulls_field_ref = FieldRef::from(Field::new("result", DataType::Int32, true));
4077 let all_nulls_result = variant_get(
4078 &variant_array,
4079 GetOptions::new_with_path(VariantPath::try_from("all_nulls").unwrap())
4080 .with_as_type(Some(all_nulls_field_ref)),
4081 )
4082 .unwrap();
4083 assert!(Arc::ptr_eq(&all_nulls_result, &all_nulls_erased));
4084
4085 let some_nulls_field_ref = FieldRef::from(Field::new("result", DataType::Int32, true));
4087 let some_nulls_result = variant_get(
4088 &variant_array,
4089 GetOptions::new_with_path(VariantPath::try_from("some_nulls").unwrap())
4090 .with_as_type(Some(some_nulls_field_ref)),
4091 )
4092 .unwrap();
4093 assert!(Arc::ptr_eq(&some_nulls_result, &some_nulls_erased));
4094
4095 let struct_child_fields = Fields::from(vec![Field::new("inner", DataType::Int32, true)]);
4097 let struct_field_ref = FieldRef::from(Field::new(
4098 "result",
4099 DataType::Struct(struct_child_fields.clone()),
4100 true,
4101 ));
4102 let struct_result = variant_get(
4103 &variant_array,
4104 GetOptions::new_with_path(VariantPath::try_from("struct_field").unwrap())
4105 .with_as_type(Some(struct_field_ref)),
4106 )
4107 .unwrap();
4108 let struct_array = struct_result
4109 .as_any()
4110 .downcast_ref::<StructArray>()
4111 .unwrap();
4112 assert_eq!(struct_array.len(), 3);
4113 assert_eq!(struct_array.null_count(), 0);
4114
4115 let inner_values_result = struct_array
4116 .column(0)
4117 .as_any()
4118 .downcast_ref::<Int32Array>()
4119 .unwrap();
4120 assert_eq!(inner_values_result.len(), 3);
4121 assert_eq!(inner_values_result.value(0), 111);
4122 assert!(inner_values_result.is_null(1));
4123 assert_eq!(inner_values_result.value(2), 333);
4124 }
4125
4126 #[test]
4127 fn test_variant_get_list_like_safe_cast() {
4128 let string_array: ArrayRef = Arc::new(StringArray::from(vec![
4129 r#"{"outer":{"list":[1, "two", 3]}}"#,
4130 r#"{"outer":{"list":"not a list"}}"#,
4131 ]));
4132 let variant_array = ArrayRef::from(json_to_variant(&string_array).unwrap());
4133
4134 let element_array: ArrayRef = Arc::new(Int64Array::from(vec![Some(1), None, Some(3)]));
4135 let field = Arc::new(Field::new("item", Int64, true));
4136
4137 let expectations = vec![
4138 (
4139 DataType::List(field.clone()),
4140 Arc::new(ListArray::new(
4141 field.clone(),
4142 OffsetBuffer::new(ScalarBuffer::from(vec![0, 3, 3])),
4143 element_array.clone(),
4144 Some(NullBuffer::from(vec![true, false])),
4145 )) as ArrayRef,
4146 ),
4147 (
4148 DataType::LargeList(field.clone()),
4149 Arc::new(LargeListArray::new(
4150 field.clone(),
4151 OffsetBuffer::new(ScalarBuffer::from(vec![0, 3, 3])),
4152 element_array.clone(),
4153 Some(NullBuffer::from(vec![true, false])),
4154 )) as ArrayRef,
4155 ),
4156 (
4157 DataType::ListView(field.clone()),
4158 Arc::new(ListViewArray::new(
4159 field.clone(),
4160 ScalarBuffer::from(vec![0, 3]),
4161 ScalarBuffer::from(vec![3, 0]),
4162 element_array.clone(),
4163 Some(NullBuffer::from(vec![true, false])),
4164 )) as ArrayRef,
4165 ),
4166 (
4167 DataType::LargeListView(field.clone()),
4168 Arc::new(LargeListViewArray::new(
4169 field,
4170 ScalarBuffer::from(vec![0, 3]),
4171 ScalarBuffer::from(vec![3, 0]),
4172 element_array,
4173 Some(NullBuffer::from(vec![true, false])),
4174 )) as ArrayRef,
4175 ),
4176 ];
4177
4178 for (request_type, expected) in expectations {
4179 let options =
4180 GetOptions::new_with_path(VariantPath::try_from("outer").unwrap().join("list"))
4181 .with_as_type(Some(FieldRef::from(Field::new(
4182 "result",
4183 request_type.clone(),
4184 true,
4185 ))));
4186
4187 let result = variant_get(&variant_array, options).unwrap();
4188 assert_eq!(result.data_type(), expected.data_type());
4189 assert_eq!(&result, &expected);
4190 }
4191
4192 for (idx, expected) in [
4193 (0, vec![Some(1), None]),
4194 (1, vec![None, None]),
4195 (2, vec![Some(3), None]),
4196 ] {
4197 let index_options = GetOptions::new_with_path(
4198 VariantPath::try_from("outer")
4199 .unwrap()
4200 .join("list")
4201 .join(idx),
4202 )
4203 .with_as_type(Some(FieldRef::from(Field::new(
4204 "result",
4205 DataType::Int64,
4206 true,
4207 ))));
4208 let index_result = variant_get(&variant_array, index_options).unwrap();
4209 let index_expected: ArrayRef = Arc::new(Int64Array::from(expected));
4210 assert_eq!(&index_result, &index_expected);
4211 }
4212 }
4213
4214 #[test]
4215 fn test_variant_get_nested_list() {
4216 use arrow::datatypes::Int64Type;
4217
4218 let string_array: ArrayRef = Arc::new(StringArray::from(vec![
4219 r#"[[1, 2], [3]]"#,
4220 r#"[[4], "not a list", [5, 6]]"#,
4221 ]));
4222 let variant_array = ArrayRef::from(json_to_variant(&string_array).unwrap());
4223
4224 let inner_field = Arc::new(Field::new("item", Int64, true));
4225 let outer_field = Arc::new(Field::new(
4226 "item",
4227 DataType::List(inner_field.clone()),
4228 true,
4229 ));
4230 let request_type = DataType::List(outer_field.clone());
4231
4232 let options = GetOptions::new().with_as_type(Some(FieldRef::from(Field::new(
4233 "result",
4234 request_type,
4235 true,
4236 ))));
4237 let result = variant_get(&variant_array, options).unwrap();
4238 let outer = result.as_list::<i32>();
4239
4240 let row0 = outer.value(0);
4242 let row0 = row0.as_list::<i32>();
4243 assert_eq!(row0.len(), 2);
4244 let elem0 = row0.value(0);
4245 assert_eq!(elem0.as_primitive::<Int64Type>().values(), &[1, 2]);
4246 let elem1 = row0.value(1);
4247 assert_eq!(elem1.as_primitive::<Int64Type>().values(), &[3]);
4248
4249 let row1 = outer.value(1);
4251 let row1 = row1.as_list::<i32>();
4252 assert_eq!(row1.len(), 3);
4253 let elem0 = row1.value(0);
4254 assert_eq!(elem0.as_primitive::<Int64Type>().values(), &[4]);
4255 assert!(row1.is_null(1));
4256 let elem2 = row1.value(2);
4257 assert_eq!(elem2.as_primitive::<Int64Type>().values(), &[5, 6]);
4258 }
4259
4260 #[test]
4261 fn test_variant_get_list_like_unsafe_cast_errors_on_element_mismatch() {
4262 let string_array: ArrayRef =
4263 Arc::new(StringArray::from(vec![r#"[1, "two", 3]"#, "[4, 5]"]));
4264 let variant_array = ArrayRef::from(json_to_variant(&string_array).unwrap());
4265 let cast_options = CastOptions {
4266 safe: false,
4267 ..Default::default()
4268 };
4269
4270 let item_field = Arc::new(Field::new("item", DataType::Int64, true));
4271 let request_types = vec![
4272 DataType::List(item_field.clone()),
4273 DataType::LargeList(item_field.clone()),
4274 DataType::ListView(item_field.clone()),
4275 DataType::LargeListView(item_field),
4276 ];
4277
4278 for request_type in request_types {
4279 let options = GetOptions::new()
4280 .with_as_type(Some(FieldRef::from(Field::new(
4281 "result",
4282 request_type.clone(),
4283 true,
4284 ))))
4285 .with_cast_options(cast_options.clone());
4286
4287 let err = variant_get(&variant_array, options).unwrap_err();
4288 assert!(
4289 err.to_string()
4290 .contains("Failed to extract primitive of type Int64")
4291 );
4292 }
4293 }
4294
4295 #[test]
4296 fn test_variant_get_list_like_unsafe_cast_preserves_null_elements() {
4297 let string_array: ArrayRef = Arc::new(StringArray::from(vec![r#"[1, null, 3]"#]));
4298 let variant_array = ArrayRef::from(json_to_variant(&string_array).unwrap());
4299 let cast_options = CastOptions {
4300 safe: false,
4301 ..Default::default()
4302 };
4303 let options = GetOptions::new()
4304 .with_as_type(Some(FieldRef::from(Field::new(
4305 "result",
4306 DataType::List(Arc::new(Field::new("item", DataType::Int64, true))),
4307 true,
4308 ))))
4309 .with_cast_options(cast_options);
4310
4311 let result = variant_get(&variant_array, options).unwrap();
4312 let list_array = result.as_any().downcast_ref::<ListArray>().unwrap();
4313 let values = list_array
4314 .values()
4315 .as_any()
4316 .downcast_ref::<Int64Array>()
4317 .unwrap();
4318
4319 assert_eq!(values.len(), 3);
4320 assert_eq!(values.value(0), 1);
4321 assert!(values.is_null(1));
4322 assert_eq!(values.value(2), 3);
4323 }
4324
4325 #[test]
4326 fn test_variant_get_list_like_unsafe_cast_errors_on_non_list() {
4327 let string_array: ArrayRef = Arc::new(StringArray::from(vec!["[1, 2]", "\"not a list\""]));
4328 let variant_array = ArrayRef::from(json_to_variant(&string_array).unwrap());
4329 let cast_options = CastOptions {
4330 safe: false,
4331 ..Default::default()
4332 };
4333 let item_field = Arc::new(Field::new("item", Int64, true));
4334 let data_types = vec![
4335 DataType::List(item_field.clone()),
4336 DataType::LargeList(item_field.clone()),
4337 DataType::ListView(item_field.clone()),
4338 DataType::LargeListView(item_field),
4339 ];
4340
4341 for data_type in data_types {
4342 let options = GetOptions::new()
4343 .with_as_type(Some(FieldRef::from(Field::new("result", data_type, true))))
4344 .with_cast_options(cast_options.clone());
4345
4346 let err = variant_get(&variant_array, options).unwrap_err();
4347 assert!(
4348 err.to_string()
4349 .contains("Failed to extract list from variant"),
4350 );
4351 }
4352 }
4353
4354 #[test]
4355 fn test_variant_get_fixed_size_list_not_implemented() {
4356 let string_array: ArrayRef = Arc::new(StringArray::from(vec!["[1, 2]", "\"not a list\""]));
4357 let variant_array = ArrayRef::from(json_to_variant(&string_array).unwrap());
4358 let item_field = Arc::new(Field::new("item", Int64, true));
4359 for safe in [true, false] {
4360 let options = GetOptions::new()
4361 .with_as_type(Some(FieldRef::from(Field::new(
4362 "result",
4363 DataType::FixedSizeList(item_field.clone(), 2),
4364 true,
4365 ))))
4366 .with_cast_options(CastOptions {
4367 safe,
4368 ..Default::default()
4369 });
4370
4371 let err = variant_get(&variant_array, options).unwrap_err();
4372 assert!(
4373 err.to_string()
4374 .contains("Converting unshredded variant arrays to arrow fixed-size lists")
4375 );
4376 }
4377 }
4378}