1use arrow::{
18 array::{
19 self, Array, ArrayRef, GenericListArray, GenericListViewArray, ListLikeArray, StructArray,
20 UInt64Array, make_array,
21 },
22 buffer::NullBuffer,
23 compute::{CastOptions, take},
24 datatypes::Field,
25 error::Result,
26};
27use arrow_schema::{ArrowError, DataType, FieldRef};
28use parquet_variant::{VariantPath, VariantPathElement};
29
30use crate::ShreddingState;
31use crate::variant_array::all_null_value_column;
32use crate::variant_to_arrow::make_variant_to_arrow_row_builder;
33use crate::{VariantArray, VariantType, unshred_variant};
34
35use arrow::array::AsArray;
36use std::sync::Arc;
37
38pub(crate) enum ShreddedPathStep {
39 Success(ShreddingState),
41 Missing,
44 NotShredded,
48}
49
50fn take_list_like_index_as_shredding_state<L: ListLikeArray + 'static>(
53 typed_value: &dyn Array,
54 index: usize,
55) -> Result<Option<ShreddingState>> {
56 let list_array = typed_value.as_any().downcast_ref::<L>().ok_or_else(|| {
57 ArrowError::ComputeError(format!(
58 "Expected array type '{}' while handling list-like path step, got '{}'",
59 std::any::type_name::<L>(),
60 typed_value.data_type()
61 ))
62 })?;
63
64 let values = list_array.values();
65
66 let Some(struct_array) = values.as_struct_opt() else {
67 return Ok(None);
68 };
69 let shredding_state = ShreddingState::try_from(struct_array)?;
70
71 let value_array = shredding_state.value_column();
72 let typed_array = shredding_state.typed_value_column();
73
74 if typed_array.is_none() && value_array.null_count() == value_array.len() {
76 return Ok(None);
77 }
78
79 let mut take_indices = Vec::with_capacity(list_array.len());
80 for row in 0..list_array.len() {
81 let row_range = list_array.element_range(row);
82 let take_index = (index < row_range.len()).then(|| (row_range.start + index) as u64);
83 take_indices.push(take_index);
84 }
85
86 let index_array = UInt64Array::from(take_indices);
87
88 let taken_value = take(value_array, &index_array, None)?;
90 let taken_typed = typed_array
91 .map(|typed| take(typed, &index_array, None))
92 .transpose()?;
93
94 Ok(Some(ShreddingState::new(taken_value, taken_typed)))
95}
96
97pub(crate) fn follow_shredded_path_element(
113 shredding_state: &ShreddingState,
114 path_element: &VariantPathElement<'_>,
115 _cast_options: &CastOptions,
116) -> Result<ShreddedPathStep> {
117 let missing_path_step = || {
120 let value = shredding_state.value_column();
121 if value.null_count() == value.len() {
122 ShreddedPathStep::Missing
123 } else {
124 ShreddedPathStep::NotShredded
125 }
126 };
127
128 let Some(typed_value) = shredding_state.typed_value_column() else {
129 return Ok(missing_path_step());
130 };
131
132 match path_element {
133 VariantPathElement::Field { name } => {
134 let Some(struct_array) = typed_value.as_struct_opt() else {
137 return Ok(missing_path_step());
139 };
140
141 let Some(field) = struct_array.column_by_name(name) else {
143 return Ok(missing_path_step());
145 };
146
147 let struct_array = field.as_struct_opt().ok_or_else(|| {
148 ArrowError::InvalidArgumentError(format!(
151 "Shredded object field '{name}' must be a Struct containing 'value' and/or \
152 'typed_value', got {}",
153 field.data_type(),
154 ))
155 })?;
156
157 let state = ShreddingState::try_from(struct_array)?;
158 Ok(ShreddedPathStep::Success(state))
159 }
160 VariantPathElement::Index { index } => {
161 let state = match typed_value.data_type() {
162 DataType::List(_) => take_list_like_index_as_shredding_state::<
163 GenericListArray<i32>,
164 >(typed_value.as_ref(), *index)?,
165 DataType::LargeList(_) => take_list_like_index_as_shredding_state::<
166 GenericListArray<i64>,
167 >(typed_value.as_ref(), *index)?,
168 DataType::ListView(_) => take_list_like_index_as_shredding_state::<
169 GenericListViewArray<i32>,
170 >(typed_value.as_ref(), *index)?,
171 DataType::LargeListView(_) => take_list_like_index_as_shredding_state::<
172 GenericListViewArray<i64>,
173 >(typed_value.as_ref(), *index)?,
174 _ => {
175 return Ok(missing_path_step());
177 }
178 };
179
180 match state {
181 Some(state) => Ok(ShreddedPathStep::Success(state)),
182 None => Ok(missing_path_step()),
183 }
184 }
185 VariantPathElement::ListElement => Err(ArrowError::InvalidArgumentError(
186 "variant_get does not support [*] path elements".to_string(),
187 )),
188 }
189}
190
191fn shredded_get_path(
195 input: &VariantArray,
196 path: &[VariantPathElement<'_>],
197 as_field: Option<&Field>,
198 cast_options: &CastOptions,
199) -> Result<ArrayRef> {
200 let make_target_variant =
203 |value: ArrayRef, typed_value: Option<ArrayRef>, accumulated_nulls: Option<NullBuffer>| {
204 let metadata = input.metadata_column().clone();
205 VariantArray::from_parts(metadata, value, typed_value, accumulated_nulls)
206 };
207
208 let shred_basic_variant =
211 |target: VariantArray, path: VariantPath<'_>, as_field: Option<&Field>| {
212 let requested_variant =
215 as_field.is_some_and(Field::has_valid_extension_type::<VariantType>);
216
217 if requested_variant && requested_field_is_shredded(as_field) {
222 return Err(ArrowError::NotYetImplemented(
223 "variant_get with shredded `Variant` output is not yet supported".to_string(),
224 ));
225 }
226
227 let target = if requested_variant {
233 unshred_variant(&target)?
234 } else {
235 target
236 };
237
238 if requested_variant && path.is_empty() {
240 return Ok(ArrayRef::from(target));
241 }
242
243 let as_type = if requested_variant {
244 None
245 } else {
246 as_field.map(|f| f.data_type())
247 };
248 let mut builder = make_variant_to_arrow_row_builder(
249 target.metadata_column(),
250 path,
251 as_type,
252 cast_options,
253 target.len(),
254 )?;
255 for i in 0..target.len() {
256 if target.is_null(i) {
257 builder.append_null()?;
258 } else if !cast_options.safe {
259 let value = target.try_value(i)?;
260 builder.append_value(value)?;
261 } else {
262 let _ = match target.try_value(i) {
263 Ok(v) => builder.append_value(v)?,
264 Err(_) => {
265 builder.append_null()?;
266 false }
268 };
269 }
270 }
271 builder.finish()
272 };
273
274 let mut shredding_state = input.shredding_state().clone();
277 let mut accumulated_nulls = input.inner().nulls().cloned();
278 let mut path_index = 0;
279 for path_element in path {
280 match follow_shredded_path_element(&shredding_state, path_element, cast_options)? {
281 ShreddedPathStep::Success(state) => {
282 if let Some(typed_value) = shredding_state.typed_value_column() {
284 accumulated_nulls =
285 NullBuffer::union(accumulated_nulls.as_ref(), typed_value.nulls());
286 }
287 shredding_state = state;
288 path_index += 1;
289 }
290 ShreddedPathStep::Missing => {
291 let num_rows = input.len();
292 if as_field.is_some_and(Field::has_valid_extension_type::<VariantType>) {
293 let all_nulls = Some(arrow::buffer::NullBuffer::from(vec![false; num_rows]));
294 let metadata = input.metadata_column().clone();
297 let arr = VariantArray::from_parts_unshredded(
298 metadata,
299 all_null_value_column(num_rows),
300 all_nulls,
301 );
302 return Ok(ArrayRef::from(arr));
303 }
304 let arr = match as_field.map(|f| f.data_type()) {
305 Some(data_type) => array::new_null_array(data_type, num_rows),
306 None => Arc::new(array::NullArray::new(num_rows)) as _,
307 };
308 return Ok(arr);
309 }
310 ShreddedPathStep::NotShredded => {
311 let target = make_target_variant(
312 shredding_state.value_column().clone(),
313 None,
314 accumulated_nulls,
315 );
316 return shred_basic_variant(target, path[path_index..].into(), as_field);
317 }
318 }
319 }
320
321 let target = make_target_variant(
323 shredding_state.value_column().clone(),
324 shredding_state.typed_value_column().cloned(),
325 accumulated_nulls,
326 );
327
328 let Some(as_field) = as_field else {
330 return Ok(ArrayRef::from(target));
331 };
332
333 if let Some(shredded) = try_perfect_shredding(&target, as_field) {
335 return Ok(shredded);
336 }
337
338 if !as_field.has_valid_extension_type::<VariantType>()
348 && let DataType::Struct(fields) = as_field.data_type()
349 {
350 if target.typed_value_column().is_none() {
351 return shred_basic_variant(target, VariantPath::default(), Some(as_field));
352 }
353
354 let children = fields
355 .iter()
356 .map(|field| {
357 let path = &[VariantPathElement::from(field.name().as_str())];
358 shredded_get_path(&target, path, Some(field), cast_options)
359 })
360 .collect::<Result<Vec<_>>>()?;
361
362 return Ok(Arc::new(StructArray::try_new(
363 fields.clone(),
364 children,
365 target.nulls().cloned(),
366 )?));
367 }
368
369 shred_basic_variant(target, VariantPath::default(), Some(as_field))
371}
372
373fn requested_field_is_shredded(as_field: Option<&Field>) -> bool {
378 as_field.is_some_and(|f| match f.data_type() {
379 DataType::Struct(fields) => fields.iter().any(|field| field.name() == "typed_value"),
380 _ => false,
381 })
382}
383
384fn try_perfect_shredding(variant_array: &VariantArray, as_field: &Field) -> Option<ArrayRef> {
385 if matches!(as_field.data_type(), DataType::Struct(_)) {
387 return None;
388 }
389 let typed_value = variant_array.typed_value_column()?;
390
391 let value = variant_array.value_column();
392 if typed_value.data_type() == as_field.data_type() && value.null_count() == value.len() {
393 let parent_nulls = variant_array.nulls();
400
401 let target_array = if parent_nulls.is_none() || typed_value.data_type().is_null() {
403 typed_value.clone()
404 } else {
405 let merged_nulls = NullBuffer::union(parent_nulls, typed_value.nulls());
406 let data = typed_value
407 .to_data()
408 .into_builder()
409 .nulls(merged_nulls)
410 .build()
411 .ok()?;
412 make_array(data)
413 };
414
415 return Some(target_array);
416 }
417
418 None
419}
420
421pub fn variant_get(input: &ArrayRef, options: GetOptions) -> Result<ArrayRef> {
453 let variant_array = VariantArray::try_new(input)?;
454
455 let GetOptions {
456 as_type,
457 path,
458 cast_options,
459 } = options;
460
461 if path
462 .iter()
463 .any(|element| matches!(element, VariantPathElement::ListElement))
464 {
465 return Err(ArrowError::InvalidArgumentError(
466 "variant_get does not support [*] path elements".to_string(),
467 ));
468 }
469
470 shredded_get_path(&variant_array, &path, as_type.as_deref(), &cast_options)
471}
472
473#[derive(Debug, Clone, Default)]
475pub struct GetOptions<'a> {
476 pub path: VariantPath<'a>,
478 pub as_type: Option<FieldRef>,
482 pub cast_options: CastOptions<'a>,
484}
485
486impl<'a> GetOptions<'a> {
487 pub fn new() -> Self {
489 Default::default()
490 }
491
492 pub fn new_with_path(path: VariantPath<'a>) -> Self {
494 Self {
495 path,
496 as_type: None,
497 cast_options: Default::default(),
498 }
499 }
500
501 pub fn with_as_type(mut self, as_type: Option<FieldRef>) -> Self {
503 self.as_type = as_type;
504 self
505 }
506
507 pub fn with_cast_options(mut self, cast_options: CastOptions<'a>) -> Self {
509 self.cast_options = cast_options;
510 self
511 }
512}
513
514#[cfg(test)]
515mod test {
516 use std::str::FromStr;
517 use std::sync::Arc;
518
519 use super::{GetOptions, requested_field_is_shredded, variant_get};
520 use crate::variant_array::{ShreddedVariantFieldArray, all_null_value_column};
521 use crate::{
522 ShreddedSchemaBuilder, VariantArray, VariantArrayBuilder, cast_to_variant, json_to_variant,
523 shred_variant,
524 };
525 use arrow::array::{
526 Array, ArrayRef, AsArray, BinaryArray, BinaryViewArray, BooleanArray, Date32Array,
527 Date64Array, Decimal32Array, Decimal64Array, Decimal128Array, Decimal256Array,
528 FixedSizeListArray, Float32Array, Float64Array, Int8Array, Int16Array, Int32Array,
529 Int64Array, Int64Builder, LargeBinaryArray, LargeListArray, LargeListViewArray,
530 LargeStringArray, ListArray, ListBuilder, ListViewArray, MapBuilder, NullArray,
531 NullBuilder, StringArray, StringBuilder, StringViewArray, StructArray,
532 StructArrayAssembler, Time32MillisecondArray, Time32SecondArray, Time64MicrosecondArray,
533 Time64NanosecondArray, UnionArray,
534 };
535 use arrow::buffer::{NullBuffer, OffsetBuffer, ScalarBuffer};
536 use arrow::compute::{CastOptions, cast};
537 use arrow::datatypes::DataType::{Int16, Int32, Int64};
538 use arrow::datatypes::i256;
539 use arrow::util::display::FormatOptions;
540 use arrow_schema::ArrowError;
541 use arrow_schema::DataType::{Boolean, Float32, Float64, Int8};
542 use arrow_schema::{
543 DataType, Field, FieldRef, Fields, IntervalUnit, TimeUnit, UnionFields, UnionMode,
544 };
545 use chrono::DateTime;
546 use parquet_variant::{
547 EMPTY_VARIANT_METADATA_BYTES, Variant, VariantDecimal4, VariantDecimal8, VariantDecimal16,
548 VariantDecimalType, VariantPath,
549 };
550
551 fn single_variant_get_test(input_json: &str, path: VariantPath, expected_json: &str) {
552 let input_array_ref: ArrayRef = Arc::new(StringArray::from(vec![Some(input_json)]));
554 let input_variant_array_ref = ArrayRef::from(json_to_variant(&input_array_ref).unwrap());
555
556 let result =
557 variant_get(&input_variant_array_ref, GetOptions::new_with_path(path)).unwrap();
558
559 let expected_array_ref: ArrayRef = Arc::new(StringArray::from(vec![Some(expected_json)]));
561 let expected_variant_array = json_to_variant(&expected_array_ref).unwrap();
562
563 let result_array = VariantArray::try_new(&result).unwrap();
564 assert_eq!(
565 result_array.len(),
566 1,
567 "Expected result array to have length 1"
568 );
569 assert!(
570 result_array.nulls().is_none(),
571 "Expected no nulls in result array"
572 );
573 let result_variant = result_array.value(0);
574 let expected_variant = expected_variant_array.value(0);
575 assert_eq!(
576 result_variant, expected_variant,
577 "Result variant does not match expected variant"
578 );
579 }
580
581 #[test]
582 fn get_primitive_variant_field() {
583 single_variant_get_test(
584 r#"{"some_field": 1234}"#,
585 VariantPath::try_from("some_field").unwrap(),
586 "1234",
587 );
588 }
589
590 #[test]
591 fn get_primitive_variant_list_index() {
592 single_variant_get_test("[1234, 5678]", VariantPath::from(0), "1234");
593 }
594
595 #[test]
596 fn get_primitive_variant_inside_object_of_object() {
597 single_variant_get_test(
598 r#"{"top_level_field": {"inner_field": 1234}}"#,
599 VariantPath::try_from("top_level_field")
600 .unwrap()
601 .join("inner_field"),
602 "1234",
603 );
604 }
605
606 #[test]
607 fn get_primitive_variant_inside_list_of_object() {
608 single_variant_get_test(
609 r#"[{"some_field": 1234}]"#,
610 VariantPath::from(0).join("some_field"),
611 "1234",
612 );
613 }
614
615 #[test]
616 fn get_primitive_variant_inside_object_of_list() {
617 single_variant_get_test(
618 r#"{"some_field": [1234]}"#,
619 VariantPath::try_from("some_field[0]").unwrap(),
620 "1234",
621 );
622 }
623
624 #[test]
625 fn get_complex_variant() {
626 single_variant_get_test(
627 r#"{"top_level_field": {"inner_field": 1234}}"#,
628 VariantPath::try_from("top_level_field").unwrap(),
629 r#"{"inner_field": 1234}"#,
630 );
631 }
632
633 macro_rules! numeric_partially_shredded_test {
635 ($primitive_type:ty, $data_fn:ident) => {
636 let array = $data_fn();
637 let options = GetOptions::new();
638 let result = variant_get(&array, options).unwrap();
639
640 let result = VariantArray::try_new(&result).unwrap();
642 assert_eq!(result.len(), 4);
643
644 assert_eq!(
646 result.value(0),
647 Variant::from(<$primitive_type>::try_from(34u8).unwrap())
648 );
649 assert!(!result.is_valid(1));
650 assert_eq!(result.value(2), Variant::from("n/a"));
651 assert_eq!(
652 result.value(3),
653 Variant::from(<$primitive_type>::try_from(100u8).unwrap())
654 );
655 };
656 }
657
658 macro_rules! partially_shredded_variant_array_gen {
661 ($func_name:ident, $typed_value_array_gen: expr) => {
662 partially_shredded_variant_array_gen!(
663 $func_name,
664 $typed_value_array_gen,
665 Variant::from("n/a")
666 );
667 };
668 ($func_name:ident, $typed_value_array_gen: expr, $fallback_variant:expr) => {
669 fn $func_name() -> ArrayRef {
670 let typed_value: ArrayRef = Arc::new($typed_value_array_gen());
671 let typed_as_variant = cast_to_variant(typed_value.as_ref())
672 .expect("should cast typed array to variant");
673 let mut input_builder = VariantArrayBuilder::new(typed_as_variant.len());
674 input_builder.append_variant(typed_as_variant.value(0));
675 input_builder.append_null();
676 input_builder.append_variant($fallback_variant);
677 input_builder.append_variant(typed_as_variant.value(3));
678
679 let variant_array = shred_variant(&input_builder.build(), typed_value.data_type())
680 .expect("should shred variant array");
681 ArrayRef::from(variant_array)
682 }
683 };
684 }
685
686 macro_rules! numeric_partially_shredded_variant_array_fn {
688 ($func:ident, $array_type:ident, $primitive_type:ty) => {
689 partially_shredded_variant_array_gen!($func, || $array_type::from(vec![
690 Some(<$primitive_type>::try_from(34u8).unwrap()),
691 None,
692 None,
693 Some(<$primitive_type>::try_from(100u8).unwrap()),
694 ]));
695 };
696 }
697
698 numeric_partially_shredded_variant_array_fn!(
699 partially_shredded_int8_variant_array,
700 Int8Array,
701 i8
702 );
703 numeric_partially_shredded_variant_array_fn!(
704 partially_shredded_int16_variant_array,
705 Int16Array,
706 i16
707 );
708 numeric_partially_shredded_variant_array_fn!(
709 partially_shredded_int32_variant_array,
710 Int32Array,
711 i32
712 );
713 numeric_partially_shredded_variant_array_fn!(
714 partially_shredded_int64_variant_array,
715 Int64Array,
716 i64
717 );
718 numeric_partially_shredded_variant_array_fn!(
719 partially_shredded_float32_variant_array,
720 Float32Array,
721 f32
722 );
723 numeric_partially_shredded_variant_array_fn!(
724 partially_shredded_float64_variant_array,
725 Float64Array,
726 f64
727 );
728
729 partially_shredded_variant_array_gen!(partially_shredded_bool_variant_array, || {
730 arrow::array::BooleanArray::from(vec![Some(true), None, None, Some(false)])
731 });
732
733 partially_shredded_variant_array_gen!(
734 partially_shredded_utf8_variant_array,
735 || { StringArray::from(vec![Some("hello"), None, None, Some("world")]) },
736 Variant::from(42i32)
737 );
738
739 partially_shredded_variant_array_gen!(partially_shredded_date32_variant_array, || {
740 Date32Array::from(vec![
741 Some(20348), None,
743 None,
744 Some(20340), ])
746 });
747
748 #[test]
749 fn get_variant_partially_shredded_int8_as_variant() {
750 numeric_partially_shredded_test!(i8, partially_shredded_int8_variant_array);
751 }
752
753 #[test]
754 fn get_variant_partially_shredded_int16_as_variant() {
755 numeric_partially_shredded_test!(i16, partially_shredded_int16_variant_array);
756 }
757
758 #[test]
759 fn get_variant_partially_shredded_int32_as_variant() {
760 numeric_partially_shredded_test!(i32, partially_shredded_int32_variant_array);
761 }
762
763 #[test]
764 fn get_variant_partially_shredded_int64_as_variant() {
765 numeric_partially_shredded_test!(i64, partially_shredded_int64_variant_array);
766 }
767
768 #[test]
769 fn get_variant_partially_shredded_float32_as_variant() {
770 numeric_partially_shredded_test!(f32, partially_shredded_float32_variant_array);
771 }
772
773 #[test]
774 fn get_variant_partially_shredded_float64_as_variant() {
775 numeric_partially_shredded_test!(f64, partially_shredded_float64_variant_array);
776 }
777
778 #[test]
779 fn get_variant_partially_shredded_bool_as_variant() {
780 let array = partially_shredded_bool_variant_array();
781 let options = GetOptions::new();
782 let result = variant_get(&array, options).unwrap();
783
784 let result = VariantArray::try_new(&result).unwrap();
786 assert_eq!(result.len(), 4);
787
788 assert_eq!(result.value(0), Variant::from(true));
790 assert!(!result.is_valid(1));
791 assert_eq!(result.value(2), Variant::from("n/a"));
792 assert_eq!(result.value(3), Variant::from(false));
793 }
794
795 #[test]
796 fn get_variant_partially_shredded_utf8_as_variant() {
797 let array = partially_shredded_utf8_variant_array();
798 let options = GetOptions::new();
799 let result = variant_get(&array, options).unwrap();
800
801 let result = VariantArray::try_new(&result).unwrap();
803 assert_eq!(result.len(), 4);
804
805 assert_eq!(result.value(0), Variant::from("hello"));
807 assert!(!result.is_valid(1));
808 assert_eq!(result.value(2), Variant::from(42i32));
809 assert_eq!(result.value(3), Variant::from("world"));
810 }
811
812 partially_shredded_variant_array_gen!(partially_shredded_binary_view_variant_array, || {
813 BinaryViewArray::from(vec![
814 Some(&[1u8, 2u8, 3u8][..]), None, None, Some(&[4u8, 5u8, 6u8][..]), ])
819 });
820
821 #[test]
822 fn get_variant_partially_shredded_date32_as_variant() {
823 let array = partially_shredded_date32_variant_array();
824 let options = GetOptions::new();
825 let result = variant_get(&array, options).unwrap();
826
827 let result = VariantArray::try_new(&result).unwrap();
829 assert_eq!(result.len(), 4);
830
831 use chrono::NaiveDate;
833 let date1 = NaiveDate::from_ymd_opt(2025, 9, 17).unwrap();
834 let date2 = NaiveDate::from_ymd_opt(2025, 9, 9).unwrap();
835 assert_eq!(result.value(0), Variant::from(date1));
836 assert!(!result.is_valid(1));
837 assert_eq!(result.value(2), Variant::from("n/a"));
838 assert_eq!(result.value(3), Variant::from(date2));
839 }
840
841 #[test]
842 fn get_variant_partially_shredded_binary_view_as_variant() {
843 let array = partially_shredded_binary_view_variant_array();
844 let options = GetOptions::new();
845 let result = variant_get(&array, options).unwrap();
846
847 let result = VariantArray::try_new(&result).unwrap();
849 assert_eq!(result.len(), 4);
850
851 assert_eq!(result.value(0), Variant::from(&[1u8, 2u8, 3u8][..]));
853 assert!(!result.is_valid(1));
854 assert_eq!(result.value(2), Variant::from("n/a"));
855 assert_eq!(result.value(3), Variant::from(&[4u8, 5u8, 6u8][..]));
856 }
857
858 macro_rules! assert_variant_get_as_variant_array_with_default_option {
860 ($variant_array: expr, $array_expected: expr) => {{
861 let options = GetOptions::new();
862 let array = $variant_array;
863 let result = variant_get(&array, options).unwrap();
864 let result = VariantArray::try_new(&result).unwrap();
865
866 assert_eq!(result.len(), $array_expected.len());
867
868 for (idx, item) in $array_expected.into_iter().enumerate() {
869 match item {
870 Some(item) => assert_eq!(result.value(idx), item),
871 None => assert!(result.is_null(idx)),
872 }
873 }
874 }};
875 }
876
877 partially_shredded_variant_array_gen!(
878 partially_shredded_timestamp_micro_ntz_variant_array,
879 || {
880 arrow::array::TimestampMicrosecondArray::from(vec![
881 Some(-456000),
882 None,
883 None,
884 Some(1758602096000000),
885 ])
886 }
887 );
888
889 #[test]
890 fn get_variant_partial_shredded_timestamp_micro_ntz_as_variant() {
891 let array = partially_shredded_timestamp_micro_ntz_variant_array();
892 assert_variant_get_as_variant_array_with_default_option!(
893 array,
894 vec![
895 Some(Variant::from(
896 DateTime::from_timestamp_micros(-456000i64)
897 .unwrap()
898 .naive_utc(),
899 )),
900 None,
901 Some(Variant::from("n/a")),
902 Some(Variant::from(
903 DateTime::parse_from_rfc3339("2025-09-23T12:34:56+08:00")
904 .unwrap()
905 .naive_utc(),
906 )),
907 ]
908 )
909 }
910
911 partially_shredded_variant_array_gen!(partially_shredded_timestamp_micro_variant_array, || {
912 arrow::array::TimestampMicrosecondArray::from(vec![
913 Some(-456000),
914 None,
915 None,
916 Some(1758602096000000),
917 ])
918 .with_timezone("+00:00")
919 });
920
921 #[test]
922 fn get_variant_partial_shredded_timestamp_micro_as_variant() {
923 let array = partially_shredded_timestamp_micro_variant_array();
924 assert_variant_get_as_variant_array_with_default_option!(
925 array,
926 vec![
927 Some(Variant::from(
928 DateTime::from_timestamp_micros(-456000i64)
929 .unwrap()
930 .to_utc(),
931 )),
932 None,
933 Some(Variant::from("n/a")),
934 Some(Variant::from(
935 DateTime::parse_from_rfc3339("2025-09-23T12:34:56+08:00")
936 .unwrap()
937 .to_utc(),
938 )),
939 ]
940 )
941 }
942
943 partially_shredded_variant_array_gen!(
944 partially_shredded_timestamp_nano_ntz_variant_array,
945 || {
946 arrow::array::TimestampNanosecondArray::from(vec![
947 Some(-4999999561),
948 None,
949 None,
950 Some(1758602096000000000),
951 ])
952 }
953 );
954
955 #[test]
956 fn get_variant_partial_shredded_timestamp_nano_ntz_as_variant() {
957 let array = partially_shredded_timestamp_nano_ntz_variant_array();
958 assert_variant_get_as_variant_array_with_default_option!(
959 array,
960 vec![
961 Some(Variant::from(
962 DateTime::from_timestamp(-5, 439).unwrap().naive_utc()
963 )),
964 None,
965 Some(Variant::from("n/a")),
966 Some(Variant::from(
967 DateTime::parse_from_rfc3339("2025-09-23T12:34:56+08:00")
968 .unwrap()
969 .naive_utc()
970 )),
971 ]
972 )
973 }
974
975 partially_shredded_variant_array_gen!(partially_shredded_timestamp_nano_variant_array, || {
976 arrow::array::TimestampNanosecondArray::from(vec![
977 Some(-4999999561),
978 None,
979 None,
980 Some(1758602096000000000),
981 ])
982 .with_timezone("+00:00")
983 });
984
985 #[test]
986 fn get_variant_partial_shredded_timestamp_nano_as_variant() {
987 let array = partially_shredded_timestamp_nano_variant_array();
988 assert_variant_get_as_variant_array_with_default_option!(
989 array,
990 vec![
991 Some(Variant::from(
992 DateTime::from_timestamp(-5, 439).unwrap().to_utc()
993 )),
994 None,
995 Some(Variant::from("n/a")),
996 Some(Variant::from(
997 DateTime::parse_from_rfc3339("2025-09-23T12:34:56+08:00")
998 .unwrap()
999 .to_utc()
1000 )),
1001 ]
1002 )
1003 }
1004
1005 #[test]
1007 fn get_variant_shredded_int32_as_int32_safe_cast() {
1008 let array = partially_shredded_int32_variant_array();
1010 let field = Field::new("typed_value", DataType::Int32, true);
1012 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
1013 let result = variant_get(&array, options).unwrap();
1014 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
1015 Some(34),
1016 None,
1017 None, Some(100),
1019 ]));
1020 assert_eq!(&result, &expected)
1021 }
1022
1023 #[test]
1025 fn get_variant_shredded_int32_as_int32_unsafe_cast() {
1026 let array = partially_shredded_int32_variant_array();
1028 let field = Field::new("typed_value", DataType::Int32, true);
1029 let cast_options = CastOptions {
1030 safe: false, ..Default::default()
1032 };
1033 let options = GetOptions::new()
1034 .with_as_type(Some(FieldRef::from(field)))
1035 .with_cast_options(cast_options);
1036
1037 let err = variant_get(&array, options).unwrap_err();
1038 assert_eq!(
1040 err.to_string(),
1041 "Cast error: Failed to extract primitive of type Int32 from variant ShortString(ShortString(\"n/a\")) at path VariantPath([])"
1042 );
1043 }
1044
1045 macro_rules! numeric_perfectly_shredded_test {
1047 ($primitive_type:ty, $data_fn:ident) => {
1048 let array = $data_fn();
1049 let options = GetOptions::new();
1050 let result = variant_get(&array, options).unwrap();
1051
1052 let result = VariantArray::try_new(&result).unwrap();
1054 assert_eq!(result.len(), 3);
1055
1056 assert_eq!(
1058 result.value(0),
1059 Variant::from(<$primitive_type>::try_from(1u8).unwrap())
1060 );
1061 assert_eq!(
1062 result.value(1),
1063 Variant::from(<$primitive_type>::try_from(2u8).unwrap())
1064 );
1065 assert_eq!(
1066 result.value(2),
1067 Variant::from(<$primitive_type>::try_from(3u8).unwrap())
1068 );
1069 };
1070 }
1071
1072 #[test]
1073 fn get_variant_perfectly_shredded_int8_as_variant() {
1074 numeric_perfectly_shredded_test!(i8, perfectly_shredded_int8_variant_array);
1075 }
1076
1077 #[test]
1078 fn get_variant_perfectly_shredded_int16_as_variant() {
1079 numeric_perfectly_shredded_test!(i16, perfectly_shredded_int16_variant_array);
1080 }
1081
1082 #[test]
1083 fn get_variant_perfectly_shredded_int32_as_variant() {
1084 numeric_perfectly_shredded_test!(i32, perfectly_shredded_int32_variant_array);
1085 }
1086
1087 #[test]
1088 fn get_variant_perfectly_shredded_int64_as_variant() {
1089 numeric_perfectly_shredded_test!(i64, perfectly_shredded_int64_variant_array);
1090 }
1091
1092 #[test]
1093 fn get_variant_perfectly_shredded_float32_as_variant() {
1094 numeric_perfectly_shredded_test!(f32, perfectly_shredded_float32_variant_array);
1095 }
1096
1097 #[test]
1098 fn get_variant_perfectly_shredded_float64_as_variant() {
1099 numeric_perfectly_shredded_test!(f64, perfectly_shredded_float64_variant_array);
1100 }
1101
1102 #[test]
1104 fn get_variant_all_null_as_variant() {
1105 let array = all_null_variant_array();
1106 let options = GetOptions::new();
1107 let result = variant_get(&array, options).unwrap();
1108
1109 let result = VariantArray::try_new(&result).unwrap();
1111 assert_eq!(result.len(), 3);
1112
1113 assert!(!result.is_valid(0));
1115 assert!(!result.is_valid(1));
1116 assert!(!result.is_valid(2));
1117 }
1118
1119 #[test]
1121 fn get_variant_all_null_as_int32() {
1122 let array = all_null_variant_array();
1123 let field = Field::new("typed_value", DataType::Int32, true);
1125 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
1126 let result = variant_get(&array, options).unwrap();
1127
1128 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
1129 Option::<i32>::None,
1130 Option::<i32>::None,
1131 Option::<i32>::None,
1132 ]));
1133 assert_eq!(&result, &expected)
1134 }
1135
1136 macro_rules! perfectly_shredded_to_arrow_primitive_test {
1137 ($name:ident, $primitive_type:expr, $perfectly_shredded_array_gen_fun:ident, $expected_array:expr) => {
1138 #[test]
1139 fn $name() {
1140 let array = $perfectly_shredded_array_gen_fun();
1141 let field = Field::new("typed_value", $primitive_type, true);
1142 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
1143 let result = variant_get(&array, options).unwrap();
1144 let expected_array: ArrayRef = Arc::new($expected_array);
1145 assert_eq!(&result, &expected_array);
1146 }
1147 };
1148 }
1149
1150 perfectly_shredded_to_arrow_primitive_test!(
1151 get_variant_perfectly_shredded_int18_as_int8,
1152 Int8,
1153 perfectly_shredded_int8_variant_array,
1154 Int8Array::from(vec![Some(1), Some(2), Some(3)])
1155 );
1156
1157 perfectly_shredded_to_arrow_primitive_test!(
1158 get_variant_perfectly_shredded_int16_as_int16,
1159 Int16,
1160 perfectly_shredded_int16_variant_array,
1161 Int16Array::from(vec![Some(1), Some(2), Some(3)])
1162 );
1163
1164 perfectly_shredded_to_arrow_primitive_test!(
1165 get_variant_perfectly_shredded_int32_as_int32,
1166 Int32,
1167 perfectly_shredded_int32_variant_array,
1168 Int32Array::from(vec![Some(1), Some(2), Some(3)])
1169 );
1170
1171 perfectly_shredded_to_arrow_primitive_test!(
1172 get_variant_perfectly_shredded_int64_as_int64,
1173 Int64,
1174 perfectly_shredded_int64_variant_array,
1175 Int64Array::from(vec![Some(1), Some(2), Some(3)])
1176 );
1177
1178 perfectly_shredded_to_arrow_primitive_test!(
1179 get_variant_perfectly_shredded_float32_as_float32,
1180 Float32,
1181 perfectly_shredded_float32_variant_array,
1182 Float32Array::from(vec![Some(1.0), Some(2.0), Some(3.0)])
1183 );
1184
1185 perfectly_shredded_to_arrow_primitive_test!(
1186 get_variant_perfectly_shredded_float64_as_float64,
1187 Float64,
1188 perfectly_shredded_float64_variant_array,
1189 Float64Array::from(vec![Some(1.0), Some(2.0), Some(3.0)])
1190 );
1191
1192 perfectly_shredded_to_arrow_primitive_test!(
1193 get_variant_perfectly_shredded_boolean_as_boolean,
1194 Boolean,
1195 perfectly_shredded_bool_variant_array,
1196 BooleanArray::from(vec![Some(true), Some(false), Some(true)])
1197 );
1198
1199 perfectly_shredded_to_arrow_primitive_test!(
1200 get_variant_perfectly_shredded_utf8_as_utf8,
1201 DataType::Utf8,
1202 perfectly_shredded_utf8_variant_array,
1203 StringArray::from(vec![Some("foo"), Some("bar"), Some("baz")])
1204 );
1205
1206 perfectly_shredded_to_arrow_primitive_test!(
1207 get_variant_perfectly_shredded_large_utf8_as_utf8,
1208 DataType::Utf8,
1209 perfectly_shredded_large_utf8_variant_array,
1210 StringArray::from(vec![Some("foo"), Some("bar"), Some("baz")])
1211 );
1212
1213 perfectly_shredded_to_arrow_primitive_test!(
1214 get_variant_perfectly_shredded_utf8_view_as_utf8,
1215 DataType::Utf8,
1216 perfectly_shredded_utf8_view_variant_array,
1217 StringArray::from(vec![Some("foo"), Some("bar"), Some("baz")])
1218 );
1219
1220 macro_rules! perfectly_shredded_variant_array_fn {
1221 ($func:ident, $typed_value_gen:expr) => {
1222 fn $func() -> ArrayRef {
1223 let typed_value: ArrayRef = Arc::new($typed_value_gen());
1226 if let Some(shredded) = cast_to_variant(typed_value.as_ref())
1227 .ok()
1228 .and_then(|unshredded| shred_variant(&unshredded, typed_value.data_type()).ok())
1229 {
1230 return shredded.into();
1231 }
1232
1233 let metadata = BinaryViewArray::from_iter_values(std::iter::repeat_n(
1234 EMPTY_VARIANT_METADATA_BYTES,
1235 typed_value.len(),
1236 ));
1237 VariantArray::perfectly_shredded(Arc::new(metadata), typed_value, None).into()
1238 }
1239 };
1240 }
1241
1242 perfectly_shredded_variant_array_fn!(perfectly_shredded_utf8_variant_array, || {
1243 StringArray::from(vec![Some("foo"), Some("bar"), Some("baz")])
1244 });
1245
1246 perfectly_shredded_variant_array_fn!(perfectly_shredded_large_utf8_variant_array, || {
1247 LargeStringArray::from(vec![Some("foo"), Some("bar"), Some("baz")])
1248 });
1249
1250 perfectly_shredded_variant_array_fn!(perfectly_shredded_utf8_view_variant_array, || {
1251 StringViewArray::from(vec![Some("foo"), Some("bar"), Some("baz")])
1252 });
1253
1254 perfectly_shredded_variant_array_fn!(perfectly_shredded_bool_variant_array, || {
1255 BooleanArray::from(vec![Some(true), Some(false), Some(true)])
1256 });
1257
1258 macro_rules! numeric_perfectly_shredded_variant_array_fn {
1270 ($func:ident, $array_type:ident, $primitive_type:ty) => {
1271 perfectly_shredded_variant_array_fn!($func, || {
1272 $array_type::from(vec![
1273 Some(<$primitive_type>::try_from(1u8).unwrap()),
1274 Some(<$primitive_type>::try_from(2u8).unwrap()),
1275 Some(<$primitive_type>::try_from(3u8).unwrap()),
1276 ])
1277 });
1278 };
1279 }
1280
1281 numeric_perfectly_shredded_variant_array_fn!(
1282 perfectly_shredded_int8_variant_array,
1283 Int8Array,
1284 i8
1285 );
1286 numeric_perfectly_shredded_variant_array_fn!(
1287 perfectly_shredded_int16_variant_array,
1288 Int16Array,
1289 i16
1290 );
1291 numeric_perfectly_shredded_variant_array_fn!(
1292 perfectly_shredded_int32_variant_array,
1293 Int32Array,
1294 i32
1295 );
1296 numeric_perfectly_shredded_variant_array_fn!(
1297 perfectly_shredded_int64_variant_array,
1298 Int64Array,
1299 i64
1300 );
1301 numeric_perfectly_shredded_variant_array_fn!(
1302 perfectly_shredded_float32_variant_array,
1303 Float32Array,
1304 f32
1305 );
1306 numeric_perfectly_shredded_variant_array_fn!(
1307 perfectly_shredded_float64_variant_array,
1308 Float64Array,
1309 f64
1310 );
1311
1312 perfectly_shredded_variant_array_fn!(
1313 perfectly_shredded_timestamp_micro_ntz_variant_array,
1314 || {
1315 arrow::array::TimestampMicrosecondArray::from(vec![
1316 Some(-456000),
1317 Some(1758602096000001),
1318 Some(1758602096000002),
1319 ])
1320 }
1321 );
1322
1323 perfectly_shredded_to_arrow_primitive_test!(
1324 get_variant_perfectly_shredded_timestamp_micro_ntz_as_timestamp_micro_ntz,
1325 DataType::Timestamp(TimeUnit::Microsecond, None),
1326 perfectly_shredded_timestamp_micro_ntz_variant_array,
1327 arrow::array::TimestampMicrosecondArray::from(vec![
1328 Some(-456000),
1329 Some(1758602096000001),
1330 Some(1758602096000002),
1331 ])
1332 );
1333
1334 perfectly_shredded_to_arrow_primitive_test!(
1336 get_variant_perfectly_shredded_timestamp_micro_ntz_as_nano_ntz,
1337 DataType::Timestamp(TimeUnit::Nanosecond, None),
1338 perfectly_shredded_timestamp_micro_ntz_variant_array,
1339 arrow::array::TimestampNanosecondArray::from(vec![
1340 Some(-456000000),
1341 Some(1758602096000001000),
1342 Some(1758602096000002000)
1343 ])
1344 );
1345
1346 perfectly_shredded_variant_array_fn!(perfectly_shredded_timestamp_micro_variant_array, || {
1347 arrow::array::TimestampMicrosecondArray::from(vec![
1348 Some(-456000),
1349 Some(1758602096000001),
1350 Some(1758602096000002),
1351 ])
1352 .with_timezone("+00:00")
1353 });
1354
1355 perfectly_shredded_to_arrow_primitive_test!(
1356 get_variant_perfectly_shredded_timestamp_micro_as_timestamp_micro,
1357 DataType::Timestamp(TimeUnit::Microsecond, Some(Arc::from("+00:00"))),
1358 perfectly_shredded_timestamp_micro_variant_array,
1359 arrow::array::TimestampMicrosecondArray::from(vec![
1360 Some(-456000),
1361 Some(1758602096000001),
1362 Some(1758602096000002),
1363 ])
1364 .with_timezone("+00:00")
1365 );
1366
1367 perfectly_shredded_to_arrow_primitive_test!(
1369 get_variant_perfectly_shredded_timestamp_micro_as_nano,
1370 DataType::Timestamp(TimeUnit::Nanosecond, Some(Arc::from("+00:00"))),
1371 perfectly_shredded_timestamp_micro_variant_array,
1372 arrow::array::TimestampNanosecondArray::from(vec![
1373 Some(-456000000),
1374 Some(1758602096000001000),
1375 Some(1758602096000002000)
1376 ])
1377 .with_timezone("+00:00")
1378 );
1379
1380 perfectly_shredded_variant_array_fn!(
1381 perfectly_shredded_timestamp_nano_ntz_variant_array,
1382 || {
1383 arrow::array::TimestampNanosecondArray::from(vec![
1384 Some(-4999999561),
1385 Some(1758602096000000001),
1386 Some(1758602096000000002),
1387 ])
1388 }
1389 );
1390
1391 perfectly_shredded_variant_array_fn!(
1392 perfectly_shredded_timestamp_micro_variant_array_for_second_and_milli_second,
1393 || {
1394 arrow::array::TimestampMicrosecondArray::from(vec![
1395 Some(1234), Some(1234000), Some(1234000000), ])
1399 .with_timezone("+00:00")
1400 }
1401 );
1402
1403 perfectly_shredded_to_arrow_primitive_test!(
1406 get_variant_perfectly_shredded_timestamp_micro_as_timestamp_second,
1407 DataType::Timestamp(TimeUnit::Second, Some(Arc::from("+00:00"))),
1408 perfectly_shredded_timestamp_micro_variant_array_for_second_and_milli_second,
1409 arrow::array::TimestampSecondArray::from(vec![
1410 None,
1411 None, Some(1234)
1413 ])
1414 .with_timezone("+00:00")
1415 );
1416
1417 perfectly_shredded_to_arrow_primitive_test!(
1418 get_variant_perfectly_shredded_timestamp_micro_as_timestamp_milli,
1419 DataType::Timestamp(TimeUnit::Millisecond, Some(Arc::from("+00:00"))),
1420 perfectly_shredded_timestamp_micro_variant_array_for_second_and_milli_second,
1421 arrow::array::TimestampMillisecondArray::from(vec![
1422 None, Some(1234),
1424 Some(1234000)
1425 ])
1426 .with_timezone("+00:00")
1427 );
1428
1429 perfectly_shredded_variant_array_fn!(
1430 perfectly_shredded_timestamp_micro_ntz_variant_array_for_second_and_milli_second,
1431 || {
1432 arrow::array::TimestampMicrosecondArray::from(vec![
1433 Some(1234), Some(1234000), Some(1234000000), ])
1437 }
1438 );
1439
1440 perfectly_shredded_to_arrow_primitive_test!(
1443 get_variant_perfectly_shredded_timestamp_micro_ntz_as_timestamp_second,
1444 DataType::Timestamp(TimeUnit::Second, None),
1445 perfectly_shredded_timestamp_micro_ntz_variant_array_for_second_and_milli_second,
1446 arrow::array::TimestampSecondArray::from(vec![
1447 None,
1448 None, Some(1234)
1450 ])
1451 );
1452
1453 perfectly_shredded_to_arrow_primitive_test!(
1454 get_variant_perfectly_shredded_timestamp_micro_ntz_as_timestamp_milli,
1455 DataType::Timestamp(TimeUnit::Millisecond, None),
1456 perfectly_shredded_timestamp_micro_ntz_variant_array_for_second_and_milli_second,
1457 arrow::array::TimestampMillisecondArray::from(vec![
1458 None, Some(1234),
1460 Some(1234000)
1461 ])
1462 );
1463
1464 perfectly_shredded_variant_array_fn!(
1465 perfectly_shredded_timestamp_nano_variant_array_for_second_and_milli_second,
1466 || {
1467 arrow::array::TimestampNanosecondArray::from(vec![
1468 Some(1234000), Some(1234000000), Some(1234000000000), ])
1472 .with_timezone("+00:00")
1473 }
1474 );
1475
1476 perfectly_shredded_to_arrow_primitive_test!(
1479 get_variant_perfectly_shredded_timestamp_nano_as_timestamp_second,
1480 DataType::Timestamp(TimeUnit::Second, Some(Arc::from("+00:00"))),
1481 perfectly_shredded_timestamp_nano_variant_array_for_second_and_milli_second,
1482 arrow::array::TimestampSecondArray::from(vec![
1483 None,
1484 None, Some(1234)
1486 ])
1487 .with_timezone("+00:00")
1488 );
1489
1490 perfectly_shredded_to_arrow_primitive_test!(
1491 get_variant_perfectly_shredded_timestamp_nano_as_timestamp_milli,
1492 DataType::Timestamp(TimeUnit::Millisecond, Some(Arc::from("+00:00"))),
1493 perfectly_shredded_timestamp_nano_variant_array_for_second_and_milli_second,
1494 arrow::array::TimestampMillisecondArray::from(vec![
1495 None, Some(1234),
1497 Some(1234000)
1498 ])
1499 .with_timezone("+00:00")
1500 );
1501
1502 perfectly_shredded_variant_array_fn!(
1503 perfectly_shredded_timestamp_nano_ntz_variant_array_for_second_and_milli_second,
1504 || {
1505 arrow::array::TimestampNanosecondArray::from(vec![
1506 Some(1234000), Some(1234000000), Some(1234000000000), ])
1510 }
1511 );
1512
1513 perfectly_shredded_to_arrow_primitive_test!(
1516 get_variant_perfectly_shredded_timestamp_nano_ntz_as_timestamp_second,
1517 DataType::Timestamp(TimeUnit::Second, None),
1518 perfectly_shredded_timestamp_nano_ntz_variant_array_for_second_and_milli_second,
1519 arrow::array::TimestampSecondArray::from(vec![
1520 None,
1521 None, Some(1234)
1523 ])
1524 );
1525
1526 perfectly_shredded_to_arrow_primitive_test!(
1527 get_variant_perfectly_shredded_timestamp_nano_ntz_as_timestamp_milli,
1528 DataType::Timestamp(TimeUnit::Millisecond, None),
1529 perfectly_shredded_timestamp_nano_ntz_variant_array_for_second_and_milli_second,
1530 arrow::array::TimestampMillisecondArray::from(vec![
1531 None, Some(1234),
1533 Some(1234000)
1534 ])
1535 );
1536
1537 perfectly_shredded_to_arrow_primitive_test!(
1538 get_variant_perfectly_shredded_timestamp_nano_ntz_as_timestamp_nano_ntz,
1539 DataType::Timestamp(TimeUnit::Nanosecond, None),
1540 perfectly_shredded_timestamp_nano_ntz_variant_array,
1541 arrow::array::TimestampNanosecondArray::from(vec![
1542 Some(-4999999561),
1543 Some(1758602096000000001),
1544 Some(1758602096000000002),
1545 ])
1546 );
1547
1548 perfectly_shredded_variant_array_fn!(perfectly_shredded_timestamp_nano_variant_array, || {
1549 arrow::array::TimestampNanosecondArray::from(vec![
1550 Some(-4999999561),
1551 Some(1758602096000000001),
1552 Some(1758602096000000002),
1553 ])
1554 .with_timezone("+00:00")
1555 });
1556
1557 perfectly_shredded_to_arrow_primitive_test!(
1558 get_variant_perfectly_shredded_timestamp_nano_as_timestamp_nano,
1559 DataType::Timestamp(TimeUnit::Nanosecond, Some(Arc::from("+00:00"))),
1560 perfectly_shredded_timestamp_nano_variant_array,
1561 arrow::array::TimestampNanosecondArray::from(vec![
1562 Some(-4999999561),
1563 Some(1758602096000000001),
1564 Some(1758602096000000002),
1565 ])
1566 .with_timezone("+00:00")
1567 );
1568
1569 perfectly_shredded_variant_array_fn!(perfectly_shredded_date_variant_array, || {
1570 Date32Array::from(vec![Some(-12345), Some(17586), Some(20000)])
1571 });
1572
1573 perfectly_shredded_to_arrow_primitive_test!(
1574 get_variant_perfectly_shredded_date_as_date,
1575 DataType::Date32,
1576 perfectly_shredded_date_variant_array,
1577 Date32Array::from(vec![Some(-12345), Some(17586), Some(20000)])
1578 );
1579
1580 perfectly_shredded_to_arrow_primitive_test!(
1581 get_variant_perfectly_shredded_date_as_date64,
1582 DataType::Date64,
1583 perfectly_shredded_date_variant_array,
1584 Date64Array::from(vec![
1585 Some(-1066608000000),
1586 Some(1519430400000),
1587 Some(1728000000000)
1588 ])
1589 );
1590
1591 perfectly_shredded_variant_array_fn!(perfectly_shredded_time_variant_array, || {
1592 Time64MicrosecondArray::from(vec![Some(12345000), Some(87654000), Some(135792000)])
1593 });
1594
1595 perfectly_shredded_to_arrow_primitive_test!(
1596 get_variant_perfectly_shredded_time_as_time,
1597 DataType::Time64(TimeUnit::Microsecond),
1598 perfectly_shredded_time_variant_array,
1599 Time64MicrosecondArray::from(vec![Some(12345000), Some(87654000), Some(135792000)])
1600 );
1601
1602 perfectly_shredded_to_arrow_primitive_test!(
1603 get_variant_perfectly_shredded_time_as_time64_nano,
1604 DataType::Time64(TimeUnit::Nanosecond),
1605 perfectly_shredded_time_variant_array,
1606 Time64NanosecondArray::from(vec![
1607 Some(12345000000),
1608 Some(87654000000),
1609 Some(135792000000)
1610 ])
1611 );
1612
1613 perfectly_shredded_variant_array_fn!(perfectly_shredded_time_variant_array_for_time32, || {
1614 Time64MicrosecondArray::from(vec![
1615 Some(1234), Some(7654000), Some(35792000000), ])
1619 });
1620
1621 perfectly_shredded_to_arrow_primitive_test!(
1622 get_variant_perfectly_shredded_time_as_time32_second,
1623 DataType::Time32(TimeUnit::Second),
1624 perfectly_shredded_time_variant_array_for_time32,
1625 Time32SecondArray::from(vec![
1626 None,
1627 None, Some(35792)
1629 ])
1630 );
1631
1632 perfectly_shredded_to_arrow_primitive_test!(
1633 get_variant_perfectly_shredded_time_as_time32_milli,
1634 DataType::Time32(TimeUnit::Millisecond),
1635 perfectly_shredded_time_variant_array_for_time32,
1636 Time32MillisecondArray::from(vec![
1637 None, Some(7654),
1639 Some(35792000)
1640 ])
1641 );
1642
1643 perfectly_shredded_variant_array_fn!(perfectly_shredded_null_variant_array, || {
1644 let mut builder = NullBuilder::new();
1645 builder.append_nulls(3);
1646 builder.finish()
1647 });
1648
1649 perfectly_shredded_to_arrow_primitive_test!(
1650 get_variant_perfectly_shredded_null_as_null,
1651 DataType::Null,
1652 perfectly_shredded_null_variant_array,
1653 arrow::array::NullArray::new(3)
1654 );
1655
1656 perfectly_shredded_variant_array_fn!(perfectly_shredded_null_variant_array_with_int, || {
1657 Int32Array::from(vec![Some(32), Some(64), Some(48)])
1658 });
1659
1660 perfectly_shredded_to_arrow_primitive_test!(
1662 get_variant_perfectly_shredded_null_with_type_mismatch_in_safe_mode,
1663 DataType::Null,
1664 perfectly_shredded_null_variant_array_with_int,
1665 arrow::array::NullArray::new(3)
1666 );
1667
1668 #[test]
1670 fn get_variant_perfectly_shredded_null_as_null_with_type_mismatch_in_strict_mode() {
1671 let array = perfectly_shredded_null_variant_array_with_int();
1672 let field = Field::new("typed_value", DataType::Null, true);
1673 let options = GetOptions::new()
1674 .with_as_type(Some(FieldRef::from(field)))
1675 .with_cast_options(CastOptions {
1676 safe: false,
1677 format_options: FormatOptions::default(),
1678 });
1679
1680 let result = variant_get(&array, options);
1681
1682 assert!(result.is_err());
1683 let error_msg = format!("{}", result.unwrap_err());
1684 assert!(
1685 error_msg
1686 .contains("Cast error: Failed to extract primitive of type Null from variant Int32(32) at path VariantPath([])"),
1687 "Expected=[Cast error: Failed to extract primitive of type Null from variant Int32(32) at path VariantPath([])],\
1688 Got error message=[{error_msg}]"
1689 );
1690 }
1691
1692 perfectly_shredded_variant_array_fn!(perfectly_shredded_decimal4_variant_array, || {
1693 Decimal32Array::from(vec![Some(12345), Some(23400), Some(-12342)])
1694 .with_precision_and_scale(5, 2)
1695 .unwrap()
1696 });
1697
1698 perfectly_shredded_to_arrow_primitive_test!(
1699 get_variant_perfectly_shredded_decimal4_as_decimal4,
1700 DataType::Decimal32(5, 2),
1701 perfectly_shredded_decimal4_variant_array,
1702 Decimal32Array::from(vec![Some(12345), Some(23400), Some(-12342)])
1703 .with_precision_and_scale(5, 2)
1704 .unwrap()
1705 );
1706
1707 perfectly_shredded_variant_array_fn!(
1708 perfectly_shredded_decimal8_variant_array_cast2decimal32,
1709 || {
1710 Decimal64Array::from(vec![Some(123456), Some(145678), Some(-123456)])
1711 .with_precision_and_scale(6, 1)
1712 .unwrap()
1713 }
1714 );
1715
1716 perfectly_shredded_to_arrow_primitive_test!(
1720 get_variant_perfectly_shredded_decimal8_through_decimal32_as_decimal8,
1721 DataType::Decimal64(6, 1),
1722 perfectly_shredded_decimal8_variant_array_cast2decimal32,
1723 Decimal64Array::from(vec![Some(123456), Some(145678), Some(-123456)])
1724 .with_precision_and_scale(6, 1)
1725 .unwrap()
1726 );
1727
1728 perfectly_shredded_variant_array_fn!(perfectly_shredded_decimal8_variant_array, || {
1731 Decimal64Array::from(vec![Some(1234567809), Some(1456787000), Some(-1234561203)])
1732 .with_precision_and_scale(10, 1)
1733 .unwrap()
1734 });
1735
1736 perfectly_shredded_to_arrow_primitive_test!(
1737 get_variant_perfectly_shredded_decimal8_as_decimal8,
1738 DataType::Decimal64(10, 1),
1739 perfectly_shredded_decimal8_variant_array,
1740 Decimal64Array::from(vec![Some(1234567809), Some(1456787000), Some(-1234561203)])
1741 .with_precision_and_scale(10, 1)
1742 .unwrap()
1743 );
1744
1745 perfectly_shredded_variant_array_fn!(
1748 perfectly_shredded_decimal16_within_decimal4_variant_array,
1749 || {
1750 Decimal128Array::from(vec![
1751 Some(i128::from(1234589)),
1752 Some(i128::from(2344444)),
1753 Some(i128::from(-1234789)),
1754 ])
1755 .with_precision_and_scale(7, 3)
1756 .unwrap()
1757 }
1758 );
1759
1760 perfectly_shredded_to_arrow_primitive_test!(
1763 get_variant_perfectly_shredded_decimal16_within_decimal4_as_decimal16,
1764 DataType::Decimal128(7, 3),
1765 perfectly_shredded_decimal16_within_decimal4_variant_array,
1766 Decimal128Array::from(vec![
1767 Some(i128::from(1234589)),
1768 Some(i128::from(2344444)),
1769 Some(i128::from(-1234789)),
1770 ])
1771 .with_precision_and_scale(7, 3)
1772 .unwrap()
1773 );
1774
1775 perfectly_shredded_variant_array_fn!(
1776 perfectly_shredded_decimal16_within_decimal8_variant_array,
1777 || {
1778 Decimal128Array::from(vec![Some(1234567809), Some(1456787000), Some(-1234561203)])
1779 .with_precision_and_scale(10, 1)
1780 .unwrap()
1781 }
1782 );
1783
1784 perfectly_shredded_to_arrow_primitive_test!(
1787 get_variant_perfectly_shredded_decimal16_within8_as_decimal16,
1788 DataType::Decimal128(10, 1),
1789 perfectly_shredded_decimal16_within_decimal8_variant_array,
1790 Decimal128Array::from(vec![Some(1234567809), Some(1456787000), Some(-1234561203)])
1791 .with_precision_and_scale(10, 1)
1792 .unwrap()
1793 );
1794
1795 perfectly_shredded_variant_array_fn!(perfectly_shredded_decimal16_variant_array, || {
1796 Decimal128Array::from(vec![
1797 Some(i128::from_str("12345678901234567899").unwrap()),
1798 Some(i128::from_str("23445677483748324300").unwrap()),
1799 Some(i128::from_str("-12345678901234567899").unwrap()),
1800 ])
1801 .with_precision_and_scale(20, 3)
1802 .unwrap()
1803 });
1804
1805 perfectly_shredded_to_arrow_primitive_test!(
1808 get_variant_perfectly_shredded_decimal16_as_decimal16,
1809 DataType::Decimal128(20, 3),
1810 perfectly_shredded_decimal16_variant_array,
1811 Decimal128Array::from(vec![
1812 Some(i128::from_str("12345678901234567899").unwrap()),
1813 Some(i128::from_str("23445677483748324300").unwrap()),
1814 Some(i128::from_str("-12345678901234567899").unwrap())
1815 ])
1816 .with_precision_and_scale(20, 3)
1817 .unwrap()
1818 );
1819
1820 perfectly_shredded_variant_array_fn!(perfectly_shredded_binary_variant_array, || {
1821 BinaryArray::from(vec![
1822 Some(b"Apache" as &[u8]),
1823 Some(b"Arrow-rs" as &[u8]),
1824 Some(b"Parquet-variant" as &[u8]),
1825 ])
1826 });
1827
1828 perfectly_shredded_to_arrow_primitive_test!(
1829 get_variant_perfectly_shredded_binary_as_binary,
1830 DataType::Binary,
1831 perfectly_shredded_binary_variant_array,
1832 BinaryArray::from(vec![
1833 Some(b"Apache" as &[u8]),
1834 Some(b"Arrow-rs" as &[u8]),
1835 Some(b"Parquet-variant" as &[u8]),
1836 ])
1837 );
1838
1839 perfectly_shredded_variant_array_fn!(perfectly_shredded_large_binary_variant_array, || {
1840 LargeBinaryArray::from(vec![
1841 Some(b"Apache" as &[u8]),
1842 Some(b"Arrow-rs" as &[u8]),
1843 Some(b"Parquet-variant" as &[u8]),
1844 ])
1845 });
1846
1847 perfectly_shredded_to_arrow_primitive_test!(
1848 get_variant_perfectly_shredded_large_binary_as_large_binary,
1849 DataType::LargeBinary,
1850 perfectly_shredded_large_binary_variant_array,
1851 LargeBinaryArray::from(vec![
1852 Some(b"Apache" as &[u8]),
1853 Some(b"Arrow-rs" as &[u8]),
1854 Some(b"Parquet-variant" as &[u8]),
1855 ])
1856 );
1857
1858 perfectly_shredded_variant_array_fn!(perfectly_shredded_binary_view_variant_array, || {
1859 BinaryViewArray::from(vec![
1860 Some(b"Apache" as &[u8]),
1861 Some(b"Arrow-rs" as &[u8]),
1862 Some(b"Parquet-variant" as &[u8]),
1863 ])
1864 });
1865
1866 perfectly_shredded_to_arrow_primitive_test!(
1867 get_variant_perfectly_shredded_binary_view_as_binary_view,
1868 DataType::BinaryView,
1869 perfectly_shredded_binary_view_variant_array,
1870 BinaryViewArray::from(vec![
1871 Some(b"Apache" as &[u8]),
1872 Some(b"Arrow-rs" as &[u8]),
1873 Some(b"Parquet-variant" as &[u8]),
1874 ])
1875 );
1876
1877 fn all_null_variant_array() -> ArrayRef {
1894 let nulls = NullBuffer::from(vec![
1895 false, false, false, ]);
1899
1900 let metadata =
1902 BinaryViewArray::from_iter_values(std::iter::repeat_n(EMPTY_VARIANT_METADATA_BYTES, 3));
1903
1904 ArrayRef::from(VariantArray::from_parts(
1905 Arc::new(metadata),
1906 all_null_value_column(3),
1907 None,
1908 Some(nulls),
1909 ))
1910 }
1911
1912 #[test]
1916 fn test_shredded_object_field_access() {
1917 let array = shredded_object_with_x_field_variant_array();
1918
1919 let options = GetOptions::new_with_path(VariantPath::try_from("x").unwrap());
1921 let result = variant_get(&array, options).unwrap();
1922
1923 let result_variant = VariantArray::try_new(&result).unwrap();
1924 assert_eq!(result_variant.len(), 2);
1925
1926 assert_eq!(result_variant.value(0), Variant::Int32(1));
1928 assert_eq!(result_variant.value(1), Variant::Int32(42));
1930 }
1931
1932 #[test]
1933 fn test_malformed_shredded_object_field_reports_field_and_type() {
1934 let metadata =
1935 BinaryViewArray::from_iter_values(std::iter::repeat_n(EMPTY_VARIANT_METADATA_BYTES, 2));
1936 let typed_value = StructArray::try_new(
1937 Fields::from(vec![Field::new("x", DataType::Int32, true)]),
1938 vec![Arc::new(Int32Array::from(vec![Some(1), Some(42)]))],
1939 None,
1940 )
1941 .unwrap();
1942 let array = ArrayRef::from(VariantArray::from_parts(
1943 Arc::new(metadata),
1944 all_null_value_column(2),
1945 Some(Arc::new(typed_value)),
1946 None,
1947 ));
1948
1949 let options = GetOptions::new_with_path(VariantPath::try_from("x").unwrap());
1950 let err = variant_get(&array, options).unwrap_err();
1951
1952 assert_eq!(
1953 err.to_string(),
1954 "Invalid argument error: Shredded object field 'x' must be a Struct containing \
1955 'value' and/or 'typed_value', got Int32"
1956 );
1957 }
1958
1959 #[test]
1961 fn test_shredded_object_field_as_int32() {
1962 let array = shredded_object_with_x_field_variant_array();
1963
1964 let field = Field::new("x", DataType::Int32, false);
1966 let options = GetOptions::new_with_path(VariantPath::try_from("x").unwrap())
1967 .with_as_type(Some(FieldRef::from(field)));
1968 let result = variant_get(&array, options).unwrap();
1969
1970 let expected: ArrayRef = Arc::new(Int32Array::from(vec![Some(1), Some(42)]));
1972 assert_eq!(&result, &expected);
1973 }
1974
1975 type ShreddedListLikeArrayGen = fn() -> ArrayRef;
1976 type ShreddedListLikeCase = (&'static str, ShreddedListLikeArrayGen);
1977
1978 fn shredded_list_like_cases() -> [ShreddedListLikeCase; 4] {
1979 [
1980 ("list", shredded_list_variant_array),
1981 ("large_list", shredded_large_list_variant_array),
1982 ("list_view", shredded_list_view_variant_array),
1983 ("large_list_view", shredded_large_list_view_variant_array),
1984 ]
1985 }
1986
1987 #[test]
1988 fn test_shredded_list_like_index_access_from_value_field() {
1989 let options = GetOptions::new_with_path(VariantPath::from(1));
1990
1991 for (case, array_gen) in shredded_list_like_cases() {
1992 let array = array_gen();
1993 let result = variant_get(&array, options.clone()).unwrap();
1994 let result_variant = VariantArray::try_new(&result).unwrap();
1995
1996 assert_eq!(result_variant.value(0), Variant::from("drama"), "{case}");
1997 assert_eq!(result_variant.value(1).as_int64(), Some(123), "{case}");
1998 }
1999 }
2000
2001 #[test]
2002 fn test_shredded_list_like_index_out_of_bounds_unsafe_cast_returns_null() {
2003 let options =
2004 GetOptions::new_with_path(VariantPath::from(10)).with_cast_options(CastOptions {
2005 safe: false,
2006 ..Default::default()
2007 });
2008
2009 for (case, array_gen) in shredded_list_like_cases() {
2010 let result = variant_get(&array_gen(), options.clone()).unwrap();
2011 let result_variant = VariantArray::try_new(&result).unwrap();
2012 assert_eq!(result_variant.value(0), Variant::Null, "{case}");
2013 assert_eq!(result_variant.value(1), Variant::Null, "{case}");
2014 }
2015 }
2016
2017 #[test]
2019 fn test_shredded_list_like_as_string() {
2020 let field = Field::new("typed_value", DataType::Utf8, false);
2021 let options = GetOptions::new_with_path(VariantPath::from(0))
2022 .with_as_type(Some(FieldRef::from(field)));
2023 let expected: ArrayRef = Arc::new(StringArray::from(vec![Some("comedy"), Some("horror")]));
2024
2025 for (case, array_gen) in shredded_list_like_cases() {
2026 let result = variant_get(&array_gen(), options.clone()).unwrap();
2027 assert_eq!(&result, &expected, "{case}");
2028 }
2029 }
2030
2031 #[test]
2032 fn test_shredded_list_like_index_access_from_value_field_as_int64() {
2033 let field = Field::new("typed_value", DataType::Int64, true);
2034 let options = GetOptions::new_with_path(VariantPath::from(1))
2035 .with_as_type(Some(FieldRef::from(field)));
2036 let expected: ArrayRef = Arc::new(Int64Array::from(vec![None, Some(123)]));
2037
2038 for (case, array_gen) in shredded_list_like_cases() {
2039 let result = variant_get(&array_gen(), options.clone()).unwrap();
2040 assert_eq!(&result, &expected, "{case}");
2042 }
2043 }
2044
2045 #[test]
2046 fn test_shredded_list_in_struct_index_access() {
2047 let array = shredded_struct_with_list_variant_array();
2048 let options = GetOptions::new_with_path(VariantPath::try_from("a[1]").unwrap());
2049 let result = variant_get(&array, options).unwrap();
2050 let result_variant = VariantArray::try_new(&result).unwrap();
2051
2052 assert_eq!(result_variant.value(0), Variant::from("drama"));
2053 assert_eq!(result_variant.value(1).as_int64(), Some(123));
2054 }
2055
2056 #[test]
2057 fn test_shredded_struct_in_list_field_access() {
2058 let array = shredded_list_of_struct_variant_array();
2059 let field = Field::new("x", DataType::Int32, true);
2060 let path = VariantPath::from(0).join("x");
2061 let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
2062 let result = variant_get(&array, options).unwrap();
2063
2064 let expected: ArrayRef = Arc::new(Int32Array::from(vec![Some(1), Some(3)]));
2065 assert_eq!(&result, &expected);
2066 }
2067
2068 #[test]
2069 fn test_shredded_list_of_lists_index_access() {
2070 let array = shredded_list_of_lists_variant_array();
2071 let path = VariantPath::from(0).join(1);
2072
2073 let result = variant_get(&array, GetOptions::new_with_path(path.clone())).unwrap();
2074 let result_variant = VariantArray::try_new(&result).unwrap();
2075 assert_eq!(result_variant.value(0), Variant::from("b"));
2076 assert_eq!(result_variant.value(1).as_int64(), Some(123));
2077
2078 let field = Field::new("typed_value", DataType::Int64, true);
2079 let casted = variant_get(
2080 &array,
2081 GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field))),
2082 )
2083 .unwrap();
2084 let expected: ArrayRef = Arc::new(Int64Array::from(vec![None, Some(123)]));
2085 assert_eq!(&casted, &expected);
2086 }
2087
2088 fn shredded_list_like_variant_array(list_schema: DataType) -> ArrayRef {
2094 let json_rows: ArrayRef = Arc::new(StringArray::from(vec![
2095 Some(r#"["comedy", "drama"]"#),
2096 Some(r#"["horror", 123]"#),
2097 ]));
2098 let input = json_to_variant(&json_rows).unwrap();
2099
2100 let shredded = shred_variant(&input, &list_schema).unwrap();
2101 ArrayRef::from(shredded)
2102 }
2103
2104 fn shredded_list_of_lists_variant_array() -> ArrayRef {
2105 let json_rows: ArrayRef = Arc::new(StringArray::from(vec![
2106 Some(r#"[["a", "b"], ["c", "d"]]"#),
2107 Some(r#"[["x", 123], ["y", "z"]]"#),
2108 ]));
2109 let input = json_to_variant(&json_rows).unwrap();
2110
2111 let inner_list = DataType::List(Arc::new(Field::new("item", DataType::Utf8, true)));
2112 let outer_list = DataType::List(Arc::new(Field::new("item", inner_list, true)));
2113 let shredded = shred_variant(&input, &outer_list).unwrap();
2114 ArrayRef::from(shredded)
2115 }
2116
2117 fn shredded_list_variant_array() -> ArrayRef {
2118 shredded_list_like_variant_array(DataType::List(Arc::new(Field::new(
2119 "item",
2120 DataType::Utf8,
2121 true,
2122 ))))
2123 }
2124
2125 fn shredded_large_list_variant_array() -> ArrayRef {
2126 shredded_list_like_variant_array(DataType::LargeList(Arc::new(Field::new(
2127 "item",
2128 DataType::Utf8,
2129 true,
2130 ))))
2131 }
2132
2133 fn shredded_list_view_variant_array() -> ArrayRef {
2134 shredded_list_like_variant_array(DataType::ListView(Arc::new(Field::new(
2135 "item",
2136 DataType::Utf8,
2137 true,
2138 ))))
2139 }
2140
2141 fn shredded_large_list_view_variant_array() -> ArrayRef {
2142 shredded_list_like_variant_array(DataType::LargeListView(Arc::new(Field::new(
2143 "item",
2144 DataType::Utf8,
2145 true,
2146 ))))
2147 }
2148
2149 fn shredded_struct_with_list_variant_array() -> ArrayRef {
2150 let json_rows: ArrayRef = Arc::new(StringArray::from(vec![
2151 Some(r#"{"a": ["comedy", "drama"]}"#),
2152 Some(r#"{"a": ["horror", 123]}"#),
2153 ]));
2154 let input = json_to_variant(&json_rows).unwrap();
2155
2156 let list_schema = DataType::List(Arc::new(Field::new("item", DataType::Utf8, true)));
2157 let shredding_schema = ShreddedSchemaBuilder::default()
2158 .with_path("a", &list_schema)
2159 .unwrap()
2160 .build();
2161 let shredded = shred_variant(&input, &shredding_schema).unwrap();
2162 ArrayRef::from(shredded)
2163 }
2164
2165 fn shredded_list_of_struct_variant_array() -> ArrayRef {
2166 let json_rows: ArrayRef = Arc::new(StringArray::from(vec![
2167 Some(r#"[{"x": 1}, {"x": 2}]"#),
2168 Some(r#"[{"x": 3}, {"y": 4}]"#),
2169 ]));
2170 let input = json_to_variant(&json_rows).unwrap();
2171
2172 let struct_type =
2173 DataType::Struct(Fields::from(vec![Field::new("x", DataType::Int32, true)]));
2174 let list_schema = DataType::List(Arc::new(Field::new("item", struct_type, true)));
2175 let shredded = shred_variant(&input, &list_schema).unwrap();
2176 ArrayRef::from(shredded)
2177 }
2178
2179 fn shredded_object_with_x_field_variant_array() -> ArrayRef {
2191 let (metadata, y_field_value) = {
2193 let mut builder = parquet_variant::VariantBuilder::new();
2194 let mut obj = builder.new_object();
2195 obj.insert("x", Variant::Int32(42));
2196 obj.insert("y", Variant::from("foo"));
2197 obj.finish();
2198 builder.finish()
2199 };
2200
2201 let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 2));
2203
2204 let empty_object_value = {
2209 let mut builder = parquet_variant::VariantBuilder::new();
2210 let obj = builder.new_object();
2211 obj.finish();
2212 let (_, value) = builder.finish();
2213 value
2214 };
2215
2216 let value_array = BinaryViewArray::from(vec![
2217 Some(y_field_value.as_slice()), Some(empty_object_value.as_slice()), ]);
2220
2221 let x_field_typed_value = Int32Array::from(vec![Some(1), Some(42)]);
2224
2225 let x_field_shredded = ShreddedVariantFieldArray::perfectly_shredded(Arc::new(
2227 x_field_typed_value,
2228 ) as ArrayRef);
2229
2230 let typed_value_fields = Fields::from(vec![Field::new(
2232 "x",
2233 x_field_shredded.data_type().clone(),
2234 true,
2235 )]);
2236 let typed_value_struct = StructArray::try_new(
2237 typed_value_fields,
2238 vec![ArrayRef::from(x_field_shredded)],
2239 None, )
2241 .unwrap();
2242
2243 ArrayRef::from(VariantArray::from_parts(
2245 Arc::new(metadata_array),
2246 Arc::new(value_array),
2247 Some(Arc::new(typed_value_struct)),
2248 None,
2249 ))
2250 }
2251
2252 #[test]
2254 fn test_simple_nested_path_support() {
2255 println!("Testing path parsing:");
2257
2258 let path_x = VariantPath::try_from("x").unwrap();
2259 let elements_x: Vec<_> = path_x.iter().collect();
2260 println!(" 'x' -> {} elements: {:?}", elements_x.len(), elements_x);
2261
2262 let path_ax = VariantPath::try_from("a.x").unwrap();
2263 let elements_ax: Vec<_> = path_ax.iter().collect();
2264 println!(
2265 " 'a.x' -> {} elements: {:?}",
2266 elements_ax.len(),
2267 elements_ax
2268 );
2269
2270 let path_ax_alt = VariantPath::try_from("$.a.x").unwrap();
2271 let elements_ax_alt: Vec<_> = path_ax_alt.iter().collect();
2272 println!(
2273 " '$.a.x' -> {} elements: {:?}",
2274 elements_ax_alt.len(),
2275 elements_ax_alt
2276 );
2277
2278 let path_nested = VariantPath::try_from("a").unwrap().join("x");
2279 let elements_nested: Vec<_> = path_nested.iter().collect();
2280 println!(
2281 " VariantPath::try_from('a').unwrap().join('x') -> {} elements: {:?}",
2282 elements_nested.len(),
2283 elements_nested
2284 );
2285
2286 let array = shredded_object_with_x_field_variant_array();
2288
2289 let real_nested_path = VariantPath::try_from("a").unwrap().join("x");
2291 let options = GetOptions::new_with_path(real_nested_path);
2292 let result = variant_get(&array, options);
2293
2294 match result {
2295 Ok(_) => {
2296 println!("Nested path 'a.x' works unexpectedly!");
2297 }
2298 Err(e) => {
2299 println!("Nested path 'a.x' error: {e}");
2300 if e.to_string().contains("Not yet implemented")
2301 || e.to_string().contains("NotYetImplemented")
2302 {
2303 println!("This is expected - nested paths are not implemented");
2304 return;
2305 }
2306 println!("This shows nested paths need implementation");
2308 }
2309 }
2310 }
2311
2312 #[test]
2316 fn test_depth_0_int32_conversion() {
2317 println!("=== Testing Depth 0: Direct field access ===");
2318
2319 let unshredded_array = create_depth_0_test_data();
2321
2322 let field = Field::new("result", DataType::Int32, true);
2323 let path = VariantPath::try_from("x").unwrap();
2324 let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
2325 let result = variant_get(&unshredded_array, options).unwrap();
2326
2327 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
2328 Some(42), None, None, ]));
2332 assert_eq!(&result, &expected);
2333 println!("Depth 0 (unshredded) passed");
2334
2335 let shredded_array = create_depth_0_shredded_test_data_simple();
2337
2338 let field = Field::new("result", DataType::Int32, true);
2339 let path = VariantPath::try_from("x").unwrap();
2340 let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
2341 let result = variant_get(&shredded_array, options).unwrap();
2342
2343 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
2344 Some(42), None, ]));
2347 assert_eq!(&result, &expected);
2348 println!("Depth 0 (shredded) passed");
2349 }
2350
2351 #[test]
2354 fn test_depth_1_int32_conversion() {
2355 println!("=== Testing Depth 1: Single nested field access ===");
2356
2357 let unshredded_array = create_nested_path_test_data();
2359
2360 let field = Field::new("result", DataType::Int32, true);
2361 let path = VariantPath::try_from("a.x").unwrap(); let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
2363 let result = variant_get(&unshredded_array, options).unwrap();
2364
2365 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
2366 Some(55), None, ]));
2369 assert_eq!(&result, &expected);
2370 println!("Depth 1 (unshredded) passed");
2371
2372 let shredded_array = create_depth_1_shredded_test_data_working();
2374
2375 let field = Field::new("result", DataType::Int32, true);
2376 let path = VariantPath::try_from("a.x").unwrap(); let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
2378 let result = variant_get(&shredded_array, options).unwrap();
2379
2380 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
2381 Some(55), None, ]));
2384 assert_eq!(&result, &expected);
2385 println!("Depth 1 (shredded) passed");
2386 }
2387
2388 #[test]
2391 fn test_depth_2_int32_conversion() {
2392 println!("=== Testing Depth 2: Double nested field access ===");
2393
2394 let unshredded_array = create_depth_2_test_data();
2396
2397 let field = Field::new("result", DataType::Int32, true);
2398 let path = VariantPath::try_from("a.b.x").unwrap(); let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
2400 let result = variant_get(&unshredded_array, options).unwrap();
2401
2402 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
2403 Some(100), None, None, ]));
2407 assert_eq!(&result, &expected);
2408 println!("Depth 2 (unshredded) passed");
2409
2410 let shredded_array = create_depth_2_shredded_test_data_working();
2412
2413 let field = Field::new("result", DataType::Int32, true);
2414 let path = VariantPath::try_from("a.b.x").unwrap(); let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
2416 let result = variant_get(&shredded_array, options).unwrap();
2417
2418 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
2419 Some(100), None, None, ]));
2423 assert_eq!(&result, &expected);
2424 println!("Depth 2 (shredded) passed");
2425 }
2426
2427 #[test]
2432 fn test_current_nested_path_functionality() {
2433 let array = shredded_object_with_x_field_variant_array();
2434
2435 let single_path = VariantPath::try_from("x").unwrap();
2437 let field = Field::new("result", DataType::Int32, true);
2438 let options =
2439 GetOptions::new_with_path(single_path).with_as_type(Some(FieldRef::from(field)));
2440 let result = variant_get(&array, options).unwrap();
2441
2442 println!("Single path 'x' works - result: {result:?}");
2443
2444 let nested_path = VariantPath::try_from("a").unwrap().join("x");
2446 let field = Field::new("result", DataType::Int32, true);
2447 let options =
2448 GetOptions::new_with_path(nested_path).with_as_type(Some(FieldRef::from(field)));
2449 let result = variant_get(&array, options).unwrap();
2450
2451 println!("Nested path 'a.x' result: {result:?}");
2452 }
2453
2454 #[test]
2455 fn test_variant_get_as_variant_from_unshredded_input() {
2456 let (unshredded, _) = create_variant_get_as_variant_test_data();
2457 let unshredded_field = VariantArray::try_new(&unshredded).unwrap().field("result");
2458 assert_variant_field_extraction_returns_unshredded_variant(&unshredded, &unshredded_field);
2459 }
2460
2461 #[test]
2462 fn test_variant_get_as_variant_from_shredded_input() {
2463 let (unshredded, shredded) = create_variant_get_as_variant_test_data();
2464 let unshredded_field = VariantArray::try_new(&unshredded).unwrap().field("result");
2465 assert_variant_field_extraction_returns_unshredded_variant(&shredded, &unshredded_field);
2466 }
2467
2468 #[test]
2469 fn test_variant_get_as_shredded_variant_is_not_yet_supported() {
2470 let (_, shredded) = create_variant_get_as_variant_test_data();
2471 let shredded_field = VariantArray::try_new(&shredded).unwrap().field("result");
2476 assert!(requested_field_is_shredded(Some(&shredded_field)));
2477
2478 let options = GetOptions::new_with_path(VariantPath::try_from("field_name").unwrap())
2479 .with_as_type(Some(FieldRef::from(shredded_field)));
2480 let err = variant_get(&shredded, options).unwrap_err();
2481 assert!(
2482 matches!(err, ArrowError::NotYetImplemented(_)),
2483 "expected NotYetImplemented, got {err:?}"
2484 );
2485 }
2486
2487 #[test]
2488 fn test_variant_get_list_element_wildcard_is_invalid_argument() {
2489 let (unshredded, _) = create_variant_get_as_variant_test_data();
2490 let options = GetOptions::new_with_path(VariantPath::try_from("field_name[*]").unwrap());
2491 let err = variant_get(&unshredded, options).unwrap_err();
2492 assert!(
2493 matches!(err, ArrowError::InvalidArgumentError(_)),
2494 "expected InvalidArgumentError, got {err:?}"
2495 );
2496 }
2497
2498 #[test]
2499 fn test_variant_get_missing_path_as_variant_annotates_value_non_nullable() {
2500 let (unshredded, shredded) = create_variant_get_as_variant_test_data();
2501 let variant_field = VariantArray::try_new(&unshredded).unwrap().field("result");
2502
2503 let options = GetOptions::new_with_path(VariantPath::try_from("field_name[0]").unwrap())
2505 .with_as_type(Some(FieldRef::from(variant_field)));
2506 let result = variant_get(&shredded, options).unwrap();
2507 let result_variant = VariantArray::try_new(&result).unwrap();
2508
2509 assert_eq!(result_variant.inner().null_count(), result_variant.len());
2510 let value_field = result_variant.inner().field_by_name("value").unwrap();
2511 assert!(!value_field.is_nullable());
2512 }
2513
2514 fn create_variant_get_as_variant_test_data() -> (ArrayRef, ArrayRef) {
2515 let input_json: ArrayRef = Arc::new(StringArray::from(vec![
2516 Some(r#"{"field_name": {"k": 100000}}"#),
2517 Some(r#"{"field_name": {"k": "s"}}"#),
2518 ]));
2519
2520 let unshredded = ArrayRef::from(json_to_variant(&input_json).unwrap());
2521 let unshredded_variant = VariantArray::try_new(&unshredded).unwrap();
2522
2523 let as_type = DataType::Struct(Fields::from(vec![Field::new(
2524 "field_name",
2525 DataType::Struct(Fields::from(vec![Field::new("k", DataType::Int32, true)])),
2526 true,
2527 )]));
2528 let shredded = ArrayRef::from(shred_variant(&unshredded_variant, &as_type).unwrap());
2529
2530 (unshredded, shredded)
2531 }
2532
2533 fn assert_variant_field_extraction_returns_unshredded_variant(
2534 input: &ArrayRef,
2535 variant_field: &Field,
2536 ) {
2537 let options = GetOptions::new_with_path(VariantPath::try_from("field_name").unwrap())
2538 .with_as_type(Some(FieldRef::from(variant_field.clone())));
2539
2540 let result = variant_get(input, options).unwrap();
2541 let result_variant = VariantArray::try_new(&result).unwrap();
2542
2543 assert!(result_variant.typed_value_column().is_none());
2544 assert!(result_variant.value_column().null_count() < result_variant.len());
2545 let value_field = result_variant.inner().field_by_name("value").unwrap();
2546 assert!(!value_field.is_nullable());
2547
2548 let expected_json: ArrayRef = Arc::new(StringArray::from(vec![
2549 Some(r#"{"k":100000}"#),
2550 Some(r#"{"k":"s"}"#),
2551 ]));
2552 let expected = json_to_variant(&expected_json).unwrap();
2553
2554 assert_eq!(result_variant.len(), expected.len());
2555 for i in 0..result_variant.len() {
2556 assert_eq!(result_variant.is_null(i), expected.is_null(i));
2557 if !result_variant.is_null(i) {
2558 assert_eq!(result_variant.value(i), expected.value(i));
2559 }
2560 }
2561 }
2562
2563 fn create_depth_0_test_data() -> ArrayRef {
2566 let mut builder = crate::VariantArrayBuilder::new(3);
2567
2568 {
2570 let json_str = r#"{"x": 42}"#;
2571 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2572 if let Ok(variant_array) = json_to_variant(&string_array) {
2573 builder.append_variant(variant_array.value(0));
2574 } else {
2575 builder.append_null();
2576 }
2577 }
2578
2579 {
2581 let json_str = r#"{"x": "foo"}"#;
2582 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2583 if let Ok(variant_array) = json_to_variant(&string_array) {
2584 builder.append_variant(variant_array.value(0));
2585 } else {
2586 builder.append_null();
2587 }
2588 }
2589
2590 {
2592 let json_str = r#"{"y": 10}"#;
2593 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2594 if let Ok(variant_array) = json_to_variant(&string_array) {
2595 builder.append_variant(variant_array.value(0));
2596 } else {
2597 builder.append_null();
2598 }
2599 }
2600
2601 ArrayRef::from(builder.build())
2602 }
2603
2604 fn create_nested_path_test_data() -> ArrayRef {
2607 let mut builder = crate::VariantArrayBuilder::new(2);
2608
2609 {
2611 let json_str = r#"{"a": {"x": 55}, "b": 42}"#;
2612 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2613 if let Ok(variant_array) = json_to_variant(&string_array) {
2614 builder.append_variant(variant_array.value(0));
2615 } else {
2616 builder.append_null();
2617 }
2618 }
2619
2620 {
2622 let json_str = r#"{"a": {"x": "foo"}, "b": 42}"#;
2623 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2624 if let Ok(variant_array) = json_to_variant(&string_array) {
2625 builder.append_variant(variant_array.value(0));
2626 } else {
2627 builder.append_null();
2628 }
2629 }
2630
2631 ArrayRef::from(builder.build())
2632 }
2633
2634 fn create_depth_2_test_data() -> ArrayRef {
2637 let mut builder = crate::VariantArrayBuilder::new(3);
2638
2639 {
2641 let json_str = r#"{"a": {"b": {"x": 100}}}"#;
2642 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2643 if let Ok(variant_array) = json_to_variant(&string_array) {
2644 builder.append_variant(variant_array.value(0));
2645 } else {
2646 builder.append_null();
2647 }
2648 }
2649
2650 {
2652 let json_str = r#"{"a": {"b": {"x": "bar"}}}"#;
2653 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2654 if let Ok(variant_array) = json_to_variant(&string_array) {
2655 builder.append_variant(variant_array.value(0));
2656 } else {
2657 builder.append_null();
2658 }
2659 }
2660
2661 {
2663 let json_str = r#"{"a": {"b": {"y": 200}}}"#;
2664 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2665 if let Ok(variant_array) = json_to_variant(&string_array) {
2666 builder.append_variant(variant_array.value(0));
2667 } else {
2668 builder.append_null();
2669 }
2670 }
2671
2672 ArrayRef::from(builder.build())
2673 }
2674
2675 fn create_depth_0_shredded_test_data_simple() -> ArrayRef {
2678 let (metadata, string_x_value) = {
2680 let mut builder = parquet_variant::VariantBuilder::new();
2681 let mut obj = builder.new_object();
2682 obj.insert("x", Variant::from("foo"));
2683 obj.finish();
2684 builder.finish()
2685 };
2686
2687 let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 2));
2689
2690 let empty_object_value = {
2694 let mut builder = parquet_variant::VariantBuilder::new();
2695 let obj = builder.new_object();
2696 obj.finish();
2697 let (_, value) = builder.finish();
2698 value
2699 };
2700
2701 let value_array = BinaryViewArray::from(vec![
2702 Some(empty_object_value.as_slice()), Some(string_x_value.as_slice()), ]);
2705
2706 let x_field_typed_value = Int32Array::from(vec![Some(42), None]);
2708
2709 let x_field_shredded = ShreddedVariantFieldArray::perfectly_shredded(Arc::new(
2711 x_field_typed_value,
2712 ) as ArrayRef);
2713
2714 let typed_value_fields = Fields::from(vec![Field::new(
2716 "x",
2717 x_field_shredded.data_type().clone(),
2718 true,
2719 )]);
2720 let typed_value_struct = StructArray::try_new(
2721 typed_value_fields,
2722 vec![ArrayRef::from(x_field_shredded)],
2723 None,
2724 )
2725 .unwrap();
2726
2727 ArrayRef::from(VariantArray::from_parts(
2729 Arc::new(metadata_array),
2730 Arc::new(value_array),
2731 Some(Arc::new(typed_value_struct)),
2732 None,
2733 ))
2734 }
2735
2736 fn create_depth_1_shredded_test_data_working() -> ArrayRef {
2741 let (metadata, _) = {
2743 let mut builder = parquet_variant::VariantBuilder::new();
2745 let mut obj = builder.new_object();
2746
2747 let mut a_obj = obj.new_object("a");
2749 a_obj.insert("x", Variant::Int32(55));
2750 a_obj.finish();
2751
2752 obj.insert("b", Variant::Int32(42));
2753 obj.finish();
2754 builder.finish()
2755 };
2756
2757 let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 2));
2758
2759 let empty_object_value = {
2762 let mut builder = parquet_variant::VariantBuilder::new();
2763 let obj = builder.new_object();
2764 obj.finish();
2765 let (_, value) = builder.finish();
2766 value
2767 };
2768
2769 let row1_fallback = {
2772 let mut builder = parquet_variant::VariantBuilder::new();
2773 let mut obj = builder.new_object();
2774 obj.insert("fallback", Variant::from("data"));
2775 obj.finish();
2776 let (_, value) = builder.finish();
2777 value
2778 };
2779
2780 let value_array = BinaryViewArray::from(vec![
2781 Some(empty_object_value.as_slice()), Some(row1_fallback.as_slice()), ]);
2784
2785 let x_typed_value = Int32Array::from(vec![Some(55), None]);
2788 let x_field_shredded =
2789 ShreddedVariantFieldArray::perfectly_shredded(Arc::new(x_typed_value) as ArrayRef);
2790
2791 let a_value_data = {
2796 let mut builder = parquet_variant::VariantBuilder::new();
2797 let obj = builder.new_object();
2798 obj.finish();
2799 let (_, value) = builder.finish();
2800 value
2801 };
2802 let a_value_array = BinaryViewArray::from(vec![
2803 None, Some(a_value_data.as_slice()), ]);
2806
2807 let a_inner_fields = Fields::from(vec![Field::new(
2808 "x",
2809 x_field_shredded.data_type().clone(),
2810 true,
2811 )]);
2812 let a_inner_typed_value = Arc::new(
2813 StructArray::try_new(a_inner_fields, vec![ArrayRef::from(x_field_shredded)], None)
2814 .unwrap(),
2815 ) as ArrayRef;
2816 let a_field_shredded = ShreddedVariantFieldArray::from_parts(
2817 Arc::new(a_value_array),
2818 Some(a_inner_typed_value),
2819 None,
2820 );
2821
2822 let typed_value_fields = Fields::from(vec![Field::new(
2824 "a",
2825 a_field_shredded.data_type().clone(),
2826 true,
2827 )]);
2828 let typed_value_struct = StructArray::try_new(
2829 typed_value_fields,
2830 vec![ArrayRef::from(a_field_shredded)],
2831 None,
2832 )
2833 .unwrap();
2834
2835 ArrayRef::from(VariantArray::from_parts(
2837 Arc::new(metadata_array),
2838 Arc::new(value_array),
2839 Some(Arc::new(typed_value_struct)),
2840 None,
2841 ))
2842 }
2843
2844 fn create_depth_2_shredded_test_data_working() -> ArrayRef {
2850 let (metadata, _) = {
2852 let mut builder = parquet_variant::VariantBuilder::new();
2854 let mut obj = builder.new_object();
2855
2856 let mut a_obj = obj.new_object("a");
2858 let mut b_obj = a_obj.new_object("b");
2859 b_obj.insert("x", Variant::Int32(100));
2860 b_obj.finish();
2861 a_obj.finish();
2862
2863 obj.finish();
2864 builder.finish()
2865 };
2866
2867 let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 3));
2868
2869 let empty_object_value = {
2871 let mut builder = parquet_variant::VariantBuilder::new();
2872 let obj = builder.new_object();
2873 obj.finish();
2874 let (_, value) = builder.finish();
2875 value
2876 };
2877
2878 let value_array = BinaryViewArray::from(vec![
2880 Some(empty_object_value.as_slice()), Some(empty_object_value.as_slice()), Some(empty_object_value.as_slice()), ]);
2884
2885 let x_typed_value = Int32Array::from(vec![Some(100), None, None]);
2889 let x_field_shredded =
2890 ShreddedVariantFieldArray::perfectly_shredded(Arc::new(x_typed_value) as ArrayRef);
2891
2892 let b_value_data = {
2894 let mut builder = parquet_variant::VariantBuilder::new();
2895 let obj = builder.new_object();
2896 obj.finish();
2897 let (_, value) = builder.finish();
2898 value
2899 };
2900 let b_value_array = BinaryViewArray::from(vec![
2901 None, Some(b_value_data.as_slice()), Some(b_value_data.as_slice()), ]);
2905
2906 let b_inner_fields = Fields::from(vec![Field::new(
2907 "x",
2908 x_field_shredded.data_type().clone(),
2909 true,
2910 )]);
2911 let b_inner_typed_value = Arc::new(
2912 StructArray::try_new(b_inner_fields, vec![ArrayRef::from(x_field_shredded)], None)
2913 .unwrap(),
2914 ) as ArrayRef;
2915 let b_field_shredded = ShreddedVariantFieldArray::from_parts(
2916 Arc::new(b_value_array),
2917 Some(b_inner_typed_value),
2918 None,
2919 );
2920
2921 let a_value_data = {
2923 let mut builder = parquet_variant::VariantBuilder::new();
2924 let obj = builder.new_object();
2925 obj.finish();
2926 let (_, value) = builder.finish();
2927 value
2928 };
2929 let a_value_array = BinaryViewArray::from(vec![
2930 None, Some(a_value_data.as_slice()), Some(a_value_data.as_slice()), ]);
2934
2935 let a_inner_fields = Fields::from(vec![Field::new(
2936 "b",
2937 b_field_shredded.data_type().clone(),
2938 true,
2939 )]);
2940 let a_inner_typed_value = Arc::new(
2941 StructArray::try_new(a_inner_fields, vec![ArrayRef::from(b_field_shredded)], None)
2942 .unwrap(),
2943 ) as ArrayRef;
2944 let a_field_shredded = ShreddedVariantFieldArray::from_parts(
2945 Arc::new(a_value_array),
2946 Some(a_inner_typed_value),
2947 None,
2948 );
2949
2950 let typed_value_fields = Fields::from(vec![Field::new(
2952 "a",
2953 a_field_shredded.data_type().clone(),
2954 true,
2955 )]);
2956 let typed_value_struct = StructArray::try_new(
2957 typed_value_fields,
2958 vec![ArrayRef::from(a_field_shredded)],
2959 None,
2960 )
2961 .unwrap();
2962
2963 ArrayRef::from(VariantArray::from_parts(
2965 Arc::new(metadata_array),
2966 Arc::new(value_array),
2967 Some(Arc::new(typed_value_struct)),
2968 None,
2969 ))
2970 }
2971
2972 #[test]
2973 fn test_field_path_non_struct_returns_missing_path_step() {
2974 let variant_array = perfectly_shredded_int32_variant_array();
2976
2977 for safe in [true, false] {
2978 let options = GetOptions {
2979 path: VariantPath::try_from("nonexistent_field").unwrap(),
2980 as_type: Some(Arc::new(Field::new("result", DataType::Int32, true))),
2981 cast_options: CastOptions {
2982 safe,
2983 ..Default::default()
2984 },
2985 };
2986
2987 let result_array = variant_get(&variant_array, options).unwrap();
2988 assert_eq!(result_array.len(), 3);
2989 assert!(result_array.is_null(0));
2990 assert!(result_array.is_null(1));
2991 assert!(result_array.is_null(2));
2992 }
2993 }
2994
2995 #[test]
2996 fn test_strict_cast_options_index_on_non_list_returns_null() {
2997 use arrow::compute::CastOptions;
2998 use arrow::datatypes::{DataType, Field};
2999 use parquet_variant::VariantPath;
3000 use std::sync::Arc;
3001
3002 let variant_array = perfectly_shredded_int32_variant_array();
3004 let options = GetOptions {
3005 path: VariantPath::from(0),
3006 as_type: Some(Arc::new(Field::new("result", DataType::Int32, true))),
3007 cast_options: CastOptions {
3008 safe: false,
3009 ..Default::default()
3010 },
3011 };
3012
3013 let variant_array_ref: Arc<dyn Array> = variant_array.clone();
3014 let result = variant_get(&variant_array_ref, options).unwrap();
3015
3016 assert_eq!(result.len(), 3);
3017 assert!(result.is_null(0));
3018 assert!(result.is_null(1));
3019 assert!(result.is_null(2));
3020 }
3021
3022 #[test]
3023 fn test_error_message_boolean_type_display() {
3024 let variant_array: ArrayRef = ArrayRef::from(VariantArray::from_iter([Some("abcd")]));
3025
3026 let options = GetOptions {
3028 path: VariantPath::default(),
3029 as_type: Some(Arc::new(Field::new("result", DataType::Boolean, true))),
3030 cast_options: CastOptions {
3031 safe: false,
3032 ..Default::default()
3033 },
3034 };
3035
3036 let err = variant_get(&variant_array, options).unwrap_err();
3037 let msg = err.to_string();
3038 assert!(msg.contains("Failed to extract primitive of type Boolean"));
3039 }
3040
3041 #[test]
3042 fn test_error_message_numeric_type_display() {
3043 let variant_array: ArrayRef = ArrayRef::from(VariantArray::from_iter([Some("abcd")]));
3044
3045 let options = GetOptions {
3047 path: VariantPath::default(),
3048 as_type: Some(Arc::new(Field::new("result", DataType::Float32, true))),
3049 cast_options: CastOptions {
3050 safe: false,
3051 ..Default::default()
3052 },
3053 };
3054
3055 let err = variant_get(&variant_array, options).unwrap_err();
3056 let msg = err.to_string();
3057 assert!(msg.contains("Failed to extract primitive of type Float32"));
3058 }
3059
3060 #[test]
3061 fn test_error_message_temporal_type_display() {
3062 let variant_array: ArrayRef = ArrayRef::from(VariantArray::from_iter([Some(false)]));
3063
3064 let options = GetOptions {
3066 path: VariantPath::default(),
3067 as_type: Some(Arc::new(Field::new(
3068 "result",
3069 DataType::Timestamp(TimeUnit::Nanosecond, None),
3070 true,
3071 ))),
3072 cast_options: CastOptions {
3073 safe: false,
3074 ..Default::default()
3075 },
3076 };
3077
3078 let err = variant_get(&variant_array, options).unwrap_err();
3079 let msg = err.to_string();
3080 assert!(msg.contains("Failed to extract primitive of type Timestamp(ns)"));
3081 }
3082
3083 #[test]
3084 fn test_null_buffer_union_for_shredded_paths() {
3085 let variant_array = create_depth_1_shredded_test_data_working();
3094
3095 let options = GetOptions {
3100 path: VariantPath::try_from("a.x").unwrap(),
3101 as_type: Some(Arc::new(Field::new("result", DataType::Int32, true))),
3102 cast_options: CastOptions::default(),
3103 };
3104
3105 let result = variant_get(&variant_array, options).unwrap();
3106
3107 assert_eq!(result.len(), variant_array.len());
3109
3110 assert!(!result.is_null(0), "Row 0 should have valid Int32 data");
3114 assert!(
3115 result.is_null(1),
3116 "Row 1 should be null due to type casting failure"
3117 );
3118
3119 let int32_result = result.as_any().downcast_ref::<Int32Array>().unwrap();
3121 assert_eq!(int32_result.value(0), 55); }
3123
3124 #[test]
3125 fn test_struct_null_mask_union_from_children() {
3126 let json_strings = vec![
3131 r#"{"a": 42, "b": "hello"}"#, r#"{"a": "world", "b": 100}"#, r#"{"a": 55, "b": 77}"#, ];
3135
3136 let string_array: Arc<dyn arrow::array::Array> = Arc::new(StringArray::from(json_strings));
3137 let variant_array = json_to_variant(&string_array).unwrap();
3138
3139 let struct_fields = Fields::from(vec![
3142 Field::new("a", DataType::Int32, true),
3143 Field::new("b", DataType::Int32, true),
3144 ]);
3145 let struct_type = DataType::Struct(struct_fields);
3146
3147 let options = GetOptions {
3148 path: VariantPath::default(), as_type: Some(Arc::new(Field::new("result", struct_type, true))),
3150 cast_options: CastOptions::default(),
3151 };
3152
3153 let variant_array_ref = ArrayRef::from(variant_array);
3154 let result = variant_get(&variant_array_ref, options).unwrap();
3155
3156 let struct_result = result.as_struct();
3158 assert_eq!(struct_result.len(), 3);
3159
3160 let field_a = struct_result
3162 .column(0)
3163 .as_any()
3164 .downcast_ref::<Int32Array>()
3165 .unwrap();
3166 let field_b = struct_result
3167 .column(1)
3168 .as_any()
3169 .downcast_ref::<Int32Array>()
3170 .unwrap();
3171
3172 assert!(!field_a.is_null(0));
3175 assert_eq!(field_a.value(0), 42);
3176 assert!(field_b.is_null(0)); assert!(field_a.is_null(1)); assert!(!field_b.is_null(1));
3181 assert_eq!(field_b.value(1), 100);
3182
3183 assert!(!field_a.is_null(2));
3185 assert_eq!(field_a.value(2), 55);
3186 assert!(!field_b.is_null(2));
3187 assert_eq!(field_b.value(2), 77);
3188
3189 assert!(!struct_result.is_null(0)); assert!(!struct_result.is_null(1)); assert!(!struct_result.is_null(2)); }
3196
3197 #[test]
3198 fn test_field_nullability_preservation() {
3199 let json_strings = vec![
3202 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}"#, ];
3212
3213 let string_array: Arc<dyn arrow::array::Array> = Arc::new(StringArray::from(json_strings));
3214 let variant_array = json_to_variant(&string_array).unwrap();
3215
3216 let nullable_field = Arc::new(Field::new("result", DataType::Int32, true));
3218 let options_nullable = GetOptions {
3219 path: VariantPath::try_from("x").unwrap(),
3220 as_type: Some(nullable_field.clone()),
3221 cast_options: CastOptions::default(),
3222 };
3223
3224 let variant_array_ref = ArrayRef::from(variant_array);
3225 let result_nullable = variant_get(&variant_array_ref, options_nullable).unwrap();
3226
3227 let int32_result = result_nullable
3229 .as_any()
3230 .downcast_ref::<Int32Array>()
3231 .unwrap();
3232 assert_eq!(int32_result.len(), 9);
3233
3234 assert!(!int32_result.is_null(0));
3236 assert_eq!(int32_result.value(0), 42);
3237
3238 assert!(int32_result.is_null(1));
3240
3241 assert!(int32_result.is_null(2));
3243
3244 assert!(int32_result.is_null(3));
3246
3247 assert!(int32_result.is_null(4));
3249
3250 assert!(!int32_result.is_null(5));
3253 assert_eq!(int32_result.value(5), 127);
3254
3255 assert!(!int32_result.is_null(6));
3258 assert_eq!(int32_result.value(6), 32767);
3259
3260 assert!(!int32_result.is_null(7));
3263 assert_eq!(int32_result.value(7), 2147483647);
3264
3265 assert!(int32_result.is_null(8));
3268
3269 let non_nullable_field = Arc::new(Field::new("result", DataType::Int32, false));
3271 let options_non_nullable = GetOptions {
3272 path: VariantPath::try_from("x").unwrap(),
3273 as_type: Some(non_nullable_field.clone()),
3274 cast_options: CastOptions::default(), };
3276
3277 let variant_array_2 = json_to_variant(&string_array).unwrap();
3279 let variant_array_ref_2 = ArrayRef::from(variant_array_2);
3280 let result_non_nullable = variant_get(&variant_array_ref_2, options_non_nullable).unwrap();
3281 let int32_result_2 = result_non_nullable
3282 .as_any()
3283 .downcast_ref::<Int32Array>()
3284 .unwrap();
3285
3286 assert_eq!(int32_result_2.len(), 9);
3288
3289 assert!(!int32_result_2.is_null(0));
3291 assert_eq!(int32_result_2.value(0), 42);
3292
3293 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);
3303 assert!(!int32_result_2.is_null(6)); assert_eq!(int32_result_2.value(6), 32767);
3305 assert!(!int32_result_2.is_null(7)); assert_eq!(int32_result_2.value(7), 2147483647);
3307
3308 assert!(int32_result_2.is_null(8)); }
3311
3312 #[test]
3313 fn test_struct_extraction_subset_superset_schema_perfectly_shredded() {
3314 let variant_array = create_comprehensive_shredded_variant();
3316
3317 let struct_fields = Fields::from(vec![
3319 Field::new("a", DataType::Int32, true),
3320 Field::new("b", DataType::Int32, true),
3321 Field::new("d", DataType::Int32, true),
3322 ]);
3323 let struct_type = DataType::Struct(struct_fields);
3324
3325 let options = GetOptions {
3326 path: VariantPath::default(),
3327 as_type: Some(Arc::new(Field::new("result", struct_type, true))),
3328 cast_options: CastOptions::default(),
3329 };
3330
3331 let result = variant_get(&variant_array, options).unwrap();
3332
3333 let struct_result = result.as_any().downcast_ref::<StructArray>().unwrap();
3335 assert_eq!(struct_result.len(), 5);
3336 assert_eq!(struct_result.num_columns(), 3);
3337
3338 let field_a = struct_result
3339 .column(0)
3340 .as_any()
3341 .downcast_ref::<Int32Array>()
3342 .unwrap();
3343 let field_b = struct_result
3344 .column(1)
3345 .as_any()
3346 .downcast_ref::<Int32Array>()
3347 .unwrap();
3348 let field_d = struct_result
3349 .column(2)
3350 .as_any()
3351 .downcast_ref::<Int32Array>()
3352 .unwrap();
3353
3354 assert!(!struct_result.is_null(0));
3356 assert_eq!(field_a.value(0), 1);
3357 assert_eq!(field_b.value(0), 2);
3358 assert!(field_d.is_null(0)); assert!(struct_result.is_null(1));
3362
3363 assert!(!struct_result.is_null(2));
3365 assert!(field_a.is_null(2)); assert_eq!(field_b.value(2), 2);
3367 assert!(field_d.is_null(2)); assert!(!struct_result.is_null(3));
3371 assert_eq!(field_a.value(3), 1);
3372 assert!(field_b.is_null(3)); assert!(field_d.is_null(3)); assert!(!struct_result.is_null(4));
3377 assert!(field_a.is_null(4)); assert!(field_b.is_null(4)); assert!(field_d.is_null(4)); }
3381
3382 #[test]
3383 fn test_nested_struct_extraction_perfectly_shredded() {
3384 let variant_array = create_comprehensive_nested_shredded_variant();
3386 println!("variant_array: {variant_array:?}");
3387
3388 let inner_field = Field::new("inner", DataType::Int32, true);
3390 let inner_type = DataType::Struct(Fields::from(vec![inner_field]));
3391 let outer_field = Field::new("outer", inner_type, true);
3392 let result_type = DataType::Struct(Fields::from(vec![outer_field]));
3393
3394 let options = GetOptions {
3395 path: VariantPath::default(),
3396 as_type: Some(Arc::new(Field::new("result", result_type, true))),
3397 cast_options: CastOptions::default(),
3398 };
3399
3400 let result = variant_get(&variant_array, options).unwrap();
3401 println!("result: {result:?}");
3402
3403 let outer_struct = result.as_any().downcast_ref::<StructArray>().unwrap();
3405 assert_eq!(outer_struct.len(), 4);
3406 assert_eq!(outer_struct.num_columns(), 1);
3407
3408 let inner_struct = outer_struct
3410 .column(0)
3411 .as_any()
3412 .downcast_ref::<StructArray>()
3413 .unwrap();
3414 assert_eq!(inner_struct.num_columns(), 1);
3415
3416 let leaf_field = inner_struct
3418 .column(0)
3419 .as_any()
3420 .downcast_ref::<Int32Array>()
3421 .unwrap();
3422
3423 assert!(!outer_struct.is_null(0));
3425 assert!(!inner_struct.is_null(0));
3426 assert_eq!(leaf_field.value(0), 42);
3427
3428 assert!(!outer_struct.is_null(1));
3430 assert!(!inner_struct.is_null(1)); assert!(leaf_field.is_null(1)); assert!(!outer_struct.is_null(2));
3435 assert!(inner_struct.is_null(2)); assert!(outer_struct.is_null(3));
3439 }
3440
3441 #[test]
3442 fn test_path_based_null_masks_one_step() {
3443 let variant_array = create_comprehensive_nested_shredded_variant();
3445
3446 let path = VariantPath::try_from("outer").unwrap();
3448 let inner_field = Field::new("inner", DataType::Int32, true);
3449 let result_type = DataType::Struct(Fields::from(vec![inner_field]));
3450
3451 let options = GetOptions {
3452 path,
3453 as_type: Some(Arc::new(Field::new("result", result_type, true))),
3454 cast_options: CastOptions::default(),
3455 };
3456
3457 let result = variant_get(&variant_array, options).unwrap();
3458
3459 let outer_result = result.as_any().downcast_ref::<StructArray>().unwrap();
3461 assert_eq!(outer_result.len(), 4);
3462 assert_eq!(outer_result.num_columns(), 1);
3463
3464 let inner_field = outer_result
3466 .column(0)
3467 .as_any()
3468 .downcast_ref::<Int32Array>()
3469 .unwrap();
3470
3471 assert!(!outer_result.is_null(0));
3473 assert_eq!(inner_field.value(0), 42);
3474
3475 assert!(!outer_result.is_null(1));
3477 assert!(inner_field.is_null(1));
3478
3479 assert!(outer_result.is_null(2));
3481
3482 assert!(outer_result.is_null(3));
3484 }
3485
3486 #[test]
3487 fn test_path_based_null_masks_two_steps() {
3488 let variant_array = create_comprehensive_nested_shredded_variant();
3490
3491 let path = VariantPath::try_from("outer").unwrap().join("inner");
3493
3494 let options = GetOptions {
3495 path,
3496 as_type: Some(Arc::new(Field::new("result", DataType::Int32, true))),
3497 cast_options: CastOptions::default(),
3498 };
3499
3500 let result = variant_get(&variant_array, options).unwrap();
3501
3502 let int_result = result.as_any().downcast_ref::<Int32Array>().unwrap();
3504 assert_eq!(int_result.len(), 4);
3505
3506 assert!(!int_result.is_null(0));
3508 assert_eq!(int_result.value(0), 42);
3509
3510 assert!(int_result.is_null(1));
3512
3513 assert!(int_result.is_null(2));
3515
3516 assert!(int_result.is_null(3));
3518 }
3519
3520 #[test]
3521 fn test_struct_extraction_mixed_and_unshredded() {
3522 let variant_array = create_mixed_and_unshredded_variant();
3524
3525 let struct_fields = Fields::from(vec![
3527 Field::new("x", DataType::Int32, true),
3528 Field::new("y", DataType::Int32, true),
3529 ]);
3530 let struct_type = DataType::Struct(struct_fields);
3531
3532 let options = GetOptions {
3533 path: VariantPath::default(),
3534 as_type: Some(Arc::new(Field::new("result", struct_type, true))),
3535 cast_options: CastOptions::default(),
3536 };
3537
3538 let result = variant_get(&variant_array, options).unwrap();
3539
3540 let struct_result = result.as_any().downcast_ref::<StructArray>().unwrap();
3542 assert_eq!(struct_result.len(), 4);
3543 assert_eq!(struct_result.num_columns(), 2);
3544
3545 let field_x = struct_result
3546 .column(0)
3547 .as_any()
3548 .downcast_ref::<Int32Array>()
3549 .unwrap();
3550 let field_y = struct_result
3551 .column(1)
3552 .as_any()
3553 .downcast_ref::<Int32Array>()
3554 .unwrap();
3555
3556 assert_eq!(field_x.value(0), 1);
3558 assert_eq!(field_y.value(0), 42);
3559
3560 assert_eq!(field_x.value(1), 2);
3562 assert!(field_y.is_null(1));
3563
3564 assert_eq!(field_x.value(2), 3);
3566 assert!(field_y.is_null(2));
3567
3568 assert!(struct_result.is_null(3));
3570 }
3571
3572 #[test]
3573 fn test_struct_row_builder_handles_unshredded_nested_structs() {
3574 let json_strings = vec![
3576 r#"{"outer": {"inner": 42}}"#,
3577 r#"{"outer": {"inner": 100}}"#,
3578 ];
3579 let string_array: Arc<dyn Array> = Arc::new(StringArray::from(json_strings));
3580 let variant_array = json_to_variant(&string_array).unwrap();
3581
3582 let inner_fields = Fields::from(vec![Field::new("inner", DataType::Int32, true)]);
3584 let inner_struct_type = DataType::Struct(inner_fields);
3585 let outer_fields = Fields::from(vec![Field::new("outer", inner_struct_type, true)]);
3586 let outer_struct_type = DataType::Struct(outer_fields);
3587
3588 let options = GetOptions {
3589 path: VariantPath::default(),
3590 as_type: Some(Arc::new(Field::new("result", outer_struct_type, true))),
3591 cast_options: CastOptions::default(),
3592 };
3593
3594 let variant_array_ref = ArrayRef::from(variant_array);
3595 let result = variant_get(&variant_array_ref, options).unwrap();
3596
3597 let outer_struct = result.as_struct();
3598 assert_eq!(outer_struct.len(), 2);
3599 assert_eq!(outer_struct.num_columns(), 1);
3600
3601 let inner_struct = outer_struct.column(0).as_struct();
3602 assert_eq!(inner_struct.num_columns(), 1);
3603
3604 let inner_values = inner_struct
3605 .column(0)
3606 .as_any()
3607 .downcast_ref::<Int32Array>()
3608 .unwrap();
3609 assert_eq!(inner_values.value(0), 42);
3610 assert_eq!(inner_values.value(1), 100);
3611 }
3612
3613 #[test]
3614 fn test_unshredded_struct_safe_cast_and_field_mismatches() {
3615 let json_strings = vec![r#"{"a": 1, "b": 2, "extra": 3}"#, "123", "{}"];
3616 let string_array: Arc<dyn Array> = Arc::new(StringArray::from(json_strings));
3617 let variant_array_ref = ArrayRef::from(json_to_variant(&string_array).unwrap());
3618
3619 let struct_fields = Fields::from(vec![
3620 Field::new("a", DataType::Int32, true),
3621 Field::new("b", DataType::Int32, true),
3622 ]);
3623 let options = GetOptions {
3624 path: VariantPath::default(),
3625 as_type: Some(Arc::new(Field::new(
3626 "result",
3627 DataType::Struct(struct_fields),
3628 true,
3629 ))),
3630 cast_options: CastOptions::default(),
3631 };
3632
3633 let result = variant_get(&variant_array_ref, options).unwrap();
3634 let struct_result = result.as_struct();
3635 let field_a = struct_result
3636 .column(0)
3637 .as_primitive::<arrow::datatypes::Int32Type>();
3638 let field_b = struct_result
3639 .column(1)
3640 .as_primitive::<arrow::datatypes::Int32Type>();
3641
3642 assert!(!struct_result.is_null(0));
3645 assert_eq!(field_a.value(0), 1);
3646 assert_eq!(field_b.value(0), 2);
3647
3648 assert!(struct_result.is_null(1));
3650 assert!(field_a.is_null(1));
3651 assert!(field_b.is_null(1));
3652
3653 assert!(!struct_result.is_null(2));
3655 assert!(field_a.is_null(2));
3656 assert!(field_b.is_null(2));
3657 }
3658
3659 #[test]
3660 fn test_unshredded_struct_missing_non_nullable_field_errors() {
3661 let string_array: Arc<dyn Array> = Arc::new(StringArray::from(vec![r#"{"a": 1}"#]));
3662 let variant_array_ref = ArrayRef::from(json_to_variant(&string_array).unwrap());
3663
3664 let struct_fields = Fields::from(vec![
3665 Field::new("a", DataType::Int32, false),
3666 Field::new("missing", DataType::Int32, false),
3667 ]);
3668 let options = GetOptions {
3669 path: VariantPath::default(),
3670 as_type: Some(Arc::new(Field::new(
3671 "result",
3672 DataType::Struct(struct_fields),
3673 true,
3674 ))),
3675 cast_options: CastOptions::default(),
3676 };
3677
3678 let err = variant_get(&variant_array_ref, options).unwrap_err();
3679 assert!(
3680 err.to_string()
3681 .contains("unmasked nulls for non-nullable StructArray field \"missing\""),
3682 "unexpected error: {err}"
3683 );
3684 }
3685
3686 #[test]
3687 fn test_unshredded_struct_strict_cast_non_object_errors() {
3688 let json_strings = vec![r#"{"a": 1, "b": 2}"#, "123"];
3689 let string_array: Arc<dyn Array> = Arc::new(StringArray::from(json_strings));
3690 let variant_array_ref = ArrayRef::from(json_to_variant(&string_array).unwrap());
3691
3692 let struct_fields = Fields::from(vec![
3693 Field::new("a", DataType::Int32, true),
3694 Field::new("b", DataType::Int32, true),
3695 ]);
3696 let options = GetOptions {
3697 path: VariantPath::default(),
3698 as_type: Some(Arc::new(Field::new(
3699 "result",
3700 DataType::Struct(struct_fields),
3701 true,
3702 ))),
3703 cast_options: CastOptions {
3704 safe: false,
3705 ..Default::default()
3706 },
3707 };
3708
3709 let err = variant_get(&variant_array_ref, options).unwrap_err();
3710 assert!(
3711 err.to_string()
3712 .contains("Failed to extract struct from variant")
3713 );
3714 }
3715
3716 fn create_comprehensive_shredded_variant() -> ArrayRef {
3719 let (metadata, _) = {
3720 let mut builder = parquet_variant::VariantBuilder::new();
3721 let obj = builder.new_object();
3722 obj.finish();
3723 builder.finish()
3724 };
3725
3726 let nulls = NullBuffer::from(vec![
3728 true, false, true, true, true, ]);
3734
3735 let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 5));
3736
3737 let a_field_typed_value = Int32Array::from(vec![Some(1), None, None, Some(1), None]);
3740 let a_field_shredded = ShreddedVariantFieldArray::perfectly_shredded(Arc::new(
3741 a_field_typed_value,
3742 ) as ArrayRef);
3743
3744 let b_field_typed_value = Int32Array::from(vec![Some(2), None, Some(2), None, None]);
3746 let b_field_shredded = ShreddedVariantFieldArray::perfectly_shredded(Arc::new(
3747 b_field_typed_value,
3748 ) as ArrayRef);
3749
3750 let c_field_typed_value = Int32Array::from(vec![Some(3), None, None, None, None]);
3752 let c_field_shredded = ShreddedVariantFieldArray::perfectly_shredded(Arc::new(
3753 c_field_typed_value,
3754 ) as ArrayRef);
3755
3756 let typed_value_fields = Fields::from(vec![
3758 Field::new("a", a_field_shredded.data_type().clone(), true),
3759 Field::new("b", b_field_shredded.data_type().clone(), true),
3760 Field::new("c", c_field_shredded.data_type().clone(), true),
3761 ]);
3762 let typed_value_struct = StructArray::try_new(
3763 typed_value_fields,
3764 vec![
3765 ArrayRef::from(a_field_shredded),
3766 ArrayRef::from(b_field_shredded),
3767 ArrayRef::from(c_field_shredded),
3768 ],
3769 None,
3770 )
3771 .unwrap();
3772
3773 ArrayRef::from(VariantArray::perfectly_shredded(
3775 Arc::new(metadata_array),
3776 Arc::new(typed_value_struct),
3777 Some(nulls),
3778 ))
3779 }
3780
3781 fn create_comprehensive_nested_shredded_variant() -> ArrayRef {
3786 let inner_typed_value = Int32Array::from(vec![Some(42), None, None, None]); let inner =
3790 ShreddedVariantFieldArray::perfectly_shredded(Arc::new(inner_typed_value) as ArrayRef);
3791
3792 let outer_typed_value_nulls = NullBuffer::from(vec![
3793 true, false, false, false, ]);
3798 let outer_typed_value = StructArrayAssembler::new()
3799 .with_field("inner", ArrayRef::from(inner), false)
3800 .with_nulls(outer_typed_value_nulls)
3801 .build()
3802 .unwrap();
3803
3804 let outer =
3805 ShreddedVariantFieldArray::perfectly_shredded(Arc::new(outer_typed_value) as ArrayRef);
3806
3807 let typed_value_nulls = NullBuffer::from(vec![
3808 true, true, false, false, ]);
3813 let typed_value = StructArrayAssembler::new()
3814 .with_field("outer", ArrayRef::from(outer), false)
3815 .with_nulls(typed_value_nulls)
3816 .build()
3817 .unwrap();
3818
3819 let metadata_array =
3821 BinaryViewArray::from_iter_values(std::iter::repeat_n(EMPTY_VARIANT_METADATA_BYTES, 4));
3822 let nulls = NullBuffer::from(vec![
3823 true, true, true, false, ]);
3828 ArrayRef::from(VariantArray::perfectly_shredded(
3829 Arc::new(metadata_array),
3830 Arc::new(typed_value),
3831 Some(nulls),
3832 ))
3833 }
3834
3835 fn create_mixed_and_unshredded_variant() -> ArrayRef {
3838 let (metadata, y_field_value) = {
3843 let mut builder = parquet_variant::VariantBuilder::new();
3844 let mut obj = builder.new_object();
3845 obj.insert("y", Variant::from(42));
3846 obj.finish();
3847 builder.finish()
3848 };
3849
3850 let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 4));
3851
3852 let empty_object_value = {
3859 let mut builder = parquet_variant::VariantBuilder::new();
3860 builder.new_object().finish();
3861 let (_, value) = builder.finish();
3862 value
3863 };
3864
3865 let y_null_value = {
3866 let mut builder = parquet_variant::VariantBuilder::new();
3867 builder.new_object().with_field("y", Variant::Null).finish();
3868 let (_, value) = builder.finish();
3869 value
3870 };
3871
3872 let value_array = BinaryViewArray::from(vec![
3873 Some(y_field_value.as_slice()), Some(empty_object_value.as_slice()), Some(y_null_value.as_slice()), Some(empty_object_value.as_slice()), ]);
3878
3879 let x_field_typed_value = Int32Array::from(vec![Some(1), Some(2), Some(3), Some(0)]);
3882 let x_field_shredded = ShreddedVariantFieldArray::perfectly_shredded(Arc::new(
3883 x_field_typed_value,
3884 ) as ArrayRef);
3885
3886 let typed_value_struct = StructArrayAssembler::new()
3888 .with_field("x", ArrayRef::from(x_field_shredded), false)
3889 .build()
3890 .unwrap();
3891
3892 let variant_nulls = NullBuffer::from(vec![true, true, true, false]); ArrayRef::from(VariantArray::from_parts(
3896 Arc::new(metadata_array),
3897 Arc::new(value_array),
3898 Some(Arc::new(typed_value_struct)),
3899 Some(variant_nulls),
3900 ))
3901 }
3902
3903 #[test]
3904 fn get_decimal32_rescaled_to_scale2() {
3905 let mut builder = crate::VariantArrayBuilder::new(5);
3907 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();
3911 builder.append_variant(
3912 VariantDecimal8::try_new((VariantDecimal4::MAX_UNSCALED_VALUE as i64) + 1, 3)
3913 .unwrap()
3914 .into(),
3915 ); let variant_array: ArrayRef = ArrayRef::from(builder.build());
3917
3918 let field = Field::new("result", DataType::Decimal32(9, 2), true);
3919 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3920 let result = variant_get(&variant_array, options).unwrap();
3921 let result = result.as_any().downcast_ref::<Decimal32Array>().unwrap();
3922
3923 assert_eq!(result.precision(), 9);
3924 assert_eq!(result.scale(), 2);
3925 assert_eq!(result.value(0), 1234);
3926 assert_eq!(result.value(1), 123);
3927 assert_eq!(result.value(2), 123400);
3928 assert!(result.is_null(3));
3929 assert_eq!(
3930 result.value(4),
3931 VariantDecimal4::MAX_UNSCALED_VALUE / 10 + 1
3932 ); }
3934
3935 #[test]
3936 fn get_decimal32_scale_down_rounding() {
3937 let variant_array: ArrayRef = ArrayRef::from(VariantArray::from_iter([
3938 Some(VariantDecimal4::try_new(1235, 0).unwrap()),
3939 Some(VariantDecimal4::try_new(1245, 0).unwrap()),
3940 Some(VariantDecimal4::try_new(-1235, 0).unwrap()),
3941 Some(VariantDecimal4::try_new(-1245, 0).unwrap()),
3942 Some(VariantDecimal4::try_new(1235, 2).unwrap()), Some(VariantDecimal4::try_new(1235, 3).unwrap()), Some(VariantDecimal4::try_new(5235, 3).unwrap()), ]));
3946
3947 let field = Field::new("result", DataType::Decimal32(9, -1), true);
3948 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3949 let result = variant_get(&variant_array, options).unwrap();
3950 let result = result.as_any().downcast_ref::<Decimal32Array>().unwrap();
3951
3952 assert_eq!(result.precision(), 9);
3953 assert_eq!(result.scale(), -1);
3954 assert_eq!(result.value(0), 124);
3955 assert_eq!(result.value(1), 125);
3956 assert_eq!(result.value(2), -124);
3957 assert_eq!(result.value(3), -125);
3958 assert_eq!(result.value(4), 1);
3959 assert!(result.is_valid(5));
3960 assert_eq!(result.value(5), 0);
3961 assert_eq!(result.value(6), 1);
3962 }
3963
3964 #[test]
3965 fn get_decimal32_large_scale_reduction() {
3966 let variant_array: ArrayRef = ArrayRef::from(VariantArray::from_iter([
3967 Some(VariantDecimal4::try_new(-VariantDecimal4::MAX_UNSCALED_VALUE, 0).unwrap()),
3968 Some(VariantDecimal4::try_new(VariantDecimal4::MAX_UNSCALED_VALUE, 0).unwrap()),
3969 ]));
3970
3971 let field = Field::new("result", DataType::Decimal32(9, -9), true);
3972 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3973 let result = variant_get(&variant_array, options).unwrap();
3974 let result = result.as_any().downcast_ref::<Decimal32Array>().unwrap();
3975
3976 assert_eq!(result.precision(), 9);
3977 assert_eq!(result.scale(), -9);
3978 assert_eq!(result.value(0), -1);
3979 assert_eq!(result.value(1), 1);
3980
3981 let field = Field::new("result", DataType::Decimal32(9, -10), true);
3982 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3983 let result = variant_get(&variant_array, options).unwrap();
3984 let result = result.as_any().downcast_ref::<Decimal32Array>().unwrap();
3985
3986 assert_eq!(result.precision(), 9);
3987 assert_eq!(result.scale(), -10);
3988 assert!(result.is_valid(0));
3989 assert_eq!(result.value(0), 0);
3990 assert!(result.is_valid(1));
3991 assert_eq!(result.value(1), 0);
3992 }
3993
3994 #[test]
3995 fn get_decimal32_precision_overflow_safe() {
3996 let variant_array = ArrayRef::from(VariantArray::from_iter([
3998 Some(Variant::from(
3999 VariantDecimal4::try_new(VariantDecimal4::MAX_UNSCALED_VALUE, 0).unwrap(),
4000 )),
4001 Some(Variant::from(
4003 VariantDecimal4::try_new(VariantDecimal4::MAX_UNSCALED_VALUE, 9).unwrap(),
4004 )),
4005 Some(Variant::Float(1.1)),
4007 Some(Variant::Double(1.1)),
4008 Some(Variant::Float(0.999)),
4009 Some(Variant::Double(0.999)),
4010 ]));
4011
4012 let field = Field::new("result", DataType::Decimal32(2, 2), true);
4013 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
4014 let result = variant_get(&variant_array, options).unwrap();
4015 let result = result.as_any().downcast_ref::<Decimal32Array>().unwrap();
4016
4017 assert_eq!(result.null_count(), 6); }
4019
4020 #[test]
4021 fn get_decimal32_precision_overflow_unsafe_errors() {
4022 for (value, kind) in [
4023 (
4024 VariantDecimal4::try_new(VariantDecimal4::MAX_UNSCALED_VALUE, 0)
4025 .unwrap()
4026 .into(),
4027 "Decimal4",
4028 ),
4029 (Variant::Float(1.1), "Float"),
4030 (Variant::Double(1.1), "Double"),
4031 (Variant::Float(0.999), "Float"),
4032 (Variant::Double(0.999), "Double"),
4033 ] {
4034 let variant_array = ArrayRef::from(VariantArray::from_iter([Some(value)]));
4035 let field = Field::new("result", DataType::Decimal32(2, 2), true);
4036 let options = GetOptions::new()
4037 .with_as_type(Some(FieldRef::from(field)))
4038 .with_cast_options(CastOptions {
4039 safe: false,
4040 ..Default::default()
4041 });
4042 let err = variant_get(&variant_array, options).unwrap_err();
4043 assert!(err.to_string().contains(&format!(
4044 "Failed to cast to Decimal32(precision=2, scale=2) from variant {kind}"
4045 )));
4046 }
4047 }
4048
4049 #[test]
4050 fn get_decimal64_rescaled_to_scale2() {
4051 let mut builder = crate::VariantArrayBuilder::new(5);
4052 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();
4056 builder.append_variant(
4057 VariantDecimal16::try_new((VariantDecimal8::MAX_UNSCALED_VALUE as i128) + 1, 3)
4058 .unwrap()
4059 .into(),
4060 ); let variant_array: ArrayRef = ArrayRef::from(builder.build());
4062
4063 let field = Field::new("result", DataType::Decimal64(18, 2), true);
4064 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
4065 let result = variant_get(&variant_array, options).unwrap();
4066 let result = result.as_any().downcast_ref::<Decimal64Array>().unwrap();
4067
4068 assert_eq!(result.precision(), 18);
4069 assert_eq!(result.scale(), 2);
4070 assert_eq!(result.value(0), 1234);
4071 assert_eq!(result.value(1), 123);
4072 assert_eq!(result.value(2), 123400);
4073 assert!(result.is_null(3));
4074 assert_eq!(
4075 result.value(4),
4076 VariantDecimal8::MAX_UNSCALED_VALUE / 10 + 1
4077 ); }
4079
4080 #[test]
4081 fn get_decimal64_scale_down_rounding() {
4082 let variant_array: ArrayRef = ArrayRef::from(VariantArray::from_iter([
4083 Some(VariantDecimal8::try_new(1235, 0).unwrap()),
4084 Some(VariantDecimal8::try_new(1245, 0).unwrap()),
4085 Some(VariantDecimal8::try_new(-1235, 0).unwrap()),
4086 Some(VariantDecimal8::try_new(-1245, 0).unwrap()),
4087 Some(VariantDecimal8::try_new(1235, 2).unwrap()), Some(VariantDecimal8::try_new(1235, 3).unwrap()), Some(VariantDecimal8::try_new(5235, 3).unwrap()), ]));
4091
4092 let field = Field::new("result", DataType::Decimal64(18, -1), true);
4093 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
4094 let result = variant_get(&variant_array, options).unwrap();
4095 let result = result.as_any().downcast_ref::<Decimal64Array>().unwrap();
4096
4097 assert_eq!(result.precision(), 18);
4098 assert_eq!(result.scale(), -1);
4099 assert_eq!(result.value(0), 124);
4100 assert_eq!(result.value(1), 125);
4101 assert_eq!(result.value(2), -124);
4102 assert_eq!(result.value(3), -125);
4103 assert_eq!(result.value(4), 1);
4104 assert!(result.is_valid(5));
4105 assert_eq!(result.value(5), 0);
4106 assert_eq!(result.value(6), 1);
4107 }
4108
4109 #[test]
4110 fn get_decimal64_large_scale_reduction() {
4111 let variant_array: ArrayRef = ArrayRef::from(VariantArray::from_iter([
4112 Some(VariantDecimal8::try_new(-VariantDecimal8::MAX_UNSCALED_VALUE, 0).unwrap()),
4113 Some(VariantDecimal8::try_new(VariantDecimal8::MAX_UNSCALED_VALUE, 0).unwrap()),
4114 ]));
4115
4116 let field = Field::new("result", DataType::Decimal64(18, -18), true);
4117 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
4118 let result = variant_get(&variant_array, options).unwrap();
4119 let result = result.as_any().downcast_ref::<Decimal64Array>().unwrap();
4120
4121 assert_eq!(result.precision(), 18);
4122 assert_eq!(result.scale(), -18);
4123 assert_eq!(result.value(0), -1);
4124 assert_eq!(result.value(1), 1);
4125
4126 let field = Field::new("result", DataType::Decimal64(18, -19), true);
4127 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
4128 let result = variant_get(&variant_array, options).unwrap();
4129 let result = result.as_any().downcast_ref::<Decimal64Array>().unwrap();
4130
4131 assert_eq!(result.precision(), 18);
4132 assert_eq!(result.scale(), -19);
4133 assert!(result.is_valid(0));
4134 assert_eq!(result.value(0), 0);
4135 assert!(result.is_valid(1));
4136 assert_eq!(result.value(1), 0);
4137 }
4138
4139 #[test]
4140 fn get_decimal64_precision_overflow_safe() {
4141 let variant_array: ArrayRef = ArrayRef::from(VariantArray::from_iter([
4143 Some(VariantDecimal8::try_new(VariantDecimal8::MAX_UNSCALED_VALUE, 0).unwrap()),
4144 Some(VariantDecimal8::try_new(VariantDecimal8::MAX_UNSCALED_VALUE, 18).unwrap()),
4146 ]));
4147
4148 let field = Field::new("result", DataType::Decimal64(2, 2), true);
4149 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
4150 let result = variant_get(&variant_array, options).unwrap();
4151 let result = result.as_any().downcast_ref::<Decimal64Array>().unwrap();
4152
4153 assert!(result.is_null(0));
4154 assert!(result.is_null(1));
4155 }
4156
4157 #[test]
4158 fn get_decimal64_precision_overflow_unsafe_errors() {
4159 let variant_array: ArrayRef = ArrayRef::from(VariantArray::from_iter([Some(
4160 VariantDecimal8::try_new(VariantDecimal8::MAX_UNSCALED_VALUE, 0).unwrap(),
4161 )]));
4162
4163 let field = Field::new("result", DataType::Decimal64(18, 2), true);
4164 let cast_options = CastOptions {
4165 safe: false,
4166 ..Default::default()
4167 };
4168 let options = GetOptions::new()
4169 .with_as_type(Some(FieldRef::from(field)))
4170 .with_cast_options(cast_options);
4171 let err = variant_get(&variant_array, options).unwrap_err();
4172
4173 assert!(
4174 err.to_string().contains(
4175 "Failed to cast to Decimal64(precision=18, scale=2) from variant Decimal8"
4176 )
4177 );
4178 }
4179
4180 #[test]
4181 fn get_decimal128_rescaled_to_scale2() {
4182 let variant_array: ArrayRef = ArrayRef::from(VariantArray::from_iter([
4183 Some(VariantDecimal16::try_new(1234, 2).unwrap()),
4184 Some(VariantDecimal16::try_new(1234, 3).unwrap()),
4185 Some(VariantDecimal16::try_new(1234, 0).unwrap()),
4186 None,
4187 ]));
4188
4189 let field = Field::new("result", DataType::Decimal128(38, 2), true);
4190 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
4191 let result = variant_get(&variant_array, options).unwrap();
4192 let result = result.as_any().downcast_ref::<Decimal128Array>().unwrap();
4193
4194 assert_eq!(result.precision(), 38);
4195 assert_eq!(result.scale(), 2);
4196 assert_eq!(result.value(0), 1234);
4197 assert_eq!(result.value(1), 123);
4198 assert_eq!(result.value(2), 123400);
4199 assert!(result.is_null(3));
4200 }
4201
4202 #[test]
4203 fn get_decimal128_scale_down_rounding() {
4204 let variant_array: ArrayRef = ArrayRef::from(VariantArray::from_iter([
4205 Some(VariantDecimal16::try_new(1235, 0).unwrap()),
4206 Some(VariantDecimal16::try_new(1245, 0).unwrap()),
4207 Some(VariantDecimal16::try_new(-1235, 0).unwrap()),
4208 Some(VariantDecimal16::try_new(-1245, 0).unwrap()),
4209 Some(VariantDecimal16::try_new(1235, 2).unwrap()), Some(VariantDecimal16::try_new(1235, 3).unwrap()), Some(VariantDecimal16::try_new(5235, 3).unwrap()), ]));
4213
4214 let field = Field::new("result", DataType::Decimal128(38, -1), true);
4215 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
4216 let result = variant_get(&variant_array, options).unwrap();
4217 let result = result.as_any().downcast_ref::<Decimal128Array>().unwrap();
4218
4219 assert_eq!(result.precision(), 38);
4220 assert_eq!(result.scale(), -1);
4221 assert_eq!(result.value(0), 124);
4222 assert_eq!(result.value(1), 125);
4223 assert_eq!(result.value(2), -124);
4224 assert_eq!(result.value(3), -125);
4225 assert_eq!(result.value(4), 1);
4226 assert!(result.is_valid(5));
4227 assert_eq!(result.value(5), 0);
4228 assert_eq!(result.value(6), 1);
4229 }
4230
4231 #[test]
4232 fn get_decimal128_precision_overflow_safe() {
4233 let variant_array: ArrayRef = ArrayRef::from(VariantArray::from_iter([
4235 Some(VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 0).unwrap()),
4236 Some(VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 38).unwrap()),
4238 ]));
4239
4240 let field = Field::new("result", DataType::Decimal128(2, 2), true);
4241 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
4242 let result = variant_get(&variant_array, options).unwrap();
4243 let result = result.as_any().downcast_ref::<Decimal128Array>().unwrap();
4244
4245 assert!(result.is_null(0));
4246 assert!(result.is_null(1)); }
4248
4249 #[test]
4250 fn get_decimal128_precision_overflow_unsafe_errors() {
4251 let variant_array: ArrayRef = ArrayRef::from(VariantArray::from_iter([Some(
4252 VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 0).unwrap(),
4253 )]));
4254
4255 let field = Field::new("result", DataType::Decimal128(38, 2), true);
4256 let cast_options = CastOptions {
4257 safe: false,
4258 ..Default::default()
4259 };
4260 let options = GetOptions::new()
4261 .with_as_type(Some(FieldRef::from(field)))
4262 .with_cast_options(cast_options);
4263 let err = variant_get(&variant_array, options).unwrap_err();
4264
4265 assert!(err.to_string().contains(
4266 "Failed to cast to Decimal128(precision=38, scale=2) from variant Decimal16"
4267 ));
4268 }
4269
4270 #[test]
4271 fn get_decimal256_rescaled_to_scale2() {
4272 let variant_array: ArrayRef = ArrayRef::from(VariantArray::from_iter([
4274 Some(VariantDecimal16::try_new(1234, 2).unwrap()), Some(VariantDecimal16::try_new(1234, 3).unwrap()), Some(VariantDecimal16::try_new(1234, 0).unwrap()), None,
4278 ]));
4279
4280 let field = Field::new("result", DataType::Decimal256(76, 2), true);
4281 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
4282 let result = variant_get(&variant_array, options).unwrap();
4283 let result = result.as_any().downcast_ref::<Decimal256Array>().unwrap();
4284
4285 assert_eq!(result.precision(), 76);
4286 assert_eq!(result.scale(), 2);
4287 assert_eq!(result.value(0), i256::from_i128(1234));
4288 assert_eq!(result.value(1), i256::from_i128(123));
4289 assert_eq!(result.value(2), i256::from_i128(123400));
4290 assert!(result.is_null(3));
4291 }
4292
4293 #[test]
4294 fn get_decimal256_scale_down_rounding() {
4295 let variant_array: ArrayRef = ArrayRef::from(VariantArray::from_iter([
4296 Some(VariantDecimal16::try_new(1235, 0).unwrap()),
4297 Some(VariantDecimal16::try_new(1245, 0).unwrap()),
4298 Some(VariantDecimal16::try_new(-1235, 0).unwrap()),
4299 Some(VariantDecimal16::try_new(-1245, 0).unwrap()),
4300 Some(VariantDecimal16::try_new(1235, 2).unwrap()), Some(VariantDecimal16::try_new(1235, 3).unwrap()), Some(VariantDecimal16::try_new(5235, 3).unwrap()), ]));
4304
4305 let field = Field::new("result", DataType::Decimal256(76, -1), true);
4306 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
4307 let result = variant_get(&variant_array, options).unwrap();
4308 let result = result.as_any().downcast_ref::<Decimal256Array>().unwrap();
4309
4310 assert_eq!(result.precision(), 76);
4311 assert_eq!(result.scale(), -1);
4312 assert_eq!(result.value(0), i256::from_i128(124));
4313 assert_eq!(result.value(1), i256::from_i128(125));
4314 assert_eq!(result.value(2), i256::from_i128(-124));
4315 assert_eq!(result.value(3), i256::from_i128(-125));
4316 assert_eq!(result.value(4), i256::from_i128(1));
4317 assert!(result.is_valid(5));
4318 assert_eq!(result.value(5), i256::from_i128(0));
4319 assert_eq!(result.value(6), i256::from_i128(1));
4320 }
4321
4322 #[test]
4323 fn get_decimal256_precision_overflow_safe() {
4324 let variant_array: ArrayRef = ArrayRef::from(VariantArray::from_iter([
4326 Some(VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 1).unwrap()),
4327 Some(VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 0).unwrap()),
4328 ]));
4329
4330 let field = Field::new("result", DataType::Decimal256(76, 39), true);
4331 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
4332 let result = variant_get(&variant_array, options).unwrap();
4333 let result = result.as_any().downcast_ref::<Decimal256Array>().unwrap();
4334
4335 let base = i256::from_i128(10);
4338 let factor = base.checked_pow(38).unwrap();
4339 let expected = i256::from_i128(VariantDecimal16::MAX_UNSCALED_VALUE)
4340 .checked_mul(factor)
4341 .unwrap();
4342 assert_eq!(result.value(0), expected);
4343 assert!(result.is_null(1));
4344 }
4345
4346 #[test]
4347 fn get_decimal256_precision_overflow_unsafe_errors() {
4348 let variant_array: ArrayRef = ArrayRef::from(VariantArray::from_iter([
4350 Some(VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 1).unwrap()),
4351 Some(VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 0).unwrap()),
4352 ]));
4353
4354 let field = Field::new("result", DataType::Decimal256(76, 39), true);
4355 let cast_options = CastOptions {
4356 safe: false,
4357 ..Default::default()
4358 };
4359 let options = GetOptions::new()
4360 .with_as_type(Some(FieldRef::from(field)))
4361 .with_cast_options(cast_options);
4362 let err = variant_get(&variant_array, options).unwrap_err();
4363
4364 assert!(err.to_string().contains(
4365 "Failed to cast to Decimal256(precision=76, scale=39) from variant Decimal16"
4366 ));
4367 }
4368
4369 #[test]
4370 fn get_non_supported_temporal_types_error() {
4371 let values = vec![None, Some(Variant::Null), Some(Variant::BooleanFalse)];
4372 let variant_array: ArrayRef = ArrayRef::from(VariantArray::from_iter(values));
4373
4374 let test_cases = vec![
4375 FieldRef::from(Field::new(
4376 "result",
4377 DataType::Duration(TimeUnit::Microsecond),
4378 true,
4379 )),
4380 FieldRef::from(Field::new(
4381 "result",
4382 DataType::Interval(IntervalUnit::YearMonth),
4383 true,
4384 )),
4385 ];
4386
4387 for field in test_cases {
4388 let options = GetOptions::new().with_as_type(Some(field));
4389 let err = variant_get(&variant_array, options).unwrap_err();
4390 assert!(
4391 err.to_string()
4392 .contains("Casting Variant to duration/interval types is not supported")
4393 );
4394 }
4395 }
4396
4397 #[test]
4398 fn get_variant_as_dictionary() {
4399 let variant_array: ArrayRef = ArrayRef::from(VariantArray::from_iter([
4400 Some("apple"),
4401 Some("banana"),
4402 None,
4403 Some("apple"),
4404 ]));
4405 let data_type = DataType::Dictionary(Box::new(DataType::Int32), Box::new(DataType::Utf8));
4406 let options = GetOptions::new().with_as_type(Some(FieldRef::from(Field::new(
4407 "dict",
4408 data_type.clone(),
4409 true,
4410 ))));
4411
4412 let result = variant_get(&variant_array, options).unwrap();
4413 assert_eq!(result.data_type(), &data_type);
4414
4415 let decoded = cast(result.as_ref(), &DataType::Utf8).unwrap();
4416 let expected = StringArray::from(vec![Some("apple"), Some("banana"), None, Some("apple")]);
4417 assert_eq!(decoded.as_ref(), &expected);
4418 }
4419
4420 #[test]
4421 fn get_variant_as_numeric_dictionary() {
4422 let variant_array: ArrayRef =
4423 ArrayRef::from(VariantArray::from_iter([Some(42), Some(7), None, Some(42)]));
4424 let data_type = DataType::Dictionary(Box::new(DataType::Int16), Box::new(DataType::Int32));
4425 let options = GetOptions::new().with_as_type(Some(FieldRef::from(Field::new(
4426 "dict",
4427 data_type.clone(),
4428 true,
4429 ))));
4430
4431 let result = variant_get(&variant_array, options).unwrap();
4432 assert_eq!(result.data_type(), &data_type);
4433
4434 let decoded = cast(result.as_ref(), &DataType::Int32).unwrap();
4435 let expected = Int32Array::from(vec![Some(42), Some(7), None, Some(42)]);
4436 assert_eq!(decoded.as_ref(), &expected);
4437 }
4438
4439 #[test]
4440 fn get_variant_as_run_end_encoded() {
4441 let variant_array: ArrayRef = ArrayRef::from(VariantArray::from_iter([
4442 Some("apple"),
4443 Some("apple"),
4444 None,
4445 Some("banana"),
4446 Some("banana"),
4447 ]));
4448 let run_ends = Arc::new(Field::new(
4449 Field::REE_RUN_ENDS_FIELD_DEFAULT_NAME,
4450 DataType::Int32,
4451 false,
4452 ));
4453 let values = Arc::new(Field::new(
4454 Field::REE_VALUES_FIELD_DEFAULT_NAME,
4455 DataType::Utf8,
4456 true,
4457 ));
4458 let data_type = DataType::RunEndEncoded(run_ends, values);
4459 let options = GetOptions::new().with_as_type(Some(FieldRef::from(Field::new(
4460 "ree",
4461 data_type.clone(),
4462 true,
4463 ))));
4464
4465 let result = variant_get(&variant_array, options).unwrap();
4466 assert_eq!(result.data_type(), &data_type);
4467
4468 let decoded = cast(result.as_ref(), &DataType::Utf8).unwrap();
4469 let expected = StringArray::from(vec![
4470 Some("apple"),
4471 Some("apple"),
4472 None,
4473 Some("banana"),
4474 Some("banana"),
4475 ]);
4476 assert_eq!(decoded.as_ref(), &expected);
4477 }
4478
4479 fn map_data_type(value_type: DataType) -> DataType {
4482 DataType::Map(
4483 Arc::new(Field::new(
4484 "entries",
4485 DataType::Struct(Fields::from(vec![
4486 Field::new("keys", DataType::Utf8, false),
4487 Field::new("values", value_type, true),
4488 ])),
4489 false,
4490 )),
4491 false,
4492 )
4493 }
4494
4495 fn map_get_options(data_type: &DataType) -> GetOptions<'static> {
4496 GetOptions::new().with_as_type(Some(FieldRef::from(Field::new(
4497 "map",
4498 data_type.clone(),
4499 true,
4500 ))))
4501 }
4502
4503 #[test]
4504 fn get_variant_as_map() {
4505 let input: ArrayRef = Arc::new(StringArray::from(vec![
4506 Some(r#"{"a": 1, "b": 2}"#),
4507 Some(r#"{"c": 3}"#),
4508 None,
4509 Some("{}"),
4510 Some(r#"{"d": null}"#),
4511 ]));
4512 let variant_array = ArrayRef::from(json_to_variant(&input).unwrap());
4513
4514 let data_type = map_data_type(DataType::Int64);
4515 let result = variant_get(&variant_array, map_get_options(&data_type)).unwrap();
4516 assert_eq!(result.data_type(), &data_type);
4517
4518 let mut expected = MapBuilder::new(None, StringBuilder::new(), Int64Builder::new());
4519 expected.keys().append_value("a");
4520 expected.values().append_value(1);
4521 expected.keys().append_value("b");
4522 expected.values().append_value(2);
4523 expected.append(true).unwrap();
4524 expected.keys().append_value("c");
4525 expected.values().append_value(3);
4526 expected.append(true).unwrap();
4527 expected.append(false).unwrap(); expected.append(true).unwrap(); expected.keys().append_value("d");
4530 expected.values().append_null(); expected.append(true).unwrap();
4532 let expected = expected.finish();
4533 assert_eq!(result.as_ref(), &expected);
4534 }
4535
4536 #[test]
4537 fn get_variant_as_map_of_lists() {
4538 let input: ArrayRef = Arc::new(StringArray::from(vec![
4539 Some(r#"{"a": [1, 2], "b": []}"#),
4540 Some(r#"{"c": [3]}"#),
4541 ]));
4542 let variant_array = ArrayRef::from(json_to_variant(&input).unwrap());
4543
4544 let data_type = map_data_type(DataType::List(Arc::new(Field::new(
4545 "item",
4546 DataType::Int64,
4547 true,
4548 ))));
4549 let result = variant_get(&variant_array, map_get_options(&data_type)).unwrap();
4550 assert_eq!(result.data_type(), &data_type);
4551
4552 let mut expected = MapBuilder::new(
4553 None,
4554 StringBuilder::new(),
4555 ListBuilder::new(Int64Builder::new()),
4556 );
4557 expected.keys().append_value("a");
4558 expected.values().append_value([Some(1), Some(2)]);
4559 expected.keys().append_value("b");
4560 expected.values().append_value([]);
4561 expected.append(true).unwrap();
4562 expected.keys().append_value("c");
4563 expected.values().append_value([Some(3)]);
4564 expected.append(true).unwrap();
4565 let expected = expected.finish();
4566 assert_eq!(result.as_ref(), &expected);
4567 }
4568
4569 #[test]
4570 fn get_variant_as_map_non_object_rows() {
4571 let input: ArrayRef = Arc::new(StringArray::from(vec![
4572 Some(r#"{"a": 1}"#),
4573 Some("42"), ]));
4575 let variant_array = ArrayRef::from(json_to_variant(&input).unwrap());
4576 let data_type = map_data_type(DataType::Int64);
4577
4578 let result = variant_get(&variant_array, map_get_options(&data_type)).unwrap();
4580 let mut expected = MapBuilder::new(None, StringBuilder::new(), Int64Builder::new());
4581 expected.keys().append_value("a");
4582 expected.values().append_value(1);
4583 expected.append(true).unwrap();
4584 expected.append(false).unwrap();
4585 let expected = expected.finish();
4586 assert_eq!(result.as_ref(), &expected);
4587
4588 let options = map_get_options(&data_type).with_cast_options(CastOptions {
4590 safe: false,
4591 format_options: FormatOptions::default(),
4592 });
4593 let err = variant_get(&variant_array, options).unwrap_err();
4594 assert!(
4595 err.to_string().contains("Failed to extract object"),
4596 "unexpected error: {err}"
4597 );
4598 }
4599
4600 #[test]
4601 fn get_variant_as_map_invalid_entries() {
4602 let input: ArrayRef = Arc::new(StringArray::from(vec![Some(r#"{"a": 1}"#)]));
4603 let variant_array = ArrayRef::from(json_to_variant(&input).unwrap());
4604
4605 let data_type = DataType::Map(
4607 Arc::new(Field::new("entries", DataType::Int32, false)),
4608 false,
4609 );
4610 let err = variant_get(&variant_array, map_get_options(&data_type)).unwrap_err();
4611 assert!(
4612 err.to_string().contains("Map entries must be Struct"),
4613 "unexpected error: {err}"
4614 );
4615
4616 let data_type = DataType::Map(
4618 Arc::new(Field::new(
4619 "entries",
4620 DataType::Struct(Fields::from(vec![Field::new(
4621 "keys",
4622 DataType::Utf8,
4623 false,
4624 )])),
4625 false,
4626 )),
4627 false,
4628 );
4629 let err = variant_get(&variant_array, map_get_options(&data_type)).unwrap_err();
4630 assert!(
4631 err.to_string()
4632 .contains("Map entries must have exactly two fields"),
4633 "unexpected error: {err}"
4634 );
4635 }
4636
4637 fn invalid_time_variant_array() -> ArrayRef {
4638 ArrayRef::from(VariantArray::from_iter([Some(86401000000_i64); 3]))
4640 }
4641
4642 #[test]
4643 fn test_variant_get_error_when_cast_failure_and_safe_false() {
4644 let variant_array = invalid_time_variant_array();
4645
4646 let field = Field::new("result", DataType::Time64(TimeUnit::Microsecond), true);
4647 let cast_options = CastOptions {
4648 safe: false, ..Default::default()
4650 };
4651 let options = GetOptions::new()
4652 .with_as_type(Some(FieldRef::from(field)))
4653 .with_cast_options(cast_options);
4654 let err = variant_get(&variant_array, options).unwrap_err();
4655 assert!(
4656 err.to_string().contains(
4657 "Cast error: Failed to extract primitive of type Time64(µs) from variant Int64(86401000000) at path VariantPath([])"
4658 ),
4659 "actual: {err}",
4660 );
4661 }
4662
4663 #[test]
4664 fn test_variant_get_return_null_when_cast_failure_and_safe_true() {
4665 let variant_array = invalid_time_variant_array();
4666
4667 let field = Field::new("result", DataType::Time64(TimeUnit::Microsecond), true);
4668 let cast_options = CastOptions {
4669 safe: true, ..Default::default()
4671 };
4672 let options = GetOptions::new()
4673 .with_as_type(Some(FieldRef::from(field)))
4674 .with_cast_options(cast_options);
4675 let result = variant_get(&variant_array, options).unwrap();
4676 assert_eq!(3, result.len());
4677
4678 for i in 0..3 {
4679 assert!(result.is_null(i));
4680 }
4681 }
4682
4683 #[test]
4684 fn test_perfect_shredding_returns_same_arc_ptr() {
4685 let variant_array = perfectly_shredded_int32_variant_array();
4686
4687 let variant_array_ref = VariantArray::try_new(&variant_array).unwrap();
4688 let typed_value_arc = variant_array_ref.typed_value_column().unwrap().clone();
4689
4690 let field = Field::new("result", DataType::Int32, true);
4691 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
4692 let result = variant_get(&variant_array, options).unwrap();
4693
4694 assert!(Arc::ptr_eq(&typed_value_arc, &result));
4695 }
4696
4697 #[test]
4698 fn test_perfect_shredding_three_typed_value_columns() {
4699 let all_nulls_values: Arc<Int32Array> = Arc::new(Int32Array::from(vec![
4701 Option::<i32>::None,
4702 Option::<i32>::None,
4703 Option::<i32>::None,
4704 ]));
4705 let all_nulls_erased: ArrayRef = all_nulls_values.clone();
4706 let all_nulls_field =
4707 ShreddedVariantFieldArray::perfectly_shredded(all_nulls_erased.clone());
4708 let all_nulls_type = all_nulls_field.data_type().clone();
4709 let all_nulls_struct: ArrayRef = ArrayRef::from(all_nulls_field);
4710
4711 let some_nulls_values: Arc<Int32Array> =
4713 Arc::new(Int32Array::from(vec![Some(10), None, Some(30)]));
4714 let some_nulls_erased: ArrayRef = some_nulls_values.clone();
4715 let some_nulls_field =
4716 ShreddedVariantFieldArray::perfectly_shredded(some_nulls_erased.clone());
4717 let some_nulls_type = some_nulls_field.data_type().clone();
4718 let some_nulls_struct: ArrayRef = ArrayRef::from(some_nulls_field);
4719
4720 let inner_values: Arc<Int32Array> =
4722 Arc::new(Int32Array::from(vec![Some(111), None, Some(333)]));
4723 let inner_erased: ArrayRef = inner_values.clone();
4724 let inner_field = ShreddedVariantFieldArray::perfectly_shredded(inner_erased.clone());
4725 let inner_field_type = inner_field.data_type().clone();
4726 let inner_struct_array: ArrayRef = ArrayRef::from(inner_field);
4727
4728 let nested_struct = Arc::new(
4729 StructArray::try_new(
4730 Fields::from(vec![Field::new("inner", inner_field_type, true)]),
4731 vec![inner_struct_array],
4732 None,
4733 )
4734 .unwrap(),
4735 );
4736 let nested_struct_erased: ArrayRef = nested_struct.clone();
4737 let struct_field =
4738 ShreddedVariantFieldArray::perfectly_shredded(nested_struct_erased.clone());
4739 let struct_field_type = struct_field.data_type().clone();
4740 let struct_field_struct: ArrayRef = ArrayRef::from(struct_field);
4741
4742 let typed_value_struct = StructArray::try_new(
4744 Fields::from(vec![
4745 Field::new("all_nulls", all_nulls_type, true),
4746 Field::new("some_nulls", some_nulls_type, true),
4747 Field::new("struct_field", struct_field_type, true),
4748 ]),
4749 vec![all_nulls_struct, some_nulls_struct, struct_field_struct],
4750 None,
4751 )
4752 .unwrap();
4753
4754 let metadata = BinaryViewArray::from_iter_values(std::iter::repeat_n(
4755 EMPTY_VARIANT_METADATA_BYTES,
4756 all_nulls_values.len(),
4757 ));
4758 let variant_array: ArrayRef = VariantArray::perfectly_shredded(
4759 Arc::new(metadata),
4760 Arc::new(typed_value_struct),
4761 None,
4762 )
4763 .into();
4764
4765 let all_nulls_field_ref = FieldRef::from(Field::new("result", DataType::Int32, true));
4767 let all_nulls_result = variant_get(
4768 &variant_array,
4769 GetOptions::new_with_path(VariantPath::try_from("all_nulls").unwrap())
4770 .with_as_type(Some(all_nulls_field_ref)),
4771 )
4772 .unwrap();
4773 assert!(Arc::ptr_eq(&all_nulls_result, &all_nulls_erased));
4774
4775 let some_nulls_field_ref = FieldRef::from(Field::new("result", DataType::Int32, true));
4777 let some_nulls_result = variant_get(
4778 &variant_array,
4779 GetOptions::new_with_path(VariantPath::try_from("some_nulls").unwrap())
4780 .with_as_type(Some(some_nulls_field_ref)),
4781 )
4782 .unwrap();
4783 assert!(Arc::ptr_eq(&some_nulls_result, &some_nulls_erased));
4784
4785 let struct_child_fields = Fields::from(vec![Field::new("inner", DataType::Int32, true)]);
4787 let struct_field_ref = FieldRef::from(Field::new(
4788 "result",
4789 DataType::Struct(struct_child_fields.clone()),
4790 true,
4791 ));
4792 let struct_result = variant_get(
4793 &variant_array,
4794 GetOptions::new_with_path(VariantPath::try_from("struct_field").unwrap())
4795 .with_as_type(Some(struct_field_ref)),
4796 )
4797 .unwrap();
4798 let struct_array = struct_result
4799 .as_any()
4800 .downcast_ref::<StructArray>()
4801 .unwrap();
4802 assert_eq!(struct_array.len(), 3);
4803 assert_eq!(struct_array.null_count(), 0);
4804
4805 let inner_values_result = struct_array
4806 .column(0)
4807 .as_any()
4808 .downcast_ref::<Int32Array>()
4809 .unwrap();
4810 assert_eq!(inner_values_result.len(), 3);
4811 assert_eq!(inner_values_result.value(0), 111);
4812 assert!(inner_values_result.is_null(1));
4813 assert_eq!(inner_values_result.value(2), 333);
4814 }
4815
4816 #[test]
4817 fn test_variant_get_list_like_safe_cast() {
4818 let string_array: ArrayRef = Arc::new(StringArray::from(vec![
4819 r#"{"outer":{"list":[1, "two", 3]}}"#,
4820 r#"{"outer":{"list":"not a list"}}"#,
4821 ]));
4822 let variant_array = ArrayRef::from(json_to_variant(&string_array).unwrap());
4823
4824 let element_array: ArrayRef = Arc::new(Int64Array::from(vec![Some(1), None, Some(3)]));
4825 let field = Arc::new(Field::new("item", Int64, true));
4826
4827 let expectations = vec![
4828 (
4829 DataType::List(field.clone()),
4830 Arc::new(ListArray::new(
4831 field.clone(),
4832 OffsetBuffer::new(ScalarBuffer::from(vec![0, 3, 3])),
4833 element_array.clone(),
4834 Some(NullBuffer::from(vec![true, false])),
4835 )) as ArrayRef,
4836 ),
4837 (
4838 DataType::LargeList(field.clone()),
4839 Arc::new(LargeListArray::new(
4840 field.clone(),
4841 OffsetBuffer::new(ScalarBuffer::from(vec![0, 3, 3])),
4842 element_array.clone(),
4843 Some(NullBuffer::from(vec![true, false])),
4844 )) as ArrayRef,
4845 ),
4846 (
4847 DataType::ListView(field.clone()),
4848 Arc::new(ListViewArray::new(
4849 field.clone(),
4850 ScalarBuffer::from(vec![0, 3]),
4851 ScalarBuffer::from(vec![3, 0]),
4852 element_array.clone(),
4853 Some(NullBuffer::from(vec![true, false])),
4854 )) as ArrayRef,
4855 ),
4856 (
4857 DataType::LargeListView(field.clone()),
4858 Arc::new(LargeListViewArray::new(
4859 field.clone(),
4860 ScalarBuffer::from(vec![0, 3]),
4861 ScalarBuffer::from(vec![3, 0]),
4862 element_array,
4863 Some(NullBuffer::from(vec![true, false])),
4864 )) as ArrayRef,
4865 ),
4866 (
4867 DataType::FixedSizeList(field.clone(), 3),
4868 Arc::new(FixedSizeListArray::new(
4869 field,
4870 3,
4871 Arc::new(Int64Array::from(vec![
4872 Some(1),
4873 None,
4874 Some(3),
4875 None,
4876 None,
4877 None,
4878 ])),
4879 Some(NullBuffer::from(vec![true, false])),
4880 )) as ArrayRef,
4881 ),
4882 ];
4883
4884 for (request_type, expected) in expectations {
4885 let options =
4886 GetOptions::new_with_path(VariantPath::try_from("outer").unwrap().join("list"))
4887 .with_as_type(Some(FieldRef::from(Field::new(
4888 "result",
4889 request_type.clone(),
4890 true,
4891 ))));
4892
4893 let result = variant_get(&variant_array, options).unwrap();
4894 assert_eq!(result.data_type(), expected.data_type());
4895 assert_eq!(&result, &expected);
4896 }
4897
4898 for (idx, expected) in [
4899 (0, vec![Some(1), None]),
4900 (1, vec![None, None]),
4901 (2, vec![Some(3), None]),
4902 ] {
4903 let index_options = GetOptions::new_with_path(
4904 VariantPath::try_from("outer")
4905 .unwrap()
4906 .join("list")
4907 .join(idx),
4908 )
4909 .with_as_type(Some(FieldRef::from(Field::new(
4910 "result",
4911 DataType::Int64,
4912 true,
4913 ))));
4914 let index_result = variant_get(&variant_array, index_options).unwrap();
4915 let index_expected: ArrayRef = Arc::new(Int64Array::from(expected));
4916 assert_eq!(&index_result, &index_expected);
4917 }
4918 }
4919
4920 #[test]
4921 fn test_variant_get_nested_list() {
4922 use arrow::datatypes::Int64Type;
4923
4924 let string_array: ArrayRef = Arc::new(StringArray::from(vec![
4925 "[[1, 2], [3]]",
4926 r#"[[4], "not a list", [5, 6]]"#,
4927 ]));
4928 let variant_array = ArrayRef::from(json_to_variant(&string_array).unwrap());
4929
4930 let inner_field = Arc::new(Field::new("item", Int64, true));
4931 let outer_field = Arc::new(Field::new(
4932 "item",
4933 DataType::List(inner_field.clone()),
4934 true,
4935 ));
4936 let request_type = DataType::List(outer_field.clone());
4937
4938 let options = GetOptions::new().with_as_type(Some(FieldRef::from(Field::new(
4939 "result",
4940 request_type,
4941 true,
4942 ))));
4943 let result = variant_get(&variant_array, options).unwrap();
4944 let outer = result.as_list::<i32>();
4945
4946 let row0 = outer.value(0);
4948 let row0 = row0.as_list::<i32>();
4949 assert_eq!(row0.len(), 2);
4950 let elem0 = row0.value(0);
4951 assert_eq!(elem0.as_primitive::<Int64Type>().values(), &[1, 2]);
4952 let elem1 = row0.value(1);
4953 assert_eq!(elem1.as_primitive::<Int64Type>().values(), &[3]);
4954
4955 let row1 = outer.value(1);
4957 let row1 = row1.as_list::<i32>();
4958 assert_eq!(row1.len(), 3);
4959 let elem0 = row1.value(0);
4960 assert_eq!(elem0.as_primitive::<Int64Type>().values(), &[4]);
4961 assert!(row1.is_null(1));
4962 let elem2 = row1.value(2);
4963 assert_eq!(elem2.as_primitive::<Int64Type>().values(), &[5, 6]);
4964 }
4965
4966 #[test]
4967 fn test_variant_get_list_like_unsafe_cast_errors_on_element_mismatch() {
4968 let string_array: ArrayRef =
4969 Arc::new(StringArray::from(vec![r#"[1, "two", 3]"#, "[4, 5]"]));
4970 let variant_array = ArrayRef::from(json_to_variant(&string_array).unwrap());
4971 let cast_options = CastOptions {
4972 safe: false,
4973 ..Default::default()
4974 };
4975
4976 let item_field = Arc::new(Field::new("item", DataType::Int64, true));
4977 let request_types = vec![
4978 DataType::List(item_field.clone()),
4979 DataType::LargeList(item_field.clone()),
4980 DataType::ListView(item_field.clone()),
4981 DataType::LargeListView(item_field),
4982 ];
4983
4984 for request_type in request_types {
4985 let options = GetOptions::new()
4986 .with_as_type(Some(FieldRef::from(Field::new(
4987 "result",
4988 request_type.clone(),
4989 true,
4990 ))))
4991 .with_cast_options(cast_options.clone());
4992
4993 let err = variant_get(&variant_array, options).unwrap_err();
4994 assert!(
4995 err.to_string()
4996 .contains("Failed to extract primitive of type Int64")
4997 );
4998 }
4999 }
5000
5001 #[test]
5002 fn test_variant_get_list_like_unsafe_cast_preserves_null_elements() {
5003 let string_array: ArrayRef = Arc::new(StringArray::from(vec!["[1, null, 3]"]));
5004 let variant_array = ArrayRef::from(json_to_variant(&string_array).unwrap());
5005 let cast_options = CastOptions {
5006 safe: false,
5007 ..Default::default()
5008 };
5009 let options = GetOptions::new()
5010 .with_as_type(Some(FieldRef::from(Field::new(
5011 "result",
5012 DataType::List(Arc::new(Field::new("item", DataType::Int64, true))),
5013 true,
5014 ))))
5015 .with_cast_options(cast_options);
5016
5017 let result = variant_get(&variant_array, options).unwrap();
5018 let list_array = result.as_any().downcast_ref::<ListArray>().unwrap();
5019 let values = list_array
5020 .values()
5021 .as_any()
5022 .downcast_ref::<Int64Array>()
5023 .unwrap();
5024
5025 assert_eq!(values.len(), 3);
5026 assert_eq!(values.value(0), 1);
5027 assert!(values.is_null(1));
5028 assert_eq!(values.value(2), 3);
5029 }
5030
5031 #[test]
5032 fn test_variant_get_list_like_null_element_in_non_nullable_item() {
5033 let item_field = Arc::new(Field::new("item", Int64, false));
5034 let data_types = [
5035 (DataType::List(item_field.clone()), "ListArray"),
5036 (DataType::LargeList(item_field.clone()), "LargeListArray"),
5037 (DataType::ListView(item_field.clone()), "ListViewArray"),
5038 (DataType::LargeListView(item_field), "LargeListViewArray"),
5039 ];
5040 for json in ["[1, null, 3]", r#"[1, "two", 3]"#] {
5042 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json]));
5043 let variant_array = ArrayRef::from(json_to_variant(&string_array).unwrap());
5044 for (data_type, array_name) in &data_types {
5045 let options = GetOptions::new().with_as_type(Some(FieldRef::from(Field::new(
5046 "result",
5047 data_type.clone(),
5048 true,
5049 ))));
5050 let err = variant_get(&variant_array, options).unwrap_err();
5051 assert_eq!(
5052 err.to_string(),
5053 format!(
5054 "Invalid argument error: Non-nullable field of {array_name} \"item\" cannot contain nulls"
5055 )
5056 );
5057 }
5058 }
5059 }
5060
5061 #[test]
5062 fn test_variant_get_list_like_unsafe_cast_errors_on_non_list() {
5063 let string_array: ArrayRef = Arc::new(StringArray::from(vec!["[1, 2]", "\"not a list\""]));
5064 let variant_array = ArrayRef::from(json_to_variant(&string_array).unwrap());
5065 let cast_options = CastOptions {
5066 safe: false,
5067 ..Default::default()
5068 };
5069 let item_field = Arc::new(Field::new("item", Int64, true));
5070 let data_types = vec![
5071 DataType::List(item_field.clone()),
5072 DataType::LargeList(item_field.clone()),
5073 DataType::ListView(item_field.clone()),
5074 DataType::LargeListView(item_field.clone()),
5075 DataType::FixedSizeList(item_field, 2),
5076 ];
5077
5078 for data_type in data_types {
5079 let options = GetOptions::new()
5080 .with_as_type(Some(FieldRef::from(Field::new("result", data_type, true))))
5081 .with_cast_options(cast_options.clone());
5082
5083 let err = variant_get(&variant_array, options).unwrap_err();
5084 assert!(
5085 err.to_string()
5086 .contains("Failed to extract list from variant"),
5087 );
5088 }
5089 }
5090
5091 #[test]
5092 fn test_variant_get_fixed_size_list_wrong_size() {
5093 let string_array: ArrayRef = Arc::new(StringArray::from(vec!["[1, 2, 3]"]));
5094 let variant_array = ArrayRef::from(json_to_variant(&string_array).unwrap());
5095 let item_field = Arc::new(Field::new("item", Int64, true));
5096
5097 let options = GetOptions::new()
5099 .with_as_type(Some(FieldRef::from(Field::new(
5100 "result",
5101 DataType::FixedSizeList(item_field.clone(), 2),
5102 true,
5103 ))))
5104 .with_cast_options(CastOptions {
5105 safe: true,
5106 ..Default::default()
5107 });
5108 let result = variant_get(&variant_array, options).unwrap();
5109 let fixed_size_list = result
5110 .as_any()
5111 .downcast_ref::<FixedSizeListArray>()
5112 .expect("Expected FixedSizeListArray");
5113 assert_eq!(fixed_size_list.len(), 1);
5114 assert!(fixed_size_list.is_null(0));
5115
5116 let options = GetOptions::new()
5118 .with_as_type(Some(FieldRef::from(Field::new(
5119 "result",
5120 DataType::FixedSizeList(item_field.clone(), 2),
5121 true,
5122 ))))
5123 .with_cast_options(CastOptions {
5124 safe: false,
5125 ..Default::default()
5126 });
5127 let err = variant_get(&variant_array, options).unwrap_err();
5128 assert!(
5129 err.to_string()
5130 .contains("Expected fixed size list of size 2, got size 3"),
5131 "got: {err}",
5132 );
5133 }
5134
5135 macro_rules! perfectly_shredded_preserves_top_level_nulls_test {
5136 ($name:ident, $result_type:expr, $typed_value:expr, $expected_array:expr) => {
5137 perfectly_shredded_preserves_top_level_nulls_test!(
5138 $name,
5139 $result_type,
5140 $typed_value,
5141 Some(NullBuffer::from(vec![true, false, true])),
5142 $expected_array
5143 );
5144 };
5145 ($name:ident, $result_type:expr, $typed_value:expr, $parent_nulls:expr, $expected_array:expr) => {
5146 #[test]
5147 fn $name() {
5148 let metadata = Arc::new(BinaryViewArray::from_iter_values(std::iter::repeat_n(
5149 EMPTY_VARIANT_METADATA_BYTES,
5150 3,
5151 )));
5152 let typed_value: ArrayRef = Arc::new($typed_value);
5153 let variant_array: ArrayRef =
5154 VariantArray::perfectly_shredded(metadata, typed_value, $parent_nulls).into();
5155
5156 let result = variant_get(
5157 &variant_array,
5158 GetOptions::new().with_as_type(Some(FieldRef::from(Field::new(
5159 "result",
5160 $result_type,
5161 true,
5162 )))),
5163 )
5164 .unwrap();
5165
5166 let expected_array: ArrayRef = Arc::new($expected_array);
5167 assert_eq!(&result, &expected_array);
5168 }
5169 };
5170 }
5171
5172 perfectly_shredded_preserves_top_level_nulls_test!(
5173 test_variant_get_perfectly_shredded_integer_preserves_top_level_nulls,
5174 DataType::Int32,
5175 Int32Array::from(vec![Some(0_i32), Some(1_i32), Some(2_i32)]),
5176 Int32Array::from(vec![Some(0_i32), None, Some(2_i32)])
5177 );
5178
5179 perfectly_shredded_preserves_top_level_nulls_test!(
5180 test_variant_get_perfectly_shredded_integer_unions_child_and_top_level_nulls,
5181 DataType::Int32,
5182 Int32Array::from(vec![None, Some(1_i32), Some(2_i32)]),
5183 Some(NullBuffer::from(vec![true, false, true])),
5184 Int32Array::from(vec![None, None, Some(2_i32)])
5185 );
5186
5187 perfectly_shredded_preserves_top_level_nulls_test!(
5188 test_variant_get_perfectly_shredded_null_preserves_top_level_nulls,
5189 DataType::Null,
5190 NullArray::new(3),
5191 NullArray::new(3)
5192 );
5193
5194 perfectly_shredded_preserves_top_level_nulls_test!(
5195 test_variant_get_perfectly_shredded_binary_view_preserves_top_level_nulls,
5196 DataType::BinaryView,
5197 BinaryViewArray::from(vec![
5198 Some(b"Apache" as &[u8]),
5199 Some(b"masked-null" as &[u8]),
5200 Some(b"Parquet-variant" as &[u8]),
5201 ]),
5202 BinaryViewArray::from(vec![
5203 Some(b"Apache" as &[u8]),
5204 None,
5205 Some(b"Parquet-variant" as &[u8]),
5206 ])
5207 );
5208
5209 perfectly_shredded_preserves_top_level_nulls_test!(
5210 test_variant_get_perfectly_shredded_binary_preserves_top_level_nulls,
5211 DataType::Binary,
5212 BinaryArray::from(vec![
5213 Some(b"Apache" as &[u8]),
5214 Some(b"masked-null" as &[u8]),
5215 Some(b"Parquet-variant" as &[u8]),
5216 ]),
5217 BinaryArray::from(vec![
5218 Some(b"Apache" as &[u8]),
5219 None,
5220 Some(b"Parquet-variant" as &[u8]),
5221 ])
5222 );
5223
5224 perfectly_shredded_preserves_top_level_nulls_test!(
5225 test_variant_get_perfectly_shredded_decimal4_preserves_top_level_nulls,
5226 DataType::Decimal32(5, 2),
5227 Decimal32Array::from(vec![Some(12345), Some(23400), Some(-12342)])
5228 .with_precision_and_scale(5, 2)
5229 .unwrap(),
5230 Decimal32Array::from(vec![Some(12345), None, Some(-12342)])
5231 .with_precision_and_scale(5, 2)
5232 .unwrap()
5233 );
5234
5235 perfectly_shredded_preserves_top_level_nulls_test!(
5236 test_variant_get_perfectly_shredded_decimal8_preserves_top_level_nulls,
5237 DataType::Decimal64(10, 1),
5238 Decimal64Array::from(vec![Some(1234567809), Some(1456787000), Some(-1234561203)])
5239 .with_precision_and_scale(10, 1)
5240 .unwrap(),
5241 Decimal64Array::from(vec![Some(1234567809), None, Some(-1234561203)])
5242 .with_precision_and_scale(10, 1)
5243 .unwrap()
5244 );
5245
5246 perfectly_shredded_preserves_top_level_nulls_test!(
5247 test_variant_get_perfectly_shredded_decimal16_preserves_top_level_nulls,
5248 DataType::Decimal128(20, 3),
5249 Decimal128Array::from(vec![
5250 Some(i128::from_str("12345678901234567899").unwrap()),
5251 Some(i128::from_str("23445677483748324300").unwrap()),
5252 Some(i128::from_str("-12345678901234567899").unwrap()),
5253 ])
5254 .with_precision_and_scale(20, 3)
5255 .unwrap(),
5256 Decimal128Array::from(vec![
5257 Some(i128::from_str("12345678901234567899").unwrap()),
5258 None,
5259 Some(i128::from_str("-12345678901234567899").unwrap()),
5260 ])
5261 .with_precision_and_scale(20, 3)
5262 .unwrap()
5263 );
5264
5265 fn union_get_options(fields: &UnionFields, mode: UnionMode) -> GetOptions<'static> {
5266 let field = Field::new("union", DataType::Union(fields.clone(), mode), true);
5267 GetOptions::new().with_as_type(Some(FieldRef::from(field)))
5268 }
5269
5270 fn int_str_bool_union_fields() -> UnionFields {
5271 UnionFields::try_new(
5272 vec![0, 1, 2],
5273 vec![
5274 Field::new("int", DataType::Int64, true),
5275 Field::new("str", DataType::Utf8, true),
5276 Field::new("bool", DataType::Boolean, true),
5277 ],
5278 )
5279 .unwrap()
5280 }
5281
5282 fn mixed_variant_array() -> ArrayRef {
5284 let mut builder = VariantArrayBuilder::new(7);
5285 builder.append_variant(Variant::Int8(1));
5286 builder.append_variant(Variant::from("hello"));
5287 builder.append_variant(Variant::from(true));
5288 builder.append_null();
5289 builder.append_variant(Variant::Null);
5290 builder.append_variant(Variant::Double(2.5));
5291 builder.append_variant(Variant::Int64(5_000_000_000));
5292 ArrayRef::from(builder.build())
5293 }
5294
5295 #[test]
5296 fn get_variant_as_dense_union() {
5297 let fields = int_str_bool_union_fields();
5298 let array = mixed_variant_array();
5299 let result = variant_get(&array, union_get_options(&fields, UnionMode::Dense)).unwrap();
5300
5301 let expected: ArrayRef = Arc::new(
5303 UnionArray::try_new(
5304 fields,
5305 ScalarBuffer::from(vec![0i8, 1, 2, 0, 0, 0, 0]),
5306 Some(ScalarBuffer::from(vec![0i32, 0, 0, 1, 2, 3, 4])),
5307 vec![
5308 Arc::new(Int64Array::from(vec![
5309 Some(1),
5310 None,
5311 None,
5312 None,
5313 Some(5_000_000_000),
5314 ])),
5315 Arc::new(StringArray::from(vec!["hello"])),
5316 Arc::new(BooleanArray::from(vec![true])),
5317 ],
5318 )
5319 .unwrap(),
5320 );
5321 assert_eq!(&result, &expected);
5322 }
5323
5324 #[test]
5325 fn get_variant_as_sparse_union() {
5326 let fields = int_str_bool_union_fields();
5327 let array = mixed_variant_array();
5328 let result = variant_get(&array, union_get_options(&fields, UnionMode::Sparse)).unwrap();
5329
5330 let expected: ArrayRef = Arc::new(
5331 UnionArray::try_new(
5332 fields,
5333 ScalarBuffer::from(vec![0i8, 1, 2, 0, 0, 0, 0]),
5334 None,
5335 vec![
5336 Arc::new(Int64Array::from(vec![
5337 Some(1),
5338 None,
5339 None,
5340 None,
5341 None,
5342 None,
5343 Some(5_000_000_000),
5344 ])),
5345 Arc::new(StringArray::from(vec![
5346 None,
5347 Some("hello"),
5348 None,
5349 None,
5350 None,
5351 None,
5352 None,
5353 ])),
5354 Arc::new(BooleanArray::from(vec![
5355 None,
5356 None,
5357 Some(true),
5358 None,
5359 None,
5360 None,
5361 None,
5362 ])),
5363 ],
5364 )
5365 .unwrap(),
5366 );
5367 assert_eq!(&result, &expected);
5368 }
5369
5370 #[test]
5371 fn get_variant_as_union_prefers_most_exact_field() {
5372 let fields = UnionFields::try_new(
5374 vec![0, 1],
5375 vec![
5376 Field::new("big", DataType::Int64, true),
5377 Field::new("small", DataType::Int32, true),
5378 ],
5379 )
5380 .unwrap();
5381 let mut builder = VariantArrayBuilder::new(3);
5382 builder.append_variant(Variant::Int8(1));
5383 builder.append_variant(Variant::Int32(2));
5384 builder.append_variant(Variant::Int64(3));
5385 let array = ArrayRef::from(builder.build());
5386
5387 let result = variant_get(&array, union_get_options(&fields, UnionMode::Dense)).unwrap();
5388
5389 let expected: ArrayRef = Arc::new(
5390 UnionArray::try_new(
5391 fields,
5392 ScalarBuffer::from(vec![1i8, 1, 0]),
5393 Some(ScalarBuffer::from(vec![0i32, 1, 0])),
5394 vec![
5395 Arc::new(Int64Array::from(vec![3])),
5396 Arc::new(Int32Array::from(vec![1, 2])),
5397 ],
5398 )
5399 .unwrap(),
5400 );
5401 assert_eq!(&result, &expected);
5402 }
5403
5404 #[test]
5405 fn get_variant_as_union_with_encoded_children() {
5406 let encoded_types = [
5407 DataType::Dictionary(Box::new(DataType::Int32), Box::new(DataType::Utf8)),
5408 DataType::RunEndEncoded(
5409 Arc::new(Field::new(
5410 Field::REE_RUN_ENDS_FIELD_DEFAULT_NAME,
5411 DataType::Int32,
5412 false,
5413 )),
5414 Arc::new(Field::new(
5415 Field::REE_VALUES_FIELD_DEFAULT_NAME,
5416 DataType::Utf8,
5417 true,
5418 )),
5419 ),
5420 ];
5421
5422 for data_type in encoded_types {
5423 let fields = UnionFields::try_new(
5424 vec![0],
5425 vec![Field::new("encoded", data_type.clone(), true)],
5426 )
5427 .unwrap();
5428 let array = ArrayRef::from(VariantArray::from_iter([Some("apple"), Some("banana")]));
5429 let options =
5430 union_get_options(&fields, UnionMode::Dense).with_cast_options(CastOptions {
5431 safe: false,
5432 ..Default::default()
5433 });
5434
5435 let result = variant_get(&array, options).unwrap();
5436 let union = result.as_any().downcast_ref::<UnionArray>().unwrap();
5437 assert_eq!(union.type_ids(), &[0i8, 0]);
5438 assert_eq!(union.child(0).data_type(), &data_type);
5439
5440 let decoded = cast(union.child(0).as_ref(), &DataType::Utf8).unwrap();
5441 let expected = StringArray::from(vec!["apple", "banana"]);
5442 assert_eq!(decoded.as_ref(), &expected);
5443 }
5444 }
5445
5446 #[test]
5447 fn get_variant_as_union_with_fixed_size_list_child() {
5448 let item = Arc::new(Field::new("item", DataType::Int64, true));
5449 let fields = UnionFields::try_new(
5450 vec![0],
5451 vec![Field::new("fixed", DataType::FixedSizeList(item, 2), true)],
5452 )
5453 .unwrap();
5454 let json = StringArray::from(vec!["[1, 2]"]);
5455 let array = ArrayRef::from(json_to_variant(&(Arc::new(json) as ArrayRef)).unwrap());
5456
5457 for safe in [true, false] {
5458 let options =
5459 union_get_options(&fields, UnionMode::Dense).with_cast_options(CastOptions {
5460 safe,
5461 ..Default::default()
5462 });
5463 let result = variant_get(&array, options).unwrap();
5464 let union = result.as_any().downcast_ref::<UnionArray>().unwrap();
5465 assert_eq!(union.type_ids(), &[0i8]);
5466 let list = union
5467 .child(0)
5468 .as_any()
5469 .downcast_ref::<FixedSizeListArray>()
5470 .unwrap();
5471 assert_eq!(
5472 list.value(0)
5473 .as_primitive::<arrow::datatypes::Int64Type>()
5474 .values(),
5475 &[1, 2]
5476 );
5477 }
5478 }
5479
5480 #[test]
5481 fn get_variant_as_union_skips_decimal_that_cannot_fit() {
5482 let fields = UnionFields::try_new(
5483 vec![0, 1],
5484 vec![
5485 Field::new("too_narrow", DataType::Decimal32(3, 2), true),
5486 Field::new("fits", DataType::Decimal32(5, 2), true),
5487 ],
5488 )
5489 .unwrap();
5490 let array = ArrayRef::from(VariantArray::from_iter([Some(
5491 VariantDecimal4::try_new(12_345, 2).unwrap(),
5492 )]));
5493
5494 for safe in [true, false] {
5495 let options =
5496 union_get_options(&fields, UnionMode::Dense).with_cast_options(CastOptions {
5497 safe,
5498 ..Default::default()
5499 });
5500 let result = variant_get(&array, options).unwrap();
5501 let union = result.as_any().downcast_ref::<UnionArray>().unwrap();
5502 assert_eq!(union.type_ids(), &[1i8]);
5503 let decimal = union
5504 .child(1)
5505 .as_any()
5506 .downcast_ref::<Decimal32Array>()
5507 .unwrap();
5508 assert_eq!(decimal.value(0), 12_345);
5509 }
5510 }
5511
5512 #[test]
5513 fn get_variant_as_union_with_null_field() {
5514 let fields = UnionFields::try_new(
5516 vec![0, 1],
5517 vec![
5518 Field::new("int", DataType::Int64, true),
5519 Field::new("null", DataType::Null, true),
5520 ],
5521 )
5522 .unwrap();
5523 let mut builder = VariantArrayBuilder::new(4);
5524 builder.append_variant(Variant::Int8(1));
5525 builder.append_null();
5526 builder.append_variant(Variant::Null);
5527 builder.append_variant(Variant::from("no matching field"));
5528 let array = ArrayRef::from(builder.build());
5529
5530 let result = variant_get(&array, union_get_options(&fields, UnionMode::Dense)).unwrap();
5531
5532 let expected: ArrayRef = Arc::new(
5533 UnionArray::try_new(
5534 fields,
5535 ScalarBuffer::from(vec![0i8, 1, 1, 1]),
5536 Some(ScalarBuffer::from(vec![0i32, 0, 1, 2])),
5537 vec![
5538 Arc::new(Int64Array::from(vec![1])),
5539 Arc::new(NullArray::new(3)),
5540 ],
5541 )
5542 .unwrap(),
5543 );
5544 assert_eq!(&result, &expected);
5545 }
5546
5547 #[test]
5548 fn get_variant_as_union_of_nested_types() {
5549 let fields = UnionFields::try_new(
5550 vec![0, 1, 2],
5551 vec![
5552 Field::new(
5553 "struct",
5554 DataType::Struct(Fields::from(vec![Field::new("a", DataType::Int64, true)])),
5555 true,
5556 ),
5557 Field::new(
5558 "list",
5559 DataType::List(Arc::new(Field::new("item", DataType::Int64, true))),
5560 true,
5561 ),
5562 Field::new("str", DataType::Utf8, true),
5563 ],
5564 )
5565 .unwrap();
5566 let json = StringArray::from(vec![r#"{"a": 1}"#, "[1, 2, 3]", "\"s\""]);
5567 let array = ArrayRef::from(json_to_variant(&(Arc::new(json) as ArrayRef)).unwrap());
5568
5569 let result = variant_get(&array, union_get_options(&fields, UnionMode::Dense)).unwrap();
5570
5571 let mut list_builder = ListBuilder::new(Int64Builder::new());
5572 list_builder.append_value([Some(1), Some(2), Some(3)]);
5573 let expected: ArrayRef = Arc::new(
5574 UnionArray::try_new(
5575 fields,
5576 ScalarBuffer::from(vec![0i8, 1, 2]),
5577 Some(ScalarBuffer::from(vec![0i32, 0, 0])),
5578 vec![
5579 Arc::new(StructArray::from(vec![(
5580 Arc::new(Field::new("a", DataType::Int64, true)),
5581 Arc::new(Int64Array::from(vec![1])) as ArrayRef,
5582 )])),
5583 Arc::new(list_builder.finish()),
5584 Arc::new(StringArray::from(vec!["s"])),
5585 ],
5586 )
5587 .unwrap(),
5588 );
5589 assert_eq!(&result, &expected);
5590 }
5591
5592 #[test]
5593 fn get_variant_as_union_with_map_field() {
5594 let fields = UnionFields::try_new(
5596 vec![0, 1],
5597 vec![
5598 Field::new("map", map_data_type(DataType::Int64), true),
5599 Field::new("str", DataType::Utf8, true),
5600 ],
5601 )
5602 .unwrap();
5603 let json = StringArray::from(vec![r#"{"a": 1, "b": 2}"#, "\"hi\""]);
5604 let array = ArrayRef::from(json_to_variant(&(Arc::new(json) as ArrayRef)).unwrap());
5605
5606 let result = variant_get(&array, union_get_options(&fields, UnionMode::Dense)).unwrap();
5607
5608 let mut map_builder = MapBuilder::new(None, StringBuilder::new(), Int64Builder::new());
5609 map_builder.keys().append_value("a");
5610 map_builder.values().append_value(1);
5611 map_builder.keys().append_value("b");
5612 map_builder.values().append_value(2);
5613 map_builder.append(true).unwrap();
5614 let expected: ArrayRef = Arc::new(
5615 UnionArray::try_new(
5616 fields,
5617 ScalarBuffer::from(vec![0i8, 1]),
5618 Some(ScalarBuffer::from(vec![0i32, 0])),
5619 vec![
5620 Arc::new(map_builder.finish()),
5621 Arc::new(StringArray::from(vec!["hi"])),
5622 ],
5623 )
5624 .unwrap(),
5625 );
5626 assert_eq!(&result, &expected);
5627 }
5628
5629 #[test]
5630 fn get_variant_as_union_prefers_struct_over_map() {
5631 let fields = UnionFields::try_new(
5634 vec![0, 1],
5635 vec![
5636 Field::new("map", map_data_type(DataType::Int64), true),
5637 Field::new(
5638 "struct",
5639 DataType::Struct(Fields::from(vec![Field::new("a", DataType::Int64, true)])),
5640 true,
5641 ),
5642 ],
5643 )
5644 .unwrap();
5645 let json = StringArray::from(vec![r#"{"a": 1}"#]);
5646 let array = ArrayRef::from(json_to_variant(&(Arc::new(json) as ArrayRef)).unwrap());
5647
5648 let result = variant_get(&array, union_get_options(&fields, UnionMode::Dense)).unwrap();
5649 let union = result.as_any().downcast_ref::<UnionArray>().unwrap();
5650 assert_eq!(union.type_ids(), &[1i8]);
5652 }
5653
5654 #[test]
5655 fn get_variant_as_union_no_matching_field() {
5656 let fields =
5658 UnionFields::try_new(vec![0], vec![Field::new("str", DataType::Utf8, false)]).unwrap();
5659 let mut builder = VariantArrayBuilder::new(2);
5660 builder.append_variant(Variant::from("kept"));
5661 builder.append_variant(Variant::Int8(1));
5662 let array = ArrayRef::from(builder.build());
5663
5664 let result = variant_get(&array, union_get_options(&fields, UnionMode::Dense)).unwrap();
5666 let expected: ArrayRef = Arc::new(
5667 UnionArray::try_new(
5668 fields.clone(),
5669 ScalarBuffer::from(vec![0i8, 0]),
5670 Some(ScalarBuffer::from(vec![0i32, 1])),
5671 vec![Arc::new(StringArray::from(vec![Some("kept"), None]))],
5672 )
5673 .unwrap(),
5674 );
5675 assert_eq!(&result, &expected);
5676
5677 let options = union_get_options(&fields, UnionMode::Dense).with_cast_options(CastOptions {
5679 safe: false,
5680 ..Default::default()
5681 });
5682 let err = variant_get(&array, options).unwrap_err();
5683 assert!(
5684 err.to_string().contains("no field can represent it"),
5685 "unexpected error: {err}"
5686 );
5687 }
5688
5689 #[test]
5690 fn get_variant_as_union_empty_fields_errors() {
5691 let array = ArrayRef::from(VariantArray::from_iter([Some(1_i8)]));
5692
5693 let err = variant_get(
5694 &array,
5695 union_get_options(&UnionFields::empty(), UnionMode::Dense),
5696 )
5697 .unwrap_err();
5698 assert!(
5699 err.to_string().contains("at least one union field"),
5700 "unexpected error: {err}"
5701 );
5702 }
5703}