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