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