1use arrow::{
18 array::{
19 self, Array, ArrayRef, GenericListArray, GenericListViewArray, ListLikeArray, StructArray,
20 UInt64Array, make_array,
21 },
22 buffer::NullBuffer,
23 compute::{CastOptions, take},
24 datatypes::Field,
25 error::Result,
26};
27use arrow_schema::{ArrowError, DataType, FieldRef};
28use parquet_variant::{VariantPath, VariantPathElement};
29
30use crate::ShreddingState;
31use crate::variant_array::all_null_value_column;
32use crate::variant_to_arrow::make_variant_to_arrow_row_builder;
33use crate::{VariantArray, VariantType, unshred_variant};
34
35use arrow::array::AsArray;
36use std::sync::Arc;
37
38pub(crate) enum ShreddedPathStep {
39 Success(ShreddingState),
41 Missing,
44 NotShredded,
48}
49
50fn take_list_like_index_as_shredding_state<L: ListLikeArray + 'static>(
53 typed_value: &dyn Array,
54 index: usize,
55) -> Result<Option<ShreddingState>> {
56 let list_array = typed_value.as_any().downcast_ref::<L>().ok_or_else(|| {
57 ArrowError::ComputeError(format!(
58 "Expected array type '{}' while handling list-like path step, got '{}'",
59 std::any::type_name::<L>(),
60 typed_value.data_type()
61 ))
62 })?;
63
64 let values = list_array.values();
65
66 let Some(struct_array) = values.as_struct_opt() else {
67 return Ok(None);
68 };
69 let shredding_state = ShreddingState::try_from(struct_array)?;
70
71 let value_array = shredding_state.value_column();
72 let typed_array = shredding_state.typed_value_column();
73
74 if typed_array.is_none() && value_array.null_count() == value_array.len() {
76 return Ok(None);
77 }
78
79 let mut take_indices = Vec::with_capacity(list_array.len());
80 for row in 0..list_array.len() {
81 let row_range = list_array.element_range(row);
82 let take_index = (index < row_range.len()).then(|| (row_range.start + index) as u64);
83 take_indices.push(take_index);
84 }
85
86 let index_array = UInt64Array::from(take_indices);
87
88 let taken_value = take(value_array, &index_array, None)?;
90 let taken_typed = typed_array
91 .map(|typed| take(typed, &index_array, None))
92 .transpose()?;
93
94 Ok(Some(ShreddingState::new(taken_value, taken_typed)))
95}
96
97pub(crate) fn follow_shredded_path_element(
113 shredding_state: &ShreddingState,
114 path_element: &VariantPathElement<'_>,
115 _cast_options: &CastOptions,
116) -> Result<ShreddedPathStep> {
117 let missing_path_step = || {
120 let value = shredding_state.value_column();
121 if value.null_count() == value.len() {
122 ShreddedPathStep::Missing
123 } else {
124 ShreddedPathStep::NotShredded
125 }
126 };
127
128 let Some(typed_value) = shredding_state.typed_value_column() else {
129 return Ok(missing_path_step());
130 };
131
132 match path_element {
133 VariantPathElement::Field { name } => {
134 let Some(struct_array) = typed_value.as_struct_opt() else {
137 return Ok(missing_path_step());
139 };
140
141 let Some(field) = struct_array.column_by_name(name) else {
143 return Ok(missing_path_step());
145 };
146
147 let struct_array = field.as_struct_opt().ok_or_else(|| {
148 ArrowError::InvalidArgumentError(format!(
152 "Expected Struct array while following path, got {}",
153 field.data_type(),
154 ))
155 })?;
156
157 let state = ShreddingState::try_from(struct_array)?;
158 Ok(ShreddedPathStep::Success(state))
159 }
160 VariantPathElement::Index { index } => {
161 let state = match typed_value.data_type() {
162 DataType::List(_) => take_list_like_index_as_shredding_state::<
163 GenericListArray<i32>,
164 >(typed_value.as_ref(), *index)?,
165 DataType::LargeList(_) => take_list_like_index_as_shredding_state::<
166 GenericListArray<i64>,
167 >(typed_value.as_ref(), *index)?,
168 DataType::ListView(_) => take_list_like_index_as_shredding_state::<
169 GenericListViewArray<i32>,
170 >(typed_value.as_ref(), *index)?,
171 DataType::LargeListView(_) => take_list_like_index_as_shredding_state::<
172 GenericListViewArray<i64>,
173 >(typed_value.as_ref(), *index)?,
174 _ => {
175 return Ok(missing_path_step());
177 }
178 };
179
180 match state {
181 Some(state) => Ok(ShreddedPathStep::Success(state)),
182 None => Ok(missing_path_step()),
183 }
184 }
185 }
186}
187
188fn shredded_get_path(
192 input: &VariantArray,
193 path: &[VariantPathElement<'_>],
194 as_field: Option<&Field>,
195 cast_options: &CastOptions,
196) -> Result<ArrayRef> {
197 let make_target_variant =
200 |value: ArrayRef, typed_value: Option<ArrayRef>, accumulated_nulls: Option<NullBuffer>| {
201 let metadata = input.metadata_column().clone();
202 VariantArray::from_parts(metadata, value, typed_value, accumulated_nulls)
203 };
204
205 let shred_basic_variant =
208 |target: VariantArray, path: VariantPath<'_>, as_field: Option<&Field>| {
209 let requested_variant =
212 as_field.is_some_and(Field::has_valid_extension_type::<VariantType>);
213
214 if requested_variant && requested_field_is_shredded(as_field) {
219 return Err(ArrowError::NotYetImplemented(
220 "variant_get with shredded `Variant` output is not yet supported".to_string(),
221 ));
222 }
223
224 let target = if requested_variant {
230 unshred_variant(&target)?
231 } else {
232 target
233 };
234
235 if requested_variant && path.is_empty() {
237 return Ok(ArrayRef::from(target));
238 }
239
240 let as_type = if requested_variant {
241 None
242 } else {
243 as_field.map(|f| f.data_type())
244 };
245 let mut builder = make_variant_to_arrow_row_builder(
246 target.metadata_column(),
247 path,
248 as_type,
249 cast_options,
250 target.len(),
251 )?;
252 for i in 0..target.len() {
253 if target.is_null(i) {
254 builder.append_null()?;
255 } else if !cast_options.safe {
256 let value = target.try_value(i)?;
257 builder.append_value(value)?;
258 } else {
259 let _ = match target.try_value(i) {
260 Ok(v) => builder.append_value(v)?,
261 Err(_) => {
262 builder.append_null()?;
263 false }
265 };
266 }
267 }
268 builder.finish()
269 };
270
271 let mut shredding_state = input.shredding_state().clone();
274 let mut accumulated_nulls = input.inner().nulls().cloned();
275 let mut path_index = 0;
276 for path_element in path {
277 match follow_shredded_path_element(&shredding_state, path_element, cast_options)? {
278 ShreddedPathStep::Success(state) => {
279 if let Some(typed_value) = shredding_state.typed_value_column() {
281 accumulated_nulls =
282 NullBuffer::union(accumulated_nulls.as_ref(), typed_value.nulls());
283 }
284 shredding_state = state;
285 path_index += 1;
286 continue;
287 }
288 ShreddedPathStep::Missing => {
289 let num_rows = input.len();
290 if as_field.is_some_and(Field::has_valid_extension_type::<VariantType>) {
291 let all_nulls = Some(arrow::buffer::NullBuffer::from(vec![false; num_rows]));
292 let metadata = input.metadata_column().clone();
295 let arr = VariantArray::from_parts(
296 metadata,
297 all_null_value_column(num_rows),
298 None,
299 all_nulls,
300 );
301 return Ok(ArrayRef::from(arr));
302 }
303 let arr = match as_field.map(|f| f.data_type()) {
304 Some(data_type) => array::new_null_array(data_type, num_rows),
305 None => Arc::new(array::NullArray::new(num_rows)) as _,
306 };
307 return Ok(arr);
308 }
309 ShreddedPathStep::NotShredded => {
310 let target = make_target_variant(
311 shredding_state.value_column().clone(),
312 None,
313 accumulated_nulls,
314 );
315 return shred_basic_variant(target, path[path_index..].into(), as_field);
316 }
317 };
318 }
319
320 let target = make_target_variant(
322 shredding_state.value_column().clone(),
323 shredding_state.typed_value_column().cloned(),
324 accumulated_nulls,
325 );
326
327 let Some(as_field) = as_field else {
329 return Ok(ArrayRef::from(target));
330 };
331
332 if let Some(shredded) = try_perfect_shredding(&target, as_field) {
334 return Ok(shredded);
335 }
336
337 if !as_field.has_valid_extension_type::<VariantType>() {
347 if let DataType::Struct(fields) = as_field.data_type() {
348 if target.typed_value_column().is_none() {
349 return shred_basic_variant(target, VariantPath::default(), Some(as_field));
350 }
351
352 let children = fields
353 .iter()
354 .map(|field| {
355 let path = &[VariantPathElement::from(field.name().as_str())];
356 shredded_get_path(&target, path, Some(field), cast_options)
357 })
358 .collect::<Result<Vec<_>>>()?;
359
360 return Ok(Arc::new(StructArray::try_new(
361 fields.clone(),
362 children,
363 target.nulls().cloned(),
364 )?));
365 }
366 }
367
368 shred_basic_variant(target, VariantPath::default(), Some(as_field))
370}
371
372fn requested_field_is_shredded(as_field: Option<&Field>) -> bool {
377 as_field.is_some_and(|f| match f.data_type() {
378 DataType::Struct(fields) => fields.iter().any(|field| field.name() == "typed_value"),
379 _ => false,
380 })
381}
382
383fn try_perfect_shredding(variant_array: &VariantArray, as_field: &Field) -> Option<ArrayRef> {
384 if matches!(as_field.data_type(), DataType::Struct(_)) {
386 return None;
387 }
388 let typed_value = variant_array.typed_value_column()?;
389
390 let value = variant_array.value_column();
391 if typed_value.data_type() == as_field.data_type() && value.null_count() == value.len() {
392 let parent_nulls = variant_array.nulls();
399
400 let target_array = if parent_nulls.is_none() || typed_value.data_type().is_null() {
402 typed_value.clone()
403 } else {
404 let merged_nulls = NullBuffer::union(parent_nulls, typed_value.nulls());
405 let data = typed_value
406 .to_data()
407 .into_builder()
408 .nulls(merged_nulls)
409 .build()
410 .ok()?;
411 make_array(data)
412 };
413
414 return Some(target_array);
415 }
416
417 None
418}
419
420pub fn variant_get(input: &ArrayRef, options: GetOptions) -> Result<ArrayRef> {
432 let variant_array = VariantArray::try_new(input)?;
433
434 let GetOptions {
435 as_type,
436 path,
437 cast_options,
438 } = options;
439
440 shredded_get_path(&variant_array, &path, as_type.as_deref(), &cast_options)
441}
442
443#[derive(Debug, Clone, Default)]
445pub struct GetOptions<'a> {
446 pub path: VariantPath<'a>,
448 pub as_type: Option<FieldRef>,
452 pub cast_options: CastOptions<'a>,
454}
455
456impl<'a> GetOptions<'a> {
457 pub fn new() -> Self {
459 Default::default()
460 }
461
462 pub fn new_with_path(path: VariantPath<'a>) -> Self {
464 Self {
465 path,
466 as_type: None,
467 cast_options: Default::default(),
468 }
469 }
470
471 pub fn with_as_type(mut self, as_type: Option<FieldRef>) -> Self {
473 self.as_type = as_type;
474 self
475 }
476
477 pub fn with_cast_options(mut self, cast_options: CastOptions<'a>) -> Self {
479 self.cast_options = cast_options;
480 self
481 }
482}
483
484#[cfg(test)]
485mod test {
486 use std::str::FromStr;
487 use std::sync::Arc;
488
489 use super::{GetOptions, requested_field_is_shredded, variant_get};
490 use crate::variant_array::{
491 ShreddedVariantFieldArray, StructArrayBuilder, all_null_value_column,
492 };
493 use crate::{
494 ShreddedSchemaBuilder, VariantArray, VariantArrayBuilder, cast_to_variant, json_to_variant,
495 shred_variant,
496 };
497 use arrow::array::{
498 Array, ArrayRef, AsArray, BinaryArray, BinaryViewArray, BooleanArray, Date32Array,
499 Date64Array, Decimal32Array, Decimal64Array, Decimal128Array, Decimal256Array,
500 FixedSizeListArray, Float32Array, Float64Array, Int8Array, Int16Array, Int32Array,
501 Int64Array, Int64Builder, LargeBinaryArray, LargeListArray, LargeListViewArray,
502 LargeStringArray, ListArray, ListBuilder, ListViewArray, MapBuilder, NullArray,
503 NullBuilder, StringArray, StringBuilder, StringViewArray, StructArray,
504 Time32MillisecondArray, Time32SecondArray, Time64MicrosecondArray, Time64NanosecondArray,
505 };
506 use arrow::buffer::{NullBuffer, OffsetBuffer, ScalarBuffer};
507 use arrow::compute::{CastOptions, cast};
508 use arrow::datatypes::DataType::{Int16, Int32, Int64};
509 use arrow::datatypes::i256;
510 use arrow::util::display::FormatOptions;
511 use arrow_schema::ArrowError;
512 use arrow_schema::DataType::{Boolean, Float32, Float64, Int8};
513 use arrow_schema::{DataType, Field, FieldRef, Fields, IntervalUnit, TimeUnit};
514 use chrono::DateTime;
515 use parquet_variant::{
516 EMPTY_VARIANT_METADATA_BYTES, Variant, VariantDecimal4, VariantDecimal8, VariantDecimal16,
517 VariantDecimalType, VariantPath,
518 };
519
520 fn single_variant_get_test(input_json: &str, path: VariantPath, expected_json: &str) {
521 let input_array_ref: ArrayRef = Arc::new(StringArray::from(vec![Some(input_json)]));
523 let input_variant_array_ref = ArrayRef::from(json_to_variant(&input_array_ref).unwrap());
524
525 let result =
526 variant_get(&input_variant_array_ref, GetOptions::new_with_path(path)).unwrap();
527
528 let expected_array_ref: ArrayRef = Arc::new(StringArray::from(vec![Some(expected_json)]));
530 let expected_variant_array = json_to_variant(&expected_array_ref).unwrap();
531
532 let result_array = VariantArray::try_new(&result).unwrap();
533 assert_eq!(
534 result_array.len(),
535 1,
536 "Expected result array to have length 1"
537 );
538 assert!(
539 result_array.nulls().is_none(),
540 "Expected no nulls in result array"
541 );
542 let result_variant = result_array.value(0);
543 let expected_variant = expected_variant_array.value(0);
544 assert_eq!(
545 result_variant, expected_variant,
546 "Result variant does not match expected variant"
547 );
548 }
549
550 #[test]
551 fn get_primitive_variant_field() {
552 single_variant_get_test(
553 r#"{"some_field": 1234}"#,
554 VariantPath::try_from("some_field").unwrap(),
555 "1234",
556 );
557 }
558
559 #[test]
560 fn get_primitive_variant_list_index() {
561 single_variant_get_test("[1234, 5678]", VariantPath::from(0), "1234");
562 }
563
564 #[test]
565 fn get_primitive_variant_inside_object_of_object() {
566 single_variant_get_test(
567 r#"{"top_level_field": {"inner_field": 1234}}"#,
568 VariantPath::try_from("top_level_field")
569 .unwrap()
570 .join("inner_field"),
571 "1234",
572 );
573 }
574
575 #[test]
576 fn get_primitive_variant_inside_list_of_object() {
577 single_variant_get_test(
578 r#"[{"some_field": 1234}]"#,
579 VariantPath::from(0).join("some_field"),
580 "1234",
581 );
582 }
583
584 #[test]
585 fn get_primitive_variant_inside_object_of_list() {
586 single_variant_get_test(
587 r#"{"some_field": [1234]}"#,
588 VariantPath::try_from("some_field[0]").unwrap(),
589 "1234",
590 );
591 }
592
593 #[test]
594 fn get_complex_variant() {
595 single_variant_get_test(
596 r#"{"top_level_field": {"inner_field": 1234}}"#,
597 VariantPath::try_from("top_level_field").unwrap(),
598 r#"{"inner_field": 1234}"#,
599 );
600 }
601
602 macro_rules! numeric_partially_shredded_test {
604 ($primitive_type:ty, $data_fn:ident) => {
605 let array = $data_fn();
606 let options = GetOptions::new();
607 let result = variant_get(&array, options).unwrap();
608
609 let result = VariantArray::try_new(&result).unwrap();
611 assert_eq!(result.len(), 4);
612
613 assert_eq!(
615 result.value(0),
616 Variant::from(<$primitive_type>::try_from(34u8).unwrap())
617 );
618 assert!(!result.is_valid(1));
619 assert_eq!(result.value(2), Variant::from("n/a"));
620 assert_eq!(
621 result.value(3),
622 Variant::from(<$primitive_type>::try_from(100u8).unwrap())
623 );
624 };
625 }
626
627 macro_rules! partially_shredded_variant_array_gen {
630 ($func_name:ident, $typed_value_array_gen: expr) => {
631 partially_shredded_variant_array_gen!(
632 $func_name,
633 $typed_value_array_gen,
634 Variant::from("n/a")
635 );
636 };
637 ($func_name:ident, $typed_value_array_gen: expr, $fallback_variant:expr) => {
638 fn $func_name() -> ArrayRef {
639 let typed_value: ArrayRef = Arc::new($typed_value_array_gen());
640 let typed_as_variant = cast_to_variant(typed_value.as_ref())
641 .expect("should cast typed array to variant");
642 let mut input_builder = VariantArrayBuilder::new(typed_as_variant.len());
643 input_builder.append_variant(typed_as_variant.value(0));
644 input_builder.append_null();
645 input_builder.append_variant($fallback_variant);
646 input_builder.append_variant(typed_as_variant.value(3));
647
648 let variant_array = shred_variant(&input_builder.build(), typed_value.data_type())
649 .expect("should shred variant array");
650 ArrayRef::from(variant_array)
651 }
652 };
653 }
654
655 macro_rules! numeric_partially_shredded_variant_array_fn {
657 ($func:ident, $array_type:ident, $primitive_type:ty) => {
658 partially_shredded_variant_array_gen!($func, || $array_type::from(vec![
659 Some(<$primitive_type>::try_from(34u8).unwrap()),
660 None,
661 None,
662 Some(<$primitive_type>::try_from(100u8).unwrap()),
663 ]));
664 };
665 }
666
667 numeric_partially_shredded_variant_array_fn!(
668 partially_shredded_int8_variant_array,
669 Int8Array,
670 i8
671 );
672 numeric_partially_shredded_variant_array_fn!(
673 partially_shredded_int16_variant_array,
674 Int16Array,
675 i16
676 );
677 numeric_partially_shredded_variant_array_fn!(
678 partially_shredded_int32_variant_array,
679 Int32Array,
680 i32
681 );
682 numeric_partially_shredded_variant_array_fn!(
683 partially_shredded_int64_variant_array,
684 Int64Array,
685 i64
686 );
687 numeric_partially_shredded_variant_array_fn!(
688 partially_shredded_float32_variant_array,
689 Float32Array,
690 f32
691 );
692 numeric_partially_shredded_variant_array_fn!(
693 partially_shredded_float64_variant_array,
694 Float64Array,
695 f64
696 );
697
698 partially_shredded_variant_array_gen!(partially_shredded_bool_variant_array, || {
699 arrow::array::BooleanArray::from(vec![Some(true), None, None, Some(false)])
700 });
701
702 partially_shredded_variant_array_gen!(
703 partially_shredded_utf8_variant_array,
704 || { StringArray::from(vec![Some("hello"), None, None, Some("world")]) },
705 Variant::from(42i32)
706 );
707
708 partially_shredded_variant_array_gen!(partially_shredded_date32_variant_array, || {
709 Date32Array::from(vec![
710 Some(20348), None,
712 None,
713 Some(20340), ])
715 });
716
717 #[test]
718 fn get_variant_partially_shredded_int8_as_variant() {
719 numeric_partially_shredded_test!(i8, partially_shredded_int8_variant_array);
720 }
721
722 #[test]
723 fn get_variant_partially_shredded_int16_as_variant() {
724 numeric_partially_shredded_test!(i16, partially_shredded_int16_variant_array);
725 }
726
727 #[test]
728 fn get_variant_partially_shredded_int32_as_variant() {
729 numeric_partially_shredded_test!(i32, partially_shredded_int32_variant_array);
730 }
731
732 #[test]
733 fn get_variant_partially_shredded_int64_as_variant() {
734 numeric_partially_shredded_test!(i64, partially_shredded_int64_variant_array);
735 }
736
737 #[test]
738 fn get_variant_partially_shredded_float32_as_variant() {
739 numeric_partially_shredded_test!(f32, partially_shredded_float32_variant_array);
740 }
741
742 #[test]
743 fn get_variant_partially_shredded_float64_as_variant() {
744 numeric_partially_shredded_test!(f64, partially_shredded_float64_variant_array);
745 }
746
747 #[test]
748 fn get_variant_partially_shredded_bool_as_variant() {
749 let array = partially_shredded_bool_variant_array();
750 let options = GetOptions::new();
751 let result = variant_get(&array, options).unwrap();
752
753 let result = VariantArray::try_new(&result).unwrap();
755 assert_eq!(result.len(), 4);
756
757 assert_eq!(result.value(0), Variant::from(true));
759 assert!(!result.is_valid(1));
760 assert_eq!(result.value(2), Variant::from("n/a"));
761 assert_eq!(result.value(3), Variant::from(false));
762 }
763
764 #[test]
765 fn get_variant_partially_shredded_utf8_as_variant() {
766 let array = partially_shredded_utf8_variant_array();
767 let options = GetOptions::new();
768 let result = variant_get(&array, options).unwrap();
769
770 let result = VariantArray::try_new(&result).unwrap();
772 assert_eq!(result.len(), 4);
773
774 assert_eq!(result.value(0), Variant::from("hello"));
776 assert!(!result.is_valid(1));
777 assert_eq!(result.value(2), Variant::from(42i32));
778 assert_eq!(result.value(3), Variant::from("world"));
779 }
780
781 partially_shredded_variant_array_gen!(partially_shredded_binary_view_variant_array, || {
782 BinaryViewArray::from(vec![
783 Some(&[1u8, 2u8, 3u8][..]), None, None, Some(&[4u8, 5u8, 6u8][..]), ])
788 });
789
790 #[test]
791 fn get_variant_partially_shredded_date32_as_variant() {
792 let array = partially_shredded_date32_variant_array();
793 let options = GetOptions::new();
794 let result = variant_get(&array, options).unwrap();
795
796 let result = VariantArray::try_new(&result).unwrap();
798 assert_eq!(result.len(), 4);
799
800 use chrono::NaiveDate;
802 let date1 = NaiveDate::from_ymd_opt(2025, 9, 17).unwrap();
803 let date2 = NaiveDate::from_ymd_opt(2025, 9, 9).unwrap();
804 assert_eq!(result.value(0), Variant::from(date1));
805 assert!(!result.is_valid(1));
806 assert_eq!(result.value(2), Variant::from("n/a"));
807 assert_eq!(result.value(3), Variant::from(date2));
808 }
809
810 #[test]
811 fn get_variant_partially_shredded_binary_view_as_variant() {
812 let array = partially_shredded_binary_view_variant_array();
813 let options = GetOptions::new();
814 let result = variant_get(&array, options).unwrap();
815
816 let result = VariantArray::try_new(&result).unwrap();
818 assert_eq!(result.len(), 4);
819
820 assert_eq!(result.value(0), Variant::from(&[1u8, 2u8, 3u8][..]));
822 assert!(!result.is_valid(1));
823 assert_eq!(result.value(2), Variant::from("n/a"));
824 assert_eq!(result.value(3), Variant::from(&[4u8, 5u8, 6u8][..]));
825 }
826
827 macro_rules! assert_variant_get_as_variant_array_with_default_option {
829 ($variant_array: expr, $array_expected: expr) => {{
830 let options = GetOptions::new();
831 let array = $variant_array;
832 let result = variant_get(&array, options).unwrap();
833 let result = VariantArray::try_new(&result).unwrap();
834
835 assert_eq!(result.len(), $array_expected.len());
836
837 for (idx, item) in $array_expected.into_iter().enumerate() {
838 match item {
839 Some(item) => assert_eq!(result.value(idx), item),
840 None => assert!(result.is_null(idx)),
841 }
842 }
843 }};
844 }
845
846 partially_shredded_variant_array_gen!(
847 partially_shredded_timestamp_micro_ntz_variant_array,
848 || {
849 arrow::array::TimestampMicrosecondArray::from(vec![
850 Some(-456000),
851 None,
852 None,
853 Some(1758602096000000),
854 ])
855 }
856 );
857
858 #[test]
859 fn get_variant_partial_shredded_timestamp_micro_ntz_as_variant() {
860 let array = partially_shredded_timestamp_micro_ntz_variant_array();
861 assert_variant_get_as_variant_array_with_default_option!(
862 array,
863 vec![
864 Some(Variant::from(
865 DateTime::from_timestamp_micros(-456000i64)
866 .unwrap()
867 .naive_utc(),
868 )),
869 None,
870 Some(Variant::from("n/a")),
871 Some(Variant::from(
872 DateTime::parse_from_rfc3339("2025-09-23T12:34:56+08:00")
873 .unwrap()
874 .naive_utc(),
875 )),
876 ]
877 )
878 }
879
880 partially_shredded_variant_array_gen!(partially_shredded_timestamp_micro_variant_array, || {
881 arrow::array::TimestampMicrosecondArray::from(vec![
882 Some(-456000),
883 None,
884 None,
885 Some(1758602096000000),
886 ])
887 .with_timezone("+00:00")
888 });
889
890 #[test]
891 fn get_variant_partial_shredded_timestamp_micro_as_variant() {
892 let array = partially_shredded_timestamp_micro_variant_array();
893 assert_variant_get_as_variant_array_with_default_option!(
894 array,
895 vec![
896 Some(Variant::from(
897 DateTime::from_timestamp_micros(-456000i64)
898 .unwrap()
899 .to_utc(),
900 )),
901 None,
902 Some(Variant::from("n/a")),
903 Some(Variant::from(
904 DateTime::parse_from_rfc3339("2025-09-23T12:34:56+08:00")
905 .unwrap()
906 .to_utc(),
907 )),
908 ]
909 )
910 }
911
912 partially_shredded_variant_array_gen!(
913 partially_shredded_timestamp_nano_ntz_variant_array,
914 || {
915 arrow::array::TimestampNanosecondArray::from(vec![
916 Some(-4999999561),
917 None,
918 None,
919 Some(1758602096000000000),
920 ])
921 }
922 );
923
924 #[test]
925 fn get_variant_partial_shredded_timestamp_nano_ntz_as_variant() {
926 let array = partially_shredded_timestamp_nano_ntz_variant_array();
927 assert_variant_get_as_variant_array_with_default_option!(
928 array,
929 vec![
930 Some(Variant::from(
931 DateTime::from_timestamp(-5, 439).unwrap().naive_utc()
932 )),
933 None,
934 Some(Variant::from("n/a")),
935 Some(Variant::from(
936 DateTime::parse_from_rfc3339("2025-09-23T12:34:56+08:00")
937 .unwrap()
938 .naive_utc()
939 )),
940 ]
941 )
942 }
943
944 partially_shredded_variant_array_gen!(partially_shredded_timestamp_nano_variant_array, || {
945 arrow::array::TimestampNanosecondArray::from(vec![
946 Some(-4999999561),
947 None,
948 None,
949 Some(1758602096000000000),
950 ])
951 .with_timezone("+00:00")
952 });
953
954 #[test]
955 fn get_variant_partial_shredded_timestamp_nano_as_variant() {
956 let array = partially_shredded_timestamp_nano_variant_array();
957 assert_variant_get_as_variant_array_with_default_option!(
958 array,
959 vec![
960 Some(Variant::from(
961 DateTime::from_timestamp(-5, 439).unwrap().to_utc()
962 )),
963 None,
964 Some(Variant::from("n/a")),
965 Some(Variant::from(
966 DateTime::parse_from_rfc3339("2025-09-23T12:34:56+08:00")
967 .unwrap()
968 .to_utc()
969 )),
970 ]
971 )
972 }
973
974 #[test]
976 fn get_variant_shredded_int32_as_int32_safe_cast() {
977 let array = partially_shredded_int32_variant_array();
979 let field = Field::new("typed_value", DataType::Int32, true);
981 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
982 let result = variant_get(&array, options).unwrap();
983 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
984 Some(34),
985 None,
986 None, Some(100),
988 ]));
989 assert_eq!(&result, &expected)
990 }
991
992 #[test]
994 fn get_variant_shredded_int32_as_int32_unsafe_cast() {
995 let array = partially_shredded_int32_variant_array();
997 let field = Field::new("typed_value", DataType::Int32, true);
998 let cast_options = CastOptions {
999 safe: false, ..Default::default()
1001 };
1002 let options = GetOptions::new()
1003 .with_as_type(Some(FieldRef::from(field)))
1004 .with_cast_options(cast_options);
1005
1006 let err = variant_get(&array, options).unwrap_err();
1007 assert_eq!(
1009 err.to_string(),
1010 "Cast error: Failed to extract primitive of type Int32 from variant ShortString(ShortString(\"n/a\")) at path VariantPath([])"
1011 );
1012 }
1013
1014 macro_rules! numeric_perfectly_shredded_test {
1016 ($primitive_type:ty, $data_fn:ident) => {
1017 let array = $data_fn();
1018 let options = GetOptions::new();
1019 let result = variant_get(&array, options).unwrap();
1020
1021 let result = VariantArray::try_new(&result).unwrap();
1023 assert_eq!(result.len(), 3);
1024
1025 assert_eq!(
1027 result.value(0),
1028 Variant::from(<$primitive_type>::try_from(1u8).unwrap())
1029 );
1030 assert_eq!(
1031 result.value(1),
1032 Variant::from(<$primitive_type>::try_from(2u8).unwrap())
1033 );
1034 assert_eq!(
1035 result.value(2),
1036 Variant::from(<$primitive_type>::try_from(3u8).unwrap())
1037 );
1038 };
1039 }
1040
1041 #[test]
1042 fn get_variant_perfectly_shredded_int8_as_variant() {
1043 numeric_perfectly_shredded_test!(i8, perfectly_shredded_int8_variant_array);
1044 }
1045
1046 #[test]
1047 fn get_variant_perfectly_shredded_int16_as_variant() {
1048 numeric_perfectly_shredded_test!(i16, perfectly_shredded_int16_variant_array);
1049 }
1050
1051 #[test]
1052 fn get_variant_perfectly_shredded_int32_as_variant() {
1053 numeric_perfectly_shredded_test!(i32, perfectly_shredded_int32_variant_array);
1054 }
1055
1056 #[test]
1057 fn get_variant_perfectly_shredded_int64_as_variant() {
1058 numeric_perfectly_shredded_test!(i64, perfectly_shredded_int64_variant_array);
1059 }
1060
1061 #[test]
1062 fn get_variant_perfectly_shredded_float32_as_variant() {
1063 numeric_perfectly_shredded_test!(f32, perfectly_shredded_float32_variant_array);
1064 }
1065
1066 #[test]
1067 fn get_variant_perfectly_shredded_float64_as_variant() {
1068 numeric_perfectly_shredded_test!(f64, perfectly_shredded_float64_variant_array);
1069 }
1070
1071 #[test]
1073 fn get_variant_all_null_as_variant() {
1074 let array = all_null_variant_array();
1075 let options = GetOptions::new();
1076 let result = variant_get(&array, options).unwrap();
1077
1078 let result = VariantArray::try_new(&result).unwrap();
1080 assert_eq!(result.len(), 3);
1081
1082 assert!(!result.is_valid(0));
1084 assert!(!result.is_valid(1));
1085 assert!(!result.is_valid(2));
1086 }
1087
1088 #[test]
1090 fn get_variant_all_null_as_int32() {
1091 let array = all_null_variant_array();
1092 let field = Field::new("typed_value", DataType::Int32, true);
1094 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
1095 let result = variant_get(&array, options).unwrap();
1096
1097 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
1098 Option::<i32>::None,
1099 Option::<i32>::None,
1100 Option::<i32>::None,
1101 ]));
1102 assert_eq!(&result, &expected)
1103 }
1104
1105 macro_rules! perfectly_shredded_to_arrow_primitive_test {
1106 ($name:ident, $primitive_type:expr, $perfectly_shredded_array_gen_fun:ident, $expected_array:expr) => {
1107 #[test]
1108 fn $name() {
1109 let array = $perfectly_shredded_array_gen_fun();
1110 let field = Field::new("typed_value", $primitive_type, true);
1111 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
1112 let result = variant_get(&array, options).unwrap();
1113 let expected_array: ArrayRef = Arc::new($expected_array);
1114 assert_eq!(&result, &expected_array);
1115 }
1116 };
1117 }
1118
1119 perfectly_shredded_to_arrow_primitive_test!(
1120 get_variant_perfectly_shredded_int18_as_int8,
1121 Int8,
1122 perfectly_shredded_int8_variant_array,
1123 Int8Array::from(vec![Some(1), Some(2), Some(3)])
1124 );
1125
1126 perfectly_shredded_to_arrow_primitive_test!(
1127 get_variant_perfectly_shredded_int16_as_int16,
1128 Int16,
1129 perfectly_shredded_int16_variant_array,
1130 Int16Array::from(vec![Some(1), Some(2), Some(3)])
1131 );
1132
1133 perfectly_shredded_to_arrow_primitive_test!(
1134 get_variant_perfectly_shredded_int32_as_int32,
1135 Int32,
1136 perfectly_shredded_int32_variant_array,
1137 Int32Array::from(vec![Some(1), Some(2), Some(3)])
1138 );
1139
1140 perfectly_shredded_to_arrow_primitive_test!(
1141 get_variant_perfectly_shredded_int64_as_int64,
1142 Int64,
1143 perfectly_shredded_int64_variant_array,
1144 Int64Array::from(vec![Some(1), Some(2), Some(3)])
1145 );
1146
1147 perfectly_shredded_to_arrow_primitive_test!(
1148 get_variant_perfectly_shredded_float32_as_float32,
1149 Float32,
1150 perfectly_shredded_float32_variant_array,
1151 Float32Array::from(vec![Some(1.0), Some(2.0), Some(3.0)])
1152 );
1153
1154 perfectly_shredded_to_arrow_primitive_test!(
1155 get_variant_perfectly_shredded_float64_as_float64,
1156 Float64,
1157 perfectly_shredded_float64_variant_array,
1158 Float64Array::from(vec![Some(1.0), Some(2.0), Some(3.0)])
1159 );
1160
1161 perfectly_shredded_to_arrow_primitive_test!(
1162 get_variant_perfectly_shredded_boolean_as_boolean,
1163 Boolean,
1164 perfectly_shredded_bool_variant_array,
1165 BooleanArray::from(vec![Some(true), Some(false), Some(true)])
1166 );
1167
1168 perfectly_shredded_to_arrow_primitive_test!(
1169 get_variant_perfectly_shredded_utf8_as_utf8,
1170 DataType::Utf8,
1171 perfectly_shredded_utf8_variant_array,
1172 StringArray::from(vec![Some("foo"), Some("bar"), Some("baz")])
1173 );
1174
1175 perfectly_shredded_to_arrow_primitive_test!(
1176 get_variant_perfectly_shredded_large_utf8_as_utf8,
1177 DataType::Utf8,
1178 perfectly_shredded_large_utf8_variant_array,
1179 StringArray::from(vec![Some("foo"), Some("bar"), Some("baz")])
1180 );
1181
1182 perfectly_shredded_to_arrow_primitive_test!(
1183 get_variant_perfectly_shredded_utf8_view_as_utf8,
1184 DataType::Utf8,
1185 perfectly_shredded_utf8_view_variant_array,
1186 StringArray::from(vec![Some("foo"), Some("bar"), Some("baz")])
1187 );
1188
1189 macro_rules! perfectly_shredded_variant_array_fn {
1190 ($func:ident, $typed_value_gen:expr) => {
1191 fn $func() -> ArrayRef {
1192 let typed_value: ArrayRef = Arc::new($typed_value_gen());
1195 if let Some(shredded) = cast_to_variant(typed_value.as_ref())
1196 .ok()
1197 .and_then(|unshredded| shred_variant(&unshredded, typed_value.data_type()).ok())
1198 {
1199 return shredded.into();
1200 }
1201
1202 let metadata = BinaryViewArray::from_iter_values(std::iter::repeat_n(
1203 EMPTY_VARIANT_METADATA_BYTES,
1204 typed_value.len(),
1205 ));
1206 VariantArray::perfectly_shredded(Arc::new(metadata), typed_value, None).into()
1207 }
1208 };
1209 }
1210
1211 perfectly_shredded_variant_array_fn!(perfectly_shredded_utf8_variant_array, || {
1212 StringArray::from(vec![Some("foo"), Some("bar"), Some("baz")])
1213 });
1214
1215 perfectly_shredded_variant_array_fn!(perfectly_shredded_large_utf8_variant_array, || {
1216 LargeStringArray::from(vec![Some("foo"), Some("bar"), Some("baz")])
1217 });
1218
1219 perfectly_shredded_variant_array_fn!(perfectly_shredded_utf8_view_variant_array, || {
1220 StringViewArray::from(vec![Some("foo"), Some("bar"), Some("baz")])
1221 });
1222
1223 perfectly_shredded_variant_array_fn!(perfectly_shredded_bool_variant_array, || {
1224 BooleanArray::from(vec![Some(true), Some(false), Some(true)])
1225 });
1226
1227 macro_rules! numeric_perfectly_shredded_variant_array_fn {
1239 ($func:ident, $array_type:ident, $primitive_type:ty) => {
1240 perfectly_shredded_variant_array_fn!($func, || {
1241 $array_type::from(vec![
1242 Some(<$primitive_type>::try_from(1u8).unwrap()),
1243 Some(<$primitive_type>::try_from(2u8).unwrap()),
1244 Some(<$primitive_type>::try_from(3u8).unwrap()),
1245 ])
1246 });
1247 };
1248 }
1249
1250 numeric_perfectly_shredded_variant_array_fn!(
1251 perfectly_shredded_int8_variant_array,
1252 Int8Array,
1253 i8
1254 );
1255 numeric_perfectly_shredded_variant_array_fn!(
1256 perfectly_shredded_int16_variant_array,
1257 Int16Array,
1258 i16
1259 );
1260 numeric_perfectly_shredded_variant_array_fn!(
1261 perfectly_shredded_int32_variant_array,
1262 Int32Array,
1263 i32
1264 );
1265 numeric_perfectly_shredded_variant_array_fn!(
1266 perfectly_shredded_int64_variant_array,
1267 Int64Array,
1268 i64
1269 );
1270 numeric_perfectly_shredded_variant_array_fn!(
1271 perfectly_shredded_float32_variant_array,
1272 Float32Array,
1273 f32
1274 );
1275 numeric_perfectly_shredded_variant_array_fn!(
1276 perfectly_shredded_float64_variant_array,
1277 Float64Array,
1278 f64
1279 );
1280
1281 perfectly_shredded_variant_array_fn!(
1282 perfectly_shredded_timestamp_micro_ntz_variant_array,
1283 || {
1284 arrow::array::TimestampMicrosecondArray::from(vec![
1285 Some(-456000),
1286 Some(1758602096000001),
1287 Some(1758602096000002),
1288 ])
1289 }
1290 );
1291
1292 perfectly_shredded_to_arrow_primitive_test!(
1293 get_variant_perfectly_shredded_timestamp_micro_ntz_as_timestamp_micro_ntz,
1294 DataType::Timestamp(TimeUnit::Microsecond, None),
1295 perfectly_shredded_timestamp_micro_ntz_variant_array,
1296 arrow::array::TimestampMicrosecondArray::from(vec![
1297 Some(-456000),
1298 Some(1758602096000001),
1299 Some(1758602096000002),
1300 ])
1301 );
1302
1303 perfectly_shredded_to_arrow_primitive_test!(
1305 get_variant_perfectly_shredded_timestamp_micro_ntz_as_nano_ntz,
1306 DataType::Timestamp(TimeUnit::Nanosecond, None),
1307 perfectly_shredded_timestamp_micro_ntz_variant_array,
1308 arrow::array::TimestampNanosecondArray::from(vec![
1309 Some(-456000000),
1310 Some(1758602096000001000),
1311 Some(1758602096000002000)
1312 ])
1313 );
1314
1315 perfectly_shredded_variant_array_fn!(perfectly_shredded_timestamp_micro_variant_array, || {
1316 arrow::array::TimestampMicrosecondArray::from(vec![
1317 Some(-456000),
1318 Some(1758602096000001),
1319 Some(1758602096000002),
1320 ])
1321 .with_timezone("+00:00")
1322 });
1323
1324 perfectly_shredded_to_arrow_primitive_test!(
1325 get_variant_perfectly_shredded_timestamp_micro_as_timestamp_micro,
1326 DataType::Timestamp(TimeUnit::Microsecond, Some(Arc::from("+00:00"))),
1327 perfectly_shredded_timestamp_micro_variant_array,
1328 arrow::array::TimestampMicrosecondArray::from(vec![
1329 Some(-456000),
1330 Some(1758602096000001),
1331 Some(1758602096000002),
1332 ])
1333 .with_timezone("+00:00")
1334 );
1335
1336 perfectly_shredded_to_arrow_primitive_test!(
1338 get_variant_perfectly_shredded_timestamp_micro_as_nano,
1339 DataType::Timestamp(TimeUnit::Nanosecond, Some(Arc::from("+00:00"))),
1340 perfectly_shredded_timestamp_micro_variant_array,
1341 arrow::array::TimestampNanosecondArray::from(vec![
1342 Some(-456000000),
1343 Some(1758602096000001000),
1344 Some(1758602096000002000)
1345 ])
1346 .with_timezone("+00:00")
1347 );
1348
1349 perfectly_shredded_variant_array_fn!(
1350 perfectly_shredded_timestamp_nano_ntz_variant_array,
1351 || {
1352 arrow::array::TimestampNanosecondArray::from(vec![
1353 Some(-4999999561),
1354 Some(1758602096000000001),
1355 Some(1758602096000000002),
1356 ])
1357 }
1358 );
1359
1360 perfectly_shredded_variant_array_fn!(
1361 perfectly_shredded_timestamp_micro_variant_array_for_second_and_milli_second,
1362 || {
1363 arrow::array::TimestampMicrosecondArray::from(vec![
1364 Some(1234), Some(1234000), Some(1234000000), ])
1368 .with_timezone("+00:00")
1369 }
1370 );
1371
1372 perfectly_shredded_to_arrow_primitive_test!(
1375 get_variant_perfectly_shredded_timestamp_micro_as_timestamp_second,
1376 DataType::Timestamp(TimeUnit::Second, Some(Arc::from("+00:00"))),
1377 perfectly_shredded_timestamp_micro_variant_array_for_second_and_milli_second,
1378 arrow::array::TimestampSecondArray::from(vec![
1379 None,
1380 None, Some(1234)
1382 ])
1383 .with_timezone("+00:00")
1384 );
1385
1386 perfectly_shredded_to_arrow_primitive_test!(
1387 get_variant_perfectly_shredded_timestamp_micro_as_timestamp_milli,
1388 DataType::Timestamp(TimeUnit::Millisecond, Some(Arc::from("+00:00"))),
1389 perfectly_shredded_timestamp_micro_variant_array_for_second_and_milli_second,
1390 arrow::array::TimestampMillisecondArray::from(vec![
1391 None, Some(1234),
1393 Some(1234000)
1394 ])
1395 .with_timezone("+00:00")
1396 );
1397
1398 perfectly_shredded_variant_array_fn!(
1399 perfectly_shredded_timestamp_micro_ntz_variant_array_for_second_and_milli_second,
1400 || {
1401 arrow::array::TimestampMicrosecondArray::from(vec![
1402 Some(1234), Some(1234000), Some(1234000000), ])
1406 }
1407 );
1408
1409 perfectly_shredded_to_arrow_primitive_test!(
1412 get_variant_perfectly_shredded_timestamp_micro_ntz_as_timestamp_second,
1413 DataType::Timestamp(TimeUnit::Second, None),
1414 perfectly_shredded_timestamp_micro_ntz_variant_array_for_second_and_milli_second,
1415 arrow::array::TimestampSecondArray::from(vec![
1416 None,
1417 None, Some(1234)
1419 ])
1420 );
1421
1422 perfectly_shredded_to_arrow_primitive_test!(
1423 get_variant_perfectly_shredded_timestamp_micro_ntz_as_timestamp_milli,
1424 DataType::Timestamp(TimeUnit::Millisecond, None),
1425 perfectly_shredded_timestamp_micro_ntz_variant_array_for_second_and_milli_second,
1426 arrow::array::TimestampMillisecondArray::from(vec![
1427 None, Some(1234),
1429 Some(1234000)
1430 ])
1431 );
1432
1433 perfectly_shredded_variant_array_fn!(
1434 perfectly_shredded_timestamp_nano_variant_array_for_second_and_milli_second,
1435 || {
1436 arrow::array::TimestampNanosecondArray::from(vec![
1437 Some(1234000), Some(1234000000), Some(1234000000000), ])
1441 .with_timezone("+00:00")
1442 }
1443 );
1444
1445 perfectly_shredded_to_arrow_primitive_test!(
1448 get_variant_perfectly_shredded_timestamp_nano_as_timestamp_second,
1449 DataType::Timestamp(TimeUnit::Second, Some(Arc::from("+00:00"))),
1450 perfectly_shredded_timestamp_nano_variant_array_for_second_and_milli_second,
1451 arrow::array::TimestampSecondArray::from(vec![
1452 None,
1453 None, Some(1234)
1455 ])
1456 .with_timezone("+00:00")
1457 );
1458
1459 perfectly_shredded_to_arrow_primitive_test!(
1460 get_variant_perfectly_shredded_timestamp_nano_as_timestamp_milli,
1461 DataType::Timestamp(TimeUnit::Millisecond, Some(Arc::from("+00:00"))),
1462 perfectly_shredded_timestamp_nano_variant_array_for_second_and_milli_second,
1463 arrow::array::TimestampMillisecondArray::from(vec![
1464 None, Some(1234),
1466 Some(1234000)
1467 ])
1468 .with_timezone("+00:00")
1469 );
1470
1471 perfectly_shredded_variant_array_fn!(
1472 perfectly_shredded_timestamp_nano_ntz_variant_array_for_second_and_milli_second,
1473 || {
1474 arrow::array::TimestampNanosecondArray::from(vec![
1475 Some(1234000), Some(1234000000), Some(1234000000000), ])
1479 }
1480 );
1481
1482 perfectly_shredded_to_arrow_primitive_test!(
1485 get_variant_perfectly_shredded_timestamp_nano_ntz_as_timestamp_second,
1486 DataType::Timestamp(TimeUnit::Second, None),
1487 perfectly_shredded_timestamp_nano_ntz_variant_array_for_second_and_milli_second,
1488 arrow::array::TimestampSecondArray::from(vec![
1489 None,
1490 None, Some(1234)
1492 ])
1493 );
1494
1495 perfectly_shredded_to_arrow_primitive_test!(
1496 get_variant_perfectly_shredded_timestamp_nano_ntz_as_timestamp_milli,
1497 DataType::Timestamp(TimeUnit::Millisecond, None),
1498 perfectly_shredded_timestamp_nano_ntz_variant_array_for_second_and_milli_second,
1499 arrow::array::TimestampMillisecondArray::from(vec![
1500 None, Some(1234),
1502 Some(1234000)
1503 ])
1504 );
1505
1506 perfectly_shredded_to_arrow_primitive_test!(
1507 get_variant_perfectly_shredded_timestamp_nano_ntz_as_timestamp_nano_ntz,
1508 DataType::Timestamp(TimeUnit::Nanosecond, None),
1509 perfectly_shredded_timestamp_nano_ntz_variant_array,
1510 arrow::array::TimestampNanosecondArray::from(vec![
1511 Some(-4999999561),
1512 Some(1758602096000000001),
1513 Some(1758602096000000002),
1514 ])
1515 );
1516
1517 perfectly_shredded_variant_array_fn!(perfectly_shredded_timestamp_nano_variant_array, || {
1518 arrow::array::TimestampNanosecondArray::from(vec![
1519 Some(-4999999561),
1520 Some(1758602096000000001),
1521 Some(1758602096000000002),
1522 ])
1523 .with_timezone("+00:00")
1524 });
1525
1526 perfectly_shredded_to_arrow_primitive_test!(
1527 get_variant_perfectly_shredded_timestamp_nano_as_timestamp_nano,
1528 DataType::Timestamp(TimeUnit::Nanosecond, Some(Arc::from("+00:00"))),
1529 perfectly_shredded_timestamp_nano_variant_array,
1530 arrow::array::TimestampNanosecondArray::from(vec![
1531 Some(-4999999561),
1532 Some(1758602096000000001),
1533 Some(1758602096000000002),
1534 ])
1535 .with_timezone("+00:00")
1536 );
1537
1538 perfectly_shredded_variant_array_fn!(perfectly_shredded_date_variant_array, || {
1539 Date32Array::from(vec![Some(-12345), Some(17586), Some(20000)])
1540 });
1541
1542 perfectly_shredded_to_arrow_primitive_test!(
1543 get_variant_perfectly_shredded_date_as_date,
1544 DataType::Date32,
1545 perfectly_shredded_date_variant_array,
1546 Date32Array::from(vec![Some(-12345), Some(17586), Some(20000)])
1547 );
1548
1549 perfectly_shredded_to_arrow_primitive_test!(
1550 get_variant_perfectly_shredded_date_as_date64,
1551 DataType::Date64,
1552 perfectly_shredded_date_variant_array,
1553 Date64Array::from(vec![
1554 Some(-1066608000000),
1555 Some(1519430400000),
1556 Some(1728000000000)
1557 ])
1558 );
1559
1560 perfectly_shredded_variant_array_fn!(perfectly_shredded_time_variant_array, || {
1561 Time64MicrosecondArray::from(vec![Some(12345000), Some(87654000), Some(135792000)])
1562 });
1563
1564 perfectly_shredded_to_arrow_primitive_test!(
1565 get_variant_perfectly_shredded_time_as_time,
1566 DataType::Time64(TimeUnit::Microsecond),
1567 perfectly_shredded_time_variant_array,
1568 Time64MicrosecondArray::from(vec![Some(12345000), Some(87654000), Some(135792000)])
1569 );
1570
1571 perfectly_shredded_to_arrow_primitive_test!(
1572 get_variant_perfectly_shredded_time_as_time64_nano,
1573 DataType::Time64(TimeUnit::Nanosecond),
1574 perfectly_shredded_time_variant_array,
1575 Time64NanosecondArray::from(vec![
1576 Some(12345000000),
1577 Some(87654000000),
1578 Some(135792000000)
1579 ])
1580 );
1581
1582 perfectly_shredded_variant_array_fn!(perfectly_shredded_time_variant_array_for_time32, || {
1583 Time64MicrosecondArray::from(vec![
1584 Some(1234), Some(7654000), Some(35792000000), ])
1588 });
1589
1590 perfectly_shredded_to_arrow_primitive_test!(
1591 get_variant_perfectly_shredded_time_as_time32_second,
1592 DataType::Time32(TimeUnit::Second),
1593 perfectly_shredded_time_variant_array_for_time32,
1594 Time32SecondArray::from(vec![
1595 None,
1596 None, Some(35792)
1598 ])
1599 );
1600
1601 perfectly_shredded_to_arrow_primitive_test!(
1602 get_variant_perfectly_shredded_time_as_time32_milli,
1603 DataType::Time32(TimeUnit::Millisecond),
1604 perfectly_shredded_time_variant_array_for_time32,
1605 Time32MillisecondArray::from(vec![
1606 None, Some(7654),
1608 Some(35792000)
1609 ])
1610 );
1611
1612 perfectly_shredded_variant_array_fn!(perfectly_shredded_null_variant_array, || {
1613 let mut builder = NullBuilder::new();
1614 builder.append_nulls(3);
1615 builder.finish()
1616 });
1617
1618 perfectly_shredded_to_arrow_primitive_test!(
1619 get_variant_perfectly_shredded_null_as_null,
1620 DataType::Null,
1621 perfectly_shredded_null_variant_array,
1622 arrow::array::NullArray::new(3)
1623 );
1624
1625 perfectly_shredded_variant_array_fn!(perfectly_shredded_null_variant_array_with_int, || {
1626 Int32Array::from(vec![Some(32), Some(64), Some(48)])
1627 });
1628
1629 perfectly_shredded_to_arrow_primitive_test!(
1631 get_variant_perfectly_shredded_null_with_type_missmatch_in_safe_mode,
1632 DataType::Null,
1633 perfectly_shredded_null_variant_array_with_int,
1634 arrow::array::NullArray::new(3)
1635 );
1636
1637 #[test]
1639 fn get_variant_perfectly_shredded_null_as_null_with_type_missmatch_in_strict_mode() {
1640 let array = perfectly_shredded_null_variant_array_with_int();
1641 let field = Field::new("typed_value", DataType::Null, true);
1642 let options = GetOptions::new()
1643 .with_as_type(Some(FieldRef::from(field)))
1644 .with_cast_options(CastOptions {
1645 safe: false,
1646 format_options: FormatOptions::default(),
1647 });
1648
1649 let result = variant_get(&array, options);
1650
1651 assert!(result.is_err());
1652 let error_msg = format!("{}", result.unwrap_err());
1653 assert!(
1654 error_msg
1655 .contains("Cast error: Failed to extract primitive of type Null from variant Int32(32) at path VariantPath([])"),
1656 "Expected=[Cast error: Failed to extract primitive of type Null from variant Int32(32) at path VariantPath([])],\
1657 Got error message=[{}]",
1658 error_msg
1659 );
1660 }
1661
1662 perfectly_shredded_variant_array_fn!(perfectly_shredded_decimal4_variant_array, || {
1663 Decimal32Array::from(vec![Some(12345), Some(23400), Some(-12342)])
1664 .with_precision_and_scale(5, 2)
1665 .unwrap()
1666 });
1667
1668 perfectly_shredded_to_arrow_primitive_test!(
1669 get_variant_perfectly_shredded_decimal4_as_decimal4,
1670 DataType::Decimal32(5, 2),
1671 perfectly_shredded_decimal4_variant_array,
1672 Decimal32Array::from(vec![Some(12345), Some(23400), Some(-12342)])
1673 .with_precision_and_scale(5, 2)
1674 .unwrap()
1675 );
1676
1677 perfectly_shredded_variant_array_fn!(
1678 perfectly_shredded_decimal8_variant_array_cast2decimal32,
1679 || {
1680 Decimal64Array::from(vec![Some(123456), Some(145678), Some(-123456)])
1681 .with_precision_and_scale(6, 1)
1682 .unwrap()
1683 }
1684 );
1685
1686 perfectly_shredded_to_arrow_primitive_test!(
1690 get_variant_perfectly_shredded_decimal8_through_decimal32_as_decimal8,
1691 DataType::Decimal64(6, 1),
1692 perfectly_shredded_decimal8_variant_array_cast2decimal32,
1693 Decimal64Array::from(vec![Some(123456), Some(145678), Some(-123456)])
1694 .with_precision_and_scale(6, 1)
1695 .unwrap()
1696 );
1697
1698 perfectly_shredded_variant_array_fn!(perfectly_shredded_decimal8_variant_array, || {
1701 Decimal64Array::from(vec![Some(1234567809), Some(1456787000), Some(-1234561203)])
1702 .with_precision_and_scale(10, 1)
1703 .unwrap()
1704 });
1705
1706 perfectly_shredded_to_arrow_primitive_test!(
1707 get_variant_perfectly_shredded_decimal8_as_decimal8,
1708 DataType::Decimal64(10, 1),
1709 perfectly_shredded_decimal8_variant_array,
1710 Decimal64Array::from(vec![Some(1234567809), Some(1456787000), Some(-1234561203)])
1711 .with_precision_and_scale(10, 1)
1712 .unwrap()
1713 );
1714
1715 perfectly_shredded_variant_array_fn!(
1718 perfectly_shredded_decimal16_within_decimal4_variant_array,
1719 || {
1720 Decimal128Array::from(vec![
1721 Some(i128::from(1234589)),
1722 Some(i128::from(2344444)),
1723 Some(i128::from(-1234789)),
1724 ])
1725 .with_precision_and_scale(7, 3)
1726 .unwrap()
1727 }
1728 );
1729
1730 perfectly_shredded_to_arrow_primitive_test!(
1733 get_variant_perfectly_shredded_decimal16_within_decimal4_as_decimal16,
1734 DataType::Decimal128(7, 3),
1735 perfectly_shredded_decimal16_within_decimal4_variant_array,
1736 Decimal128Array::from(vec![
1737 Some(i128::from(1234589)),
1738 Some(i128::from(2344444)),
1739 Some(i128::from(-1234789)),
1740 ])
1741 .with_precision_and_scale(7, 3)
1742 .unwrap()
1743 );
1744
1745 perfectly_shredded_variant_array_fn!(
1746 perfectly_shredded_decimal16_within_decimal8_variant_array,
1747 || {
1748 Decimal128Array::from(vec![Some(1234567809), Some(1456787000), Some(-1234561203)])
1749 .with_precision_and_scale(10, 1)
1750 .unwrap()
1751 }
1752 );
1753
1754 perfectly_shredded_to_arrow_primitive_test!(
1757 get_variant_perfectly_shredded_decimal16_within8_as_decimal16,
1758 DataType::Decimal128(10, 1),
1759 perfectly_shredded_decimal16_within_decimal8_variant_array,
1760 Decimal128Array::from(vec![Some(1234567809), Some(1456787000), Some(-1234561203)])
1761 .with_precision_and_scale(10, 1)
1762 .unwrap()
1763 );
1764
1765 perfectly_shredded_variant_array_fn!(perfectly_shredded_decimal16_variant_array, || {
1766 Decimal128Array::from(vec![
1767 Some(i128::from_str("12345678901234567899").unwrap()),
1768 Some(i128::from_str("23445677483748324300").unwrap()),
1769 Some(i128::from_str("-12345678901234567899").unwrap()),
1770 ])
1771 .with_precision_and_scale(20, 3)
1772 .unwrap()
1773 });
1774
1775 perfectly_shredded_to_arrow_primitive_test!(
1778 get_variant_perfectly_shredded_decimal16_as_decimal16,
1779 DataType::Decimal128(20, 3),
1780 perfectly_shredded_decimal16_variant_array,
1781 Decimal128Array::from(vec![
1782 Some(i128::from_str("12345678901234567899").unwrap()),
1783 Some(i128::from_str("23445677483748324300").unwrap()),
1784 Some(i128::from_str("-12345678901234567899").unwrap())
1785 ])
1786 .with_precision_and_scale(20, 3)
1787 .unwrap()
1788 );
1789
1790 perfectly_shredded_variant_array_fn!(perfectly_shredded_binary_variant_array, || {
1791 BinaryArray::from(vec![
1792 Some(b"Apache" as &[u8]),
1793 Some(b"Arrow-rs" as &[u8]),
1794 Some(b"Parquet-variant" as &[u8]),
1795 ])
1796 });
1797
1798 perfectly_shredded_to_arrow_primitive_test!(
1799 get_variant_perfectly_shredded_binary_as_binary,
1800 DataType::Binary,
1801 perfectly_shredded_binary_variant_array,
1802 BinaryArray::from(vec![
1803 Some(b"Apache" as &[u8]),
1804 Some(b"Arrow-rs" as &[u8]),
1805 Some(b"Parquet-variant" as &[u8]),
1806 ])
1807 );
1808
1809 perfectly_shredded_variant_array_fn!(perfectly_shredded_large_binary_variant_array, || {
1810 LargeBinaryArray::from(vec![
1811 Some(b"Apache" as &[u8]),
1812 Some(b"Arrow-rs" as &[u8]),
1813 Some(b"Parquet-variant" as &[u8]),
1814 ])
1815 });
1816
1817 perfectly_shredded_to_arrow_primitive_test!(
1818 get_variant_perfectly_shredded_large_binary_as_large_binary,
1819 DataType::LargeBinary,
1820 perfectly_shredded_large_binary_variant_array,
1821 LargeBinaryArray::from(vec![
1822 Some(b"Apache" as &[u8]),
1823 Some(b"Arrow-rs" as &[u8]),
1824 Some(b"Parquet-variant" as &[u8]),
1825 ])
1826 );
1827
1828 perfectly_shredded_variant_array_fn!(perfectly_shredded_binary_view_variant_array, || {
1829 BinaryViewArray::from(vec![
1830 Some(b"Apache" as &[u8]),
1831 Some(b"Arrow-rs" as &[u8]),
1832 Some(b"Parquet-variant" as &[u8]),
1833 ])
1834 });
1835
1836 perfectly_shredded_to_arrow_primitive_test!(
1837 get_variant_perfectly_shredded_binary_view_as_binary_view,
1838 DataType::BinaryView,
1839 perfectly_shredded_binary_view_variant_array,
1840 BinaryViewArray::from(vec![
1841 Some(b"Apache" as &[u8]),
1842 Some(b"Arrow-rs" as &[u8]),
1843 Some(b"Parquet-variant" as &[u8]),
1844 ])
1845 );
1846
1847 fn all_null_variant_array() -> ArrayRef {
1864 let nulls = NullBuffer::from(vec![
1865 false, false, false, ]);
1869
1870 let metadata =
1872 BinaryViewArray::from_iter_values(std::iter::repeat_n(EMPTY_VARIANT_METADATA_BYTES, 3));
1873
1874 ArrayRef::from(VariantArray::from_parts(
1875 Arc::new(metadata),
1876 all_null_value_column(3),
1877 None,
1878 Some(nulls),
1879 ))
1880 }
1881
1882 #[test]
1886 fn test_shredded_object_field_access() {
1887 let array = shredded_object_with_x_field_variant_array();
1888
1889 let options = GetOptions::new_with_path(VariantPath::try_from("x").unwrap());
1891 let result = variant_get(&array, options).unwrap();
1892
1893 let result_variant = VariantArray::try_new(&result).unwrap();
1894 assert_eq!(result_variant.len(), 2);
1895
1896 assert_eq!(result_variant.value(0), Variant::Int32(1));
1898 assert_eq!(result_variant.value(1), Variant::Int32(42));
1900 }
1901
1902 #[test]
1904 fn test_shredded_object_field_as_int32() {
1905 let array = shredded_object_with_x_field_variant_array();
1906
1907 let field = Field::new("x", DataType::Int32, false);
1909 let options = GetOptions::new_with_path(VariantPath::try_from("x").unwrap())
1910 .with_as_type(Some(FieldRef::from(field)));
1911 let result = variant_get(&array, options).unwrap();
1912
1913 let expected: ArrayRef = Arc::new(Int32Array::from(vec![Some(1), Some(42)]));
1915 assert_eq!(&result, &expected);
1916 }
1917
1918 type ShreddedListLikeArrayGen = fn() -> ArrayRef;
1919 type ShreddedListLikeCase = (&'static str, ShreddedListLikeArrayGen);
1920
1921 fn shredded_list_like_cases() -> [ShreddedListLikeCase; 4] {
1922 [
1923 ("list", shredded_list_variant_array),
1924 ("large_list", shredded_large_list_variant_array),
1925 ("list_view", shredded_list_view_variant_array),
1926 ("large_list_view", shredded_large_list_view_variant_array),
1927 ]
1928 }
1929
1930 #[test]
1931 fn test_shredded_list_like_index_access_from_value_field() {
1932 let options = GetOptions::new_with_path(VariantPath::from(1));
1933
1934 for (case, array_gen) in shredded_list_like_cases() {
1935 let array = array_gen();
1936 let result = variant_get(&array, options.clone()).unwrap();
1937 let result_variant = VariantArray::try_new(&result).unwrap();
1938
1939 assert_eq!(result_variant.value(0), Variant::from("drama"), "{case}");
1940 assert_eq!(result_variant.value(1).as_int64(), Some(123), "{case}");
1941 }
1942 }
1943
1944 #[test]
1945 fn test_shredded_list_like_index_out_of_bounds_unsafe_cast_returns_null() {
1946 let options =
1947 GetOptions::new_with_path(VariantPath::from(10)).with_cast_options(CastOptions {
1948 safe: false,
1949 ..Default::default()
1950 });
1951
1952 for (case, array_gen) in shredded_list_like_cases() {
1953 let result = variant_get(&array_gen(), options.clone()).unwrap();
1954 let result_variant = VariantArray::try_new(&result).unwrap();
1955 assert_eq!(result_variant.value(0), Variant::Null, "{case}");
1956 assert_eq!(result_variant.value(1), Variant::Null, "{case}");
1957 }
1958 }
1959
1960 #[test]
1962 fn test_shredded_list_like_as_string() {
1963 let field = Field::new("typed_value", DataType::Utf8, false);
1964 let options = GetOptions::new_with_path(VariantPath::from(0))
1965 .with_as_type(Some(FieldRef::from(field)));
1966 let expected: ArrayRef = Arc::new(StringArray::from(vec![Some("comedy"), Some("horror")]));
1967
1968 for (case, array_gen) in shredded_list_like_cases() {
1969 let result = variant_get(&array_gen(), options.clone()).unwrap();
1970 assert_eq!(&result, &expected, "{case}");
1971 }
1972 }
1973
1974 #[test]
1975 fn test_shredded_list_like_index_access_from_value_field_as_int64() {
1976 let field = Field::new("typed_value", DataType::Int64, true);
1977 let options = GetOptions::new_with_path(VariantPath::from(1))
1978 .with_as_type(Some(FieldRef::from(field)));
1979 let expected: ArrayRef = Arc::new(Int64Array::from(vec![None, Some(123)]));
1980
1981 for (case, array_gen) in shredded_list_like_cases() {
1982 let result = variant_get(&array_gen(), options.clone()).unwrap();
1983 assert_eq!(&result, &expected, "{case}");
1985 }
1986 }
1987
1988 #[test]
1989 fn test_shredded_list_in_struct_index_access() {
1990 let array = shredded_struct_with_list_variant_array();
1991 let options = GetOptions::new_with_path(VariantPath::try_from("a[1]").unwrap());
1992 let result = variant_get(&array, options).unwrap();
1993 let result_variant = VariantArray::try_new(&result).unwrap();
1994
1995 assert_eq!(result_variant.value(0), Variant::from("drama"));
1996 assert_eq!(result_variant.value(1).as_int64(), Some(123));
1997 }
1998
1999 #[test]
2000 fn test_shredded_struct_in_list_field_access() {
2001 let array = shredded_list_of_struct_variant_array();
2002 let field = Field::new("x", DataType::Int32, true);
2003 let path = VariantPath::from(0).join("x");
2004 let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
2005 let result = variant_get(&array, options).unwrap();
2006
2007 let expected: ArrayRef = Arc::new(Int32Array::from(vec![Some(1), Some(3)]));
2008 assert_eq!(&result, &expected);
2009 }
2010
2011 #[test]
2012 fn test_shredded_list_of_lists_index_access() {
2013 let array = shredded_list_of_lists_variant_array();
2014 let path = VariantPath::from(0).join(1);
2015
2016 let result = variant_get(&array, GetOptions::new_with_path(path.clone())).unwrap();
2017 let result_variant = VariantArray::try_new(&result).unwrap();
2018 assert_eq!(result_variant.value(0), Variant::from("b"));
2019 assert_eq!(result_variant.value(1).as_int64(), Some(123));
2020
2021 let field = Field::new("typed_value", DataType::Int64, true);
2022 let casted = variant_get(
2023 &array,
2024 GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field))),
2025 )
2026 .unwrap();
2027 let expected: ArrayRef = Arc::new(Int64Array::from(vec![None, Some(123)]));
2028 assert_eq!(&casted, &expected);
2029 }
2030
2031 fn shredded_list_like_variant_array(list_schema: DataType) -> ArrayRef {
2037 let json_rows: ArrayRef = Arc::new(StringArray::from(vec![
2038 Some(r#"["comedy", "drama"]"#),
2039 Some(r#"["horror", 123]"#),
2040 ]));
2041 let input = json_to_variant(&json_rows).unwrap();
2042
2043 let shredded = shred_variant(&input, &list_schema).unwrap();
2044 ArrayRef::from(shredded)
2045 }
2046
2047 fn shredded_list_of_lists_variant_array() -> ArrayRef {
2048 let json_rows: ArrayRef = Arc::new(StringArray::from(vec![
2049 Some(r#"[["a", "b"], ["c", "d"]]"#),
2050 Some(r#"[["x", 123], ["y", "z"]]"#),
2051 ]));
2052 let input = json_to_variant(&json_rows).unwrap();
2053
2054 let inner_list = DataType::List(Arc::new(Field::new("item", DataType::Utf8, true)));
2055 let outer_list = DataType::List(Arc::new(Field::new("item", inner_list, true)));
2056 let shredded = shred_variant(&input, &outer_list).unwrap();
2057 ArrayRef::from(shredded)
2058 }
2059
2060 fn shredded_list_variant_array() -> ArrayRef {
2061 shredded_list_like_variant_array(DataType::List(Arc::new(Field::new(
2062 "item",
2063 DataType::Utf8,
2064 true,
2065 ))))
2066 }
2067
2068 fn shredded_large_list_variant_array() -> ArrayRef {
2069 shredded_list_like_variant_array(DataType::LargeList(Arc::new(Field::new(
2070 "item",
2071 DataType::Utf8,
2072 true,
2073 ))))
2074 }
2075
2076 fn shredded_list_view_variant_array() -> ArrayRef {
2077 shredded_list_like_variant_array(DataType::ListView(Arc::new(Field::new(
2078 "item",
2079 DataType::Utf8,
2080 true,
2081 ))))
2082 }
2083
2084 fn shredded_large_list_view_variant_array() -> ArrayRef {
2085 shredded_list_like_variant_array(DataType::LargeListView(Arc::new(Field::new(
2086 "item",
2087 DataType::Utf8,
2088 true,
2089 ))))
2090 }
2091
2092 fn shredded_struct_with_list_variant_array() -> ArrayRef {
2093 let json_rows: ArrayRef = Arc::new(StringArray::from(vec![
2094 Some(r#"{"a": ["comedy", "drama"]}"#),
2095 Some(r#"{"a": ["horror", 123]}"#),
2096 ]));
2097 let input = json_to_variant(&json_rows).unwrap();
2098
2099 let list_schema = DataType::List(Arc::new(Field::new("item", DataType::Utf8, true)));
2100 let shredding_schema = ShreddedSchemaBuilder::default()
2101 .with_path("a", &list_schema)
2102 .unwrap()
2103 .build();
2104 let shredded = shred_variant(&input, &shredding_schema).unwrap();
2105 ArrayRef::from(shredded)
2106 }
2107
2108 fn shredded_list_of_struct_variant_array() -> ArrayRef {
2109 let json_rows: ArrayRef = Arc::new(StringArray::from(vec![
2110 Some(r#"[{"x": 1}, {"x": 2}]"#),
2111 Some(r#"[{"x": 3}, {"y": 4}]"#),
2112 ]));
2113 let input = json_to_variant(&json_rows).unwrap();
2114
2115 let struct_type =
2116 DataType::Struct(Fields::from(vec![Field::new("x", DataType::Int32, true)]));
2117 let list_schema = DataType::List(Arc::new(Field::new("item", struct_type, true)));
2118 let shredded = shred_variant(&input, &list_schema).unwrap();
2119 ArrayRef::from(shredded)
2120 }
2121
2122 fn shredded_object_with_x_field_variant_array() -> ArrayRef {
2134 let (metadata, y_field_value) = {
2136 let mut builder = parquet_variant::VariantBuilder::new();
2137 let mut obj = builder.new_object();
2138 obj.insert("x", Variant::Int32(42));
2139 obj.insert("y", Variant::from("foo"));
2140 obj.finish();
2141 builder.finish()
2142 };
2143
2144 let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 2));
2146
2147 let empty_object_value = {
2152 let mut builder = parquet_variant::VariantBuilder::new();
2153 let obj = builder.new_object();
2154 obj.finish();
2155 let (_, value) = builder.finish();
2156 value
2157 };
2158
2159 let value_array = BinaryViewArray::from(vec![
2160 Some(y_field_value.as_slice()), Some(empty_object_value.as_slice()), ]);
2163
2164 let x_field_typed_value = Int32Array::from(vec![Some(1), Some(42)]);
2167
2168 let x_field_shredded = ShreddedVariantFieldArray::perfectly_shredded(Arc::new(
2170 x_field_typed_value,
2171 ) as ArrayRef);
2172
2173 let typed_value_fields = Fields::from(vec![Field::new(
2175 "x",
2176 x_field_shredded.data_type().clone(),
2177 true,
2178 )]);
2179 let typed_value_struct = StructArray::try_new(
2180 typed_value_fields,
2181 vec![ArrayRef::from(x_field_shredded)],
2182 None, )
2184 .unwrap();
2185
2186 ArrayRef::from(VariantArray::from_parts(
2188 Arc::new(metadata_array),
2189 Arc::new(value_array),
2190 Some(Arc::new(typed_value_struct)),
2191 None,
2192 ))
2193 }
2194
2195 #[test]
2197 fn test_simple_nested_path_support() {
2198 println!("Testing path parsing:");
2200
2201 let path_x = VariantPath::try_from("x").unwrap();
2202 let elements_x: Vec<_> = path_x.iter().collect();
2203 println!(" 'x' -> {} elements: {:?}", elements_x.len(), elements_x);
2204
2205 let path_ax = VariantPath::try_from("a.x").unwrap();
2206 let elements_ax: Vec<_> = path_ax.iter().collect();
2207 println!(
2208 " 'a.x' -> {} elements: {:?}",
2209 elements_ax.len(),
2210 elements_ax
2211 );
2212
2213 let path_ax_alt = VariantPath::try_from("$.a.x").unwrap();
2214 let elements_ax_alt: Vec<_> = path_ax_alt.iter().collect();
2215 println!(
2216 " '$.a.x' -> {} elements: {:?}",
2217 elements_ax_alt.len(),
2218 elements_ax_alt
2219 );
2220
2221 let path_nested = VariantPath::try_from("a").unwrap().join("x");
2222 let elements_nested: Vec<_> = path_nested.iter().collect();
2223 println!(
2224 " VariantPath::try_from('a').unwrap().join('x') -> {} elements: {:?}",
2225 elements_nested.len(),
2226 elements_nested
2227 );
2228
2229 let array = shredded_object_with_x_field_variant_array();
2231
2232 let real_nested_path = VariantPath::try_from("a").unwrap().join("x");
2234 let options = GetOptions::new_with_path(real_nested_path);
2235 let result = variant_get(&array, options);
2236
2237 match result {
2238 Ok(_) => {
2239 println!("Nested path 'a.x' works unexpectedly!");
2240 }
2241 Err(e) => {
2242 println!("Nested path 'a.x' error: {}", e);
2243 if e.to_string().contains("Not yet implemented")
2244 || e.to_string().contains("NotYetImplemented")
2245 {
2246 println!("This is expected - nested paths are not implemented");
2247 return;
2248 }
2249 println!("This shows nested paths need implementation");
2251 }
2252 }
2253 }
2254
2255 #[test]
2259 fn test_depth_0_int32_conversion() {
2260 println!("=== Testing Depth 0: Direct field access ===");
2261
2262 let unshredded_array = create_depth_0_test_data();
2264
2265 let field = Field::new("result", DataType::Int32, true);
2266 let path = VariantPath::try_from("x").unwrap();
2267 let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
2268 let result = variant_get(&unshredded_array, options).unwrap();
2269
2270 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
2271 Some(42), None, None, ]));
2275 assert_eq!(&result, &expected);
2276 println!("Depth 0 (unshredded) passed");
2277
2278 let shredded_array = create_depth_0_shredded_test_data_simple();
2280
2281 let field = Field::new("result", DataType::Int32, true);
2282 let path = VariantPath::try_from("x").unwrap();
2283 let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
2284 let result = variant_get(&shredded_array, options).unwrap();
2285
2286 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
2287 Some(42), None, ]));
2290 assert_eq!(&result, &expected);
2291 println!("Depth 0 (shredded) passed");
2292 }
2293
2294 #[test]
2297 fn test_depth_1_int32_conversion() {
2298 println!("=== Testing Depth 1: Single nested field access ===");
2299
2300 let unshredded_array = create_nested_path_test_data();
2302
2303 let field = Field::new("result", DataType::Int32, true);
2304 let path = VariantPath::try_from("a.x").unwrap(); let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
2306 let result = variant_get(&unshredded_array, options).unwrap();
2307
2308 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
2309 Some(55), None, ]));
2312 assert_eq!(&result, &expected);
2313 println!("Depth 1 (unshredded) passed");
2314
2315 let shredded_array = create_depth_1_shredded_test_data_working();
2317
2318 let field = Field::new("result", DataType::Int32, true);
2319 let path = VariantPath::try_from("a.x").unwrap(); let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
2321 let result = variant_get(&shredded_array, options).unwrap();
2322
2323 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
2324 Some(55), None, ]));
2327 assert_eq!(&result, &expected);
2328 println!("Depth 1 (shredded) passed");
2329 }
2330
2331 #[test]
2334 fn test_depth_2_int32_conversion() {
2335 println!("=== Testing Depth 2: Double nested field access ===");
2336
2337 let unshredded_array = create_depth_2_test_data();
2339
2340 let field = Field::new("result", DataType::Int32, true);
2341 let path = VariantPath::try_from("a.b.x").unwrap(); let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
2343 let result = variant_get(&unshredded_array, options).unwrap();
2344
2345 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
2346 Some(100), None, None, ]));
2350 assert_eq!(&result, &expected);
2351 println!("Depth 2 (unshredded) passed");
2352
2353 let shredded_array = create_depth_2_shredded_test_data_working();
2355
2356 let field = Field::new("result", DataType::Int32, true);
2357 let path = VariantPath::try_from("a.b.x").unwrap(); let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
2359 let result = variant_get(&shredded_array, options).unwrap();
2360
2361 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
2362 Some(100), None, None, ]));
2366 assert_eq!(&result, &expected);
2367 println!("Depth 2 (shredded) passed");
2368 }
2369
2370 #[test]
2375 fn test_current_nested_path_functionality() {
2376 let array = shredded_object_with_x_field_variant_array();
2377
2378 let single_path = VariantPath::try_from("x").unwrap();
2380 let field = Field::new("result", DataType::Int32, true);
2381 let options =
2382 GetOptions::new_with_path(single_path).with_as_type(Some(FieldRef::from(field)));
2383 let result = variant_get(&array, options).unwrap();
2384
2385 println!("Single path 'x' works - result: {:?}", result);
2386
2387 let nested_path = VariantPath::try_from("a").unwrap().join("x");
2389 let field = Field::new("result", DataType::Int32, true);
2390 let options =
2391 GetOptions::new_with_path(nested_path).with_as_type(Some(FieldRef::from(field)));
2392 let result = variant_get(&array, options).unwrap();
2393
2394 println!("Nested path 'a.x' result: {:?}", result);
2395 }
2396
2397 #[test]
2398 fn test_variant_get_as_variant_from_unshredded_input() {
2399 let (unshredded, _) = create_variant_get_as_variant_test_data();
2400 let unshredded_field = VariantArray::try_new(&unshredded).unwrap().field("result");
2401 assert_variant_field_extraction_returns_unshredded_variant(&unshredded, &unshredded_field);
2402 }
2403
2404 #[test]
2405 fn test_variant_get_as_variant_from_shredded_input() {
2406 let (unshredded, shredded) = create_variant_get_as_variant_test_data();
2407 let unshredded_field = VariantArray::try_new(&unshredded).unwrap().field("result");
2408 assert_variant_field_extraction_returns_unshredded_variant(&shredded, &unshredded_field);
2409 }
2410
2411 #[test]
2412 fn test_variant_get_as_shredded_variant_is_not_yet_supported() {
2413 let (_, shredded) = create_variant_get_as_variant_test_data();
2414 let shredded_field = VariantArray::try_new(&shredded).unwrap().field("result");
2419 assert!(requested_field_is_shredded(Some(&shredded_field)));
2420
2421 let options = GetOptions::new_with_path(VariantPath::try_from("field_name").unwrap())
2422 .with_as_type(Some(FieldRef::from(shredded_field)));
2423 let err = variant_get(&shredded, options).unwrap_err();
2424 assert!(
2425 matches!(err, ArrowError::NotYetImplemented(_)),
2426 "expected NotYetImplemented, got {err:?}"
2427 );
2428 }
2429
2430 fn create_variant_get_as_variant_test_data() -> (ArrayRef, ArrayRef) {
2431 let input_json: ArrayRef = Arc::new(StringArray::from(vec![
2432 Some(r#"{"field_name": {"k": 100000}}"#),
2433 Some(r#"{"field_name": {"k": "s"}}"#),
2434 ]));
2435
2436 let unshredded = ArrayRef::from(json_to_variant(&input_json).unwrap());
2437 let unshredded_variant = VariantArray::try_new(&unshredded).unwrap();
2438
2439 let as_type = DataType::Struct(Fields::from(vec![Field::new(
2440 "field_name",
2441 DataType::Struct(Fields::from(vec![Field::new("k", DataType::Int32, true)])),
2442 true,
2443 )]));
2444 let shredded = ArrayRef::from(shred_variant(&unshredded_variant, &as_type).unwrap());
2445
2446 (unshredded, shredded)
2447 }
2448
2449 fn assert_variant_field_extraction_returns_unshredded_variant(
2450 input: &ArrayRef,
2451 variant_field: &Field,
2452 ) {
2453 let options = GetOptions::new_with_path(VariantPath::try_from("field_name").unwrap())
2454 .with_as_type(Some(FieldRef::from(variant_field.clone())));
2455
2456 let result = variant_get(input, options).unwrap();
2457 let result_variant = VariantArray::try_new(&result).unwrap();
2458
2459 assert!(result_variant.typed_value_column().is_none());
2460 assert!(result_variant.value_column().null_count() < result_variant.len());
2461
2462 let expected_json: ArrayRef = Arc::new(StringArray::from(vec![
2463 Some(r#"{"k":100000}"#),
2464 Some(r#"{"k":"s"}"#),
2465 ]));
2466 let expected = json_to_variant(&expected_json).unwrap();
2467
2468 assert_eq!(result_variant.len(), expected.len());
2469 for i in 0..result_variant.len() {
2470 assert_eq!(result_variant.is_null(i), expected.is_null(i));
2471 if !result_variant.is_null(i) {
2472 assert_eq!(result_variant.value(i), expected.value(i));
2473 }
2474 }
2475 }
2476
2477 fn create_depth_0_test_data() -> ArrayRef {
2480 let mut builder = crate::VariantArrayBuilder::new(3);
2481
2482 {
2484 let json_str = r#"{"x": 42}"#;
2485 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2486 if let Ok(variant_array) = json_to_variant(&string_array) {
2487 builder.append_variant(variant_array.value(0));
2488 } else {
2489 builder.append_null();
2490 }
2491 }
2492
2493 {
2495 let json_str = r#"{"x": "foo"}"#;
2496 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2497 if let Ok(variant_array) = json_to_variant(&string_array) {
2498 builder.append_variant(variant_array.value(0));
2499 } else {
2500 builder.append_null();
2501 }
2502 }
2503
2504 {
2506 let json_str = r#"{"y": 10}"#;
2507 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2508 if let Ok(variant_array) = json_to_variant(&string_array) {
2509 builder.append_variant(variant_array.value(0));
2510 } else {
2511 builder.append_null();
2512 }
2513 }
2514
2515 ArrayRef::from(builder.build())
2516 }
2517
2518 fn create_nested_path_test_data() -> ArrayRef {
2521 let mut builder = crate::VariantArrayBuilder::new(2);
2522
2523 {
2525 let json_str = r#"{"a": {"x": 55}, "b": 42}"#;
2526 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2527 if let Ok(variant_array) = json_to_variant(&string_array) {
2528 builder.append_variant(variant_array.value(0));
2529 } else {
2530 builder.append_null();
2531 }
2532 }
2533
2534 {
2536 let json_str = r#"{"a": {"x": "foo"}, "b": 42}"#;
2537 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2538 if let Ok(variant_array) = json_to_variant(&string_array) {
2539 builder.append_variant(variant_array.value(0));
2540 } else {
2541 builder.append_null();
2542 }
2543 }
2544
2545 ArrayRef::from(builder.build())
2546 }
2547
2548 fn create_depth_2_test_data() -> ArrayRef {
2551 let mut builder = crate::VariantArrayBuilder::new(3);
2552
2553 {
2555 let json_str = r#"{"a": {"b": {"x": 100}}}"#;
2556 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2557 if let Ok(variant_array) = json_to_variant(&string_array) {
2558 builder.append_variant(variant_array.value(0));
2559 } else {
2560 builder.append_null();
2561 }
2562 }
2563
2564 {
2566 let json_str = r#"{"a": {"b": {"x": "bar"}}}"#;
2567 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2568 if let Ok(variant_array) = json_to_variant(&string_array) {
2569 builder.append_variant(variant_array.value(0));
2570 } else {
2571 builder.append_null();
2572 }
2573 }
2574
2575 {
2577 let json_str = r#"{"a": {"b": {"y": 200}}}"#;
2578 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2579 if let Ok(variant_array) = json_to_variant(&string_array) {
2580 builder.append_variant(variant_array.value(0));
2581 } else {
2582 builder.append_null();
2583 }
2584 }
2585
2586 ArrayRef::from(builder.build())
2587 }
2588
2589 fn create_depth_0_shredded_test_data_simple() -> ArrayRef {
2592 let (metadata, string_x_value) = {
2594 let mut builder = parquet_variant::VariantBuilder::new();
2595 let mut obj = builder.new_object();
2596 obj.insert("x", Variant::from("foo"));
2597 obj.finish();
2598 builder.finish()
2599 };
2600
2601 let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 2));
2603
2604 let empty_object_value = {
2608 let mut builder = parquet_variant::VariantBuilder::new();
2609 let obj = builder.new_object();
2610 obj.finish();
2611 let (_, value) = builder.finish();
2612 value
2613 };
2614
2615 let value_array = BinaryViewArray::from(vec![
2616 Some(empty_object_value.as_slice()), Some(string_x_value.as_slice()), ]);
2619
2620 let x_field_typed_value = Int32Array::from(vec![Some(42), None]);
2622
2623 let x_field_shredded = ShreddedVariantFieldArray::perfectly_shredded(Arc::new(
2625 x_field_typed_value,
2626 ) as ArrayRef);
2627
2628 let typed_value_fields = Fields::from(vec![Field::new(
2630 "x",
2631 x_field_shredded.data_type().clone(),
2632 true,
2633 )]);
2634 let typed_value_struct = StructArray::try_new(
2635 typed_value_fields,
2636 vec![ArrayRef::from(x_field_shredded)],
2637 None,
2638 )
2639 .unwrap();
2640
2641 ArrayRef::from(VariantArray::from_parts(
2643 Arc::new(metadata_array),
2644 Arc::new(value_array),
2645 Some(Arc::new(typed_value_struct)),
2646 None,
2647 ))
2648 }
2649
2650 fn create_depth_1_shredded_test_data_working() -> ArrayRef {
2655 let (metadata, _) = {
2657 let mut builder = parquet_variant::VariantBuilder::new();
2659 let mut obj = builder.new_object();
2660
2661 let mut a_obj = obj.new_object("a");
2663 a_obj.insert("x", Variant::Int32(55));
2664 a_obj.finish();
2665
2666 obj.insert("b", Variant::Int32(42));
2667 obj.finish();
2668 builder.finish()
2669 };
2670
2671 let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 2));
2672
2673 let empty_object_value = {
2676 let mut builder = parquet_variant::VariantBuilder::new();
2677 let obj = builder.new_object();
2678 obj.finish();
2679 let (_, value) = builder.finish();
2680 value
2681 };
2682
2683 let row1_fallback = {
2686 let mut builder = parquet_variant::VariantBuilder::new();
2687 let mut obj = builder.new_object();
2688 obj.insert("fallback", Variant::from("data"));
2689 obj.finish();
2690 let (_, value) = builder.finish();
2691 value
2692 };
2693
2694 let value_array = BinaryViewArray::from(vec![
2695 Some(empty_object_value.as_slice()), Some(row1_fallback.as_slice()), ]);
2698
2699 let x_typed_value = Int32Array::from(vec![Some(55), None]);
2702 let x_field_shredded =
2703 ShreddedVariantFieldArray::perfectly_shredded(Arc::new(x_typed_value) as ArrayRef);
2704
2705 let a_value_data = {
2710 let mut builder = parquet_variant::VariantBuilder::new();
2711 let obj = builder.new_object();
2712 obj.finish();
2713 let (_, value) = builder.finish();
2714 value
2715 };
2716 let a_value_array = BinaryViewArray::from(vec![
2717 None, Some(a_value_data.as_slice()), ]);
2720
2721 let a_inner_fields = Fields::from(vec![Field::new(
2722 "x",
2723 x_field_shredded.data_type().clone(),
2724 true,
2725 )]);
2726 let a_inner_typed_value = Arc::new(
2727 StructArray::try_new(a_inner_fields, vec![ArrayRef::from(x_field_shredded)], None)
2728 .unwrap(),
2729 ) as ArrayRef;
2730 let a_field_shredded = ShreddedVariantFieldArray::from_parts(
2731 Arc::new(a_value_array),
2732 Some(a_inner_typed_value),
2733 None,
2734 );
2735
2736 let typed_value_fields = Fields::from(vec![Field::new(
2738 "a",
2739 a_field_shredded.data_type().clone(),
2740 true,
2741 )]);
2742 let typed_value_struct = StructArray::try_new(
2743 typed_value_fields,
2744 vec![ArrayRef::from(a_field_shredded)],
2745 None,
2746 )
2747 .unwrap();
2748
2749 ArrayRef::from(VariantArray::from_parts(
2751 Arc::new(metadata_array),
2752 Arc::new(value_array),
2753 Some(Arc::new(typed_value_struct)),
2754 None,
2755 ))
2756 }
2757
2758 fn create_depth_2_shredded_test_data_working() -> ArrayRef {
2764 let (metadata, _) = {
2766 let mut builder = parquet_variant::VariantBuilder::new();
2768 let mut obj = builder.new_object();
2769
2770 let mut a_obj = obj.new_object("a");
2772 let mut b_obj = a_obj.new_object("b");
2773 b_obj.insert("x", Variant::Int32(100));
2774 b_obj.finish();
2775 a_obj.finish();
2776
2777 obj.finish();
2778 builder.finish()
2779 };
2780
2781 let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 3));
2782
2783 let empty_object_value = {
2785 let mut builder = parquet_variant::VariantBuilder::new();
2786 let obj = builder.new_object();
2787 obj.finish();
2788 let (_, value) = builder.finish();
2789 value
2790 };
2791
2792 let value_array = BinaryViewArray::from(vec![
2794 Some(empty_object_value.as_slice()), Some(empty_object_value.as_slice()), Some(empty_object_value.as_slice()), ]);
2798
2799 let x_typed_value = Int32Array::from(vec![Some(100), None, None]);
2803 let x_field_shredded =
2804 ShreddedVariantFieldArray::perfectly_shredded(Arc::new(x_typed_value) as ArrayRef);
2805
2806 let b_value_data = {
2808 let mut builder = parquet_variant::VariantBuilder::new();
2809 let obj = builder.new_object();
2810 obj.finish();
2811 let (_, value) = builder.finish();
2812 value
2813 };
2814 let b_value_array = BinaryViewArray::from(vec![
2815 None, Some(b_value_data.as_slice()), Some(b_value_data.as_slice()), ]);
2819
2820 let b_inner_fields = Fields::from(vec![Field::new(
2821 "x",
2822 x_field_shredded.data_type().clone(),
2823 true,
2824 )]);
2825 let b_inner_typed_value = Arc::new(
2826 StructArray::try_new(b_inner_fields, vec![ArrayRef::from(x_field_shredded)], None)
2827 .unwrap(),
2828 ) as ArrayRef;
2829 let b_field_shredded = ShreddedVariantFieldArray::from_parts(
2830 Arc::new(b_value_array),
2831 Some(b_inner_typed_value),
2832 None,
2833 );
2834
2835 let a_value_data = {
2837 let mut builder = parquet_variant::VariantBuilder::new();
2838 let obj = builder.new_object();
2839 obj.finish();
2840 let (_, value) = builder.finish();
2841 value
2842 };
2843 let a_value_array = BinaryViewArray::from(vec![
2844 None, Some(a_value_data.as_slice()), Some(a_value_data.as_slice()), ]);
2848
2849 let a_inner_fields = Fields::from(vec![Field::new(
2850 "b",
2851 b_field_shredded.data_type().clone(),
2852 true,
2853 )]);
2854 let a_inner_typed_value = Arc::new(
2855 StructArray::try_new(a_inner_fields, vec![ArrayRef::from(b_field_shredded)], None)
2856 .unwrap(),
2857 ) as ArrayRef;
2858 let a_field_shredded = ShreddedVariantFieldArray::from_parts(
2859 Arc::new(a_value_array),
2860 Some(a_inner_typed_value),
2861 None,
2862 );
2863
2864 let typed_value_fields = Fields::from(vec![Field::new(
2866 "a",
2867 a_field_shredded.data_type().clone(),
2868 true,
2869 )]);
2870 let typed_value_struct = StructArray::try_new(
2871 typed_value_fields,
2872 vec![ArrayRef::from(a_field_shredded)],
2873 None,
2874 )
2875 .unwrap();
2876
2877 ArrayRef::from(VariantArray::from_parts(
2879 Arc::new(metadata_array),
2880 Arc::new(value_array),
2881 Some(Arc::new(typed_value_struct)),
2882 None,
2883 ))
2884 }
2885
2886 #[test]
2887 fn test_field_path_non_struct_returns_missing_path_step() {
2888 let variant_array = perfectly_shredded_int32_variant_array();
2890
2891 for safe in [true, false] {
2892 let options = GetOptions {
2893 path: VariantPath::try_from("nonexistent_field").unwrap(),
2894 as_type: Some(Arc::new(Field::new("result", DataType::Int32, true))),
2895 cast_options: CastOptions {
2896 safe,
2897 ..Default::default()
2898 },
2899 };
2900
2901 let result_array = variant_get(&variant_array, options).unwrap();
2902 assert_eq!(result_array.len(), 3);
2903 assert!(result_array.is_null(0));
2904 assert!(result_array.is_null(1));
2905 assert!(result_array.is_null(2));
2906 }
2907 }
2908
2909 #[test]
2910 fn test_strict_cast_options_index_on_non_list_returns_null() {
2911 use arrow::compute::CastOptions;
2912 use arrow::datatypes::{DataType, Field};
2913 use parquet_variant::VariantPath;
2914 use std::sync::Arc;
2915
2916 let variant_array = perfectly_shredded_int32_variant_array();
2918 let options = GetOptions {
2919 path: VariantPath::from(0),
2920 as_type: Some(Arc::new(Field::new("result", DataType::Int32, true))),
2921 cast_options: CastOptions {
2922 safe: false,
2923 ..Default::default()
2924 },
2925 };
2926
2927 let variant_array_ref: Arc<dyn Array> = variant_array.clone();
2928 let result = variant_get(&variant_array_ref, options).unwrap();
2929
2930 assert_eq!(result.len(), 3);
2931 assert!(result.is_null(0));
2932 assert!(result.is_null(1));
2933 assert!(result.is_null(2));
2934 }
2935
2936 #[test]
2937 fn test_error_message_boolean_type_display() {
2938 let mut builder = VariantArrayBuilder::new(1);
2939 builder.append_variant(Variant::from("abcd"));
2940 let variant_array: ArrayRef = ArrayRef::from(builder.build());
2941
2942 let options = GetOptions {
2944 path: VariantPath::default(),
2945 as_type: Some(Arc::new(Field::new("result", DataType::Boolean, true))),
2946 cast_options: CastOptions {
2947 safe: false,
2948 ..Default::default()
2949 },
2950 };
2951
2952 let err = variant_get(&variant_array, options).unwrap_err();
2953 let msg = err.to_string();
2954 assert!(msg.contains("Failed to extract primitive of type Boolean"));
2955 }
2956
2957 #[test]
2958 fn test_error_message_numeric_type_display() {
2959 let mut builder = VariantArrayBuilder::new(1);
2960 builder.append_variant(Variant::from("abcd"));
2961 let variant_array: ArrayRef = ArrayRef::from(builder.build());
2962
2963 let options = GetOptions {
2965 path: VariantPath::default(),
2966 as_type: Some(Arc::new(Field::new("result", DataType::Float32, true))),
2967 cast_options: CastOptions {
2968 safe: false,
2969 ..Default::default()
2970 },
2971 };
2972
2973 let err = variant_get(&variant_array, options).unwrap_err();
2974 let msg = err.to_string();
2975 assert!(msg.contains("Failed to extract primitive of type Float32"));
2976 }
2977
2978 #[test]
2979 fn test_error_message_temporal_type_display() {
2980 let mut builder = VariantArrayBuilder::new(1);
2981 builder.append_variant(Variant::BooleanFalse);
2982 let variant_array: ArrayRef = ArrayRef::from(builder.build());
2983
2984 let options = GetOptions {
2986 path: VariantPath::default(),
2987 as_type: Some(Arc::new(Field::new(
2988 "result",
2989 DataType::Timestamp(TimeUnit::Nanosecond, None),
2990 true,
2991 ))),
2992 cast_options: CastOptions {
2993 safe: false,
2994 ..Default::default()
2995 },
2996 };
2997
2998 let err = variant_get(&variant_array, options).unwrap_err();
2999 let msg = err.to_string();
3000 assert!(msg.contains("Failed to extract primitive of type Timestamp(ns)"));
3001 }
3002
3003 #[test]
3004 fn test_null_buffer_union_for_shredded_paths() {
3005 let variant_array = create_depth_1_shredded_test_data_working();
3014
3015 let options = GetOptions {
3020 path: VariantPath::try_from("a.x").unwrap(),
3021 as_type: Some(Arc::new(Field::new("result", DataType::Int32, true))),
3022 cast_options: CastOptions::default(),
3023 };
3024
3025 let result = variant_get(&variant_array, options).unwrap();
3026
3027 assert_eq!(result.len(), variant_array.len());
3029
3030 assert!(!result.is_null(0), "Row 0 should have valid Int32 data");
3034 assert!(
3035 result.is_null(1),
3036 "Row 1 should be null due to type casting failure"
3037 );
3038
3039 let int32_result = result.as_any().downcast_ref::<Int32Array>().unwrap();
3041 assert_eq!(int32_result.value(0), 55); }
3043
3044 #[test]
3045 fn test_struct_null_mask_union_from_children() {
3046 let json_strings = vec![
3051 r#"{"a": 42, "b": "hello"}"#, r#"{"a": "world", "b": 100}"#, r#"{"a": 55, "b": 77}"#, ];
3055
3056 let string_array: Arc<dyn arrow::array::Array> = Arc::new(StringArray::from(json_strings));
3057 let variant_array = json_to_variant(&string_array).unwrap();
3058
3059 let struct_fields = Fields::from(vec![
3062 Field::new("a", DataType::Int32, true),
3063 Field::new("b", DataType::Int32, true),
3064 ]);
3065 let struct_type = DataType::Struct(struct_fields);
3066
3067 let options = GetOptions {
3068 path: VariantPath::default(), as_type: Some(Arc::new(Field::new("result", struct_type, true))),
3070 cast_options: CastOptions::default(),
3071 };
3072
3073 let variant_array_ref = ArrayRef::from(variant_array);
3074 let result = variant_get(&variant_array_ref, options).unwrap();
3075
3076 let struct_result = result.as_struct();
3078 assert_eq!(struct_result.len(), 3);
3079
3080 let field_a = struct_result
3082 .column(0)
3083 .as_any()
3084 .downcast_ref::<Int32Array>()
3085 .unwrap();
3086 let field_b = struct_result
3087 .column(1)
3088 .as_any()
3089 .downcast_ref::<Int32Array>()
3090 .unwrap();
3091
3092 assert!(!field_a.is_null(0));
3095 assert_eq!(field_a.value(0), 42);
3096 assert!(field_b.is_null(0)); assert!(field_a.is_null(1)); assert!(!field_b.is_null(1));
3101 assert_eq!(field_b.value(1), 100);
3102
3103 assert!(!field_a.is_null(2));
3105 assert_eq!(field_a.value(2), 55);
3106 assert!(!field_b.is_null(2));
3107 assert_eq!(field_b.value(2), 77);
3108
3109 assert!(!struct_result.is_null(0)); assert!(!struct_result.is_null(1)); assert!(!struct_result.is_null(2)); }
3116
3117 #[test]
3118 fn test_field_nullability_preservation() {
3119 let json_strings = vec![
3122 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}"#, ];
3132
3133 let string_array: Arc<dyn arrow::array::Array> = Arc::new(StringArray::from(json_strings));
3134 let variant_array = json_to_variant(&string_array).unwrap();
3135
3136 let nullable_field = Arc::new(Field::new("result", DataType::Int32, true));
3138 let options_nullable = GetOptions {
3139 path: VariantPath::try_from("x").unwrap(),
3140 as_type: Some(nullable_field.clone()),
3141 cast_options: CastOptions::default(),
3142 };
3143
3144 let variant_array_ref = ArrayRef::from(variant_array);
3145 let result_nullable = variant_get(&variant_array_ref, options_nullable).unwrap();
3146
3147 let int32_result = result_nullable
3149 .as_any()
3150 .downcast_ref::<Int32Array>()
3151 .unwrap();
3152 assert_eq!(int32_result.len(), 9);
3153
3154 assert!(!int32_result.is_null(0));
3156 assert_eq!(int32_result.value(0), 42);
3157
3158 assert!(int32_result.is_null(1));
3160
3161 assert!(int32_result.is_null(2));
3163
3164 assert!(int32_result.is_null(3));
3166
3167 assert!(int32_result.is_null(4));
3169
3170 assert!(!int32_result.is_null(5));
3173 assert_eq!(int32_result.value(5), 127);
3174
3175 assert!(!int32_result.is_null(6));
3178 assert_eq!(int32_result.value(6), 32767);
3179
3180 assert!(!int32_result.is_null(7));
3183 assert_eq!(int32_result.value(7), 2147483647);
3184
3185 assert!(int32_result.is_null(8));
3188
3189 let non_nullable_field = Arc::new(Field::new("result", DataType::Int32, false));
3191 let options_non_nullable = GetOptions {
3192 path: VariantPath::try_from("x").unwrap(),
3193 as_type: Some(non_nullable_field.clone()),
3194 cast_options: CastOptions::default(), };
3196
3197 let variant_array_2 = json_to_variant(&string_array).unwrap();
3199 let variant_array_ref_2 = ArrayRef::from(variant_array_2);
3200 let result_non_nullable = variant_get(&variant_array_ref_2, options_non_nullable).unwrap();
3201 let int32_result_2 = result_non_nullable
3202 .as_any()
3203 .downcast_ref::<Int32Array>()
3204 .unwrap();
3205
3206 assert_eq!(int32_result_2.len(), 9);
3208
3209 assert!(!int32_result_2.is_null(0));
3211 assert_eq!(int32_result_2.value(0), 42);
3212
3213 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);
3223 assert!(!int32_result_2.is_null(6)); assert_eq!(int32_result_2.value(6), 32767);
3225 assert!(!int32_result_2.is_null(7)); assert_eq!(int32_result_2.value(7), 2147483647);
3227
3228 assert!(int32_result_2.is_null(8)); }
3231
3232 #[test]
3233 fn test_struct_extraction_subset_superset_schema_perfectly_shredded() {
3234 let variant_array = create_comprehensive_shredded_variant();
3236
3237 let struct_fields = Fields::from(vec![
3239 Field::new("a", DataType::Int32, true),
3240 Field::new("b", DataType::Int32, true),
3241 Field::new("d", DataType::Int32, true),
3242 ]);
3243 let struct_type = DataType::Struct(struct_fields);
3244
3245 let options = GetOptions {
3246 path: VariantPath::default(),
3247 as_type: Some(Arc::new(Field::new("result", struct_type, true))),
3248 cast_options: CastOptions::default(),
3249 };
3250
3251 let result = variant_get(&variant_array, options).unwrap();
3252
3253 let struct_result = result.as_any().downcast_ref::<StructArray>().unwrap();
3255 assert_eq!(struct_result.len(), 5);
3256 assert_eq!(struct_result.num_columns(), 3);
3257
3258 let field_a = struct_result
3259 .column(0)
3260 .as_any()
3261 .downcast_ref::<Int32Array>()
3262 .unwrap();
3263 let field_b = struct_result
3264 .column(1)
3265 .as_any()
3266 .downcast_ref::<Int32Array>()
3267 .unwrap();
3268 let field_d = struct_result
3269 .column(2)
3270 .as_any()
3271 .downcast_ref::<Int32Array>()
3272 .unwrap();
3273
3274 assert!(!struct_result.is_null(0));
3276 assert_eq!(field_a.value(0), 1);
3277 assert_eq!(field_b.value(0), 2);
3278 assert!(field_d.is_null(0)); assert!(struct_result.is_null(1));
3282
3283 assert!(!struct_result.is_null(2));
3285 assert!(field_a.is_null(2)); assert_eq!(field_b.value(2), 2);
3287 assert!(field_d.is_null(2)); assert!(!struct_result.is_null(3));
3291 assert_eq!(field_a.value(3), 1);
3292 assert!(field_b.is_null(3)); assert!(field_d.is_null(3)); assert!(!struct_result.is_null(4));
3297 assert!(field_a.is_null(4)); assert!(field_b.is_null(4)); assert!(field_d.is_null(4)); }
3301
3302 #[test]
3303 fn test_nested_struct_extraction_perfectly_shredded() {
3304 let variant_array = create_comprehensive_nested_shredded_variant();
3306 println!("variant_array: {variant_array:?}");
3307
3308 let inner_field = Field::new("inner", DataType::Int32, true);
3310 let inner_type = DataType::Struct(Fields::from(vec![inner_field]));
3311 let outer_field = Field::new("outer", inner_type, true);
3312 let result_type = DataType::Struct(Fields::from(vec![outer_field]));
3313
3314 let options = GetOptions {
3315 path: VariantPath::default(),
3316 as_type: Some(Arc::new(Field::new("result", result_type, true))),
3317 cast_options: CastOptions::default(),
3318 };
3319
3320 let result = variant_get(&variant_array, options).unwrap();
3321 println!("result: {result:?}");
3322
3323 let outer_struct = result.as_any().downcast_ref::<StructArray>().unwrap();
3325 assert_eq!(outer_struct.len(), 4);
3326 assert_eq!(outer_struct.num_columns(), 1);
3327
3328 let inner_struct = outer_struct
3330 .column(0)
3331 .as_any()
3332 .downcast_ref::<StructArray>()
3333 .unwrap();
3334 assert_eq!(inner_struct.num_columns(), 1);
3335
3336 let leaf_field = inner_struct
3338 .column(0)
3339 .as_any()
3340 .downcast_ref::<Int32Array>()
3341 .unwrap();
3342
3343 assert!(!outer_struct.is_null(0));
3345 assert!(!inner_struct.is_null(0));
3346 assert_eq!(leaf_field.value(0), 42);
3347
3348 assert!(!outer_struct.is_null(1));
3350 assert!(!inner_struct.is_null(1)); assert!(leaf_field.is_null(1)); assert!(!outer_struct.is_null(2));
3355 assert!(inner_struct.is_null(2)); assert!(outer_struct.is_null(3));
3359 }
3360
3361 #[test]
3362 fn test_path_based_null_masks_one_step() {
3363 let variant_array = create_comprehensive_nested_shredded_variant();
3365
3366 let path = VariantPath::try_from("outer").unwrap();
3368 let inner_field = Field::new("inner", DataType::Int32, true);
3369 let result_type = DataType::Struct(Fields::from(vec![inner_field]));
3370
3371 let options = GetOptions {
3372 path,
3373 as_type: Some(Arc::new(Field::new("result", result_type, true))),
3374 cast_options: CastOptions::default(),
3375 };
3376
3377 let result = variant_get(&variant_array, options).unwrap();
3378
3379 let outer_result = result.as_any().downcast_ref::<StructArray>().unwrap();
3381 assert_eq!(outer_result.len(), 4);
3382 assert_eq!(outer_result.num_columns(), 1);
3383
3384 let inner_field = outer_result
3386 .column(0)
3387 .as_any()
3388 .downcast_ref::<Int32Array>()
3389 .unwrap();
3390
3391 assert!(!outer_result.is_null(0));
3393 assert_eq!(inner_field.value(0), 42);
3394
3395 assert!(!outer_result.is_null(1));
3397 assert!(inner_field.is_null(1));
3398
3399 assert!(outer_result.is_null(2));
3401
3402 assert!(outer_result.is_null(3));
3404 }
3405
3406 #[test]
3407 fn test_path_based_null_masks_two_steps() {
3408 let variant_array = create_comprehensive_nested_shredded_variant();
3410
3411 let path = VariantPath::try_from("outer").unwrap().join("inner");
3413
3414 let options = GetOptions {
3415 path,
3416 as_type: Some(Arc::new(Field::new("result", DataType::Int32, true))),
3417 cast_options: CastOptions::default(),
3418 };
3419
3420 let result = variant_get(&variant_array, options).unwrap();
3421
3422 let int_result = result.as_any().downcast_ref::<Int32Array>().unwrap();
3424 assert_eq!(int_result.len(), 4);
3425
3426 assert!(!int_result.is_null(0));
3428 assert_eq!(int_result.value(0), 42);
3429
3430 assert!(int_result.is_null(1));
3432
3433 assert!(int_result.is_null(2));
3435
3436 assert!(int_result.is_null(3));
3438 }
3439
3440 #[test]
3441 fn test_struct_extraction_mixed_and_unshredded() {
3442 let variant_array = create_mixed_and_unshredded_variant();
3444
3445 let struct_fields = Fields::from(vec![
3447 Field::new("x", DataType::Int32, true),
3448 Field::new("y", DataType::Int32, true),
3449 ]);
3450 let struct_type = DataType::Struct(struct_fields);
3451
3452 let options = GetOptions {
3453 path: VariantPath::default(),
3454 as_type: Some(Arc::new(Field::new("result", struct_type, true))),
3455 cast_options: CastOptions::default(),
3456 };
3457
3458 let result = variant_get(&variant_array, options).unwrap();
3459
3460 let struct_result = result.as_any().downcast_ref::<StructArray>().unwrap();
3462 assert_eq!(struct_result.len(), 4);
3463 assert_eq!(struct_result.num_columns(), 2);
3464
3465 let field_x = struct_result
3466 .column(0)
3467 .as_any()
3468 .downcast_ref::<Int32Array>()
3469 .unwrap();
3470 let field_y = struct_result
3471 .column(1)
3472 .as_any()
3473 .downcast_ref::<Int32Array>()
3474 .unwrap();
3475
3476 assert_eq!(field_x.value(0), 1);
3478 assert_eq!(field_y.value(0), 42);
3479
3480 assert_eq!(field_x.value(1), 2);
3482 assert!(field_y.is_null(1));
3483
3484 assert_eq!(field_x.value(2), 3);
3486 assert!(field_y.is_null(2));
3487
3488 assert!(struct_result.is_null(3));
3490 }
3491
3492 #[test]
3493 fn test_struct_row_builder_handles_unshredded_nested_structs() {
3494 let json_strings = vec![
3496 r#"{"outer": {"inner": 42}}"#,
3497 r#"{"outer": {"inner": 100}}"#,
3498 ];
3499 let string_array: Arc<dyn Array> = Arc::new(StringArray::from(json_strings));
3500 let variant_array = json_to_variant(&string_array).unwrap();
3501
3502 let inner_fields = Fields::from(vec![Field::new("inner", DataType::Int32, true)]);
3504 let inner_struct_type = DataType::Struct(inner_fields);
3505 let outer_fields = Fields::from(vec![Field::new("outer", inner_struct_type, true)]);
3506 let outer_struct_type = DataType::Struct(outer_fields);
3507
3508 let options = GetOptions {
3509 path: VariantPath::default(),
3510 as_type: Some(Arc::new(Field::new("result", outer_struct_type, true))),
3511 cast_options: CastOptions::default(),
3512 };
3513
3514 let variant_array_ref = ArrayRef::from(variant_array);
3515 let result = variant_get(&variant_array_ref, options).unwrap();
3516
3517 let outer_struct = result.as_struct();
3518 assert_eq!(outer_struct.len(), 2);
3519 assert_eq!(outer_struct.num_columns(), 1);
3520
3521 let inner_struct = outer_struct.column(0).as_struct();
3522 assert_eq!(inner_struct.num_columns(), 1);
3523
3524 let inner_values = inner_struct
3525 .column(0)
3526 .as_any()
3527 .downcast_ref::<Int32Array>()
3528 .unwrap();
3529 assert_eq!(inner_values.value(0), 42);
3530 assert_eq!(inner_values.value(1), 100);
3531 }
3532
3533 #[test]
3534 fn test_unshredded_struct_safe_cast_non_object_rows_are_null() {
3535 let json_strings = vec![r#"{"a": 1, "b": 2}"#, "123", "{}"];
3536 let string_array: Arc<dyn Array> = Arc::new(StringArray::from(json_strings));
3537 let variant_array_ref = ArrayRef::from(json_to_variant(&string_array).unwrap());
3538
3539 let struct_fields = Fields::from(vec![
3540 Field::new("a", DataType::Int32, true),
3541 Field::new("b", DataType::Int32, true),
3542 ]);
3543 let options = GetOptions {
3544 path: VariantPath::default(),
3545 as_type: Some(Arc::new(Field::new(
3546 "result",
3547 DataType::Struct(struct_fields),
3548 true,
3549 ))),
3550 cast_options: CastOptions::default(),
3551 };
3552
3553 let result = variant_get(&variant_array_ref, options).unwrap();
3554 let struct_result = result.as_struct();
3555 let field_a = struct_result
3556 .column(0)
3557 .as_primitive::<arrow::datatypes::Int32Type>();
3558 let field_b = struct_result
3559 .column(1)
3560 .as_primitive::<arrow::datatypes::Int32Type>();
3561
3562 assert!(!struct_result.is_null(0));
3564 assert_eq!(field_a.value(0), 1);
3565 assert_eq!(field_b.value(0), 2);
3566
3567 assert!(struct_result.is_null(1));
3569 assert!(field_a.is_null(1));
3570 assert!(field_b.is_null(1));
3571
3572 assert!(!struct_result.is_null(2));
3574 assert!(field_a.is_null(2));
3575 assert!(field_b.is_null(2));
3576 }
3577
3578 #[test]
3579 fn test_unshredded_struct_strict_cast_non_object_errors() {
3580 let json_strings = vec![r#"{"a": 1, "b": 2}"#, "123"];
3581 let string_array: Arc<dyn Array> = Arc::new(StringArray::from(json_strings));
3582 let variant_array_ref = ArrayRef::from(json_to_variant(&string_array).unwrap());
3583
3584 let struct_fields = Fields::from(vec![
3585 Field::new("a", DataType::Int32, true),
3586 Field::new("b", DataType::Int32, true),
3587 ]);
3588 let options = GetOptions {
3589 path: VariantPath::default(),
3590 as_type: Some(Arc::new(Field::new(
3591 "result",
3592 DataType::Struct(struct_fields),
3593 true,
3594 ))),
3595 cast_options: CastOptions {
3596 safe: false,
3597 ..Default::default()
3598 },
3599 };
3600
3601 let err = variant_get(&variant_array_ref, options).unwrap_err();
3602 assert!(
3603 err.to_string()
3604 .contains("Failed to extract struct from variant")
3605 );
3606 }
3607
3608 fn create_comprehensive_shredded_variant() -> ArrayRef {
3611 let (metadata, _) = {
3612 let mut builder = parquet_variant::VariantBuilder::new();
3613 let obj = builder.new_object();
3614 obj.finish();
3615 builder.finish()
3616 };
3617
3618 let nulls = NullBuffer::from(vec![
3620 true, false, true, true, true, ]);
3626
3627 let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 5));
3628
3629 let a_field_typed_value = Int32Array::from(vec![Some(1), None, None, Some(1), None]);
3632 let a_field_shredded = ShreddedVariantFieldArray::perfectly_shredded(Arc::new(
3633 a_field_typed_value,
3634 ) as ArrayRef);
3635
3636 let b_field_typed_value = Int32Array::from(vec![Some(2), None, Some(2), None, None]);
3638 let b_field_shredded = ShreddedVariantFieldArray::perfectly_shredded(Arc::new(
3639 b_field_typed_value,
3640 ) as ArrayRef);
3641
3642 let c_field_typed_value = Int32Array::from(vec![Some(3), None, None, None, None]);
3644 let c_field_shredded = ShreddedVariantFieldArray::perfectly_shredded(Arc::new(
3645 c_field_typed_value,
3646 ) as ArrayRef);
3647
3648 let typed_value_fields = Fields::from(vec![
3650 Field::new("a", a_field_shredded.data_type().clone(), true),
3651 Field::new("b", b_field_shredded.data_type().clone(), true),
3652 Field::new("c", c_field_shredded.data_type().clone(), true),
3653 ]);
3654 let typed_value_struct = StructArray::try_new(
3655 typed_value_fields,
3656 vec![
3657 ArrayRef::from(a_field_shredded),
3658 ArrayRef::from(b_field_shredded),
3659 ArrayRef::from(c_field_shredded),
3660 ],
3661 None,
3662 )
3663 .unwrap();
3664
3665 ArrayRef::from(VariantArray::perfectly_shredded(
3667 Arc::new(metadata_array),
3668 Arc::new(typed_value_struct),
3669 Some(nulls),
3670 ))
3671 }
3672
3673 fn create_comprehensive_nested_shredded_variant() -> ArrayRef {
3678 let inner_typed_value = Int32Array::from(vec![Some(42), None, None, None]); let inner =
3682 ShreddedVariantFieldArray::perfectly_shredded(Arc::new(inner_typed_value) as ArrayRef);
3683
3684 let outer_typed_value_nulls = NullBuffer::from(vec![
3685 true, false, false, false, ]);
3690 let outer_typed_value = StructArrayBuilder::new()
3691 .with_field("inner", ArrayRef::from(inner), false)
3692 .with_nulls(outer_typed_value_nulls)
3693 .build();
3694
3695 let outer =
3696 ShreddedVariantFieldArray::perfectly_shredded(Arc::new(outer_typed_value) as ArrayRef);
3697
3698 let typed_value_nulls = NullBuffer::from(vec![
3699 true, true, false, false, ]);
3704 let typed_value = StructArrayBuilder::new()
3705 .with_field("outer", ArrayRef::from(outer), false)
3706 .with_nulls(typed_value_nulls)
3707 .build();
3708
3709 let metadata_array =
3711 BinaryViewArray::from_iter_values(std::iter::repeat_n(EMPTY_VARIANT_METADATA_BYTES, 4));
3712 let nulls = NullBuffer::from(vec![
3713 true, true, true, false, ]);
3718 ArrayRef::from(VariantArray::perfectly_shredded(
3719 Arc::new(metadata_array),
3720 Arc::new(typed_value),
3721 Some(nulls),
3722 ))
3723 }
3724
3725 fn create_mixed_and_unshredded_variant() -> ArrayRef {
3728 let (metadata, y_field_value) = {
3733 let mut builder = parquet_variant::VariantBuilder::new();
3734 let mut obj = builder.new_object();
3735 obj.insert("y", Variant::from(42));
3736 obj.finish();
3737 builder.finish()
3738 };
3739
3740 let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 4));
3741
3742 let empty_object_value = {
3749 let mut builder = parquet_variant::VariantBuilder::new();
3750 builder.new_object().finish();
3751 let (_, value) = builder.finish();
3752 value
3753 };
3754
3755 let y_null_value = {
3756 let mut builder = parquet_variant::VariantBuilder::new();
3757 builder.new_object().with_field("y", Variant::Null).finish();
3758 let (_, value) = builder.finish();
3759 value
3760 };
3761
3762 let value_array = BinaryViewArray::from(vec![
3763 Some(y_field_value.as_slice()), Some(empty_object_value.as_slice()), Some(y_null_value.as_slice()), Some(empty_object_value.as_slice()), ]);
3768
3769 let x_field_typed_value = Int32Array::from(vec![Some(1), Some(2), Some(3), Some(0)]);
3772 let x_field_shredded = ShreddedVariantFieldArray::perfectly_shredded(Arc::new(
3773 x_field_typed_value,
3774 ) as ArrayRef);
3775
3776 let typed_value_struct = StructArrayBuilder::new()
3778 .with_field("x", ArrayRef::from(x_field_shredded), false)
3779 .build();
3780
3781 let variant_nulls = NullBuffer::from(vec![true, true, true, false]); ArrayRef::from(VariantArray::from_parts(
3785 Arc::new(metadata_array),
3786 Arc::new(value_array),
3787 Some(Arc::new(typed_value_struct)),
3788 Some(variant_nulls),
3789 ))
3790 }
3791
3792 #[test]
3793 fn get_decimal32_rescaled_to_scale2() {
3794 let mut builder = crate::VariantArrayBuilder::new(5);
3796 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();
3800 builder.append_variant(
3801 VariantDecimal8::try_new((VariantDecimal4::MAX_UNSCALED_VALUE as i64) + 1, 3)
3802 .unwrap()
3803 .into(),
3804 ); let variant_array: ArrayRef = ArrayRef::from(builder.build());
3806
3807 let field = Field::new("result", DataType::Decimal32(9, 2), true);
3808 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3809 let result = variant_get(&variant_array, options).unwrap();
3810 let result = result.as_any().downcast_ref::<Decimal32Array>().unwrap();
3811
3812 assert_eq!(result.precision(), 9);
3813 assert_eq!(result.scale(), 2);
3814 assert_eq!(result.value(0), 1234);
3815 assert_eq!(result.value(1), 123);
3816 assert_eq!(result.value(2), 123400);
3817 assert!(result.is_null(3));
3818 assert_eq!(
3819 result.value(4),
3820 VariantDecimal4::MAX_UNSCALED_VALUE / 10 + 1
3821 ); }
3823
3824 #[test]
3825 fn get_decimal32_scale_down_rounding() {
3826 let mut builder = crate::VariantArrayBuilder::new(7);
3827 builder.append_variant(VariantDecimal4::try_new(1235, 0).unwrap().into());
3828 builder.append_variant(VariantDecimal4::try_new(1245, 0).unwrap().into());
3829 builder.append_variant(VariantDecimal4::try_new(-1235, 0).unwrap().into());
3830 builder.append_variant(VariantDecimal4::try_new(-1245, 0).unwrap().into());
3831 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());
3835
3836 let field = Field::new("result", DataType::Decimal32(9, -1), true);
3837 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3838 let result = variant_get(&variant_array, options).unwrap();
3839 let result = result.as_any().downcast_ref::<Decimal32Array>().unwrap();
3840
3841 assert_eq!(result.precision(), 9);
3842 assert_eq!(result.scale(), -1);
3843 assert_eq!(result.value(0), 124);
3844 assert_eq!(result.value(1), 125);
3845 assert_eq!(result.value(2), -124);
3846 assert_eq!(result.value(3), -125);
3847 assert_eq!(result.value(4), 1);
3848 assert!(result.is_valid(5));
3849 assert_eq!(result.value(5), 0);
3850 assert_eq!(result.value(6), 1);
3851 }
3852
3853 #[test]
3854 fn get_decimal32_large_scale_reduction() {
3855 let mut builder = crate::VariantArrayBuilder::new(2);
3856 builder.append_variant(
3857 VariantDecimal4::try_new(-VariantDecimal4::MAX_UNSCALED_VALUE, 0)
3858 .unwrap()
3859 .into(),
3860 );
3861 builder.append_variant(
3862 VariantDecimal4::try_new(VariantDecimal4::MAX_UNSCALED_VALUE, 0)
3863 .unwrap()
3864 .into(),
3865 );
3866 let variant_array: ArrayRef = ArrayRef::from(builder.build());
3867
3868 let field = Field::new("result", DataType::Decimal32(9, -9), true);
3869 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3870 let result = variant_get(&variant_array, options).unwrap();
3871 let result = result.as_any().downcast_ref::<Decimal32Array>().unwrap();
3872
3873 assert_eq!(result.precision(), 9);
3874 assert_eq!(result.scale(), -9);
3875 assert_eq!(result.value(0), -1);
3876 assert_eq!(result.value(1), 1);
3877
3878 let field = Field::new("result", DataType::Decimal32(9, -10), true);
3879 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3880 let result = variant_get(&variant_array, options).unwrap();
3881 let result = result.as_any().downcast_ref::<Decimal32Array>().unwrap();
3882
3883 assert_eq!(result.precision(), 9);
3884 assert_eq!(result.scale(), -10);
3885 assert!(result.is_valid(0));
3886 assert_eq!(result.value(0), 0);
3887 assert!(result.is_valid(1));
3888 assert_eq!(result.value(1), 0);
3889 }
3890
3891 #[test]
3892 fn get_decimal32_precision_overflow_safe() {
3893 let mut builder = crate::VariantArrayBuilder::new(2);
3895 builder.append_variant(
3896 VariantDecimal4::try_new(VariantDecimal4::MAX_UNSCALED_VALUE, 0)
3897 .unwrap()
3898 .into(),
3899 );
3900 builder.append_variant(
3901 VariantDecimal4::try_new(VariantDecimal4::MAX_UNSCALED_VALUE, 9)
3902 .unwrap()
3903 .into(),
3904 ); let variant_array: ArrayRef = ArrayRef::from(builder.build());
3906
3907 let field = Field::new("result", DataType::Decimal32(2, 2), true);
3908 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3909 let result = variant_get(&variant_array, options).unwrap();
3910 let result = result.as_any().downcast_ref::<Decimal32Array>().unwrap();
3911
3912 assert!(result.is_null(0));
3913 assert!(result.is_null(1)); }
3915
3916 #[test]
3917 fn get_decimal32_precision_overflow_unsafe_errors() {
3918 let mut builder = crate::VariantArrayBuilder::new(1);
3919 builder.append_variant(
3920 VariantDecimal4::try_new(VariantDecimal4::MAX_UNSCALED_VALUE, 0)
3921 .unwrap()
3922 .into(),
3923 );
3924 let variant_array: ArrayRef = ArrayRef::from(builder.build());
3925
3926 let field = Field::new("result", DataType::Decimal32(9, 2), true);
3927 let cast_options = CastOptions {
3928 safe: false,
3929 ..Default::default()
3930 };
3931 let options = GetOptions::new()
3932 .with_as_type(Some(FieldRef::from(field)))
3933 .with_cast_options(cast_options);
3934 let err = variant_get(&variant_array, options).unwrap_err();
3935
3936 assert!(
3937 err.to_string().contains(
3938 "Failed to cast to Decimal32(precision=9, scale=2) from variant Decimal4"
3939 )
3940 );
3941 }
3942
3943 #[test]
3944 fn get_decimal64_rescaled_to_scale2() {
3945 let mut builder = crate::VariantArrayBuilder::new(5);
3946 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();
3950 builder.append_variant(
3951 VariantDecimal16::try_new((VariantDecimal8::MAX_UNSCALED_VALUE as i128) + 1, 3)
3952 .unwrap()
3953 .into(),
3954 ); let variant_array: ArrayRef = ArrayRef::from(builder.build());
3956
3957 let field = Field::new("result", DataType::Decimal64(18, 2), true);
3958 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3959 let result = variant_get(&variant_array, options).unwrap();
3960 let result = result.as_any().downcast_ref::<Decimal64Array>().unwrap();
3961
3962 assert_eq!(result.precision(), 18);
3963 assert_eq!(result.scale(), 2);
3964 assert_eq!(result.value(0), 1234);
3965 assert_eq!(result.value(1), 123);
3966 assert_eq!(result.value(2), 123400);
3967 assert!(result.is_null(3));
3968 assert_eq!(
3969 result.value(4),
3970 VariantDecimal8::MAX_UNSCALED_VALUE / 10 + 1
3971 ); }
3973
3974 #[test]
3975 fn get_decimal64_scale_down_rounding() {
3976 let mut builder = crate::VariantArrayBuilder::new(7);
3977 builder.append_variant(VariantDecimal8::try_new(1235, 0).unwrap().into());
3978 builder.append_variant(VariantDecimal8::try_new(1245, 0).unwrap().into());
3979 builder.append_variant(VariantDecimal8::try_new(-1235, 0).unwrap().into());
3980 builder.append_variant(VariantDecimal8::try_new(-1245, 0).unwrap().into());
3981 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());
3985
3986 let field = Field::new("result", DataType::Decimal64(18, -1), true);
3987 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3988 let result = variant_get(&variant_array, options).unwrap();
3989 let result = result.as_any().downcast_ref::<Decimal64Array>().unwrap();
3990
3991 assert_eq!(result.precision(), 18);
3992 assert_eq!(result.scale(), -1);
3993 assert_eq!(result.value(0), 124);
3994 assert_eq!(result.value(1), 125);
3995 assert_eq!(result.value(2), -124);
3996 assert_eq!(result.value(3), -125);
3997 assert_eq!(result.value(4), 1);
3998 assert!(result.is_valid(5));
3999 assert_eq!(result.value(5), 0);
4000 assert_eq!(result.value(6), 1);
4001 }
4002
4003 #[test]
4004 fn get_decimal64_large_scale_reduction() {
4005 let mut builder = crate::VariantArrayBuilder::new(2);
4006 builder.append_variant(
4007 VariantDecimal8::try_new(-VariantDecimal8::MAX_UNSCALED_VALUE, 0)
4008 .unwrap()
4009 .into(),
4010 );
4011 builder.append_variant(
4012 VariantDecimal8::try_new(VariantDecimal8::MAX_UNSCALED_VALUE, 0)
4013 .unwrap()
4014 .into(),
4015 );
4016 let variant_array: ArrayRef = ArrayRef::from(builder.build());
4017
4018 let field = Field::new("result", DataType::Decimal64(18, -18), true);
4019 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
4020 let result = variant_get(&variant_array, options).unwrap();
4021 let result = result.as_any().downcast_ref::<Decimal64Array>().unwrap();
4022
4023 assert_eq!(result.precision(), 18);
4024 assert_eq!(result.scale(), -18);
4025 assert_eq!(result.value(0), -1);
4026 assert_eq!(result.value(1), 1);
4027
4028 let field = Field::new("result", DataType::Decimal64(18, -19), true);
4029 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
4030 let result = variant_get(&variant_array, options).unwrap();
4031 let result = result.as_any().downcast_ref::<Decimal64Array>().unwrap();
4032
4033 assert_eq!(result.precision(), 18);
4034 assert_eq!(result.scale(), -19);
4035 assert!(result.is_valid(0));
4036 assert_eq!(result.value(0), 0);
4037 assert!(result.is_valid(1));
4038 assert_eq!(result.value(1), 0);
4039 }
4040
4041 #[test]
4042 fn get_decimal64_precision_overflow_safe() {
4043 let mut builder = crate::VariantArrayBuilder::new(2);
4045 builder.append_variant(
4046 VariantDecimal8::try_new(VariantDecimal8::MAX_UNSCALED_VALUE, 0)
4047 .unwrap()
4048 .into(),
4049 );
4050 builder.append_variant(
4051 VariantDecimal8::try_new(VariantDecimal8::MAX_UNSCALED_VALUE, 18)
4052 .unwrap()
4053 .into(),
4054 ); let variant_array: ArrayRef = ArrayRef::from(builder.build());
4056
4057 let field = Field::new("result", DataType::Decimal64(2, 2), true);
4058 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
4059 let result = variant_get(&variant_array, options).unwrap();
4060 let result = result.as_any().downcast_ref::<Decimal64Array>().unwrap();
4061
4062 assert!(result.is_null(0));
4063 assert!(result.is_null(1));
4064 }
4065
4066 #[test]
4067 fn get_decimal64_precision_overflow_unsafe_errors() {
4068 let mut builder = crate::VariantArrayBuilder::new(1);
4069 builder.append_variant(
4070 VariantDecimal8::try_new(VariantDecimal8::MAX_UNSCALED_VALUE, 0)
4071 .unwrap()
4072 .into(),
4073 );
4074 let variant_array: ArrayRef = ArrayRef::from(builder.build());
4075
4076 let field = Field::new("result", DataType::Decimal64(18, 2), true);
4077 let cast_options = CastOptions {
4078 safe: false,
4079 ..Default::default()
4080 };
4081 let options = GetOptions::new()
4082 .with_as_type(Some(FieldRef::from(field)))
4083 .with_cast_options(cast_options);
4084 let err = variant_get(&variant_array, options).unwrap_err();
4085
4086 assert!(
4087 err.to_string().contains(
4088 "Failed to cast to Decimal64(precision=18, scale=2) from variant Decimal8"
4089 )
4090 );
4091 }
4092
4093 #[test]
4094 fn get_decimal128_rescaled_to_scale2() {
4095 let mut builder = crate::VariantArrayBuilder::new(4);
4096 builder.append_variant(VariantDecimal16::try_new(1234, 2).unwrap().into());
4097 builder.append_variant(VariantDecimal16::try_new(1234, 3).unwrap().into());
4098 builder.append_variant(VariantDecimal16::try_new(1234, 0).unwrap().into());
4099 builder.append_null();
4100 let variant_array: ArrayRef = ArrayRef::from(builder.build());
4101
4102 let field = Field::new("result", DataType::Decimal128(38, 2), true);
4103 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
4104 let result = variant_get(&variant_array, options).unwrap();
4105 let result = result.as_any().downcast_ref::<Decimal128Array>().unwrap();
4106
4107 assert_eq!(result.precision(), 38);
4108 assert_eq!(result.scale(), 2);
4109 assert_eq!(result.value(0), 1234);
4110 assert_eq!(result.value(1), 123);
4111 assert_eq!(result.value(2), 123400);
4112 assert!(result.is_null(3));
4113 }
4114
4115 #[test]
4116 fn get_decimal128_scale_down_rounding() {
4117 let mut builder = crate::VariantArrayBuilder::new(7);
4118 builder.append_variant(VariantDecimal16::try_new(1235, 0).unwrap().into());
4119 builder.append_variant(VariantDecimal16::try_new(1245, 0).unwrap().into());
4120 builder.append_variant(VariantDecimal16::try_new(-1235, 0).unwrap().into());
4121 builder.append_variant(VariantDecimal16::try_new(-1245, 0).unwrap().into());
4122 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());
4126
4127 let field = Field::new("result", DataType::Decimal128(38, -1), true);
4128 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
4129 let result = variant_get(&variant_array, options).unwrap();
4130 let result = result.as_any().downcast_ref::<Decimal128Array>().unwrap();
4131
4132 assert_eq!(result.precision(), 38);
4133 assert_eq!(result.scale(), -1);
4134 assert_eq!(result.value(0), 124);
4135 assert_eq!(result.value(1), 125);
4136 assert_eq!(result.value(2), -124);
4137 assert_eq!(result.value(3), -125);
4138 assert_eq!(result.value(4), 1);
4139 assert!(result.is_valid(5));
4140 assert_eq!(result.value(5), 0);
4141 assert_eq!(result.value(6), 1);
4142 }
4143
4144 #[test]
4145 fn get_decimal128_precision_overflow_safe() {
4146 let mut builder = crate::VariantArrayBuilder::new(2);
4148 builder.append_variant(
4149 VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 0)
4150 .unwrap()
4151 .into(),
4152 );
4153 builder.append_variant(
4154 VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 38)
4155 .unwrap()
4156 .into(),
4157 ); let variant_array: ArrayRef = ArrayRef::from(builder.build());
4159
4160 let field = Field::new("result", DataType::Decimal128(2, 2), true);
4161 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
4162 let result = variant_get(&variant_array, options).unwrap();
4163 let result = result.as_any().downcast_ref::<Decimal128Array>().unwrap();
4164
4165 assert!(result.is_null(0));
4166 assert!(result.is_null(1)); }
4168
4169 #[test]
4170 fn get_decimal128_precision_overflow_unsafe_errors() {
4171 let mut builder = crate::VariantArrayBuilder::new(1);
4172 builder.append_variant(
4173 VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 0)
4174 .unwrap()
4175 .into(),
4176 );
4177 let variant_array: ArrayRef = ArrayRef::from(builder.build());
4178
4179 let field = Field::new("result", DataType::Decimal128(38, 2), true);
4180 let cast_options = CastOptions {
4181 safe: false,
4182 ..Default::default()
4183 };
4184 let options = GetOptions::new()
4185 .with_as_type(Some(FieldRef::from(field)))
4186 .with_cast_options(cast_options);
4187 let err = variant_get(&variant_array, options).unwrap_err();
4188
4189 assert!(err.to_string().contains(
4190 "Failed to cast to Decimal128(precision=38, scale=2) from variant Decimal16"
4191 ));
4192 }
4193
4194 #[test]
4195 fn get_decimal256_rescaled_to_scale2() {
4196 let mut builder = crate::VariantArrayBuilder::new(4);
4198 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();
4202 let variant_array: ArrayRef = ArrayRef::from(builder.build());
4203
4204 let field = Field::new("result", DataType::Decimal256(76, 2), true);
4205 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
4206 let result = variant_get(&variant_array, options).unwrap();
4207 let result = result.as_any().downcast_ref::<Decimal256Array>().unwrap();
4208
4209 assert_eq!(result.precision(), 76);
4210 assert_eq!(result.scale(), 2);
4211 assert_eq!(result.value(0), i256::from_i128(1234));
4212 assert_eq!(result.value(1), i256::from_i128(123));
4213 assert_eq!(result.value(2), i256::from_i128(123400));
4214 assert!(result.is_null(3));
4215 }
4216
4217 #[test]
4218 fn get_decimal256_scale_down_rounding() {
4219 let mut builder = crate::VariantArrayBuilder::new(7);
4220 builder.append_variant(VariantDecimal16::try_new(1235, 0).unwrap().into());
4221 builder.append_variant(VariantDecimal16::try_new(1245, 0).unwrap().into());
4222 builder.append_variant(VariantDecimal16::try_new(-1235, 0).unwrap().into());
4223 builder.append_variant(VariantDecimal16::try_new(-1245, 0).unwrap().into());
4224 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());
4228
4229 let field = Field::new("result", DataType::Decimal256(76, -1), true);
4230 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
4231 let result = variant_get(&variant_array, options).unwrap();
4232 let result = result.as_any().downcast_ref::<Decimal256Array>().unwrap();
4233
4234 assert_eq!(result.precision(), 76);
4235 assert_eq!(result.scale(), -1);
4236 assert_eq!(result.value(0), i256::from_i128(124));
4237 assert_eq!(result.value(1), i256::from_i128(125));
4238 assert_eq!(result.value(2), i256::from_i128(-124));
4239 assert_eq!(result.value(3), i256::from_i128(-125));
4240 assert_eq!(result.value(4), i256::from_i128(1));
4241 assert!(result.is_valid(5));
4242 assert_eq!(result.value(5), i256::from_i128(0));
4243 assert_eq!(result.value(6), i256::from_i128(1));
4244 }
4245
4246 #[test]
4247 fn get_decimal256_precision_overflow_safe() {
4248 let mut builder = crate::VariantArrayBuilder::new(2);
4250 builder.append_variant(
4251 VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 1)
4252 .unwrap()
4253 .into(),
4254 );
4255 builder.append_variant(
4256 VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 0)
4257 .unwrap()
4258 .into(),
4259 );
4260 let variant_array: ArrayRef = ArrayRef::from(builder.build());
4261
4262 let field = Field::new("result", DataType::Decimal256(76, 39), true);
4263 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
4264 let result = variant_get(&variant_array, options).unwrap();
4265 let result = result.as_any().downcast_ref::<Decimal256Array>().unwrap();
4266
4267 let base = i256::from_i128(10);
4270 let factor = base.checked_pow(38).unwrap();
4271 let expected = i256::from_i128(VariantDecimal16::MAX_UNSCALED_VALUE)
4272 .checked_mul(factor)
4273 .unwrap();
4274 assert_eq!(result.value(0), expected);
4275 assert!(result.is_null(1));
4276 }
4277
4278 #[test]
4279 fn get_decimal256_precision_overflow_unsafe_errors() {
4280 let mut builder = crate::VariantArrayBuilder::new(2);
4282 builder.append_variant(
4283 VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 1)
4284 .unwrap()
4285 .into(),
4286 );
4287 builder.append_variant(
4288 VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 0)
4289 .unwrap()
4290 .into(),
4291 );
4292 let variant_array: ArrayRef = ArrayRef::from(builder.build());
4293
4294 let field = Field::new("result", DataType::Decimal256(76, 39), true);
4295 let cast_options = CastOptions {
4296 safe: false,
4297 ..Default::default()
4298 };
4299 let options = GetOptions::new()
4300 .with_as_type(Some(FieldRef::from(field)))
4301 .with_cast_options(cast_options);
4302 let err = variant_get(&variant_array, options).unwrap_err();
4303
4304 assert!(err.to_string().contains(
4305 "Failed to cast to Decimal256(precision=76, scale=39) from variant Decimal16"
4306 ));
4307 }
4308
4309 #[test]
4310 fn get_non_supported_temporal_types_error() {
4311 let values = vec![None, Some(Variant::Null), Some(Variant::BooleanFalse)];
4312 let variant_array: ArrayRef = ArrayRef::from(VariantArray::from_iter(values));
4313
4314 let test_cases = vec![
4315 FieldRef::from(Field::new(
4316 "result",
4317 DataType::Duration(TimeUnit::Microsecond),
4318 true,
4319 )),
4320 FieldRef::from(Field::new(
4321 "result",
4322 DataType::Interval(IntervalUnit::YearMonth),
4323 true,
4324 )),
4325 ];
4326
4327 for field in test_cases {
4328 let options = GetOptions::new().with_as_type(Some(field));
4329 let err = variant_get(&variant_array, options).unwrap_err();
4330 assert!(
4331 err.to_string()
4332 .contains("Casting Variant to duration/interval types is not supported")
4333 );
4334 }
4335 }
4336
4337 #[test]
4338 fn get_variant_as_dictionary() {
4339 let variant_array: ArrayRef = ArrayRef::from(VariantArray::from_iter(vec![
4340 Some(Variant::from("apple")),
4341 Some(Variant::from("banana")),
4342 None,
4343 Some(Variant::from("apple")),
4344 ]));
4345 let data_type = DataType::Dictionary(Box::new(DataType::Int32), Box::new(DataType::Utf8));
4346 let options = GetOptions::new().with_as_type(Some(FieldRef::from(Field::new(
4347 "dict",
4348 data_type.clone(),
4349 true,
4350 ))));
4351
4352 let result = variant_get(&variant_array, options).unwrap();
4353 assert_eq!(result.data_type(), &data_type);
4354
4355 let decoded = cast(result.as_ref(), &DataType::Utf8).unwrap();
4356 let expected = StringArray::from(vec![Some("apple"), Some("banana"), None, Some("apple")]);
4357 assert_eq!(decoded.as_ref(), &expected);
4358 }
4359
4360 #[test]
4361 fn get_variant_as_numeric_dictionary() {
4362 let variant_array: ArrayRef = ArrayRef::from(VariantArray::from_iter(vec![
4363 Some(Variant::from(42)),
4364 Some(Variant::from(7)),
4365 None,
4366 Some(Variant::from(42)),
4367 ]));
4368 let data_type = DataType::Dictionary(Box::new(DataType::Int16), Box::new(DataType::Int32));
4369 let options = GetOptions::new().with_as_type(Some(FieldRef::from(Field::new(
4370 "dict",
4371 data_type.clone(),
4372 true,
4373 ))));
4374
4375 let result = variant_get(&variant_array, options).unwrap();
4376 assert_eq!(result.data_type(), &data_type);
4377
4378 let decoded = cast(result.as_ref(), &DataType::Int32).unwrap();
4379 let expected = Int32Array::from(vec![Some(42), Some(7), None, Some(42)]);
4380 assert_eq!(decoded.as_ref(), &expected);
4381 }
4382
4383 #[test]
4384 fn get_variant_as_run_end_encoded() {
4385 let variant_array: ArrayRef = ArrayRef::from(VariantArray::from_iter(vec![
4386 Some(Variant::from("apple")),
4387 Some(Variant::from("apple")),
4388 None,
4389 Some(Variant::from("banana")),
4390 Some(Variant::from("banana")),
4391 ]));
4392 let run_ends = Arc::new(Field::new("run_ends", DataType::Int32, false));
4393 let values = Arc::new(Field::new("values", DataType::Utf8, true));
4394 let data_type = DataType::RunEndEncoded(run_ends, values);
4395 let options = GetOptions::new().with_as_type(Some(FieldRef::from(Field::new(
4396 "ree",
4397 data_type.clone(),
4398 true,
4399 ))));
4400
4401 let result = variant_get(&variant_array, options).unwrap();
4402 assert_eq!(result.data_type(), &data_type);
4403
4404 let decoded = cast(result.as_ref(), &DataType::Utf8).unwrap();
4405 let expected = StringArray::from(vec![
4406 Some("apple"),
4407 Some("apple"),
4408 None,
4409 Some("banana"),
4410 Some("banana"),
4411 ]);
4412 assert_eq!(decoded.as_ref(), &expected);
4413 }
4414
4415 fn map_data_type(value_type: DataType) -> DataType {
4418 DataType::Map(
4419 Arc::new(Field::new(
4420 "entries",
4421 DataType::Struct(Fields::from(vec![
4422 Field::new("keys", DataType::Utf8, false),
4423 Field::new("values", value_type, true),
4424 ])),
4425 false,
4426 )),
4427 false,
4428 )
4429 }
4430
4431 fn map_get_options(data_type: &DataType) -> GetOptions<'static> {
4432 GetOptions::new().with_as_type(Some(FieldRef::from(Field::new(
4433 "map",
4434 data_type.clone(),
4435 true,
4436 ))))
4437 }
4438
4439 #[test]
4440 fn get_variant_as_map() {
4441 let input: ArrayRef = Arc::new(StringArray::from(vec![
4442 Some(r#"{"a": 1, "b": 2}"#),
4443 Some(r#"{"c": 3}"#),
4444 None,
4445 Some("{}"),
4446 Some(r#"{"d": null}"#),
4447 ]));
4448 let variant_array = ArrayRef::from(json_to_variant(&input).unwrap());
4449
4450 let data_type = map_data_type(DataType::Int64);
4451 let result = variant_get(&variant_array, map_get_options(&data_type)).unwrap();
4452 assert_eq!(result.data_type(), &data_type);
4453
4454 let mut expected = MapBuilder::new(None, StringBuilder::new(), Int64Builder::new());
4455 expected.keys().append_value("a");
4456 expected.values().append_value(1);
4457 expected.keys().append_value("b");
4458 expected.values().append_value(2);
4459 expected.append(true).unwrap();
4460 expected.keys().append_value("c");
4461 expected.values().append_value(3);
4462 expected.append(true).unwrap();
4463 expected.append(false).unwrap(); expected.append(true).unwrap(); expected.keys().append_value("d");
4466 expected.values().append_null(); expected.append(true).unwrap();
4468 let expected = expected.finish();
4469 assert_eq!(result.as_ref(), &expected);
4470 }
4471
4472 #[test]
4473 fn get_variant_as_map_of_lists() {
4474 let input: ArrayRef = Arc::new(StringArray::from(vec![
4475 Some(r#"{"a": [1, 2], "b": []}"#),
4476 Some(r#"{"c": [3]}"#),
4477 ]));
4478 let variant_array = ArrayRef::from(json_to_variant(&input).unwrap());
4479
4480 let data_type = map_data_type(DataType::List(Arc::new(Field::new(
4481 "item",
4482 DataType::Int64,
4483 true,
4484 ))));
4485 let result = variant_get(&variant_array, map_get_options(&data_type)).unwrap();
4486 assert_eq!(result.data_type(), &data_type);
4487
4488 let mut expected = MapBuilder::new(
4489 None,
4490 StringBuilder::new(),
4491 ListBuilder::new(Int64Builder::new()),
4492 );
4493 expected.keys().append_value("a");
4494 expected.values().append_value([Some(1), Some(2)]);
4495 expected.keys().append_value("b");
4496 expected.values().append_value([]);
4497 expected.append(true).unwrap();
4498 expected.keys().append_value("c");
4499 expected.values().append_value([Some(3)]);
4500 expected.append(true).unwrap();
4501 let expected = expected.finish();
4502 assert_eq!(result.as_ref(), &expected);
4503 }
4504
4505 #[test]
4506 fn get_variant_as_map_non_object_rows() {
4507 let input: ArrayRef = Arc::new(StringArray::from(vec![
4508 Some(r#"{"a": 1}"#),
4509 Some("42"), ]));
4511 let variant_array = ArrayRef::from(json_to_variant(&input).unwrap());
4512 let data_type = map_data_type(DataType::Int64);
4513
4514 let result = variant_get(&variant_array, map_get_options(&data_type)).unwrap();
4516 let mut expected = MapBuilder::new(None, StringBuilder::new(), Int64Builder::new());
4517 expected.keys().append_value("a");
4518 expected.values().append_value(1);
4519 expected.append(true).unwrap();
4520 expected.append(false).unwrap();
4521 let expected = expected.finish();
4522 assert_eq!(result.as_ref(), &expected);
4523
4524 let options = map_get_options(&data_type).with_cast_options(CastOptions {
4526 safe: false,
4527 format_options: FormatOptions::default(),
4528 });
4529 let err = variant_get(&variant_array, options).unwrap_err();
4530 assert!(
4531 err.to_string().contains("Failed to extract object"),
4532 "unexpected error: {err}"
4533 );
4534 }
4535
4536 #[test]
4537 fn get_variant_as_map_invalid_entries() {
4538 let input: ArrayRef = Arc::new(StringArray::from(vec![Some(r#"{"a": 1}"#)]));
4539 let variant_array = ArrayRef::from(json_to_variant(&input).unwrap());
4540
4541 let data_type = DataType::Map(
4543 Arc::new(Field::new("entries", DataType::Int32, false)),
4544 false,
4545 );
4546 let err = variant_get(&variant_array, map_get_options(&data_type)).unwrap_err();
4547 assert!(
4548 err.to_string().contains("Map entries must be Struct"),
4549 "unexpected error: {err}"
4550 );
4551
4552 let data_type = DataType::Map(
4554 Arc::new(Field::new(
4555 "entries",
4556 DataType::Struct(Fields::from(vec![Field::new(
4557 "keys",
4558 DataType::Utf8,
4559 false,
4560 )])),
4561 false,
4562 )),
4563 false,
4564 );
4565 let err = variant_get(&variant_array, map_get_options(&data_type)).unwrap_err();
4566 assert!(
4567 err.to_string()
4568 .contains("Map entries must have exactly two fields"),
4569 "unexpected error: {err}"
4570 );
4571 }
4572
4573 fn invalid_time_variant_array() -> ArrayRef {
4574 let mut builder = VariantArrayBuilder::new(3);
4575 builder.append_variant(Variant::Int64(86401000000));
4577 builder.append_variant(Variant::Int64(86401000000));
4578 builder.append_variant(Variant::Int64(86401000000));
4579 Arc::new(builder.build().into_inner())
4580 }
4581
4582 #[test]
4583 fn test_variant_get_error_when_cast_failure_and_safe_false() {
4584 let variant_array = invalid_time_variant_array();
4585
4586 let field = Field::new("result", DataType::Time64(TimeUnit::Microsecond), true);
4587 let cast_options = CastOptions {
4588 safe: false, ..Default::default()
4590 };
4591 let options = GetOptions::new()
4592 .with_as_type(Some(FieldRef::from(field)))
4593 .with_cast_options(cast_options);
4594 let err = variant_get(&variant_array, options).unwrap_err();
4595 assert!(
4596 err.to_string().contains(
4597 "Cast error: Failed to extract primitive of type Time64(µs) from variant Int64(86401000000) at path VariantPath([])"
4598 ),
4599 "actual: {err}",
4600 );
4601 }
4602
4603 #[test]
4604 fn test_variant_get_return_null_when_cast_failure_and_safe_true() {
4605 let variant_array = invalid_time_variant_array();
4606
4607 let field = Field::new("result", DataType::Time64(TimeUnit::Microsecond), true);
4608 let cast_options = CastOptions {
4609 safe: true, ..Default::default()
4611 };
4612 let options = GetOptions::new()
4613 .with_as_type(Some(FieldRef::from(field)))
4614 .with_cast_options(cast_options);
4615 let result = variant_get(&variant_array, options).unwrap();
4616 assert_eq!(3, result.len());
4617
4618 for i in 0..3 {
4619 assert!(result.is_null(i));
4620 }
4621 }
4622
4623 #[test]
4624 fn test_perfect_shredding_returns_same_arc_ptr() {
4625 let variant_array = perfectly_shredded_int32_variant_array();
4626
4627 let variant_array_ref = VariantArray::try_new(&variant_array).unwrap();
4628 let typed_value_arc = variant_array_ref.typed_value_column().unwrap().clone();
4629
4630 let field = Field::new("result", DataType::Int32, true);
4631 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
4632 let result = variant_get(&variant_array, options).unwrap();
4633
4634 assert!(Arc::ptr_eq(&typed_value_arc, &result));
4635 }
4636
4637 #[test]
4638 fn test_perfect_shredding_three_typed_value_columns() {
4639 let all_nulls_values: Arc<Int32Array> = Arc::new(Int32Array::from(vec![
4641 Option::<i32>::None,
4642 Option::<i32>::None,
4643 Option::<i32>::None,
4644 ]));
4645 let all_nulls_erased: ArrayRef = all_nulls_values.clone();
4646 let all_nulls_field =
4647 ShreddedVariantFieldArray::perfectly_shredded(all_nulls_erased.clone());
4648 let all_nulls_type = all_nulls_field.data_type().clone();
4649 let all_nulls_struct: ArrayRef = ArrayRef::from(all_nulls_field);
4650
4651 let some_nulls_values: Arc<Int32Array> =
4653 Arc::new(Int32Array::from(vec![Some(10), None, Some(30)]));
4654 let some_nulls_erased: ArrayRef = some_nulls_values.clone();
4655 let some_nulls_field =
4656 ShreddedVariantFieldArray::perfectly_shredded(some_nulls_erased.clone());
4657 let some_nulls_type = some_nulls_field.data_type().clone();
4658 let some_nulls_struct: ArrayRef = ArrayRef::from(some_nulls_field);
4659
4660 let inner_values: Arc<Int32Array> =
4662 Arc::new(Int32Array::from(vec![Some(111), None, Some(333)]));
4663 let inner_erased: ArrayRef = inner_values.clone();
4664 let inner_field = ShreddedVariantFieldArray::perfectly_shredded(inner_erased.clone());
4665 let inner_field_type = inner_field.data_type().clone();
4666 let inner_struct_array: ArrayRef = ArrayRef::from(inner_field);
4667
4668 let nested_struct = Arc::new(
4669 StructArray::try_new(
4670 Fields::from(vec![Field::new("inner", inner_field_type, true)]),
4671 vec![inner_struct_array],
4672 None,
4673 )
4674 .unwrap(),
4675 );
4676 let nested_struct_erased: ArrayRef = nested_struct.clone();
4677 let struct_field =
4678 ShreddedVariantFieldArray::perfectly_shredded(nested_struct_erased.clone());
4679 let struct_field_type = struct_field.data_type().clone();
4680 let struct_field_struct: ArrayRef = ArrayRef::from(struct_field);
4681
4682 let typed_value_struct = StructArray::try_new(
4684 Fields::from(vec![
4685 Field::new("all_nulls", all_nulls_type, true),
4686 Field::new("some_nulls", some_nulls_type, true),
4687 Field::new("struct_field", struct_field_type, true),
4688 ]),
4689 vec![all_nulls_struct, some_nulls_struct, struct_field_struct],
4690 None,
4691 )
4692 .unwrap();
4693
4694 let metadata = BinaryViewArray::from_iter_values(std::iter::repeat_n(
4695 EMPTY_VARIANT_METADATA_BYTES,
4696 all_nulls_values.len(),
4697 ));
4698 let variant_array: ArrayRef = VariantArray::perfectly_shredded(
4699 Arc::new(metadata),
4700 Arc::new(typed_value_struct),
4701 None,
4702 )
4703 .into();
4704
4705 let all_nulls_field_ref = FieldRef::from(Field::new("result", DataType::Int32, true));
4707 let all_nulls_result = variant_get(
4708 &variant_array,
4709 GetOptions::new_with_path(VariantPath::try_from("all_nulls").unwrap())
4710 .with_as_type(Some(all_nulls_field_ref)),
4711 )
4712 .unwrap();
4713 assert!(Arc::ptr_eq(&all_nulls_result, &all_nulls_erased));
4714
4715 let some_nulls_field_ref = FieldRef::from(Field::new("result", DataType::Int32, true));
4717 let some_nulls_result = variant_get(
4718 &variant_array,
4719 GetOptions::new_with_path(VariantPath::try_from("some_nulls").unwrap())
4720 .with_as_type(Some(some_nulls_field_ref)),
4721 )
4722 .unwrap();
4723 assert!(Arc::ptr_eq(&some_nulls_result, &some_nulls_erased));
4724
4725 let struct_child_fields = Fields::from(vec![Field::new("inner", DataType::Int32, true)]);
4727 let struct_field_ref = FieldRef::from(Field::new(
4728 "result",
4729 DataType::Struct(struct_child_fields.clone()),
4730 true,
4731 ));
4732 let struct_result = variant_get(
4733 &variant_array,
4734 GetOptions::new_with_path(VariantPath::try_from("struct_field").unwrap())
4735 .with_as_type(Some(struct_field_ref)),
4736 )
4737 .unwrap();
4738 let struct_array = struct_result
4739 .as_any()
4740 .downcast_ref::<StructArray>()
4741 .unwrap();
4742 assert_eq!(struct_array.len(), 3);
4743 assert_eq!(struct_array.null_count(), 0);
4744
4745 let inner_values_result = struct_array
4746 .column(0)
4747 .as_any()
4748 .downcast_ref::<Int32Array>()
4749 .unwrap();
4750 assert_eq!(inner_values_result.len(), 3);
4751 assert_eq!(inner_values_result.value(0), 111);
4752 assert!(inner_values_result.is_null(1));
4753 assert_eq!(inner_values_result.value(2), 333);
4754 }
4755
4756 #[test]
4757 fn test_variant_get_list_like_safe_cast() {
4758 let string_array: ArrayRef = Arc::new(StringArray::from(vec![
4759 r#"{"outer":{"list":[1, "two", 3]}}"#,
4760 r#"{"outer":{"list":"not a list"}}"#,
4761 ]));
4762 let variant_array = ArrayRef::from(json_to_variant(&string_array).unwrap());
4763
4764 let element_array: ArrayRef = Arc::new(Int64Array::from(vec![Some(1), None, Some(3)]));
4765 let field = Arc::new(Field::new("item", Int64, true));
4766
4767 let expectations = vec![
4768 (
4769 DataType::List(field.clone()),
4770 Arc::new(ListArray::new(
4771 field.clone(),
4772 OffsetBuffer::new(ScalarBuffer::from(vec![0, 3, 3])),
4773 element_array.clone(),
4774 Some(NullBuffer::from(vec![true, false])),
4775 )) as ArrayRef,
4776 ),
4777 (
4778 DataType::LargeList(field.clone()),
4779 Arc::new(LargeListArray::new(
4780 field.clone(),
4781 OffsetBuffer::new(ScalarBuffer::from(vec![0, 3, 3])),
4782 element_array.clone(),
4783 Some(NullBuffer::from(vec![true, false])),
4784 )) as ArrayRef,
4785 ),
4786 (
4787 DataType::ListView(field.clone()),
4788 Arc::new(ListViewArray::new(
4789 field.clone(),
4790 ScalarBuffer::from(vec![0, 3]),
4791 ScalarBuffer::from(vec![3, 0]),
4792 element_array.clone(),
4793 Some(NullBuffer::from(vec![true, false])),
4794 )) as ArrayRef,
4795 ),
4796 (
4797 DataType::LargeListView(field.clone()),
4798 Arc::new(LargeListViewArray::new(
4799 field.clone(),
4800 ScalarBuffer::from(vec![0, 3]),
4801 ScalarBuffer::from(vec![3, 0]),
4802 element_array,
4803 Some(NullBuffer::from(vec![true, false])),
4804 )) as ArrayRef,
4805 ),
4806 (
4807 DataType::FixedSizeList(field.clone(), 3),
4808 Arc::new(FixedSizeListArray::new(
4809 field,
4810 3,
4811 Arc::new(Int64Array::from(vec![
4812 Some(1),
4813 None,
4814 Some(3),
4815 None,
4816 None,
4817 None,
4818 ])),
4819 Some(NullBuffer::from(vec![true, false])),
4820 )) as ArrayRef,
4821 ),
4822 ];
4823
4824 for (request_type, expected) in expectations {
4825 let options =
4826 GetOptions::new_with_path(VariantPath::try_from("outer").unwrap().join("list"))
4827 .with_as_type(Some(FieldRef::from(Field::new(
4828 "result",
4829 request_type.clone(),
4830 true,
4831 ))));
4832
4833 let result = variant_get(&variant_array, options).unwrap();
4834 assert_eq!(result.data_type(), expected.data_type());
4835 assert_eq!(&result, &expected);
4836 }
4837
4838 for (idx, expected) in [
4839 (0, vec![Some(1), None]),
4840 (1, vec![None, None]),
4841 (2, vec![Some(3), None]),
4842 ] {
4843 let index_options = GetOptions::new_with_path(
4844 VariantPath::try_from("outer")
4845 .unwrap()
4846 .join("list")
4847 .join(idx),
4848 )
4849 .with_as_type(Some(FieldRef::from(Field::new(
4850 "result",
4851 DataType::Int64,
4852 true,
4853 ))));
4854 let index_result = variant_get(&variant_array, index_options).unwrap();
4855 let index_expected: ArrayRef = Arc::new(Int64Array::from(expected));
4856 assert_eq!(&index_result, &index_expected);
4857 }
4858 }
4859
4860 #[test]
4861 fn test_variant_get_nested_list() {
4862 use arrow::datatypes::Int64Type;
4863
4864 let string_array: ArrayRef = Arc::new(StringArray::from(vec![
4865 r#"[[1, 2], [3]]"#,
4866 r#"[[4], "not a list", [5, 6]]"#,
4867 ]));
4868 let variant_array = ArrayRef::from(json_to_variant(&string_array).unwrap());
4869
4870 let inner_field = Arc::new(Field::new("item", Int64, true));
4871 let outer_field = Arc::new(Field::new(
4872 "item",
4873 DataType::List(inner_field.clone()),
4874 true,
4875 ));
4876 let request_type = DataType::List(outer_field.clone());
4877
4878 let options = GetOptions::new().with_as_type(Some(FieldRef::from(Field::new(
4879 "result",
4880 request_type,
4881 true,
4882 ))));
4883 let result = variant_get(&variant_array, options).unwrap();
4884 let outer = result.as_list::<i32>();
4885
4886 let row0 = outer.value(0);
4888 let row0 = row0.as_list::<i32>();
4889 assert_eq!(row0.len(), 2);
4890 let elem0 = row0.value(0);
4891 assert_eq!(elem0.as_primitive::<Int64Type>().values(), &[1, 2]);
4892 let elem1 = row0.value(1);
4893 assert_eq!(elem1.as_primitive::<Int64Type>().values(), &[3]);
4894
4895 let row1 = outer.value(1);
4897 let row1 = row1.as_list::<i32>();
4898 assert_eq!(row1.len(), 3);
4899 let elem0 = row1.value(0);
4900 assert_eq!(elem0.as_primitive::<Int64Type>().values(), &[4]);
4901 assert!(row1.is_null(1));
4902 let elem2 = row1.value(2);
4903 assert_eq!(elem2.as_primitive::<Int64Type>().values(), &[5, 6]);
4904 }
4905
4906 #[test]
4907 fn test_variant_get_list_like_unsafe_cast_errors_on_element_mismatch() {
4908 let string_array: ArrayRef =
4909 Arc::new(StringArray::from(vec![r#"[1, "two", 3]"#, "[4, 5]"]));
4910 let variant_array = ArrayRef::from(json_to_variant(&string_array).unwrap());
4911 let cast_options = CastOptions {
4912 safe: false,
4913 ..Default::default()
4914 };
4915
4916 let item_field = Arc::new(Field::new("item", DataType::Int64, true));
4917 let request_types = vec![
4918 DataType::List(item_field.clone()),
4919 DataType::LargeList(item_field.clone()),
4920 DataType::ListView(item_field.clone()),
4921 DataType::LargeListView(item_field),
4922 ];
4923
4924 for request_type in request_types {
4925 let options = GetOptions::new()
4926 .with_as_type(Some(FieldRef::from(Field::new(
4927 "result",
4928 request_type.clone(),
4929 true,
4930 ))))
4931 .with_cast_options(cast_options.clone());
4932
4933 let err = variant_get(&variant_array, options).unwrap_err();
4934 assert!(
4935 err.to_string()
4936 .contains("Failed to extract primitive of type Int64")
4937 );
4938 }
4939 }
4940
4941 #[test]
4942 fn test_variant_get_list_like_unsafe_cast_preserves_null_elements() {
4943 let string_array: ArrayRef = Arc::new(StringArray::from(vec![r#"[1, null, 3]"#]));
4944 let variant_array = ArrayRef::from(json_to_variant(&string_array).unwrap());
4945 let cast_options = CastOptions {
4946 safe: false,
4947 ..Default::default()
4948 };
4949 let options = GetOptions::new()
4950 .with_as_type(Some(FieldRef::from(Field::new(
4951 "result",
4952 DataType::List(Arc::new(Field::new("item", DataType::Int64, true))),
4953 true,
4954 ))))
4955 .with_cast_options(cast_options);
4956
4957 let result = variant_get(&variant_array, options).unwrap();
4958 let list_array = result.as_any().downcast_ref::<ListArray>().unwrap();
4959 let values = list_array
4960 .values()
4961 .as_any()
4962 .downcast_ref::<Int64Array>()
4963 .unwrap();
4964
4965 assert_eq!(values.len(), 3);
4966 assert_eq!(values.value(0), 1);
4967 assert!(values.is_null(1));
4968 assert_eq!(values.value(2), 3);
4969 }
4970
4971 #[test]
4972 fn test_variant_get_list_like_unsafe_cast_errors_on_non_list() {
4973 let string_array: ArrayRef = Arc::new(StringArray::from(vec!["[1, 2]", "\"not a list\""]));
4974 let variant_array = ArrayRef::from(json_to_variant(&string_array).unwrap());
4975 let cast_options = CastOptions {
4976 safe: false,
4977 ..Default::default()
4978 };
4979 let item_field = Arc::new(Field::new("item", Int64, true));
4980 let data_types = vec![
4981 DataType::List(item_field.clone()),
4982 DataType::LargeList(item_field.clone()),
4983 DataType::ListView(item_field.clone()),
4984 DataType::LargeListView(item_field.clone()),
4985 DataType::FixedSizeList(item_field, 2),
4986 ];
4987
4988 for data_type in data_types {
4989 let options = GetOptions::new()
4990 .with_as_type(Some(FieldRef::from(Field::new("result", data_type, true))))
4991 .with_cast_options(cast_options.clone());
4992
4993 let err = variant_get(&variant_array, options).unwrap_err();
4994 assert!(
4995 err.to_string()
4996 .contains("Failed to extract list from variant"),
4997 );
4998 }
4999 }
5000
5001 #[test]
5002 fn test_variant_get_fixed_size_list_wrong_size() {
5003 let string_array: ArrayRef = Arc::new(StringArray::from(vec!["[1, 2, 3]"]));
5004 let variant_array = ArrayRef::from(json_to_variant(&string_array).unwrap());
5005 let item_field = Arc::new(Field::new("item", Int64, true));
5006
5007 let options = GetOptions::new()
5009 .with_as_type(Some(FieldRef::from(Field::new(
5010 "result",
5011 DataType::FixedSizeList(item_field.clone(), 2),
5012 true,
5013 ))))
5014 .with_cast_options(CastOptions {
5015 safe: true,
5016 ..Default::default()
5017 });
5018 let result = variant_get(&variant_array, options).unwrap();
5019 let fixed_size_list = result
5020 .as_any()
5021 .downcast_ref::<FixedSizeListArray>()
5022 .expect("Expected FixedSizeListArray");
5023 assert_eq!(fixed_size_list.len(), 1);
5024 assert!(fixed_size_list.is_null(0));
5025
5026 let options = GetOptions::new()
5028 .with_as_type(Some(FieldRef::from(Field::new(
5029 "result",
5030 DataType::FixedSizeList(item_field.clone(), 2),
5031 true,
5032 ))))
5033 .with_cast_options(CastOptions {
5034 safe: false,
5035 ..Default::default()
5036 });
5037 let err = variant_get(&variant_array, options).unwrap_err();
5038 assert!(
5039 err.to_string()
5040 .contains("Expected fixed size list of size 2, got size 3"),
5041 "got: {err}",
5042 );
5043 }
5044
5045 macro_rules! perfectly_shredded_preserves_top_level_nulls_test {
5046 ($name:ident, $result_type:expr, $typed_value:expr, $expected_array:expr) => {
5047 perfectly_shredded_preserves_top_level_nulls_test!(
5048 $name,
5049 $result_type,
5050 $typed_value,
5051 Some(NullBuffer::from(vec![true, false, true])),
5052 $expected_array
5053 );
5054 };
5055 ($name:ident, $result_type:expr, $typed_value:expr, $parent_nulls:expr, $expected_array:expr) => {
5056 #[test]
5057 fn $name() {
5058 let metadata = Arc::new(BinaryViewArray::from_iter_values(std::iter::repeat_n(
5059 EMPTY_VARIANT_METADATA_BYTES,
5060 3,
5061 )));
5062 let typed_value: ArrayRef = Arc::new($typed_value);
5063 let variant_array: ArrayRef =
5064 VariantArray::perfectly_shredded(metadata, typed_value, $parent_nulls).into();
5065
5066 let result = variant_get(
5067 &variant_array,
5068 GetOptions::new().with_as_type(Some(FieldRef::from(Field::new(
5069 "result",
5070 $result_type,
5071 true,
5072 )))),
5073 )
5074 .unwrap();
5075
5076 let expected_array: ArrayRef = Arc::new($expected_array);
5077 assert_eq!(&result, &expected_array);
5078 }
5079 };
5080 }
5081
5082 perfectly_shredded_preserves_top_level_nulls_test!(
5083 test_variant_get_perfectly_shredded_integer_preserves_top_level_nulls,
5084 DataType::Int32,
5085 Int32Array::from(vec![Some(0_i32), Some(1_i32), Some(2_i32)]),
5086 Int32Array::from(vec![Some(0_i32), None, Some(2_i32)])
5087 );
5088
5089 perfectly_shredded_preserves_top_level_nulls_test!(
5090 test_variant_get_perfectly_shredded_integer_unions_child_and_top_level_nulls,
5091 DataType::Int32,
5092 Int32Array::from(vec![None, Some(1_i32), Some(2_i32)]),
5093 Some(NullBuffer::from(vec![true, false, true])),
5094 Int32Array::from(vec![None, None, Some(2_i32)])
5095 );
5096
5097 perfectly_shredded_preserves_top_level_nulls_test!(
5098 test_variant_get_perfectly_shredded_null_preserves_top_level_nulls,
5099 DataType::Null,
5100 NullArray::new(3),
5101 NullArray::new(3)
5102 );
5103
5104 perfectly_shredded_preserves_top_level_nulls_test!(
5105 test_variant_get_perfectly_shredded_binary_view_preserves_top_level_nulls,
5106 DataType::BinaryView,
5107 BinaryViewArray::from(vec![
5108 Some(b"Apache" as &[u8]),
5109 Some(b"masked-null" as &[u8]),
5110 Some(b"Parquet-variant" as &[u8]),
5111 ]),
5112 BinaryViewArray::from(vec![
5113 Some(b"Apache" as &[u8]),
5114 None,
5115 Some(b"Parquet-variant" as &[u8]),
5116 ])
5117 );
5118
5119 perfectly_shredded_preserves_top_level_nulls_test!(
5120 test_variant_get_perfectly_shredded_binary_preserves_top_level_nulls,
5121 DataType::Binary,
5122 BinaryArray::from(vec![
5123 Some(b"Apache" as &[u8]),
5124 Some(b"masked-null" as &[u8]),
5125 Some(b"Parquet-variant" as &[u8]),
5126 ]),
5127 BinaryArray::from(vec![
5128 Some(b"Apache" as &[u8]),
5129 None,
5130 Some(b"Parquet-variant" as &[u8]),
5131 ])
5132 );
5133
5134 perfectly_shredded_preserves_top_level_nulls_test!(
5135 test_variant_get_perfectly_shredded_decimal4_preserves_top_level_nulls,
5136 DataType::Decimal32(5, 2),
5137 Decimal32Array::from(vec![Some(12345), Some(23400), Some(-12342)])
5138 .with_precision_and_scale(5, 2)
5139 .unwrap(),
5140 Decimal32Array::from(vec![Some(12345), None, Some(-12342)])
5141 .with_precision_and_scale(5, 2)
5142 .unwrap()
5143 );
5144
5145 perfectly_shredded_preserves_top_level_nulls_test!(
5146 test_variant_get_perfectly_shredded_decimal8_preserves_top_level_nulls,
5147 DataType::Decimal64(10, 1),
5148 Decimal64Array::from(vec![Some(1234567809), Some(1456787000), Some(-1234561203)])
5149 .with_precision_and_scale(10, 1)
5150 .unwrap(),
5151 Decimal64Array::from(vec![Some(1234567809), None, Some(-1234561203)])
5152 .with_precision_and_scale(10, 1)
5153 .unwrap()
5154 );
5155
5156 perfectly_shredded_preserves_top_level_nulls_test!(
5157 test_variant_get_perfectly_shredded_decimal16_preserves_top_level_nulls,
5158 DataType::Decimal128(20, 3),
5159 Decimal128Array::from(vec![
5160 Some(i128::from_str("12345678901234567899").unwrap()),
5161 Some(i128::from_str("23445677483748324300").unwrap()),
5162 Some(i128::from_str("-12345678901234567899").unwrap()),
5163 ])
5164 .with_precision_and_scale(20, 3)
5165 .unwrap(),
5166 Decimal128Array::from(vec![
5167 Some(i128::from_str("12345678901234567899").unwrap()),
5168 None,
5169 Some(i128::from_str("-12345678901234567899").unwrap()),
5170 ])
5171 .with_precision_and_scale(20, 3)
5172 .unwrap()
5173 );
5174}