1use arrow::{
18 array::{self, Array, ArrayRef, BinaryViewArray, StructArray},
19 compute::CastOptions,
20 datatypes::Field,
21 error::Result,
22};
23use arrow_schema::{ArrowError, DataType, FieldRef};
24use parquet_variant::{VariantPath, VariantPathElement};
25
26use crate::VariantArray;
27use crate::variant_array::BorrowedShreddingState;
28use crate::variant_to_arrow::make_variant_to_arrow_row_builder;
29
30use arrow::array::AsArray;
31use std::sync::Arc;
32
33pub(crate) enum ShreddedPathStep<'a> {
34 Success(BorrowedShreddingState<'a>),
36 Missing,
39 NotShredded,
43}
44
45pub(crate) fn follow_shredded_path_element<'a>(
51 shredding_state: &BorrowedShreddingState<'a>,
52 path_element: &VariantPathElement<'_>,
53 cast_options: &CastOptions,
54) -> Result<ShreddedPathStep<'a>> {
55 let missing_path_step = || match shredding_state.value_field() {
58 Some(_) => ShreddedPathStep::NotShredded,
59 None => ShreddedPathStep::Missing,
60 };
61
62 let Some(typed_value) = shredding_state.typed_value_field() else {
63 return Ok(missing_path_step());
64 };
65
66 match path_element {
67 VariantPathElement::Field { name } => {
68 let Some(struct_array) = typed_value.as_any().downcast_ref::<StructArray>() else {
71 if !cast_options.safe {
73 return Err(ArrowError::CastError(format!(
74 "Cannot access field '{}' on non-struct type: {}",
75 name,
76 typed_value.data_type()
77 )));
78 }
79 return Ok(missing_path_step());
81 };
82
83 let Some(field) = struct_array.column_by_name(name) else {
85 return Ok(missing_path_step());
87 };
88
89 let struct_array = field.as_struct_opt().ok_or_else(|| {
90 ArrowError::InvalidArgumentError(format!(
94 "Expected Struct array while following path, got {}",
95 field.data_type(),
96 ))
97 })?;
98
99 let state = BorrowedShreddingState::try_from(struct_array)?;
100 Ok(ShreddedPathStep::Success(state))
101 }
102 VariantPathElement::Index { .. } => {
103 Err(ArrowError::NotYetImplemented(
106 "Pathing into shredded variant array index".into(),
107 ))
108 }
109 }
110}
111
112fn shredded_get_path(
116 input: &VariantArray,
117 path: &[VariantPathElement<'_>],
118 as_field: Option<&Field>,
119 cast_options: &CastOptions,
120) -> Result<ArrayRef> {
121 let make_target_variant =
124 |value: Option<BinaryViewArray>,
125 typed_value: Option<ArrayRef>,
126 accumulated_nulls: Option<arrow::buffer::NullBuffer>| {
127 let metadata = input.metadata_field().clone();
128 VariantArray::from_parts(metadata, value, typed_value, accumulated_nulls)
129 };
130
131 let shred_basic_variant =
133 |target: VariantArray, path: VariantPath<'_>, as_field: Option<&Field>| {
134 let as_type = as_field.map(|f| f.data_type());
135 let mut builder = make_variant_to_arrow_row_builder(
136 target.metadata_field(),
137 path,
138 as_type,
139 cast_options,
140 target.len(),
141 )?;
142 for i in 0..target.len() {
143 if target.is_null(i) {
144 builder.append_null()?;
145 } else if !cast_options.safe {
146 let value = target.try_value(i)?;
147 builder.append_value(value)?;
148 } else {
149 let _ = match target.try_value(i) {
150 Ok(v) => builder.append_value(v)?,
151 Err(_) => {
152 builder.append_null()?;
153 false }
155 };
156 }
157 }
158 builder.finish()
159 };
160
161 let mut shredding_state = input.shredding_state().borrow();
164 let mut accumulated_nulls = input.inner().nulls().cloned();
165 let mut path_index = 0;
166 for path_element in path {
167 match follow_shredded_path_element(&shredding_state, path_element, cast_options)? {
168 ShreddedPathStep::Success(state) => {
169 if let Some(typed_value) = shredding_state.typed_value_field() {
171 accumulated_nulls = arrow::buffer::NullBuffer::union(
172 accumulated_nulls.as_ref(),
173 typed_value.nulls(),
174 );
175 }
176 shredding_state = state;
177 path_index += 1;
178 continue;
179 }
180 ShreddedPathStep::Missing => {
181 let num_rows = input.len();
182 let arr = match as_field.map(|f| f.data_type()) {
183 Some(data_type) => array::new_null_array(data_type, num_rows),
184 None => Arc::new(array::NullArray::new(num_rows)) as _,
185 };
186 return Ok(arr);
187 }
188 ShreddedPathStep::NotShredded => {
189 let target = make_target_variant(
190 shredding_state.value_field().cloned(),
191 None,
192 accumulated_nulls,
193 );
194 return shred_basic_variant(target, path[path_index..].into(), as_field);
195 }
196 };
197 }
198
199 let target = make_target_variant(
201 shredding_state.value_field().cloned(),
202 shredding_state.typed_value_field().cloned(),
203 accumulated_nulls,
204 );
205
206 let Some(as_field) = as_field else {
208 return Ok(ArrayRef::from(target));
209 };
210
211 if let Some(shredded) = try_perfect_shredding(&target, as_field) {
213 return Ok(shredded);
214 }
215
216 if let DataType::Struct(fields) = as_field.data_type() {
219 let children = fields
220 .iter()
221 .map(|field| {
222 shredded_get_path(
223 &target,
224 &[VariantPathElement::from(field.name().as_str())],
225 Some(field),
226 cast_options,
227 )
228 })
229 .collect::<Result<Vec<_>>>()?;
230
231 let struct_nulls = target.nulls().cloned();
232
233 return Ok(Arc::new(StructArray::try_new(
234 fields.clone(),
235 children,
236 struct_nulls,
237 )?));
238 }
239
240 shred_basic_variant(target, VariantPath::default(), Some(as_field))
242}
243
244fn try_perfect_shredding(variant_array: &VariantArray, as_field: &Field) -> Option<ArrayRef> {
245 if matches!(as_field.data_type(), DataType::Struct(_)) {
247 return None;
248 }
249 let typed_value = variant_array.typed_value_field()?;
250 if typed_value.data_type() == as_field.data_type()
251 && variant_array
252 .value_field()
253 .is_none_or(|v| v.null_count() == v.len())
254 {
255 return Some(typed_value.clone());
262 }
263 None
264}
265
266pub fn variant_get(input: &ArrayRef, options: GetOptions) -> Result<ArrayRef> {
278 let variant_array = VariantArray::try_new(input)?;
279
280 let GetOptions {
281 as_type,
282 path,
283 cast_options,
284 } = options;
285
286 shredded_get_path(&variant_array, &path, as_type.as_deref(), &cast_options)
287}
288
289#[derive(Debug, Clone, Default)]
291pub struct GetOptions<'a> {
292 pub path: VariantPath<'a>,
294 pub as_type: Option<FieldRef>,
298 pub cast_options: CastOptions<'a>,
300}
301
302impl<'a> GetOptions<'a> {
303 pub fn new() -> Self {
305 Default::default()
306 }
307
308 pub fn new_with_path(path: VariantPath<'a>) -> Self {
310 Self {
311 path,
312 as_type: None,
313 cast_options: Default::default(),
314 }
315 }
316
317 pub fn with_as_type(mut self, as_type: Option<FieldRef>) -> Self {
319 self.as_type = as_type;
320 self
321 }
322
323 pub fn with_cast_options(mut self, cast_options: CastOptions<'a>) -> Self {
325 self.cast_options = cast_options;
326 self
327 }
328}
329
330#[cfg(test)]
331mod test {
332 use std::str::FromStr;
333 use std::sync::Arc;
334
335 use super::{GetOptions, variant_get};
336 use crate::variant_array::{ShreddedVariantFieldArray, StructArrayBuilder};
337 use crate::{
338 VariantArray, VariantArrayBuilder, cast_to_variant, json_to_variant, shred_variant,
339 };
340 use arrow::array::{
341 Array, ArrayRef, AsArray, BinaryArray, BinaryViewArray, BooleanArray, Date32Array,
342 Date64Array, Decimal32Array, Decimal64Array, Decimal128Array, Decimal256Array,
343 Float32Array, Float64Array, Int8Array, Int16Array, Int32Array, Int64Array,
344 LargeBinaryArray, LargeListArray, LargeListViewArray, LargeStringArray, ListArray,
345 ListViewArray, NullBuilder, StringArray, StringViewArray, StructArray,
346 Time32MillisecondArray, Time32SecondArray, Time64MicrosecondArray, Time64NanosecondArray,
347 };
348 use arrow::buffer::{NullBuffer, OffsetBuffer, ScalarBuffer};
349 use arrow::compute::CastOptions;
350 use arrow::datatypes::DataType::{Int16, Int32, Int64};
351 use arrow::datatypes::i256;
352 use arrow::util::display::FormatOptions;
353 use arrow_schema::DataType::{Boolean, Float32, Float64, Int8};
354 use arrow_schema::{DataType, Field, FieldRef, Fields, IntervalUnit, TimeUnit};
355 use chrono::DateTime;
356 use parquet_variant::{
357 EMPTY_VARIANT_METADATA_BYTES, Variant, VariantBuilder, VariantDecimal4, VariantDecimal8,
358 VariantDecimal16, VariantDecimalType, VariantPath,
359 };
360
361 fn single_variant_get_test(input_json: &str, path: VariantPath, expected_json: &str) {
362 let input_array_ref: ArrayRef = Arc::new(StringArray::from(vec![Some(input_json)]));
364 let input_variant_array_ref = ArrayRef::from(json_to_variant(&input_array_ref).unwrap());
365
366 let result =
367 variant_get(&input_variant_array_ref, GetOptions::new_with_path(path)).unwrap();
368
369 let expected_array_ref: ArrayRef = Arc::new(StringArray::from(vec![Some(expected_json)]));
371 let expected_variant_array = json_to_variant(&expected_array_ref).unwrap();
372
373 let result_array = VariantArray::try_new(&result).unwrap();
374 assert_eq!(
375 result_array.len(),
376 1,
377 "Expected result array to have length 1"
378 );
379 assert!(
380 result_array.nulls().is_none(),
381 "Expected no nulls in result array"
382 );
383 let result_variant = result_array.value(0);
384 let expected_variant = expected_variant_array.value(0);
385 assert_eq!(
386 result_variant, expected_variant,
387 "Result variant does not match expected variant"
388 );
389 }
390
391 #[test]
392 fn get_primitive_variant_field() {
393 single_variant_get_test(
394 r#"{"some_field": 1234}"#,
395 VariantPath::try_from("some_field").unwrap(),
396 "1234",
397 );
398 }
399
400 #[test]
401 fn get_primitive_variant_list_index() {
402 single_variant_get_test("[1234, 5678]", VariantPath::from(0), "1234");
403 }
404
405 #[test]
406 fn get_primitive_variant_inside_object_of_object() {
407 single_variant_get_test(
408 r#"{"top_level_field": {"inner_field": 1234}}"#,
409 VariantPath::try_from("top_level_field")
410 .unwrap()
411 .join("inner_field"),
412 "1234",
413 );
414 }
415
416 #[test]
417 fn get_primitive_variant_inside_list_of_object() {
418 single_variant_get_test(
419 r#"[{"some_field": 1234}]"#,
420 VariantPath::from(0).join("some_field"),
421 "1234",
422 );
423 }
424
425 #[test]
426 fn get_primitive_variant_inside_object_of_list() {
427 single_variant_get_test(
428 r#"{"some_field": [1234]}"#,
429 VariantPath::try_from("some_field").unwrap().join(0),
430 "1234",
431 );
432 }
433
434 #[test]
435 fn get_complex_variant() {
436 single_variant_get_test(
437 r#"{"top_level_field": {"inner_field": 1234}}"#,
438 VariantPath::try_from("top_level_field").unwrap(),
439 r#"{"inner_field": 1234}"#,
440 );
441 }
442
443 macro_rules! numeric_partially_shredded_test {
445 ($primitive_type:ty, $data_fn:ident) => {
446 let array = $data_fn();
447 let options = GetOptions::new();
448 let result = variant_get(&array, options).unwrap();
449
450 let result = VariantArray::try_new(&result).unwrap();
452 assert_eq!(result.len(), 4);
453
454 assert_eq!(
456 result.value(0),
457 Variant::from(<$primitive_type>::try_from(34u8).unwrap())
458 );
459 assert!(!result.is_valid(1));
460 assert_eq!(result.value(2), Variant::from("n/a"));
461 assert_eq!(
462 result.value(3),
463 Variant::from(<$primitive_type>::try_from(100u8).unwrap())
464 );
465 };
466 }
467
468 macro_rules! partially_shredded_variant_array_gen {
471 ($func_name:ident, $typed_value_array_gen: expr) => {
472 partially_shredded_variant_array_gen!(
473 $func_name,
474 $typed_value_array_gen,
475 Variant::from("n/a")
476 );
477 };
478 ($func_name:ident, $typed_value_array_gen: expr, $fallback_variant:expr) => {
479 fn $func_name() -> ArrayRef {
480 let typed_value: ArrayRef = Arc::new($typed_value_array_gen());
481 let typed_as_variant = cast_to_variant(typed_value.as_ref())
482 .expect("should cast typed array to variant");
483 let mut input_builder = VariantArrayBuilder::new(typed_as_variant.len());
484 input_builder.append_variant(typed_as_variant.value(0));
485 input_builder.append_null();
486 input_builder.append_variant($fallback_variant);
487 input_builder.append_variant(typed_as_variant.value(3));
488
489 let variant_array = shred_variant(&input_builder.build(), typed_value.data_type())
490 .expect("should shred variant array");
491 ArrayRef::from(variant_array)
492 }
493 };
494 }
495
496 macro_rules! numeric_partially_shredded_variant_array_fn {
498 ($func:ident, $array_type:ident, $primitive_type:ty) => {
499 partially_shredded_variant_array_gen!($func, || $array_type::from(vec![
500 Some(<$primitive_type>::try_from(34u8).unwrap()),
501 None,
502 None,
503 Some(<$primitive_type>::try_from(100u8).unwrap()),
504 ]));
505 };
506 }
507
508 numeric_partially_shredded_variant_array_fn!(
509 partially_shredded_int8_variant_array,
510 Int8Array,
511 i8
512 );
513 numeric_partially_shredded_variant_array_fn!(
514 partially_shredded_int16_variant_array,
515 Int16Array,
516 i16
517 );
518 numeric_partially_shredded_variant_array_fn!(
519 partially_shredded_int32_variant_array,
520 Int32Array,
521 i32
522 );
523 numeric_partially_shredded_variant_array_fn!(
524 partially_shredded_int64_variant_array,
525 Int64Array,
526 i64
527 );
528 numeric_partially_shredded_variant_array_fn!(
529 partially_shredded_float32_variant_array,
530 Float32Array,
531 f32
532 );
533 numeric_partially_shredded_variant_array_fn!(
534 partially_shredded_float64_variant_array,
535 Float64Array,
536 f64
537 );
538
539 partially_shredded_variant_array_gen!(partially_shredded_bool_variant_array, || {
540 arrow::array::BooleanArray::from(vec![Some(true), None, None, Some(false)])
541 });
542
543 partially_shredded_variant_array_gen!(
544 partially_shredded_utf8_variant_array,
545 || { StringArray::from(vec![Some("hello"), None, None, Some("world")]) },
546 Variant::from(42i32)
547 );
548
549 partially_shredded_variant_array_gen!(partially_shredded_date32_variant_array, || {
550 Date32Array::from(vec![
551 Some(20348), None,
553 None,
554 Some(20340), ])
556 });
557
558 #[test]
559 fn get_variant_partially_shredded_int8_as_variant() {
560 numeric_partially_shredded_test!(i8, partially_shredded_int8_variant_array);
561 }
562
563 #[test]
564 fn get_variant_partially_shredded_int16_as_variant() {
565 numeric_partially_shredded_test!(i16, partially_shredded_int16_variant_array);
566 }
567
568 #[test]
569 fn get_variant_partially_shredded_int32_as_variant() {
570 numeric_partially_shredded_test!(i32, partially_shredded_int32_variant_array);
571 }
572
573 #[test]
574 fn get_variant_partially_shredded_int64_as_variant() {
575 numeric_partially_shredded_test!(i64, partially_shredded_int64_variant_array);
576 }
577
578 #[test]
579 fn get_variant_partially_shredded_float32_as_variant() {
580 numeric_partially_shredded_test!(f32, partially_shredded_float32_variant_array);
581 }
582
583 #[test]
584 fn get_variant_partially_shredded_float64_as_variant() {
585 numeric_partially_shredded_test!(f64, partially_shredded_float64_variant_array);
586 }
587
588 #[test]
589 fn get_variant_partially_shredded_bool_as_variant() {
590 let array = partially_shredded_bool_variant_array();
591 let options = GetOptions::new();
592 let result = variant_get(&array, options).unwrap();
593
594 let result = VariantArray::try_new(&result).unwrap();
596 assert_eq!(result.len(), 4);
597
598 assert_eq!(result.value(0), Variant::from(true));
600 assert!(!result.is_valid(1));
601 assert_eq!(result.value(2), Variant::from("n/a"));
602 assert_eq!(result.value(3), Variant::from(false));
603 }
604
605 #[test]
606 fn get_variant_partially_shredded_utf8_as_variant() {
607 let array = partially_shredded_utf8_variant_array();
608 let options = GetOptions::new();
609 let result = variant_get(&array, options).unwrap();
610
611 let result = VariantArray::try_new(&result).unwrap();
613 assert_eq!(result.len(), 4);
614
615 assert_eq!(result.value(0), Variant::from("hello"));
617 assert!(!result.is_valid(1));
618 assert_eq!(result.value(2), Variant::from(42i32));
619 assert_eq!(result.value(3), Variant::from("world"));
620 }
621
622 partially_shredded_variant_array_gen!(partially_shredded_binary_view_variant_array, || {
623 BinaryViewArray::from(vec![
624 Some(&[1u8, 2u8, 3u8][..]), None, None, Some(&[4u8, 5u8, 6u8][..]), ])
629 });
630
631 #[test]
632 fn get_variant_partially_shredded_date32_as_variant() {
633 let array = partially_shredded_date32_variant_array();
634 let options = GetOptions::new();
635 let result = variant_get(&array, options).unwrap();
636
637 let result = VariantArray::try_new(&result).unwrap();
639 assert_eq!(result.len(), 4);
640
641 use chrono::NaiveDate;
643 let date1 = NaiveDate::from_ymd_opt(2025, 9, 17).unwrap();
644 let date2 = NaiveDate::from_ymd_opt(2025, 9, 9).unwrap();
645 assert_eq!(result.value(0), Variant::from(date1));
646 assert!(!result.is_valid(1));
647 assert_eq!(result.value(2), Variant::from("n/a"));
648 assert_eq!(result.value(3), Variant::from(date2));
649 }
650
651 #[test]
652 fn get_variant_partially_shredded_binary_view_as_variant() {
653 let array = partially_shredded_binary_view_variant_array();
654 let options = GetOptions::new();
655 let result = variant_get(&array, options).unwrap();
656
657 let result = VariantArray::try_new(&result).unwrap();
659 assert_eq!(result.len(), 4);
660
661 assert_eq!(result.value(0), Variant::from(&[1u8, 2u8, 3u8][..]));
663 assert!(!result.is_valid(1));
664 assert_eq!(result.value(2), Variant::from("n/a"));
665 assert_eq!(result.value(3), Variant::from(&[4u8, 5u8, 6u8][..]));
666 }
667
668 macro_rules! assert_variant_get_as_variant_array_with_default_option {
670 ($variant_array: expr, $array_expected: expr) => {{
671 let options = GetOptions::new();
672 let array = $variant_array;
673 let result = variant_get(&array, options).unwrap();
674 let result = VariantArray::try_new(&result).unwrap();
675
676 assert_eq!(result.len(), $array_expected.len());
677
678 for (idx, item) in $array_expected.into_iter().enumerate() {
679 match item {
680 Some(item) => assert_eq!(result.value(idx), item),
681 None => assert!(result.is_null(idx)),
682 }
683 }
684 }};
685 }
686
687 partially_shredded_variant_array_gen!(
688 partially_shredded_timestamp_micro_ntz_variant_array,
689 || {
690 arrow::array::TimestampMicrosecondArray::from(vec![
691 Some(-456000),
692 None,
693 None,
694 Some(1758602096000000),
695 ])
696 }
697 );
698
699 #[test]
700 fn get_variant_partial_shredded_timestamp_micro_ntz_as_variant() {
701 let array = partially_shredded_timestamp_micro_ntz_variant_array();
702 assert_variant_get_as_variant_array_with_default_option!(
703 array,
704 vec![
705 Some(Variant::from(
706 DateTime::from_timestamp_micros(-456000i64)
707 .unwrap()
708 .naive_utc(),
709 )),
710 None,
711 Some(Variant::from("n/a")),
712 Some(Variant::from(
713 DateTime::parse_from_rfc3339("2025-09-23T12:34:56+08:00")
714 .unwrap()
715 .naive_utc(),
716 )),
717 ]
718 )
719 }
720
721 partially_shredded_variant_array_gen!(partially_shredded_timestamp_micro_variant_array, || {
722 arrow::array::TimestampMicrosecondArray::from(vec![
723 Some(-456000),
724 None,
725 None,
726 Some(1758602096000000),
727 ])
728 .with_timezone("+00:00")
729 });
730
731 #[test]
732 fn get_variant_partial_shredded_timestamp_micro_as_variant() {
733 let array = partially_shredded_timestamp_micro_variant_array();
734 assert_variant_get_as_variant_array_with_default_option!(
735 array,
736 vec![
737 Some(Variant::from(
738 DateTime::from_timestamp_micros(-456000i64)
739 .unwrap()
740 .to_utc(),
741 )),
742 None,
743 Some(Variant::from("n/a")),
744 Some(Variant::from(
745 DateTime::parse_from_rfc3339("2025-09-23T12:34:56+08:00")
746 .unwrap()
747 .to_utc(),
748 )),
749 ]
750 )
751 }
752
753 partially_shredded_variant_array_gen!(
754 partially_shredded_timestamp_nano_ntz_variant_array,
755 || {
756 arrow::array::TimestampNanosecondArray::from(vec![
757 Some(-4999999561),
758 None,
759 None,
760 Some(1758602096000000000),
761 ])
762 }
763 );
764
765 #[test]
766 fn get_variant_partial_shredded_timestamp_nano_ntz_as_variant() {
767 let array = partially_shredded_timestamp_nano_ntz_variant_array();
768 assert_variant_get_as_variant_array_with_default_option!(
769 array,
770 vec![
771 Some(Variant::from(
772 DateTime::from_timestamp(-5, 439).unwrap().naive_utc()
773 )),
774 None,
775 Some(Variant::from("n/a")),
776 Some(Variant::from(
777 DateTime::parse_from_rfc3339("2025-09-23T12:34:56+08:00")
778 .unwrap()
779 .naive_utc()
780 )),
781 ]
782 )
783 }
784
785 partially_shredded_variant_array_gen!(partially_shredded_timestamp_nano_variant_array, || {
786 arrow::array::TimestampNanosecondArray::from(vec![
787 Some(-4999999561),
788 None,
789 None,
790 Some(1758602096000000000),
791 ])
792 .with_timezone("+00:00")
793 });
794
795 #[test]
796 fn get_variant_partial_shredded_timestamp_nano_as_variant() {
797 let array = partially_shredded_timestamp_nano_variant_array();
798 assert_variant_get_as_variant_array_with_default_option!(
799 array,
800 vec![
801 Some(Variant::from(
802 DateTime::from_timestamp(-5, 439).unwrap().to_utc()
803 )),
804 None,
805 Some(Variant::from("n/a")),
806 Some(Variant::from(
807 DateTime::parse_from_rfc3339("2025-09-23T12:34:56+08:00")
808 .unwrap()
809 .to_utc()
810 )),
811 ]
812 )
813 }
814
815 #[test]
817 fn get_variant_shredded_int32_as_int32_safe_cast() {
818 let array = partially_shredded_int32_variant_array();
820 let field = Field::new("typed_value", DataType::Int32, true);
822 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
823 let result = variant_get(&array, options).unwrap();
824 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
825 Some(34),
826 None,
827 None, Some(100),
829 ]));
830 assert_eq!(&result, &expected)
831 }
832
833 #[test]
835 fn get_variant_shredded_int32_as_int32_unsafe_cast() {
836 let array = partially_shredded_int32_variant_array();
838 let field = Field::new("typed_value", DataType::Int32, true);
839 let cast_options = CastOptions {
840 safe: false, ..Default::default()
842 };
843 let options = GetOptions::new()
844 .with_as_type(Some(FieldRef::from(field)))
845 .with_cast_options(cast_options);
846
847 let err = variant_get(&array, options).unwrap_err();
848 assert_eq!(
850 err.to_string(),
851 "Cast error: Failed to extract primitive of type Int32 from variant ShortString(ShortString(\"n/a\")) at path VariantPath([])"
852 );
853 }
854
855 macro_rules! numeric_perfectly_shredded_test {
857 ($primitive_type:ty, $data_fn:ident) => {
858 let array = $data_fn();
859 let options = GetOptions::new();
860 let result = variant_get(&array, options).unwrap();
861
862 let result = VariantArray::try_new(&result).unwrap();
864 assert_eq!(result.len(), 3);
865
866 assert_eq!(
868 result.value(0),
869 Variant::from(<$primitive_type>::try_from(1u8).unwrap())
870 );
871 assert_eq!(
872 result.value(1),
873 Variant::from(<$primitive_type>::try_from(2u8).unwrap())
874 );
875 assert_eq!(
876 result.value(2),
877 Variant::from(<$primitive_type>::try_from(3u8).unwrap())
878 );
879 };
880 }
881
882 #[test]
883 fn get_variant_perfectly_shredded_int8_as_variant() {
884 numeric_perfectly_shredded_test!(i8, perfectly_shredded_int8_variant_array);
885 }
886
887 #[test]
888 fn get_variant_perfectly_shredded_int16_as_variant() {
889 numeric_perfectly_shredded_test!(i16, perfectly_shredded_int16_variant_array);
890 }
891
892 #[test]
893 fn get_variant_perfectly_shredded_int32_as_variant() {
894 numeric_perfectly_shredded_test!(i32, perfectly_shredded_int32_variant_array);
895 }
896
897 #[test]
898 fn get_variant_perfectly_shredded_int64_as_variant() {
899 numeric_perfectly_shredded_test!(i64, perfectly_shredded_int64_variant_array);
900 }
901
902 #[test]
903 fn get_variant_perfectly_shredded_float32_as_variant() {
904 numeric_perfectly_shredded_test!(f32, perfectly_shredded_float32_variant_array);
905 }
906
907 #[test]
908 fn get_variant_perfectly_shredded_float64_as_variant() {
909 numeric_perfectly_shredded_test!(f64, perfectly_shredded_float64_variant_array);
910 }
911
912 #[test]
914 fn get_variant_all_null_as_variant() {
915 let array = all_null_variant_array();
916 let options = GetOptions::new();
917 let result = variant_get(&array, options).unwrap();
918
919 let result = VariantArray::try_new(&result).unwrap();
921 assert_eq!(result.len(), 3);
922
923 assert!(!result.is_valid(0));
925 assert!(!result.is_valid(1));
926 assert!(!result.is_valid(2));
927 }
928
929 #[test]
931 fn get_variant_all_null_as_int32() {
932 let array = all_null_variant_array();
933 let field = Field::new("typed_value", DataType::Int32, true);
935 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
936 let result = variant_get(&array, options).unwrap();
937
938 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
939 Option::<i32>::None,
940 Option::<i32>::None,
941 Option::<i32>::None,
942 ]));
943 assert_eq!(&result, &expected)
944 }
945
946 macro_rules! perfectly_shredded_to_arrow_primitive_test {
947 ($name:ident, $primitive_type:expr, $perfectly_shredded_array_gen_fun:ident, $expected_array:expr) => {
948 #[test]
949 fn $name() {
950 let array = $perfectly_shredded_array_gen_fun();
951 let field = Field::new("typed_value", $primitive_type, true);
952 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
953 let result = variant_get(&array, options).unwrap();
954 let expected_array: ArrayRef = Arc::new($expected_array);
955 assert_eq!(&result, &expected_array);
956 }
957 };
958 }
959
960 perfectly_shredded_to_arrow_primitive_test!(
961 get_variant_perfectly_shredded_int18_as_int8,
962 Int8,
963 perfectly_shredded_int8_variant_array,
964 Int8Array::from(vec![Some(1), Some(2), Some(3)])
965 );
966
967 perfectly_shredded_to_arrow_primitive_test!(
968 get_variant_perfectly_shredded_int16_as_int16,
969 Int16,
970 perfectly_shredded_int16_variant_array,
971 Int16Array::from(vec![Some(1), Some(2), Some(3)])
972 );
973
974 perfectly_shredded_to_arrow_primitive_test!(
975 get_variant_perfectly_shredded_int32_as_int32,
976 Int32,
977 perfectly_shredded_int32_variant_array,
978 Int32Array::from(vec![Some(1), Some(2), Some(3)])
979 );
980
981 perfectly_shredded_to_arrow_primitive_test!(
982 get_variant_perfectly_shredded_int64_as_int64,
983 Int64,
984 perfectly_shredded_int64_variant_array,
985 Int64Array::from(vec![Some(1), Some(2), Some(3)])
986 );
987
988 perfectly_shredded_to_arrow_primitive_test!(
989 get_variant_perfectly_shredded_float32_as_float32,
990 Float32,
991 perfectly_shredded_float32_variant_array,
992 Float32Array::from(vec![Some(1.0), Some(2.0), Some(3.0)])
993 );
994
995 perfectly_shredded_to_arrow_primitive_test!(
996 get_variant_perfectly_shredded_float64_as_float64,
997 Float64,
998 perfectly_shredded_float64_variant_array,
999 Float64Array::from(vec![Some(1.0), Some(2.0), Some(3.0)])
1000 );
1001
1002 perfectly_shredded_to_arrow_primitive_test!(
1003 get_variant_perfectly_shredded_boolean_as_boolean,
1004 Boolean,
1005 perfectly_shredded_bool_variant_array,
1006 BooleanArray::from(vec![Some(true), Some(false), Some(true)])
1007 );
1008
1009 perfectly_shredded_to_arrow_primitive_test!(
1010 get_variant_perfectly_shredded_utf8_as_utf8,
1011 DataType::Utf8,
1012 perfectly_shredded_utf8_variant_array,
1013 StringArray::from(vec![Some("foo"), Some("bar"), Some("baz")])
1014 );
1015
1016 perfectly_shredded_to_arrow_primitive_test!(
1017 get_variant_perfectly_shredded_large_utf8_as_utf8,
1018 DataType::Utf8,
1019 perfectly_shredded_large_utf8_variant_array,
1020 StringArray::from(vec![Some("foo"), Some("bar"), Some("baz")])
1021 );
1022
1023 perfectly_shredded_to_arrow_primitive_test!(
1024 get_variant_perfectly_shredded_utf8_view_as_utf8,
1025 DataType::Utf8,
1026 perfectly_shredded_utf8_view_variant_array,
1027 StringArray::from(vec![Some("foo"), Some("bar"), Some("baz")])
1028 );
1029
1030 macro_rules! perfectly_shredded_variant_array_fn {
1031 ($func:ident, $typed_value_gen:expr) => {
1032 fn $func() -> ArrayRef {
1033 let typed_value: ArrayRef = Arc::new($typed_value_gen());
1036 if let Some(shredded) = cast_to_variant(typed_value.as_ref())
1037 .ok()
1038 .and_then(|unshredded| shred_variant(&unshredded, typed_value.data_type()).ok())
1039 {
1040 return shredded.into();
1041 }
1042
1043 let metadata = BinaryViewArray::from_iter_values(std::iter::repeat_n(
1044 EMPTY_VARIANT_METADATA_BYTES,
1045 typed_value.len(),
1046 ));
1047 VariantArray::from_parts(metadata, None, Some(typed_value), None).into()
1048 }
1049 };
1050 }
1051
1052 perfectly_shredded_variant_array_fn!(perfectly_shredded_utf8_variant_array, || {
1053 StringArray::from(vec![Some("foo"), Some("bar"), Some("baz")])
1054 });
1055
1056 perfectly_shredded_variant_array_fn!(perfectly_shredded_large_utf8_variant_array, || {
1057 LargeStringArray::from(vec![Some("foo"), Some("bar"), Some("baz")])
1058 });
1059
1060 perfectly_shredded_variant_array_fn!(perfectly_shredded_utf8_view_variant_array, || {
1061 StringViewArray::from(vec![Some("foo"), Some("bar"), Some("baz")])
1062 });
1063
1064 perfectly_shredded_variant_array_fn!(perfectly_shredded_bool_variant_array, || {
1065 BooleanArray::from(vec![Some(true), Some(false), Some(true)])
1066 });
1067
1068 macro_rules! numeric_perfectly_shredded_variant_array_fn {
1080 ($func:ident, $array_type:ident, $primitive_type:ty) => {
1081 perfectly_shredded_variant_array_fn!($func, || {
1082 $array_type::from(vec![
1083 Some(<$primitive_type>::try_from(1u8).unwrap()),
1084 Some(<$primitive_type>::try_from(2u8).unwrap()),
1085 Some(<$primitive_type>::try_from(3u8).unwrap()),
1086 ])
1087 });
1088 };
1089 }
1090
1091 numeric_perfectly_shredded_variant_array_fn!(
1092 perfectly_shredded_int8_variant_array,
1093 Int8Array,
1094 i8
1095 );
1096 numeric_perfectly_shredded_variant_array_fn!(
1097 perfectly_shredded_int16_variant_array,
1098 Int16Array,
1099 i16
1100 );
1101 numeric_perfectly_shredded_variant_array_fn!(
1102 perfectly_shredded_int32_variant_array,
1103 Int32Array,
1104 i32
1105 );
1106 numeric_perfectly_shredded_variant_array_fn!(
1107 perfectly_shredded_int64_variant_array,
1108 Int64Array,
1109 i64
1110 );
1111 numeric_perfectly_shredded_variant_array_fn!(
1112 perfectly_shredded_float32_variant_array,
1113 Float32Array,
1114 f32
1115 );
1116 numeric_perfectly_shredded_variant_array_fn!(
1117 perfectly_shredded_float64_variant_array,
1118 Float64Array,
1119 f64
1120 );
1121
1122 perfectly_shredded_variant_array_fn!(
1123 perfectly_shredded_timestamp_micro_ntz_variant_array,
1124 || {
1125 arrow::array::TimestampMicrosecondArray::from(vec![
1126 Some(-456000),
1127 Some(1758602096000001),
1128 Some(1758602096000002),
1129 ])
1130 }
1131 );
1132
1133 perfectly_shredded_to_arrow_primitive_test!(
1134 get_variant_perfectly_shredded_timestamp_micro_ntz_as_timestamp_micro_ntz,
1135 DataType::Timestamp(TimeUnit::Microsecond, None),
1136 perfectly_shredded_timestamp_micro_ntz_variant_array,
1137 arrow::array::TimestampMicrosecondArray::from(vec![
1138 Some(-456000),
1139 Some(1758602096000001),
1140 Some(1758602096000002),
1141 ])
1142 );
1143
1144 perfectly_shredded_to_arrow_primitive_test!(
1146 get_variant_perfectly_shredded_timestamp_micro_ntz_as_nano_ntz,
1147 DataType::Timestamp(TimeUnit::Nanosecond, None),
1148 perfectly_shredded_timestamp_micro_ntz_variant_array,
1149 arrow::array::TimestampNanosecondArray::from(vec![
1150 Some(-456000000),
1151 Some(1758602096000001000),
1152 Some(1758602096000002000)
1153 ])
1154 );
1155
1156 perfectly_shredded_variant_array_fn!(perfectly_shredded_timestamp_micro_variant_array, || {
1157 arrow::array::TimestampMicrosecondArray::from(vec![
1158 Some(-456000),
1159 Some(1758602096000001),
1160 Some(1758602096000002),
1161 ])
1162 .with_timezone("+00:00")
1163 });
1164
1165 perfectly_shredded_to_arrow_primitive_test!(
1166 get_variant_perfectly_shredded_timestamp_micro_as_timestamp_micro,
1167 DataType::Timestamp(TimeUnit::Microsecond, Some(Arc::from("+00:00"))),
1168 perfectly_shredded_timestamp_micro_variant_array,
1169 arrow::array::TimestampMicrosecondArray::from(vec![
1170 Some(-456000),
1171 Some(1758602096000001),
1172 Some(1758602096000002),
1173 ])
1174 .with_timezone("+00:00")
1175 );
1176
1177 perfectly_shredded_to_arrow_primitive_test!(
1179 get_variant_perfectly_shredded_timestamp_micro_as_nano,
1180 DataType::Timestamp(TimeUnit::Nanosecond, Some(Arc::from("+00:00"))),
1181 perfectly_shredded_timestamp_micro_variant_array,
1182 arrow::array::TimestampNanosecondArray::from(vec![
1183 Some(-456000000),
1184 Some(1758602096000001000),
1185 Some(1758602096000002000)
1186 ])
1187 .with_timezone("+00:00")
1188 );
1189
1190 perfectly_shredded_variant_array_fn!(
1191 perfectly_shredded_timestamp_nano_ntz_variant_array,
1192 || {
1193 arrow::array::TimestampNanosecondArray::from(vec![
1194 Some(-4999999561),
1195 Some(1758602096000000001),
1196 Some(1758602096000000002),
1197 ])
1198 }
1199 );
1200
1201 perfectly_shredded_variant_array_fn!(
1202 perfectly_shredded_timestamp_micro_variant_array_for_second_and_milli_second,
1203 || {
1204 arrow::array::TimestampMicrosecondArray::from(vec![
1205 Some(1234), Some(1234000), Some(1234000000), ])
1209 .with_timezone("+00:00")
1210 }
1211 );
1212
1213 perfectly_shredded_to_arrow_primitive_test!(
1216 get_variant_perfectly_shredded_timestamp_micro_as_timestamp_second,
1217 DataType::Timestamp(TimeUnit::Second, Some(Arc::from("+00:00"))),
1218 perfectly_shredded_timestamp_micro_variant_array_for_second_and_milli_second,
1219 arrow::array::TimestampSecondArray::from(vec![
1220 None,
1221 None, Some(1234)
1223 ])
1224 .with_timezone("+00:00")
1225 );
1226
1227 perfectly_shredded_to_arrow_primitive_test!(
1228 get_variant_perfectly_shredded_timestamp_micro_as_timestamp_milli,
1229 DataType::Timestamp(TimeUnit::Millisecond, Some(Arc::from("+00:00"))),
1230 perfectly_shredded_timestamp_micro_variant_array_for_second_and_milli_second,
1231 arrow::array::TimestampMillisecondArray::from(vec![
1232 None, Some(1234),
1234 Some(1234000)
1235 ])
1236 .with_timezone("+00:00")
1237 );
1238
1239 perfectly_shredded_variant_array_fn!(
1240 perfectly_shredded_timestamp_micro_ntz_variant_array_for_second_and_milli_second,
1241 || {
1242 arrow::array::TimestampMicrosecondArray::from(vec![
1243 Some(1234), Some(1234000), Some(1234000000), ])
1247 }
1248 );
1249
1250 perfectly_shredded_to_arrow_primitive_test!(
1253 get_variant_perfectly_shredded_timestamp_micro_ntz_as_timestamp_second,
1254 DataType::Timestamp(TimeUnit::Second, None),
1255 perfectly_shredded_timestamp_micro_ntz_variant_array_for_second_and_milli_second,
1256 arrow::array::TimestampSecondArray::from(vec![
1257 None,
1258 None, Some(1234)
1260 ])
1261 );
1262
1263 perfectly_shredded_to_arrow_primitive_test!(
1264 get_variant_perfectly_shredded_timestamp_micro_ntz_as_timestamp_milli,
1265 DataType::Timestamp(TimeUnit::Millisecond, None),
1266 perfectly_shredded_timestamp_micro_ntz_variant_array_for_second_and_milli_second,
1267 arrow::array::TimestampMillisecondArray::from(vec![
1268 None, Some(1234),
1270 Some(1234000)
1271 ])
1272 );
1273
1274 perfectly_shredded_variant_array_fn!(
1275 perfectly_shredded_timestamp_nano_variant_array_for_second_and_milli_second,
1276 || {
1277 arrow::array::TimestampNanosecondArray::from(vec![
1278 Some(1234000), Some(1234000000), Some(1234000000000), ])
1282 .with_timezone("+00:00")
1283 }
1284 );
1285
1286 perfectly_shredded_to_arrow_primitive_test!(
1289 get_variant_perfectly_shredded_timestamp_nano_as_timestamp_second,
1290 DataType::Timestamp(TimeUnit::Second, Some(Arc::from("+00:00"))),
1291 perfectly_shredded_timestamp_nano_variant_array_for_second_and_milli_second,
1292 arrow::array::TimestampSecondArray::from(vec![
1293 None,
1294 None, Some(1234)
1296 ])
1297 .with_timezone("+00:00")
1298 );
1299
1300 perfectly_shredded_to_arrow_primitive_test!(
1301 get_variant_perfectly_shredded_timestamp_nano_as_timestamp_milli,
1302 DataType::Timestamp(TimeUnit::Millisecond, Some(Arc::from("+00:00"))),
1303 perfectly_shredded_timestamp_nano_variant_array_for_second_and_milli_second,
1304 arrow::array::TimestampMillisecondArray::from(vec![
1305 None, Some(1234),
1307 Some(1234000)
1308 ])
1309 .with_timezone("+00:00")
1310 );
1311
1312 perfectly_shredded_variant_array_fn!(
1313 perfectly_shredded_timestamp_nano_ntz_variant_array_for_second_and_milli_second,
1314 || {
1315 arrow::array::TimestampNanosecondArray::from(vec![
1316 Some(1234000), Some(1234000000), Some(1234000000000), ])
1320 }
1321 );
1322
1323 perfectly_shredded_to_arrow_primitive_test!(
1326 get_variant_perfectly_shredded_timestamp_nano_ntz_as_timestamp_second,
1327 DataType::Timestamp(TimeUnit::Second, None),
1328 perfectly_shredded_timestamp_nano_ntz_variant_array_for_second_and_milli_second,
1329 arrow::array::TimestampSecondArray::from(vec![
1330 None,
1331 None, Some(1234)
1333 ])
1334 );
1335
1336 perfectly_shredded_to_arrow_primitive_test!(
1337 get_variant_perfectly_shredded_timestamp_nano_ntz_as_timestamp_milli,
1338 DataType::Timestamp(TimeUnit::Millisecond, None),
1339 perfectly_shredded_timestamp_nano_ntz_variant_array_for_second_and_milli_second,
1340 arrow::array::TimestampMillisecondArray::from(vec![
1341 None, Some(1234),
1343 Some(1234000)
1344 ])
1345 );
1346
1347 perfectly_shredded_to_arrow_primitive_test!(
1348 get_variant_perfectly_shredded_timestamp_nano_ntz_as_timestamp_nano_ntz,
1349 DataType::Timestamp(TimeUnit::Nanosecond, None),
1350 perfectly_shredded_timestamp_nano_ntz_variant_array,
1351 arrow::array::TimestampNanosecondArray::from(vec![
1352 Some(-4999999561),
1353 Some(1758602096000000001),
1354 Some(1758602096000000002),
1355 ])
1356 );
1357
1358 perfectly_shredded_variant_array_fn!(perfectly_shredded_timestamp_nano_variant_array, || {
1359 arrow::array::TimestampNanosecondArray::from(vec![
1360 Some(-4999999561),
1361 Some(1758602096000000001),
1362 Some(1758602096000000002),
1363 ])
1364 .with_timezone("+00:00")
1365 });
1366
1367 perfectly_shredded_to_arrow_primitive_test!(
1368 get_variant_perfectly_shredded_timestamp_nano_as_timestamp_nano,
1369 DataType::Timestamp(TimeUnit::Nanosecond, Some(Arc::from("+00:00"))),
1370 perfectly_shredded_timestamp_nano_variant_array,
1371 arrow::array::TimestampNanosecondArray::from(vec![
1372 Some(-4999999561),
1373 Some(1758602096000000001),
1374 Some(1758602096000000002),
1375 ])
1376 .with_timezone("+00:00")
1377 );
1378
1379 perfectly_shredded_variant_array_fn!(perfectly_shredded_date_variant_array, || {
1380 Date32Array::from(vec![Some(-12345), Some(17586), Some(20000)])
1381 });
1382
1383 perfectly_shredded_to_arrow_primitive_test!(
1384 get_variant_perfectly_shredded_date_as_date,
1385 DataType::Date32,
1386 perfectly_shredded_date_variant_array,
1387 Date32Array::from(vec![Some(-12345), Some(17586), Some(20000)])
1388 );
1389
1390 perfectly_shredded_to_arrow_primitive_test!(
1391 get_variant_perfectly_shredded_date_as_date64,
1392 DataType::Date64,
1393 perfectly_shredded_date_variant_array,
1394 Date64Array::from(vec![
1395 Some(-1066608000000),
1396 Some(1519430400000),
1397 Some(1728000000000)
1398 ])
1399 );
1400
1401 perfectly_shredded_variant_array_fn!(perfectly_shredded_time_variant_array, || {
1402 Time64MicrosecondArray::from(vec![Some(12345000), Some(87654000), Some(135792000)])
1403 });
1404
1405 perfectly_shredded_to_arrow_primitive_test!(
1406 get_variant_perfectly_shredded_time_as_time,
1407 DataType::Time64(TimeUnit::Microsecond),
1408 perfectly_shredded_time_variant_array,
1409 Time64MicrosecondArray::from(vec![Some(12345000), Some(87654000), Some(135792000)])
1410 );
1411
1412 perfectly_shredded_to_arrow_primitive_test!(
1413 get_variant_perfectly_shredded_time_as_time64_nano,
1414 DataType::Time64(TimeUnit::Nanosecond),
1415 perfectly_shredded_time_variant_array,
1416 Time64NanosecondArray::from(vec![
1417 Some(12345000000),
1418 Some(87654000000),
1419 Some(135792000000)
1420 ])
1421 );
1422
1423 perfectly_shredded_variant_array_fn!(perfectly_shredded_time_variant_array_for_time32, || {
1424 Time64MicrosecondArray::from(vec![
1425 Some(1234), Some(7654000), Some(35792000000), ])
1429 });
1430
1431 perfectly_shredded_to_arrow_primitive_test!(
1432 get_variant_perfectly_shredded_time_as_time32_second,
1433 DataType::Time32(TimeUnit::Second),
1434 perfectly_shredded_time_variant_array_for_time32,
1435 Time32SecondArray::from(vec![
1436 None,
1437 None, Some(35792)
1439 ])
1440 );
1441
1442 perfectly_shredded_to_arrow_primitive_test!(
1443 get_variant_perfectly_shredded_time_as_time32_milli,
1444 DataType::Time32(TimeUnit::Millisecond),
1445 perfectly_shredded_time_variant_array_for_time32,
1446 Time32MillisecondArray::from(vec![
1447 None, Some(7654),
1449 Some(35792000)
1450 ])
1451 );
1452
1453 perfectly_shredded_variant_array_fn!(perfectly_shredded_null_variant_array, || {
1454 let mut builder = NullBuilder::new();
1455 builder.append_nulls(3);
1456 builder.finish()
1457 });
1458
1459 perfectly_shredded_to_arrow_primitive_test!(
1460 get_variant_perfectly_shredded_null_as_null,
1461 DataType::Null,
1462 perfectly_shredded_null_variant_array,
1463 arrow::array::NullArray::new(3)
1464 );
1465
1466 perfectly_shredded_variant_array_fn!(perfectly_shredded_null_variant_array_with_int, || {
1467 Int32Array::from(vec![Some(32), Some(64), Some(48)])
1468 });
1469
1470 perfectly_shredded_to_arrow_primitive_test!(
1472 get_variant_perfectly_shredded_null_with_type_missmatch_in_safe_mode,
1473 DataType::Null,
1474 perfectly_shredded_null_variant_array_with_int,
1475 arrow::array::NullArray::new(3)
1476 );
1477
1478 #[test]
1480 fn get_variant_perfectly_shredded_null_as_null_with_type_missmatch_in_strict_mode() {
1481 let array = perfectly_shredded_null_variant_array_with_int();
1482 let field = Field::new("typed_value", DataType::Null, true);
1483 let options = GetOptions::new()
1484 .with_as_type(Some(FieldRef::from(field)))
1485 .with_cast_options(CastOptions {
1486 safe: false,
1487 format_options: FormatOptions::default(),
1488 });
1489
1490 let result = variant_get(&array, options);
1491
1492 assert!(result.is_err());
1493 let error_msg = format!("{}", result.unwrap_err());
1494 assert!(
1495 error_msg
1496 .contains("Cast error: Failed to extract primitive of type Null from variant Int32(32) at path VariantPath([])"),
1497 "Expected=[Cast error: Failed to extract primitive of type Null from variant Int32(32) at path VariantPath([])],\
1498 Got error message=[{}]",
1499 error_msg
1500 );
1501 }
1502
1503 perfectly_shredded_variant_array_fn!(perfectly_shredded_decimal4_variant_array, || {
1504 Decimal32Array::from(vec![Some(12345), Some(23400), Some(-12342)])
1505 .with_precision_and_scale(5, 2)
1506 .unwrap()
1507 });
1508
1509 perfectly_shredded_to_arrow_primitive_test!(
1510 get_variant_perfectly_shredded_decimal4_as_decimal4,
1511 DataType::Decimal32(5, 2),
1512 perfectly_shredded_decimal4_variant_array,
1513 Decimal32Array::from(vec![Some(12345), Some(23400), Some(-12342)])
1514 .with_precision_and_scale(5, 2)
1515 .unwrap()
1516 );
1517
1518 perfectly_shredded_variant_array_fn!(
1519 perfectly_shredded_decimal8_variant_array_cast2decimal32,
1520 || {
1521 Decimal64Array::from(vec![Some(123456), Some(145678), Some(-123456)])
1522 .with_precision_and_scale(6, 1)
1523 .unwrap()
1524 }
1525 );
1526
1527 perfectly_shredded_to_arrow_primitive_test!(
1531 get_variant_perfectly_shredded_decimal8_through_decimal32_as_decimal8,
1532 DataType::Decimal64(6, 1),
1533 perfectly_shredded_decimal8_variant_array_cast2decimal32,
1534 Decimal64Array::from(vec![Some(123456), Some(145678), Some(-123456)])
1535 .with_precision_and_scale(6, 1)
1536 .unwrap()
1537 );
1538
1539 perfectly_shredded_variant_array_fn!(perfectly_shredded_decimal8_variant_array, || {
1542 Decimal64Array::from(vec![Some(1234567809), Some(1456787000), Some(-1234561203)])
1543 .with_precision_and_scale(10, 1)
1544 .unwrap()
1545 });
1546
1547 perfectly_shredded_to_arrow_primitive_test!(
1548 get_variant_perfectly_shredded_decimal8_as_decimal8,
1549 DataType::Decimal64(10, 1),
1550 perfectly_shredded_decimal8_variant_array,
1551 Decimal64Array::from(vec![Some(1234567809), Some(1456787000), Some(-1234561203)])
1552 .with_precision_and_scale(10, 1)
1553 .unwrap()
1554 );
1555
1556 perfectly_shredded_variant_array_fn!(
1559 perfectly_shredded_decimal16_within_decimal4_variant_array,
1560 || {
1561 Decimal128Array::from(vec![
1562 Some(i128::from(1234589)),
1563 Some(i128::from(2344444)),
1564 Some(i128::from(-1234789)),
1565 ])
1566 .with_precision_and_scale(7, 3)
1567 .unwrap()
1568 }
1569 );
1570
1571 perfectly_shredded_to_arrow_primitive_test!(
1574 get_variant_perfectly_shredded_decimal16_within_decimal4_as_decimal16,
1575 DataType::Decimal128(7, 3),
1576 perfectly_shredded_decimal16_within_decimal4_variant_array,
1577 Decimal128Array::from(vec![
1578 Some(i128::from(1234589)),
1579 Some(i128::from(2344444)),
1580 Some(i128::from(-1234789)),
1581 ])
1582 .with_precision_and_scale(7, 3)
1583 .unwrap()
1584 );
1585
1586 perfectly_shredded_variant_array_fn!(
1587 perfectly_shredded_decimal16_within_decimal8_variant_array,
1588 || {
1589 Decimal128Array::from(vec![Some(1234567809), Some(1456787000), Some(-1234561203)])
1590 .with_precision_and_scale(10, 1)
1591 .unwrap()
1592 }
1593 );
1594
1595 perfectly_shredded_to_arrow_primitive_test!(
1598 get_variant_perfectly_shredded_decimal16_within8_as_decimal16,
1599 DataType::Decimal128(10, 1),
1600 perfectly_shredded_decimal16_within_decimal8_variant_array,
1601 Decimal128Array::from(vec![Some(1234567809), Some(1456787000), Some(-1234561203)])
1602 .with_precision_and_scale(10, 1)
1603 .unwrap()
1604 );
1605
1606 perfectly_shredded_variant_array_fn!(perfectly_shredded_decimal16_variant_array, || {
1607 Decimal128Array::from(vec![
1608 Some(i128::from_str("12345678901234567899").unwrap()),
1609 Some(i128::from_str("23445677483748324300").unwrap()),
1610 Some(i128::from_str("-12345678901234567899").unwrap()),
1611 ])
1612 .with_precision_and_scale(20, 3)
1613 .unwrap()
1614 });
1615
1616 perfectly_shredded_to_arrow_primitive_test!(
1619 get_variant_perfectly_shredded_decimal16_as_decimal16,
1620 DataType::Decimal128(20, 3),
1621 perfectly_shredded_decimal16_variant_array,
1622 Decimal128Array::from(vec![
1623 Some(i128::from_str("12345678901234567899").unwrap()),
1624 Some(i128::from_str("23445677483748324300").unwrap()),
1625 Some(i128::from_str("-12345678901234567899").unwrap())
1626 ])
1627 .with_precision_and_scale(20, 3)
1628 .unwrap()
1629 );
1630
1631 perfectly_shredded_variant_array_fn!(perfectly_shredded_binary_variant_array, || {
1632 BinaryArray::from(vec![
1633 Some(b"Apache" as &[u8]),
1634 Some(b"Arrow-rs" as &[u8]),
1635 Some(b"Parquet-variant" as &[u8]),
1636 ])
1637 });
1638
1639 perfectly_shredded_to_arrow_primitive_test!(
1640 get_variant_perfectly_shredded_binary_as_binary,
1641 DataType::Binary,
1642 perfectly_shredded_binary_variant_array,
1643 BinaryArray::from(vec![
1644 Some(b"Apache" as &[u8]),
1645 Some(b"Arrow-rs" as &[u8]),
1646 Some(b"Parquet-variant" as &[u8]),
1647 ])
1648 );
1649
1650 perfectly_shredded_variant_array_fn!(perfectly_shredded_large_binary_variant_array, || {
1651 LargeBinaryArray::from(vec![
1652 Some(b"Apache" as &[u8]),
1653 Some(b"Arrow-rs" as &[u8]),
1654 Some(b"Parquet-variant" as &[u8]),
1655 ])
1656 });
1657
1658 perfectly_shredded_to_arrow_primitive_test!(
1659 get_variant_perfectly_shredded_large_binary_as_large_binary,
1660 DataType::LargeBinary,
1661 perfectly_shredded_large_binary_variant_array,
1662 LargeBinaryArray::from(vec![
1663 Some(b"Apache" as &[u8]),
1664 Some(b"Arrow-rs" as &[u8]),
1665 Some(b"Parquet-variant" as &[u8]),
1666 ])
1667 );
1668
1669 perfectly_shredded_variant_array_fn!(perfectly_shredded_binary_view_variant_array, || {
1670 BinaryViewArray::from(vec![
1671 Some(b"Apache" as &[u8]),
1672 Some(b"Arrow-rs" as &[u8]),
1673 Some(b"Parquet-variant" as &[u8]),
1674 ])
1675 });
1676
1677 perfectly_shredded_to_arrow_primitive_test!(
1678 get_variant_perfectly_shredded_binary_view_as_binary_view,
1679 DataType::BinaryView,
1680 perfectly_shredded_binary_view_variant_array,
1681 BinaryViewArray::from(vec![
1682 Some(b"Apache" as &[u8]),
1683 Some(b"Arrow-rs" as &[u8]),
1684 Some(b"Parquet-variant" as &[u8]),
1685 ])
1686 );
1687
1688 fn all_null_variant_array() -> ArrayRef {
1705 let nulls = NullBuffer::from(vec![
1706 false, false, false, ]);
1710
1711 let metadata =
1713 BinaryViewArray::from_iter_values(std::iter::repeat_n(EMPTY_VARIANT_METADATA_BYTES, 3));
1714
1715 ArrayRef::from(VariantArray::from_parts(metadata, None, None, Some(nulls)))
1716 }
1717 #[test]
1721 fn test_shredded_object_field_access() {
1722 let array = shredded_object_with_x_field_variant_array();
1723
1724 let options = GetOptions::new_with_path(VariantPath::try_from("x").unwrap());
1726 let result = variant_get(&array, options).unwrap();
1727
1728 let result_variant = VariantArray::try_new(&result).unwrap();
1729 assert_eq!(result_variant.len(), 2);
1730
1731 assert_eq!(result_variant.value(0), Variant::Int32(1));
1733 assert_eq!(result_variant.value(1), Variant::Int32(42));
1735 }
1736
1737 #[test]
1739 fn test_shredded_object_field_as_int32() {
1740 let array = shredded_object_with_x_field_variant_array();
1741
1742 let field = Field::new("x", DataType::Int32, false);
1744 let options = GetOptions::new_with_path(VariantPath::try_from("x").unwrap())
1745 .with_as_type(Some(FieldRef::from(field)));
1746 let result = variant_get(&array, options).unwrap();
1747
1748 let expected: ArrayRef = Arc::new(Int32Array::from(vec![Some(1), Some(42)]));
1750 assert_eq!(&result, &expected);
1751 }
1752
1753 fn shredded_object_with_x_field_variant_array() -> ArrayRef {
1765 let (metadata, y_field_value) = {
1767 let mut builder = parquet_variant::VariantBuilder::new();
1768 let mut obj = builder.new_object();
1769 obj.insert("x", Variant::Int32(42));
1770 obj.insert("y", Variant::from("foo"));
1771 obj.finish();
1772 builder.finish()
1773 };
1774
1775 let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 2));
1777
1778 let empty_object_value = {
1783 let mut builder = parquet_variant::VariantBuilder::new();
1784 let obj = builder.new_object();
1785 obj.finish();
1786 let (_, value) = builder.finish();
1787 value
1788 };
1789
1790 let value_array = BinaryViewArray::from(vec![
1791 Some(y_field_value.as_slice()), Some(empty_object_value.as_slice()), ]);
1794
1795 let x_field_typed_value = Int32Array::from(vec![Some(1), Some(42)]);
1798
1799 let x_field_shredded = ShreddedVariantFieldArray::from_parts(
1801 None,
1802 Some(Arc::new(x_field_typed_value) as ArrayRef),
1803 None,
1804 );
1805
1806 let typed_value_fields = Fields::from(vec![Field::new(
1808 "x",
1809 x_field_shredded.data_type().clone(),
1810 true,
1811 )]);
1812 let typed_value_struct = StructArray::try_new(
1813 typed_value_fields,
1814 vec![ArrayRef::from(x_field_shredded)],
1815 None, )
1817 .unwrap();
1818
1819 ArrayRef::from(VariantArray::from_parts(
1821 metadata_array,
1822 Some(value_array),
1823 Some(Arc::new(typed_value_struct)),
1824 None,
1825 ))
1826 }
1827
1828 #[test]
1830 fn test_simple_nested_path_support() {
1831 println!("Testing path parsing:");
1833
1834 let path_x = VariantPath::try_from("x").unwrap();
1835 let elements_x: Vec<_> = path_x.iter().collect();
1836 println!(" 'x' -> {} elements: {:?}", elements_x.len(), elements_x);
1837
1838 let path_ax = VariantPath::try_from("a.x").unwrap();
1839 let elements_ax: Vec<_> = path_ax.iter().collect();
1840 println!(
1841 " 'a.x' -> {} elements: {:?}",
1842 elements_ax.len(),
1843 elements_ax
1844 );
1845
1846 let path_ax_alt = VariantPath::try_from("$.a.x").unwrap();
1847 let elements_ax_alt: Vec<_> = path_ax_alt.iter().collect();
1848 println!(
1849 " '$.a.x' -> {} elements: {:?}",
1850 elements_ax_alt.len(),
1851 elements_ax_alt
1852 );
1853
1854 let path_nested = VariantPath::try_from("a").unwrap().join("x");
1855 let elements_nested: Vec<_> = path_nested.iter().collect();
1856 println!(
1857 " VariantPath::try_from('a').unwrap().join('x') -> {} elements: {:?}",
1858 elements_nested.len(),
1859 elements_nested
1860 );
1861
1862 let array = shredded_object_with_x_field_variant_array();
1864
1865 let real_nested_path = VariantPath::try_from("a").unwrap().join("x");
1867 let options = GetOptions::new_with_path(real_nested_path);
1868 let result = variant_get(&array, options);
1869
1870 match result {
1871 Ok(_) => {
1872 println!("Nested path 'a.x' works unexpectedly!");
1873 }
1874 Err(e) => {
1875 println!("Nested path 'a.x' error: {}", e);
1876 if e.to_string().contains("Not yet implemented")
1877 || e.to_string().contains("NotYetImplemented")
1878 {
1879 println!("This is expected - nested paths are not implemented");
1880 return;
1881 }
1882 println!("This shows nested paths need implementation");
1884 }
1885 }
1886 }
1887
1888 #[test]
1892 fn test_depth_0_int32_conversion() {
1893 println!("=== Testing Depth 0: Direct field access ===");
1894
1895 let unshredded_array = create_depth_0_test_data();
1897
1898 let field = Field::new("result", DataType::Int32, true);
1899 let path = VariantPath::try_from("x").unwrap();
1900 let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
1901 let result = variant_get(&unshredded_array, options).unwrap();
1902
1903 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
1904 Some(42), None, None, ]));
1908 assert_eq!(&result, &expected);
1909 println!("Depth 0 (unshredded) passed");
1910
1911 let shredded_array = create_depth_0_shredded_test_data_simple();
1913
1914 let field = Field::new("result", DataType::Int32, true);
1915 let path = VariantPath::try_from("x").unwrap();
1916 let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
1917 let result = variant_get(&shredded_array, options).unwrap();
1918
1919 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
1920 Some(42), None, ]));
1923 assert_eq!(&result, &expected);
1924 println!("Depth 0 (shredded) passed");
1925 }
1926
1927 #[test]
1930 fn test_depth_1_int32_conversion() {
1931 println!("=== Testing Depth 1: Single nested field access ===");
1932
1933 let unshredded_array = create_nested_path_test_data();
1935
1936 let field = Field::new("result", DataType::Int32, true);
1937 let path = VariantPath::try_from("a.x").unwrap(); let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
1939 let result = variant_get(&unshredded_array, options).unwrap();
1940
1941 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
1942 Some(55), None, ]));
1945 assert_eq!(&result, &expected);
1946 println!("Depth 1 (unshredded) passed");
1947
1948 let shredded_array = create_depth_1_shredded_test_data_working();
1950
1951 let field = Field::new("result", DataType::Int32, true);
1952 let path = VariantPath::try_from("a.x").unwrap(); let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
1954 let result = variant_get(&shredded_array, options).unwrap();
1955
1956 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
1957 Some(55), None, ]));
1960 assert_eq!(&result, &expected);
1961 println!("Depth 1 (shredded) passed");
1962 }
1963
1964 #[test]
1967 fn test_depth_2_int32_conversion() {
1968 println!("=== Testing Depth 2: Double nested field access ===");
1969
1970 let unshredded_array = create_depth_2_test_data();
1972
1973 let field = Field::new("result", DataType::Int32, true);
1974 let path = VariantPath::try_from("a.b.x").unwrap(); let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
1976 let result = variant_get(&unshredded_array, options).unwrap();
1977
1978 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
1979 Some(100), None, None, ]));
1983 assert_eq!(&result, &expected);
1984 println!("Depth 2 (unshredded) passed");
1985
1986 let shredded_array = create_depth_2_shredded_test_data_working();
1988
1989 let field = Field::new("result", DataType::Int32, true);
1990 let path = VariantPath::try_from("a.b.x").unwrap(); let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
1992 let result = variant_get(&shredded_array, options).unwrap();
1993
1994 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
1995 Some(100), None, None, ]));
1999 assert_eq!(&result, &expected);
2000 println!("Depth 2 (shredded) passed");
2001 }
2002
2003 #[test]
2008 fn test_current_nested_path_functionality() {
2009 let array = shredded_object_with_x_field_variant_array();
2010
2011 let single_path = VariantPath::try_from("x").unwrap();
2013 let field = Field::new("result", DataType::Int32, true);
2014 let options =
2015 GetOptions::new_with_path(single_path).with_as_type(Some(FieldRef::from(field)));
2016 let result = variant_get(&array, options).unwrap();
2017
2018 println!("Single path 'x' works - result: {:?}", result);
2019
2020 let nested_path = VariantPath::try_from("a").unwrap().join("x");
2022 let field = Field::new("result", DataType::Int32, true);
2023 let options =
2024 GetOptions::new_with_path(nested_path).with_as_type(Some(FieldRef::from(field)));
2025 let result = variant_get(&array, options).unwrap();
2026
2027 println!("Nested path 'a.x' result: {:?}", result);
2028 }
2029
2030 fn create_depth_0_test_data() -> ArrayRef {
2033 let mut builder = crate::VariantArrayBuilder::new(3);
2034
2035 {
2037 let json_str = r#"{"x": 42}"#;
2038 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2039 if let Ok(variant_array) = json_to_variant(&string_array) {
2040 builder.append_variant(variant_array.value(0));
2041 } else {
2042 builder.append_null();
2043 }
2044 }
2045
2046 {
2048 let json_str = r#"{"x": "foo"}"#;
2049 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2050 if let Ok(variant_array) = json_to_variant(&string_array) {
2051 builder.append_variant(variant_array.value(0));
2052 } else {
2053 builder.append_null();
2054 }
2055 }
2056
2057 {
2059 let json_str = r#"{"y": 10}"#;
2060 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2061 if let Ok(variant_array) = json_to_variant(&string_array) {
2062 builder.append_variant(variant_array.value(0));
2063 } else {
2064 builder.append_null();
2065 }
2066 }
2067
2068 ArrayRef::from(builder.build())
2069 }
2070
2071 fn create_nested_path_test_data() -> ArrayRef {
2074 let mut builder = crate::VariantArrayBuilder::new(2);
2075
2076 {
2078 let json_str = r#"{"a": {"x": 55}, "b": 42}"#;
2079 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2080 if let Ok(variant_array) = json_to_variant(&string_array) {
2081 builder.append_variant(variant_array.value(0));
2082 } else {
2083 builder.append_null();
2084 }
2085 }
2086
2087 {
2089 let json_str = r#"{"a": {"x": "foo"}, "b": 42}"#;
2090 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2091 if let Ok(variant_array) = json_to_variant(&string_array) {
2092 builder.append_variant(variant_array.value(0));
2093 } else {
2094 builder.append_null();
2095 }
2096 }
2097
2098 ArrayRef::from(builder.build())
2099 }
2100
2101 fn create_depth_2_test_data() -> ArrayRef {
2104 let mut builder = crate::VariantArrayBuilder::new(3);
2105
2106 {
2108 let json_str = r#"{"a": {"b": {"x": 100}}}"#;
2109 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2110 if let Ok(variant_array) = json_to_variant(&string_array) {
2111 builder.append_variant(variant_array.value(0));
2112 } else {
2113 builder.append_null();
2114 }
2115 }
2116
2117 {
2119 let json_str = r#"{"a": {"b": {"x": "bar"}}}"#;
2120 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2121 if let Ok(variant_array) = json_to_variant(&string_array) {
2122 builder.append_variant(variant_array.value(0));
2123 } else {
2124 builder.append_null();
2125 }
2126 }
2127
2128 {
2130 let json_str = r#"{"a": {"b": {"y": 200}}}"#;
2131 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2132 if let Ok(variant_array) = json_to_variant(&string_array) {
2133 builder.append_variant(variant_array.value(0));
2134 } else {
2135 builder.append_null();
2136 }
2137 }
2138
2139 ArrayRef::from(builder.build())
2140 }
2141
2142 fn create_depth_0_shredded_test_data_simple() -> ArrayRef {
2145 let (metadata, string_x_value) = {
2147 let mut builder = parquet_variant::VariantBuilder::new();
2148 let mut obj = builder.new_object();
2149 obj.insert("x", Variant::from("foo"));
2150 obj.finish();
2151 builder.finish()
2152 };
2153
2154 let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 2));
2156
2157 let empty_object_value = {
2161 let mut builder = parquet_variant::VariantBuilder::new();
2162 let obj = builder.new_object();
2163 obj.finish();
2164 let (_, value) = builder.finish();
2165 value
2166 };
2167
2168 let value_array = BinaryViewArray::from(vec![
2169 Some(empty_object_value.as_slice()), Some(string_x_value.as_slice()), ]);
2172
2173 let x_field_typed_value = Int32Array::from(vec![Some(42), None]);
2175
2176 let x_field_shredded = ShreddedVariantFieldArray::from_parts(
2178 None,
2179 Some(Arc::new(x_field_typed_value) as ArrayRef),
2180 None,
2181 );
2182
2183 let typed_value_fields = Fields::from(vec![Field::new(
2185 "x",
2186 x_field_shredded.data_type().clone(),
2187 true,
2188 )]);
2189 let typed_value_struct = StructArray::try_new(
2190 typed_value_fields,
2191 vec![ArrayRef::from(x_field_shredded)],
2192 None,
2193 )
2194 .unwrap();
2195
2196 ArrayRef::from(VariantArray::from_parts(
2198 metadata_array,
2199 Some(value_array),
2200 Some(Arc::new(typed_value_struct)),
2201 None,
2202 ))
2203 }
2204
2205 fn create_depth_1_shredded_test_data_working() -> ArrayRef {
2210 let (metadata, _) = {
2212 let mut builder = parquet_variant::VariantBuilder::new();
2214 let mut obj = builder.new_object();
2215
2216 let mut a_obj = obj.new_object("a");
2218 a_obj.insert("x", Variant::Int32(55));
2219 a_obj.finish();
2220
2221 obj.insert("b", Variant::Int32(42));
2222 obj.finish();
2223 builder.finish()
2224 };
2225
2226 let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 2));
2227
2228 let empty_object_value = {
2231 let mut builder = parquet_variant::VariantBuilder::new();
2232 let obj = builder.new_object();
2233 obj.finish();
2234 let (_, value) = builder.finish();
2235 value
2236 };
2237
2238 let row1_fallback = {
2241 let mut builder = parquet_variant::VariantBuilder::new();
2242 let mut obj = builder.new_object();
2243 obj.insert("fallback", Variant::from("data"));
2244 obj.finish();
2245 let (_, value) = builder.finish();
2246 value
2247 };
2248
2249 let value_array = BinaryViewArray::from(vec![
2250 Some(empty_object_value.as_slice()), Some(row1_fallback.as_slice()), ]);
2253
2254 let x_typed_value = Int32Array::from(vec![Some(55), None]);
2257 let x_field_shredded = ShreddedVariantFieldArray::from_parts(
2258 None,
2259 Some(Arc::new(x_typed_value) as ArrayRef),
2260 None,
2261 );
2262
2263 let a_value_data = {
2268 let mut builder = parquet_variant::VariantBuilder::new();
2269 let obj = builder.new_object();
2270 obj.finish();
2271 let (_, value) = builder.finish();
2272 value
2273 };
2274 let a_value_array = BinaryViewArray::from(vec![
2275 None, Some(a_value_data.as_slice()), ]);
2278
2279 let a_inner_fields = Fields::from(vec![Field::new(
2280 "x",
2281 x_field_shredded.data_type().clone(),
2282 true,
2283 )]);
2284 let a_inner_typed_value = Arc::new(
2285 StructArray::try_new(a_inner_fields, vec![ArrayRef::from(x_field_shredded)], None)
2286 .unwrap(),
2287 ) as ArrayRef;
2288 let a_field_shredded = ShreddedVariantFieldArray::from_parts(
2289 Some(a_value_array),
2290 Some(a_inner_typed_value),
2291 None,
2292 );
2293
2294 let typed_value_fields = Fields::from(vec![Field::new(
2296 "a",
2297 a_field_shredded.data_type().clone(),
2298 true,
2299 )]);
2300 let typed_value_struct = StructArray::try_new(
2301 typed_value_fields,
2302 vec![ArrayRef::from(a_field_shredded)],
2303 None,
2304 )
2305 .unwrap();
2306
2307 ArrayRef::from(VariantArray::from_parts(
2309 metadata_array,
2310 Some(value_array),
2311 Some(Arc::new(typed_value_struct)),
2312 None,
2313 ))
2314 }
2315
2316 fn create_depth_2_shredded_test_data_working() -> ArrayRef {
2322 let (metadata, _) = {
2324 let mut builder = parquet_variant::VariantBuilder::new();
2326 let mut obj = builder.new_object();
2327
2328 let mut a_obj = obj.new_object("a");
2330 let mut b_obj = a_obj.new_object("b");
2331 b_obj.insert("x", Variant::Int32(100));
2332 b_obj.finish();
2333 a_obj.finish();
2334
2335 obj.finish();
2336 builder.finish()
2337 };
2338
2339 let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 3));
2340
2341 let empty_object_value = {
2343 let mut builder = parquet_variant::VariantBuilder::new();
2344 let obj = builder.new_object();
2345 obj.finish();
2346 let (_, value) = builder.finish();
2347 value
2348 };
2349
2350 let value_array = BinaryViewArray::from(vec![
2352 Some(empty_object_value.as_slice()), Some(empty_object_value.as_slice()), Some(empty_object_value.as_slice()), ]);
2356
2357 let x_typed_value = Int32Array::from(vec![Some(100), None, None]);
2361 let x_field_shredded = ShreddedVariantFieldArray::from_parts(
2362 None,
2363 Some(Arc::new(x_typed_value) as ArrayRef),
2364 None,
2365 );
2366
2367 let b_value_data = {
2369 let mut builder = parquet_variant::VariantBuilder::new();
2370 let obj = builder.new_object();
2371 obj.finish();
2372 let (_, value) = builder.finish();
2373 value
2374 };
2375 let b_value_array = BinaryViewArray::from(vec![
2376 None, Some(b_value_data.as_slice()), Some(b_value_data.as_slice()), ]);
2380
2381 let b_inner_fields = Fields::from(vec![Field::new(
2382 "x",
2383 x_field_shredded.data_type().clone(),
2384 true,
2385 )]);
2386 let b_inner_typed_value = Arc::new(
2387 StructArray::try_new(b_inner_fields, vec![ArrayRef::from(x_field_shredded)], None)
2388 .unwrap(),
2389 ) as ArrayRef;
2390 let b_field_shredded = ShreddedVariantFieldArray::from_parts(
2391 Some(b_value_array),
2392 Some(b_inner_typed_value),
2393 None,
2394 );
2395
2396 let a_value_data = {
2398 let mut builder = parquet_variant::VariantBuilder::new();
2399 let obj = builder.new_object();
2400 obj.finish();
2401 let (_, value) = builder.finish();
2402 value
2403 };
2404 let a_value_array = BinaryViewArray::from(vec![
2405 None, Some(a_value_data.as_slice()), Some(a_value_data.as_slice()), ]);
2409
2410 let a_inner_fields = Fields::from(vec![Field::new(
2411 "b",
2412 b_field_shredded.data_type().clone(),
2413 true,
2414 )]);
2415 let a_inner_typed_value = Arc::new(
2416 StructArray::try_new(a_inner_fields, vec![ArrayRef::from(b_field_shredded)], None)
2417 .unwrap(),
2418 ) as ArrayRef;
2419 let a_field_shredded = ShreddedVariantFieldArray::from_parts(
2420 Some(a_value_array),
2421 Some(a_inner_typed_value),
2422 None,
2423 );
2424
2425 let typed_value_fields = Fields::from(vec![Field::new(
2427 "a",
2428 a_field_shredded.data_type().clone(),
2429 true,
2430 )]);
2431 let typed_value_struct = StructArray::try_new(
2432 typed_value_fields,
2433 vec![ArrayRef::from(a_field_shredded)],
2434 None,
2435 )
2436 .unwrap();
2437
2438 ArrayRef::from(VariantArray::from_parts(
2440 metadata_array,
2441 Some(value_array),
2442 Some(Arc::new(typed_value_struct)),
2443 None,
2444 ))
2445 }
2446
2447 #[test]
2448 fn test_strict_cast_options_downcast_failure() {
2449 use arrow::compute::CastOptions;
2450 use arrow::datatypes::{DataType, Field};
2451 use arrow::error::ArrowError;
2452 use parquet_variant::VariantPath;
2453 use std::sync::Arc;
2454
2455 let variant_array = perfectly_shredded_int32_variant_array();
2457
2458 let safe_options = GetOptions {
2460 path: VariantPath::try_from("nonexistent_field").unwrap(),
2461 as_type: Some(Arc::new(Field::new("result", DataType::Int32, true))),
2462 cast_options: CastOptions::default(), };
2464
2465 let variant_array_ref: Arc<dyn Array> = variant_array.clone();
2466 let result = variant_get(&variant_array_ref, safe_options);
2467 assert!(result.is_ok());
2469 let result_array = result.unwrap();
2470 assert_eq!(result_array.len(), 3);
2471 assert!(result_array.is_null(0));
2472 assert!(result_array.is_null(1));
2473 assert!(result_array.is_null(2));
2474
2475 let strict_options = GetOptions {
2477 path: VariantPath::try_from("nonexistent_field").unwrap(),
2478 as_type: Some(Arc::new(Field::new("result", DataType::Int32, true))),
2479 cast_options: CastOptions {
2480 safe: false,
2481 ..Default::default()
2482 },
2483 };
2484
2485 let result = variant_get(&variant_array_ref, strict_options);
2486 assert!(result.is_err());
2488 let error = result.unwrap_err();
2489 assert!(matches!(error, ArrowError::CastError(_)));
2490 assert!(
2491 error
2492 .to_string()
2493 .contains("Cannot access field 'nonexistent_field' on non-struct type")
2494 );
2495 }
2496
2497 #[test]
2498 fn test_error_message_boolean_type_display() {
2499 let mut builder = VariantArrayBuilder::new(1);
2500 builder.append_variant(Variant::Int32(123));
2501 let variant_array: ArrayRef = ArrayRef::from(builder.build());
2502
2503 let options = GetOptions {
2505 path: VariantPath::default(),
2506 as_type: Some(Arc::new(Field::new("result", DataType::Boolean, true))),
2507 cast_options: CastOptions {
2508 safe: false,
2509 ..Default::default()
2510 },
2511 };
2512
2513 let err = variant_get(&variant_array, options).unwrap_err();
2514 let msg = err.to_string();
2515 assert!(msg.contains("Failed to extract primitive of type Boolean"));
2516 }
2517
2518 #[test]
2519 fn test_error_message_numeric_type_display() {
2520 let mut builder = VariantArrayBuilder::new(1);
2521 builder.append_variant(Variant::BooleanTrue);
2522 let variant_array: ArrayRef = ArrayRef::from(builder.build());
2523
2524 let options = GetOptions {
2526 path: VariantPath::default(),
2527 as_type: Some(Arc::new(Field::new("result", DataType::Float32, true))),
2528 cast_options: CastOptions {
2529 safe: false,
2530 ..Default::default()
2531 },
2532 };
2533
2534 let err = variant_get(&variant_array, options).unwrap_err();
2535 let msg = err.to_string();
2536 assert!(msg.contains("Failed to extract primitive of type Float32"));
2537 }
2538
2539 #[test]
2540 fn test_error_message_temporal_type_display() {
2541 let mut builder = VariantArrayBuilder::new(1);
2542 builder.append_variant(Variant::BooleanFalse);
2543 let variant_array: ArrayRef = ArrayRef::from(builder.build());
2544
2545 let options = GetOptions {
2547 path: VariantPath::default(),
2548 as_type: Some(Arc::new(Field::new(
2549 "result",
2550 DataType::Timestamp(TimeUnit::Nanosecond, None),
2551 true,
2552 ))),
2553 cast_options: CastOptions {
2554 safe: false,
2555 ..Default::default()
2556 },
2557 };
2558
2559 let err = variant_get(&variant_array, options).unwrap_err();
2560 let msg = err.to_string();
2561 assert!(msg.contains("Failed to extract primitive of type Timestamp(ns)"));
2562 }
2563
2564 #[test]
2565 fn test_null_buffer_union_for_shredded_paths() {
2566 use arrow::compute::CastOptions;
2567 use arrow::datatypes::{DataType, Field};
2568 use parquet_variant::VariantPath;
2569 use std::sync::Arc;
2570
2571 let variant_array = create_depth_1_shredded_test_data_working();
2580
2581 let options = GetOptions {
2586 path: VariantPath::try_from("a.x").unwrap(),
2587 as_type: Some(Arc::new(Field::new("result", DataType::Int32, true))),
2588 cast_options: CastOptions::default(),
2589 };
2590
2591 let variant_array_ref: Arc<dyn Array> = variant_array.clone();
2592 let result = variant_get(&variant_array_ref, options).unwrap();
2593
2594 assert_eq!(result.len(), variant_array.len());
2596
2597 assert!(!result.is_null(0), "Row 0 should have valid Int32 data");
2601 assert!(
2602 result.is_null(1),
2603 "Row 1 should be null due to type casting failure"
2604 );
2605
2606 let int32_result = result.as_any().downcast_ref::<Int32Array>().unwrap();
2608 assert_eq!(int32_result.value(0), 55); }
2610
2611 #[test]
2612 fn test_struct_null_mask_union_from_children() {
2613 use arrow::compute::CastOptions;
2614 use arrow::datatypes::{DataType, Field, Fields};
2615 use parquet_variant::VariantPath;
2616 use std::sync::Arc;
2617
2618 use arrow::array::StringArray;
2619
2620 let json_strings = vec![
2625 r#"{"a": 42, "b": "hello"}"#, r#"{"a": "world", "b": 100}"#, r#"{"a": 55, "b": 77}"#, ];
2629
2630 let string_array: Arc<dyn arrow::array::Array> = Arc::new(StringArray::from(json_strings));
2631 let variant_array = json_to_variant(&string_array).unwrap();
2632
2633 let struct_fields = Fields::from(vec![
2636 Field::new("a", DataType::Int32, true),
2637 Field::new("b", DataType::Int32, true),
2638 ]);
2639 let struct_type = DataType::Struct(struct_fields);
2640
2641 let options = GetOptions {
2642 path: VariantPath::default(), as_type: Some(Arc::new(Field::new("result", struct_type, true))),
2644 cast_options: CastOptions::default(),
2645 };
2646
2647 let variant_array_ref = ArrayRef::from(variant_array);
2648 let result = variant_get(&variant_array_ref, options).unwrap();
2649
2650 let struct_result = result.as_struct();
2652 assert_eq!(struct_result.len(), 3);
2653
2654 let field_a = struct_result
2656 .column(0)
2657 .as_any()
2658 .downcast_ref::<Int32Array>()
2659 .unwrap();
2660 let field_b = struct_result
2661 .column(1)
2662 .as_any()
2663 .downcast_ref::<Int32Array>()
2664 .unwrap();
2665
2666 assert!(!field_a.is_null(0));
2669 assert_eq!(field_a.value(0), 42);
2670 assert!(field_b.is_null(0)); assert!(field_a.is_null(1)); assert!(!field_b.is_null(1));
2675 assert_eq!(field_b.value(1), 100);
2676
2677 assert!(!field_a.is_null(2));
2679 assert_eq!(field_a.value(2), 55);
2680 assert!(!field_b.is_null(2));
2681 assert_eq!(field_b.value(2), 77);
2682
2683 assert!(!struct_result.is_null(0)); assert!(!struct_result.is_null(1)); assert!(!struct_result.is_null(2)); }
2690
2691 #[test]
2692 fn test_field_nullability_preservation() {
2693 use arrow::compute::CastOptions;
2694 use arrow::datatypes::{DataType, Field};
2695 use parquet_variant::VariantPath;
2696 use std::sync::Arc;
2697
2698 use arrow::array::StringArray;
2699
2700 let json_strings = vec![
2703 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}"#, ];
2713
2714 let string_array: Arc<dyn arrow::array::Array> = Arc::new(StringArray::from(json_strings));
2715 let variant_array = json_to_variant(&string_array).unwrap();
2716
2717 let nullable_field = Arc::new(Field::new("result", DataType::Int32, true));
2719 let options_nullable = GetOptions {
2720 path: VariantPath::try_from("x").unwrap(),
2721 as_type: Some(nullable_field.clone()),
2722 cast_options: CastOptions::default(),
2723 };
2724
2725 let variant_array_ref = ArrayRef::from(variant_array);
2726 let result_nullable = variant_get(&variant_array_ref, options_nullable).unwrap();
2727
2728 let int32_result = result_nullable
2730 .as_any()
2731 .downcast_ref::<Int32Array>()
2732 .unwrap();
2733 assert_eq!(int32_result.len(), 9);
2734
2735 assert!(!int32_result.is_null(0));
2737 assert_eq!(int32_result.value(0), 42);
2738
2739 assert!(int32_result.is_null(1));
2741
2742 assert!(int32_result.is_null(2));
2744
2745 assert!(int32_result.is_null(3));
2747
2748 assert!(int32_result.is_null(4));
2750
2751 assert!(!int32_result.is_null(5));
2754 assert_eq!(int32_result.value(5), 127);
2755
2756 assert!(!int32_result.is_null(6));
2759 assert_eq!(int32_result.value(6), 32767);
2760
2761 assert!(!int32_result.is_null(7));
2764 assert_eq!(int32_result.value(7), 2147483647);
2765
2766 assert!(int32_result.is_null(8));
2769
2770 let non_nullable_field = Arc::new(Field::new("result", DataType::Int32, false));
2772 let options_non_nullable = GetOptions {
2773 path: VariantPath::try_from("x").unwrap(),
2774 as_type: Some(non_nullable_field.clone()),
2775 cast_options: CastOptions::default(), };
2777
2778 let variant_array_2 = json_to_variant(&string_array).unwrap();
2780 let variant_array_ref_2 = ArrayRef::from(variant_array_2);
2781 let result_non_nullable = variant_get(&variant_array_ref_2, options_non_nullable).unwrap();
2782 let int32_result_2 = result_non_nullable
2783 .as_any()
2784 .downcast_ref::<Int32Array>()
2785 .unwrap();
2786
2787 assert_eq!(int32_result_2.len(), 9);
2789
2790 assert!(!int32_result_2.is_null(0));
2792 assert_eq!(int32_result_2.value(0), 42);
2793
2794 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);
2804 assert!(!int32_result_2.is_null(6)); assert_eq!(int32_result_2.value(6), 32767);
2806 assert!(!int32_result_2.is_null(7)); assert_eq!(int32_result_2.value(7), 2147483647);
2808
2809 assert!(int32_result_2.is_null(8)); }
2812
2813 #[test]
2814 fn test_struct_extraction_subset_superset_schema_perfectly_shredded() {
2815 let variant_array = create_comprehensive_shredded_variant();
2817
2818 let struct_fields = Fields::from(vec![
2820 Field::new("a", DataType::Int32, true),
2821 Field::new("b", DataType::Int32, true),
2822 Field::new("d", DataType::Int32, true),
2823 ]);
2824 let struct_type = DataType::Struct(struct_fields);
2825
2826 let options = GetOptions {
2827 path: VariantPath::default(),
2828 as_type: Some(Arc::new(Field::new("result", struct_type, true))),
2829 cast_options: CastOptions::default(),
2830 };
2831
2832 let result = variant_get(&variant_array, options).unwrap();
2833
2834 let struct_result = result.as_any().downcast_ref::<StructArray>().unwrap();
2836 assert_eq!(struct_result.len(), 5);
2837 assert_eq!(struct_result.num_columns(), 3);
2838
2839 let field_a = struct_result
2840 .column(0)
2841 .as_any()
2842 .downcast_ref::<Int32Array>()
2843 .unwrap();
2844 let field_b = struct_result
2845 .column(1)
2846 .as_any()
2847 .downcast_ref::<Int32Array>()
2848 .unwrap();
2849 let field_d = struct_result
2850 .column(2)
2851 .as_any()
2852 .downcast_ref::<Int32Array>()
2853 .unwrap();
2854
2855 assert!(!struct_result.is_null(0));
2857 assert_eq!(field_a.value(0), 1);
2858 assert_eq!(field_b.value(0), 2);
2859 assert!(field_d.is_null(0)); assert!(struct_result.is_null(1));
2863
2864 assert!(!struct_result.is_null(2));
2866 assert!(field_a.is_null(2)); assert_eq!(field_b.value(2), 2);
2868 assert!(field_d.is_null(2)); assert!(!struct_result.is_null(3));
2872 assert_eq!(field_a.value(3), 1);
2873 assert!(field_b.is_null(3)); assert!(field_d.is_null(3)); assert!(!struct_result.is_null(4));
2878 assert!(field_a.is_null(4)); assert!(field_b.is_null(4)); assert!(field_d.is_null(4)); }
2882
2883 #[test]
2884 fn test_nested_struct_extraction_perfectly_shredded() {
2885 let variant_array = create_comprehensive_nested_shredded_variant();
2887 println!("variant_array: {variant_array:?}");
2888
2889 let inner_field = Field::new("inner", DataType::Int32, true);
2891 let inner_type = DataType::Struct(Fields::from(vec![inner_field]));
2892 let outer_field = Field::new("outer", inner_type, true);
2893 let result_type = DataType::Struct(Fields::from(vec![outer_field]));
2894
2895 let options = GetOptions {
2896 path: VariantPath::default(),
2897 as_type: Some(Arc::new(Field::new("result", result_type, true))),
2898 cast_options: CastOptions::default(),
2899 };
2900
2901 let result = variant_get(&variant_array, options).unwrap();
2902 println!("result: {result:?}");
2903
2904 let outer_struct = result.as_any().downcast_ref::<StructArray>().unwrap();
2906 assert_eq!(outer_struct.len(), 4);
2907 assert_eq!(outer_struct.num_columns(), 1);
2908
2909 let inner_struct = outer_struct
2911 .column(0)
2912 .as_any()
2913 .downcast_ref::<StructArray>()
2914 .unwrap();
2915 assert_eq!(inner_struct.num_columns(), 1);
2916
2917 let leaf_field = inner_struct
2919 .column(0)
2920 .as_any()
2921 .downcast_ref::<Int32Array>()
2922 .unwrap();
2923
2924 assert!(!outer_struct.is_null(0));
2926 assert!(!inner_struct.is_null(0));
2927 assert_eq!(leaf_field.value(0), 42);
2928
2929 assert!(!outer_struct.is_null(1));
2931 assert!(!inner_struct.is_null(1)); assert!(leaf_field.is_null(1)); assert!(!outer_struct.is_null(2));
2936 assert!(inner_struct.is_null(2)); assert!(outer_struct.is_null(3));
2940 }
2941
2942 #[test]
2943 fn test_path_based_null_masks_one_step() {
2944 let variant_array = create_comprehensive_nested_shredded_variant();
2946
2947 let path = VariantPath::try_from("outer").unwrap();
2949 let inner_field = Field::new("inner", DataType::Int32, true);
2950 let result_type = DataType::Struct(Fields::from(vec![inner_field]));
2951
2952 let options = GetOptions {
2953 path,
2954 as_type: Some(Arc::new(Field::new("result", result_type, true))),
2955 cast_options: CastOptions::default(),
2956 };
2957
2958 let result = variant_get(&variant_array, options).unwrap();
2959
2960 let outer_result = result.as_any().downcast_ref::<StructArray>().unwrap();
2962 assert_eq!(outer_result.len(), 4);
2963 assert_eq!(outer_result.num_columns(), 1);
2964
2965 let inner_field = outer_result
2967 .column(0)
2968 .as_any()
2969 .downcast_ref::<Int32Array>()
2970 .unwrap();
2971
2972 assert!(!outer_result.is_null(0));
2974 assert_eq!(inner_field.value(0), 42);
2975
2976 assert!(!outer_result.is_null(1));
2978 assert!(inner_field.is_null(1));
2979
2980 assert!(outer_result.is_null(2));
2982
2983 assert!(outer_result.is_null(3));
2985 }
2986
2987 #[test]
2988 fn test_path_based_null_masks_two_steps() {
2989 let variant_array = create_comprehensive_nested_shredded_variant();
2991
2992 let path = VariantPath::try_from("outer").unwrap().join("inner");
2994
2995 let options = GetOptions {
2996 path,
2997 as_type: Some(Arc::new(Field::new("result", DataType::Int32, true))),
2998 cast_options: CastOptions::default(),
2999 };
3000
3001 let result = variant_get(&variant_array, options).unwrap();
3002
3003 let int_result = result.as_any().downcast_ref::<Int32Array>().unwrap();
3005 assert_eq!(int_result.len(), 4);
3006
3007 assert!(!int_result.is_null(0));
3009 assert_eq!(int_result.value(0), 42);
3010
3011 assert!(int_result.is_null(1));
3013
3014 assert!(int_result.is_null(2));
3016
3017 assert!(int_result.is_null(3));
3019 }
3020
3021 #[test]
3022 fn test_struct_extraction_mixed_and_unshredded() {
3023 let variant_array = create_mixed_and_unshredded_variant();
3025
3026 let struct_fields = Fields::from(vec![
3028 Field::new("x", DataType::Int32, true),
3029 Field::new("y", DataType::Int32, true),
3030 ]);
3031 let struct_type = DataType::Struct(struct_fields);
3032
3033 let options = GetOptions {
3034 path: VariantPath::default(),
3035 as_type: Some(Arc::new(Field::new("result", struct_type, true))),
3036 cast_options: CastOptions::default(),
3037 };
3038
3039 let result = variant_get(&variant_array, options).unwrap();
3040
3041 let struct_result = result.as_any().downcast_ref::<StructArray>().unwrap();
3043 assert_eq!(struct_result.len(), 4);
3044 assert_eq!(struct_result.num_columns(), 2);
3045
3046 let field_x = struct_result
3047 .column(0)
3048 .as_any()
3049 .downcast_ref::<Int32Array>()
3050 .unwrap();
3051 let field_y = struct_result
3052 .column(1)
3053 .as_any()
3054 .downcast_ref::<Int32Array>()
3055 .unwrap();
3056
3057 assert_eq!(field_x.value(0), 1);
3059 assert_eq!(field_y.value(0), 42);
3060
3061 assert_eq!(field_x.value(1), 2);
3063 assert!(field_y.is_null(1));
3064
3065 assert_eq!(field_x.value(2), 3);
3067 assert!(field_y.is_null(2));
3068
3069 assert!(struct_result.is_null(3));
3071 }
3072
3073 #[test]
3074 fn test_struct_row_builder_handles_unshredded_nested_structs() {
3075 let json_strings = vec![
3077 r#"{"outer": {"inner": 42}}"#,
3078 r#"{"outer": {"inner": 100}}"#,
3079 ];
3080 let string_array: Arc<dyn Array> = Arc::new(StringArray::from(json_strings));
3081 let variant_array = json_to_variant(&string_array).unwrap();
3082
3083 let inner_fields = Fields::from(vec![Field::new("inner", DataType::Int32, true)]);
3085 let inner_struct_type = DataType::Struct(inner_fields);
3086 let outer_fields = Fields::from(vec![Field::new("outer", inner_struct_type, true)]);
3087 let outer_struct_type = DataType::Struct(outer_fields);
3088
3089 let options = GetOptions {
3090 path: VariantPath::default(),
3091 as_type: Some(Arc::new(Field::new("result", outer_struct_type, true))),
3092 cast_options: CastOptions::default(),
3093 };
3094
3095 let variant_array_ref = ArrayRef::from(variant_array);
3096 let result = variant_get(&variant_array_ref, options).unwrap();
3097
3098 let outer_struct = result.as_struct();
3099 assert_eq!(outer_struct.len(), 2);
3100 assert_eq!(outer_struct.num_columns(), 1);
3101
3102 let inner_struct = outer_struct.column(0).as_struct();
3103 assert_eq!(inner_struct.num_columns(), 1);
3104
3105 let inner_values = inner_struct
3106 .column(0)
3107 .as_any()
3108 .downcast_ref::<Int32Array>()
3109 .unwrap();
3110 assert_eq!(inner_values.value(0), 42);
3111 assert_eq!(inner_values.value(1), 100);
3112 }
3113
3114 fn create_comprehensive_shredded_variant() -> ArrayRef {
3117 let (metadata, _) = {
3118 let mut builder = parquet_variant::VariantBuilder::new();
3119 let obj = builder.new_object();
3120 obj.finish();
3121 builder.finish()
3122 };
3123
3124 let nulls = NullBuffer::from(vec![
3126 true, false, true, true, true, ]);
3132
3133 let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 5));
3134
3135 let a_field_typed_value = Int32Array::from(vec![Some(1), None, None, Some(1), None]);
3138 let a_field_shredded = ShreddedVariantFieldArray::from_parts(
3139 None,
3140 Some(Arc::new(a_field_typed_value) as ArrayRef),
3141 None,
3142 );
3143
3144 let b_field_typed_value = Int32Array::from(vec![Some(2), None, Some(2), None, None]);
3146 let b_field_shredded = ShreddedVariantFieldArray::from_parts(
3147 None,
3148 Some(Arc::new(b_field_typed_value) as ArrayRef),
3149 None,
3150 );
3151
3152 let c_field_typed_value = Int32Array::from(vec![Some(3), None, None, None, None]);
3154 let c_field_shredded = ShreddedVariantFieldArray::from_parts(
3155 None,
3156 Some(Arc::new(c_field_typed_value) as ArrayRef),
3157 None,
3158 );
3159
3160 let typed_value_fields = Fields::from(vec![
3162 Field::new("a", a_field_shredded.data_type().clone(), true),
3163 Field::new("b", b_field_shredded.data_type().clone(), true),
3164 Field::new("c", c_field_shredded.data_type().clone(), true),
3165 ]);
3166 let typed_value_struct = StructArray::try_new(
3167 typed_value_fields,
3168 vec![
3169 ArrayRef::from(a_field_shredded),
3170 ArrayRef::from(b_field_shredded),
3171 ArrayRef::from(c_field_shredded),
3172 ],
3173 None,
3174 )
3175 .unwrap();
3176
3177 ArrayRef::from(VariantArray::from_parts(
3179 metadata_array,
3180 None,
3181 Some(Arc::new(typed_value_struct)),
3182 Some(nulls),
3183 ))
3184 }
3185
3186 fn create_comprehensive_nested_shredded_variant() -> ArrayRef {
3191 let inner_typed_value = Int32Array::from(vec![Some(42), None, None, None]); let inner = ShreddedVariantFieldArray::from_parts(
3195 None,
3196 Some(Arc::new(inner_typed_value) as ArrayRef),
3197 None,
3198 );
3199
3200 let outer_typed_value_nulls = NullBuffer::from(vec![
3201 true, false, false, false, ]);
3206 let outer_typed_value = StructArrayBuilder::new()
3207 .with_field("inner", ArrayRef::from(inner), false)
3208 .with_nulls(outer_typed_value_nulls)
3209 .build();
3210
3211 let outer = ShreddedVariantFieldArray::from_parts(
3212 None,
3213 Some(Arc::new(outer_typed_value) as ArrayRef),
3214 None,
3215 );
3216
3217 let typed_value_nulls = NullBuffer::from(vec![
3218 true, true, false, false, ]);
3223 let typed_value = StructArrayBuilder::new()
3224 .with_field("outer", ArrayRef::from(outer), false)
3225 .with_nulls(typed_value_nulls)
3226 .build();
3227
3228 let metadata_array =
3230 BinaryViewArray::from_iter_values(std::iter::repeat_n(EMPTY_VARIANT_METADATA_BYTES, 4));
3231 let nulls = NullBuffer::from(vec![
3232 true, true, true, false, ]);
3237 ArrayRef::from(VariantArray::from_parts(
3238 metadata_array,
3239 None,
3240 Some(Arc::new(typed_value)),
3241 Some(nulls),
3242 ))
3243 }
3244
3245 fn create_mixed_and_unshredded_variant() -> ArrayRef {
3248 let (metadata, y_field_value) = {
3253 let mut builder = parquet_variant::VariantBuilder::new();
3254 let mut obj = builder.new_object();
3255 obj.insert("y", Variant::from(42));
3256 obj.finish();
3257 builder.finish()
3258 };
3259
3260 let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 4));
3261
3262 let empty_object_value = {
3269 let mut builder = parquet_variant::VariantBuilder::new();
3270 builder.new_object().finish();
3271 let (_, value) = builder.finish();
3272 value
3273 };
3274
3275 let y_null_value = {
3276 let mut builder = parquet_variant::VariantBuilder::new();
3277 builder.new_object().with_field("y", Variant::Null).finish();
3278 let (_, value) = builder.finish();
3279 value
3280 };
3281
3282 let value_array = BinaryViewArray::from(vec![
3283 Some(y_field_value.as_slice()), Some(empty_object_value.as_slice()), Some(y_null_value.as_slice()), Some(empty_object_value.as_slice()), ]);
3288
3289 let x_field_typed_value = Int32Array::from(vec![Some(1), Some(2), Some(3), Some(0)]);
3292 let x_field_shredded = ShreddedVariantFieldArray::from_parts(
3293 None,
3294 Some(Arc::new(x_field_typed_value) as ArrayRef),
3295 None,
3296 );
3297
3298 let typed_value_struct = StructArrayBuilder::new()
3300 .with_field("x", ArrayRef::from(x_field_shredded), false)
3301 .build();
3302
3303 let variant_nulls = NullBuffer::from(vec![true, true, true, false]); ArrayRef::from(VariantArray::from_parts(
3307 metadata_array,
3308 Some(value_array),
3309 Some(Arc::new(typed_value_struct)),
3310 Some(variant_nulls),
3311 ))
3312 }
3313
3314 #[test]
3315 fn get_decimal32_rescaled_to_scale2() {
3316 let mut builder = crate::VariantArrayBuilder::new(5);
3318 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();
3322 builder.append_variant(
3323 VariantDecimal8::try_new((VariantDecimal4::MAX_UNSCALED_VALUE as i64) + 1, 3)
3324 .unwrap()
3325 .into(),
3326 ); let variant_array: ArrayRef = ArrayRef::from(builder.build());
3328
3329 let field = Field::new("result", DataType::Decimal32(9, 2), true);
3330 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3331 let result = variant_get(&variant_array, options).unwrap();
3332 let result = result.as_any().downcast_ref::<Decimal32Array>().unwrap();
3333
3334 assert_eq!(result.precision(), 9);
3335 assert_eq!(result.scale(), 2);
3336 assert_eq!(result.value(0), 1234);
3337 assert_eq!(result.value(1), 123);
3338 assert_eq!(result.value(2), 123400);
3339 assert!(result.is_null(3));
3340 assert_eq!(
3341 result.value(4),
3342 VariantDecimal4::MAX_UNSCALED_VALUE / 10 + 1
3343 ); }
3345
3346 #[test]
3347 fn get_decimal32_scale_down_rounding() {
3348 let mut builder = crate::VariantArrayBuilder::new(7);
3349 builder.append_variant(VariantDecimal4::try_new(1235, 0).unwrap().into());
3350 builder.append_variant(VariantDecimal4::try_new(1245, 0).unwrap().into());
3351 builder.append_variant(VariantDecimal4::try_new(-1235, 0).unwrap().into());
3352 builder.append_variant(VariantDecimal4::try_new(-1245, 0).unwrap().into());
3353 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());
3357
3358 let field = Field::new("result", DataType::Decimal32(9, -1), true);
3359 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3360 let result = variant_get(&variant_array, options).unwrap();
3361 let result = result.as_any().downcast_ref::<Decimal32Array>().unwrap();
3362
3363 assert_eq!(result.precision(), 9);
3364 assert_eq!(result.scale(), -1);
3365 assert_eq!(result.value(0), 124);
3366 assert_eq!(result.value(1), 125);
3367 assert_eq!(result.value(2), -124);
3368 assert_eq!(result.value(3), -125);
3369 assert_eq!(result.value(4), 1);
3370 assert!(result.is_valid(5));
3371 assert_eq!(result.value(5), 0);
3372 assert_eq!(result.value(6), 1);
3373 }
3374
3375 #[test]
3376 fn get_decimal32_large_scale_reduction() {
3377 let mut builder = crate::VariantArrayBuilder::new(2);
3378 builder.append_variant(
3379 VariantDecimal4::try_new(-VariantDecimal4::MAX_UNSCALED_VALUE, 0)
3380 .unwrap()
3381 .into(),
3382 );
3383 builder.append_variant(
3384 VariantDecimal4::try_new(VariantDecimal4::MAX_UNSCALED_VALUE, 0)
3385 .unwrap()
3386 .into(),
3387 );
3388 let variant_array: ArrayRef = ArrayRef::from(builder.build());
3389
3390 let field = Field::new("result", DataType::Decimal32(9, -9), true);
3391 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3392 let result = variant_get(&variant_array, options).unwrap();
3393 let result = result.as_any().downcast_ref::<Decimal32Array>().unwrap();
3394
3395 assert_eq!(result.precision(), 9);
3396 assert_eq!(result.scale(), -9);
3397 assert_eq!(result.value(0), -1);
3398 assert_eq!(result.value(1), 1);
3399
3400 let field = Field::new("result", DataType::Decimal32(9, -10), true);
3401 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3402 let result = variant_get(&variant_array, options).unwrap();
3403 let result = result.as_any().downcast_ref::<Decimal32Array>().unwrap();
3404
3405 assert_eq!(result.precision(), 9);
3406 assert_eq!(result.scale(), -10);
3407 assert!(result.is_valid(0));
3408 assert_eq!(result.value(0), 0);
3409 assert!(result.is_valid(1));
3410 assert_eq!(result.value(1), 0);
3411 }
3412
3413 #[test]
3414 fn get_decimal32_precision_overflow_safe() {
3415 let mut builder = crate::VariantArrayBuilder::new(2);
3417 builder.append_variant(
3418 VariantDecimal4::try_new(VariantDecimal4::MAX_UNSCALED_VALUE, 0)
3419 .unwrap()
3420 .into(),
3421 );
3422 builder.append_variant(
3423 VariantDecimal4::try_new(VariantDecimal4::MAX_UNSCALED_VALUE, 9)
3424 .unwrap()
3425 .into(),
3426 ); let variant_array: ArrayRef = ArrayRef::from(builder.build());
3428
3429 let field = Field::new("result", DataType::Decimal32(2, 2), true);
3430 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3431 let result = variant_get(&variant_array, options).unwrap();
3432 let result = result.as_any().downcast_ref::<Decimal32Array>().unwrap();
3433
3434 assert!(result.is_null(0));
3435 assert!(result.is_null(1)); }
3437
3438 #[test]
3439 fn get_decimal32_precision_overflow_unsafe_errors() {
3440 let mut builder = crate::VariantArrayBuilder::new(1);
3441 builder.append_variant(
3442 VariantDecimal4::try_new(VariantDecimal4::MAX_UNSCALED_VALUE, 0)
3443 .unwrap()
3444 .into(),
3445 );
3446 let variant_array: ArrayRef = ArrayRef::from(builder.build());
3447
3448 let field = Field::new("result", DataType::Decimal32(9, 2), true);
3449 let cast_options = CastOptions {
3450 safe: false,
3451 ..Default::default()
3452 };
3453 let options = GetOptions::new()
3454 .with_as_type(Some(FieldRef::from(field)))
3455 .with_cast_options(cast_options);
3456 let err = variant_get(&variant_array, options).unwrap_err();
3457
3458 assert!(
3459 err.to_string().contains(
3460 "Failed to cast to Decimal32(precision=9, scale=2) from variant Decimal4"
3461 )
3462 );
3463 }
3464
3465 #[test]
3466 fn get_decimal64_rescaled_to_scale2() {
3467 let mut builder = crate::VariantArrayBuilder::new(5);
3468 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();
3472 builder.append_variant(
3473 VariantDecimal16::try_new((VariantDecimal8::MAX_UNSCALED_VALUE as i128) + 1, 3)
3474 .unwrap()
3475 .into(),
3476 ); let variant_array: ArrayRef = ArrayRef::from(builder.build());
3478
3479 let field = Field::new("result", DataType::Decimal64(18, 2), true);
3480 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3481 let result = variant_get(&variant_array, options).unwrap();
3482 let result = result.as_any().downcast_ref::<Decimal64Array>().unwrap();
3483
3484 assert_eq!(result.precision(), 18);
3485 assert_eq!(result.scale(), 2);
3486 assert_eq!(result.value(0), 1234);
3487 assert_eq!(result.value(1), 123);
3488 assert_eq!(result.value(2), 123400);
3489 assert!(result.is_null(3));
3490 assert_eq!(
3491 result.value(4),
3492 VariantDecimal8::MAX_UNSCALED_VALUE / 10 + 1
3493 ); }
3495
3496 #[test]
3497 fn get_decimal64_scale_down_rounding() {
3498 let mut builder = crate::VariantArrayBuilder::new(7);
3499 builder.append_variant(VariantDecimal8::try_new(1235, 0).unwrap().into());
3500 builder.append_variant(VariantDecimal8::try_new(1245, 0).unwrap().into());
3501 builder.append_variant(VariantDecimal8::try_new(-1235, 0).unwrap().into());
3502 builder.append_variant(VariantDecimal8::try_new(-1245, 0).unwrap().into());
3503 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());
3507
3508 let field = Field::new("result", DataType::Decimal64(18, -1), true);
3509 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3510 let result = variant_get(&variant_array, options).unwrap();
3511 let result = result.as_any().downcast_ref::<Decimal64Array>().unwrap();
3512
3513 assert_eq!(result.precision(), 18);
3514 assert_eq!(result.scale(), -1);
3515 assert_eq!(result.value(0), 124);
3516 assert_eq!(result.value(1), 125);
3517 assert_eq!(result.value(2), -124);
3518 assert_eq!(result.value(3), -125);
3519 assert_eq!(result.value(4), 1);
3520 assert!(result.is_valid(5));
3521 assert_eq!(result.value(5), 0);
3522 assert_eq!(result.value(6), 1);
3523 }
3524
3525 #[test]
3526 fn get_decimal64_large_scale_reduction() {
3527 let mut builder = crate::VariantArrayBuilder::new(2);
3528 builder.append_variant(
3529 VariantDecimal8::try_new(-VariantDecimal8::MAX_UNSCALED_VALUE, 0)
3530 .unwrap()
3531 .into(),
3532 );
3533 builder.append_variant(
3534 VariantDecimal8::try_new(VariantDecimal8::MAX_UNSCALED_VALUE, 0)
3535 .unwrap()
3536 .into(),
3537 );
3538 let variant_array: ArrayRef = ArrayRef::from(builder.build());
3539
3540 let field = Field::new("result", DataType::Decimal64(18, -18), true);
3541 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3542 let result = variant_get(&variant_array, options).unwrap();
3543 let result = result.as_any().downcast_ref::<Decimal64Array>().unwrap();
3544
3545 assert_eq!(result.precision(), 18);
3546 assert_eq!(result.scale(), -18);
3547 assert_eq!(result.value(0), -1);
3548 assert_eq!(result.value(1), 1);
3549
3550 let field = Field::new("result", DataType::Decimal64(18, -19), true);
3551 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3552 let result = variant_get(&variant_array, options).unwrap();
3553 let result = result.as_any().downcast_ref::<Decimal64Array>().unwrap();
3554
3555 assert_eq!(result.precision(), 18);
3556 assert_eq!(result.scale(), -19);
3557 assert!(result.is_valid(0));
3558 assert_eq!(result.value(0), 0);
3559 assert!(result.is_valid(1));
3560 assert_eq!(result.value(1), 0);
3561 }
3562
3563 #[test]
3564 fn get_decimal64_precision_overflow_safe() {
3565 let mut builder = crate::VariantArrayBuilder::new(2);
3567 builder.append_variant(
3568 VariantDecimal8::try_new(VariantDecimal8::MAX_UNSCALED_VALUE, 0)
3569 .unwrap()
3570 .into(),
3571 );
3572 builder.append_variant(
3573 VariantDecimal8::try_new(VariantDecimal8::MAX_UNSCALED_VALUE, 18)
3574 .unwrap()
3575 .into(),
3576 ); let variant_array: ArrayRef = ArrayRef::from(builder.build());
3578
3579 let field = Field::new("result", DataType::Decimal64(2, 2), true);
3580 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3581 let result = variant_get(&variant_array, options).unwrap();
3582 let result = result.as_any().downcast_ref::<Decimal64Array>().unwrap();
3583
3584 assert!(result.is_null(0));
3585 assert!(result.is_null(1));
3586 }
3587
3588 #[test]
3589 fn get_decimal64_precision_overflow_unsafe_errors() {
3590 let mut builder = crate::VariantArrayBuilder::new(1);
3591 builder.append_variant(
3592 VariantDecimal8::try_new(VariantDecimal8::MAX_UNSCALED_VALUE, 0)
3593 .unwrap()
3594 .into(),
3595 );
3596 let variant_array: ArrayRef = ArrayRef::from(builder.build());
3597
3598 let field = Field::new("result", DataType::Decimal64(18, 2), true);
3599 let cast_options = CastOptions {
3600 safe: false,
3601 ..Default::default()
3602 };
3603 let options = GetOptions::new()
3604 .with_as_type(Some(FieldRef::from(field)))
3605 .with_cast_options(cast_options);
3606 let err = variant_get(&variant_array, options).unwrap_err();
3607
3608 assert!(
3609 err.to_string().contains(
3610 "Failed to cast to Decimal64(precision=18, scale=2) from variant Decimal8"
3611 )
3612 );
3613 }
3614
3615 #[test]
3616 fn get_decimal128_rescaled_to_scale2() {
3617 let mut builder = crate::VariantArrayBuilder::new(4);
3618 builder.append_variant(VariantDecimal16::try_new(1234, 2).unwrap().into());
3619 builder.append_variant(VariantDecimal16::try_new(1234, 3).unwrap().into());
3620 builder.append_variant(VariantDecimal16::try_new(1234, 0).unwrap().into());
3621 builder.append_null();
3622 let variant_array: ArrayRef = ArrayRef::from(builder.build());
3623
3624 let field = Field::new("result", DataType::Decimal128(38, 2), true);
3625 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3626 let result = variant_get(&variant_array, options).unwrap();
3627 let result = result.as_any().downcast_ref::<Decimal128Array>().unwrap();
3628
3629 assert_eq!(result.precision(), 38);
3630 assert_eq!(result.scale(), 2);
3631 assert_eq!(result.value(0), 1234);
3632 assert_eq!(result.value(1), 123);
3633 assert_eq!(result.value(2), 123400);
3634 assert!(result.is_null(3));
3635 }
3636
3637 #[test]
3638 fn get_decimal128_scale_down_rounding() {
3639 let mut builder = crate::VariantArrayBuilder::new(7);
3640 builder.append_variant(VariantDecimal16::try_new(1235, 0).unwrap().into());
3641 builder.append_variant(VariantDecimal16::try_new(1245, 0).unwrap().into());
3642 builder.append_variant(VariantDecimal16::try_new(-1235, 0).unwrap().into());
3643 builder.append_variant(VariantDecimal16::try_new(-1245, 0).unwrap().into());
3644 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());
3648
3649 let field = Field::new("result", DataType::Decimal128(38, -1), true);
3650 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3651 let result = variant_get(&variant_array, options).unwrap();
3652 let result = result.as_any().downcast_ref::<Decimal128Array>().unwrap();
3653
3654 assert_eq!(result.precision(), 38);
3655 assert_eq!(result.scale(), -1);
3656 assert_eq!(result.value(0), 124);
3657 assert_eq!(result.value(1), 125);
3658 assert_eq!(result.value(2), -124);
3659 assert_eq!(result.value(3), -125);
3660 assert_eq!(result.value(4), 1);
3661 assert!(result.is_valid(5));
3662 assert_eq!(result.value(5), 0);
3663 assert_eq!(result.value(6), 1);
3664 }
3665
3666 #[test]
3667 fn get_decimal128_precision_overflow_safe() {
3668 let mut builder = crate::VariantArrayBuilder::new(2);
3670 builder.append_variant(
3671 VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 0)
3672 .unwrap()
3673 .into(),
3674 );
3675 builder.append_variant(
3676 VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 38)
3677 .unwrap()
3678 .into(),
3679 ); let variant_array: ArrayRef = ArrayRef::from(builder.build());
3681
3682 let field = Field::new("result", DataType::Decimal128(2, 2), true);
3683 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3684 let result = variant_get(&variant_array, options).unwrap();
3685 let result = result.as_any().downcast_ref::<Decimal128Array>().unwrap();
3686
3687 assert!(result.is_null(0));
3688 assert!(result.is_null(1)); }
3690
3691 #[test]
3692 fn get_decimal128_precision_overflow_unsafe_errors() {
3693 let mut builder = crate::VariantArrayBuilder::new(1);
3694 builder.append_variant(
3695 VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 0)
3696 .unwrap()
3697 .into(),
3698 );
3699 let variant_array: ArrayRef = ArrayRef::from(builder.build());
3700
3701 let field = Field::new("result", DataType::Decimal128(38, 2), true);
3702 let cast_options = CastOptions {
3703 safe: false,
3704 ..Default::default()
3705 };
3706 let options = GetOptions::new()
3707 .with_as_type(Some(FieldRef::from(field)))
3708 .with_cast_options(cast_options);
3709 let err = variant_get(&variant_array, options).unwrap_err();
3710
3711 assert!(err.to_string().contains(
3712 "Failed to cast to Decimal128(precision=38, scale=2) from variant Decimal16"
3713 ));
3714 }
3715
3716 #[test]
3717 fn get_decimal256_rescaled_to_scale2() {
3718 let mut builder = crate::VariantArrayBuilder::new(4);
3720 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();
3724 let variant_array: ArrayRef = ArrayRef::from(builder.build());
3725
3726 let field = Field::new("result", DataType::Decimal256(76, 2), true);
3727 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3728 let result = variant_get(&variant_array, options).unwrap();
3729 let result = result.as_any().downcast_ref::<Decimal256Array>().unwrap();
3730
3731 assert_eq!(result.precision(), 76);
3732 assert_eq!(result.scale(), 2);
3733 assert_eq!(result.value(0), i256::from_i128(1234));
3734 assert_eq!(result.value(1), i256::from_i128(123));
3735 assert_eq!(result.value(2), i256::from_i128(123400));
3736 assert!(result.is_null(3));
3737 }
3738
3739 #[test]
3740 fn get_decimal256_scale_down_rounding() {
3741 let mut builder = crate::VariantArrayBuilder::new(7);
3742 builder.append_variant(VariantDecimal16::try_new(1235, 0).unwrap().into());
3743 builder.append_variant(VariantDecimal16::try_new(1245, 0).unwrap().into());
3744 builder.append_variant(VariantDecimal16::try_new(-1235, 0).unwrap().into());
3745 builder.append_variant(VariantDecimal16::try_new(-1245, 0).unwrap().into());
3746 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());
3750
3751 let field = Field::new("result", DataType::Decimal256(76, -1), true);
3752 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3753 let result = variant_get(&variant_array, options).unwrap();
3754 let result = result.as_any().downcast_ref::<Decimal256Array>().unwrap();
3755
3756 assert_eq!(result.precision(), 76);
3757 assert_eq!(result.scale(), -1);
3758 assert_eq!(result.value(0), i256::from_i128(124));
3759 assert_eq!(result.value(1), i256::from_i128(125));
3760 assert_eq!(result.value(2), i256::from_i128(-124));
3761 assert_eq!(result.value(3), i256::from_i128(-125));
3762 assert_eq!(result.value(4), i256::from_i128(1));
3763 assert!(result.is_valid(5));
3764 assert_eq!(result.value(5), i256::from_i128(0));
3765 assert_eq!(result.value(6), i256::from_i128(1));
3766 }
3767
3768 #[test]
3769 fn get_decimal256_precision_overflow_safe() {
3770 let mut builder = crate::VariantArrayBuilder::new(2);
3772 builder.append_variant(
3773 VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 1)
3774 .unwrap()
3775 .into(),
3776 );
3777 builder.append_variant(
3778 VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 0)
3779 .unwrap()
3780 .into(),
3781 );
3782 let variant_array: ArrayRef = ArrayRef::from(builder.build());
3783
3784 let field = Field::new("result", DataType::Decimal256(76, 39), true);
3785 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3786 let result = variant_get(&variant_array, options).unwrap();
3787 let result = result.as_any().downcast_ref::<Decimal256Array>().unwrap();
3788
3789 let base = i256::from_i128(10);
3792 let factor = base.checked_pow(38).unwrap();
3793 let expected = i256::from_i128(VariantDecimal16::MAX_UNSCALED_VALUE)
3794 .checked_mul(factor)
3795 .unwrap();
3796 assert_eq!(result.value(0), expected);
3797 assert!(result.is_null(1));
3798 }
3799
3800 #[test]
3801 fn get_decimal256_precision_overflow_unsafe_errors() {
3802 let mut builder = crate::VariantArrayBuilder::new(2);
3804 builder.append_variant(
3805 VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 1)
3806 .unwrap()
3807 .into(),
3808 );
3809 builder.append_variant(
3810 VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 0)
3811 .unwrap()
3812 .into(),
3813 );
3814 let variant_array: ArrayRef = ArrayRef::from(builder.build());
3815
3816 let field = Field::new("result", DataType::Decimal256(76, 39), true);
3817 let cast_options = CastOptions {
3818 safe: false,
3819 ..Default::default()
3820 };
3821 let options = GetOptions::new()
3822 .with_as_type(Some(FieldRef::from(field)))
3823 .with_cast_options(cast_options);
3824 let err = variant_get(&variant_array, options).unwrap_err();
3825
3826 assert!(err.to_string().contains(
3827 "Failed to cast to Decimal256(precision=76, scale=39) from variant Decimal16"
3828 ));
3829 }
3830
3831 #[test]
3832 fn get_non_supported_temporal_types_error() {
3833 let values = vec![None, Some(Variant::Null), Some(Variant::BooleanFalse)];
3834 let variant_array: ArrayRef = ArrayRef::from(VariantArray::from_iter(values));
3835
3836 let test_cases = vec![
3837 FieldRef::from(Field::new(
3838 "result",
3839 DataType::Duration(TimeUnit::Microsecond),
3840 true,
3841 )),
3842 FieldRef::from(Field::new(
3843 "result",
3844 DataType::Interval(IntervalUnit::YearMonth),
3845 true,
3846 )),
3847 ];
3848
3849 for field in test_cases {
3850 let options = GetOptions::new().with_as_type(Some(field));
3851 let err = variant_get(&variant_array, options).unwrap_err();
3852 assert!(
3853 err.to_string()
3854 .contains("Casting Variant to duration/interval types is not supported")
3855 );
3856 }
3857 }
3858
3859 fn invalid_time_variant_array() -> ArrayRef {
3860 let mut builder = VariantArrayBuilder::new(3);
3861 builder.append_variant(Variant::Int64(86401000000));
3863 builder.append_variant(Variant::Int64(86401000000));
3864 builder.append_variant(Variant::Int64(86401000000));
3865 Arc::new(builder.build().into_inner())
3866 }
3867
3868 #[test]
3869 fn test_variant_get_error_when_cast_failure_and_safe_false() {
3870 let variant_array = invalid_time_variant_array();
3871
3872 let field = Field::new("result", DataType::Time64(TimeUnit::Microsecond), true);
3873 let cast_options = CastOptions {
3874 safe: false, ..Default::default()
3876 };
3877 let options = GetOptions::new()
3878 .with_as_type(Some(FieldRef::from(field)))
3879 .with_cast_options(cast_options);
3880 let err = variant_get(&variant_array, options).unwrap_err();
3881 assert!(
3882 err.to_string().contains(
3883 "Cast error: Failed to extract primitive of type Time64(µs) from variant Int64(86401000000) at path VariantPath([])"
3884 ),
3885 "actual: {err}",
3886 );
3887 }
3888
3889 #[test]
3890 fn test_variant_get_return_null_when_cast_failure_and_safe_true() {
3891 let variant_array = invalid_time_variant_array();
3892
3893 let field = Field::new("result", DataType::Time64(TimeUnit::Microsecond), true);
3894 let cast_options = CastOptions {
3895 safe: true, ..Default::default()
3897 };
3898 let options = GetOptions::new()
3899 .with_as_type(Some(FieldRef::from(field)))
3900 .with_cast_options(cast_options);
3901 let result = variant_get(&variant_array, options).unwrap();
3902 assert_eq!(3, result.len());
3903
3904 for i in 0..3 {
3905 assert!(result.is_null(i));
3906 }
3907 }
3908
3909 #[test]
3910 fn test_perfect_shredding_returns_same_arc_ptr() {
3911 let variant_array = perfectly_shredded_int32_variant_array();
3912
3913 let variant_array_ref = VariantArray::try_new(&variant_array).unwrap();
3914 let typed_value_arc = variant_array_ref.typed_value_field().unwrap().clone();
3915
3916 let field = Field::new("result", DataType::Int32, true);
3917 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3918 let result = variant_get(&variant_array, options).unwrap();
3919
3920 assert!(Arc::ptr_eq(&typed_value_arc, &result));
3921 }
3922
3923 #[test]
3924 fn test_perfect_shredding_three_typed_value_columns() {
3925 let all_nulls_values: Arc<Int32Array> = Arc::new(Int32Array::from(vec![
3927 Option::<i32>::None,
3928 Option::<i32>::None,
3929 Option::<i32>::None,
3930 ]));
3931 let all_nulls_erased: ArrayRef = all_nulls_values.clone();
3932 let all_nulls_field =
3933 ShreddedVariantFieldArray::from_parts(None, Some(all_nulls_erased.clone()), None);
3934 let all_nulls_type = all_nulls_field.data_type().clone();
3935 let all_nulls_struct: ArrayRef = ArrayRef::from(all_nulls_field);
3936
3937 let some_nulls_values: Arc<Int32Array> =
3939 Arc::new(Int32Array::from(vec![Some(10), None, Some(30)]));
3940 let some_nulls_erased: ArrayRef = some_nulls_values.clone();
3941 let some_nulls_field =
3942 ShreddedVariantFieldArray::from_parts(None, Some(some_nulls_erased.clone()), None);
3943 let some_nulls_type = some_nulls_field.data_type().clone();
3944 let some_nulls_struct: ArrayRef = ArrayRef::from(some_nulls_field);
3945
3946 let inner_values: Arc<Int32Array> =
3948 Arc::new(Int32Array::from(vec![Some(111), None, Some(333)]));
3949 let inner_erased: ArrayRef = inner_values.clone();
3950 let inner_field =
3951 ShreddedVariantFieldArray::from_parts(None, Some(inner_erased.clone()), None);
3952 let inner_field_type = inner_field.data_type().clone();
3953 let inner_struct_array: ArrayRef = ArrayRef::from(inner_field);
3954
3955 let nested_struct = Arc::new(
3956 StructArray::try_new(
3957 Fields::from(vec![Field::new("inner", inner_field_type, true)]),
3958 vec![inner_struct_array],
3959 None,
3960 )
3961 .unwrap(),
3962 );
3963 let nested_struct_erased: ArrayRef = nested_struct.clone();
3964 let struct_field =
3965 ShreddedVariantFieldArray::from_parts(None, Some(nested_struct_erased.clone()), None);
3966 let struct_field_type = struct_field.data_type().clone();
3967 let struct_field_struct: ArrayRef = ArrayRef::from(struct_field);
3968
3969 let typed_value_struct = StructArray::try_new(
3971 Fields::from(vec![
3972 Field::new("all_nulls", all_nulls_type, true),
3973 Field::new("some_nulls", some_nulls_type, true),
3974 Field::new("struct_field", struct_field_type, true),
3975 ]),
3976 vec![all_nulls_struct, some_nulls_struct, struct_field_struct],
3977 None,
3978 )
3979 .unwrap();
3980
3981 let metadata = BinaryViewArray::from_iter_values(std::iter::repeat_n(
3982 EMPTY_VARIANT_METADATA_BYTES,
3983 all_nulls_values.len(),
3984 ));
3985 let variant_array: ArrayRef =
3986 VariantArray::from_parts(metadata, None, Some(Arc::new(typed_value_struct)), None)
3987 .into();
3988
3989 let all_nulls_field_ref = FieldRef::from(Field::new("result", DataType::Int32, true));
3991 let all_nulls_result = variant_get(
3992 &variant_array,
3993 GetOptions::new_with_path(VariantPath::try_from("all_nulls").unwrap())
3994 .with_as_type(Some(all_nulls_field_ref)),
3995 )
3996 .unwrap();
3997 assert!(Arc::ptr_eq(&all_nulls_result, &all_nulls_erased));
3998
3999 let some_nulls_field_ref = FieldRef::from(Field::new("result", DataType::Int32, true));
4001 let some_nulls_result = variant_get(
4002 &variant_array,
4003 GetOptions::new_with_path(VariantPath::try_from("some_nulls").unwrap())
4004 .with_as_type(Some(some_nulls_field_ref)),
4005 )
4006 .unwrap();
4007 assert!(Arc::ptr_eq(&some_nulls_result, &some_nulls_erased));
4008
4009 let struct_child_fields = Fields::from(vec![Field::new("inner", DataType::Int32, true)]);
4011 let struct_field_ref = FieldRef::from(Field::new(
4012 "result",
4013 DataType::Struct(struct_child_fields.clone()),
4014 true,
4015 ));
4016 let struct_result = variant_get(
4017 &variant_array,
4018 GetOptions::new_with_path(VariantPath::try_from("struct_field").unwrap())
4019 .with_as_type(Some(struct_field_ref)),
4020 )
4021 .unwrap();
4022 let struct_array = struct_result
4023 .as_any()
4024 .downcast_ref::<StructArray>()
4025 .unwrap();
4026 assert_eq!(struct_array.len(), 3);
4027 assert_eq!(struct_array.null_count(), 0);
4028
4029 let inner_values_result = struct_array
4030 .column(0)
4031 .as_any()
4032 .downcast_ref::<Int32Array>()
4033 .unwrap();
4034 assert_eq!(inner_values_result.len(), 3);
4035 assert_eq!(inner_values_result.value(0), 111);
4036 assert!(inner_values_result.is_null(1));
4037 assert_eq!(inner_values_result.value(2), 333);
4038 }
4039
4040 #[test]
4041 fn test_variant_get_list_like_safe_cast() {
4042 let string_array: ArrayRef = Arc::new(StringArray::from(vec![
4043 r#"{"outer":{"list":[1, "two", 3]}}"#,
4044 r#"{"outer":{"list":"not a list"}}"#,
4045 ]));
4046 let variant_array = ArrayRef::from(json_to_variant(&string_array).unwrap());
4047
4048 let value_array: ArrayRef = {
4049 let mut builder = VariantBuilder::new();
4050 builder.append_value("two");
4051 let (_, value_bytes) = builder.finish();
4052 Arc::new(BinaryViewArray::from(vec![
4053 None,
4054 Some(value_bytes.as_slice()),
4055 None,
4056 ]))
4057 };
4058 let typed_value_array: ArrayRef = Arc::new(Int64Array::from(vec![Some(1), None, Some(3)]));
4059 let struct_fields = Fields::from(vec![
4060 Field::new("value", DataType::BinaryView, true),
4061 Field::new("typed_value", DataType::Int64, true),
4062 ]);
4063 let struct_array: ArrayRef = Arc::new(
4064 StructArray::try_new(
4065 struct_fields.clone(),
4066 vec![value_array.clone(), typed_value_array.clone()],
4067 None,
4068 )
4069 .unwrap(),
4070 );
4071
4072 let request_field = Arc::new(Field::new("item", DataType::Int64, true));
4073 let result_field = Arc::new(Field::new("item", DataType::Struct(struct_fields), true));
4074
4075 let expectations = vec![
4076 (
4077 DataType::List(request_field.clone()),
4078 Arc::new(ListArray::new(
4079 result_field.clone(),
4080 OffsetBuffer::new(ScalarBuffer::from(vec![0, 3, 3])),
4081 struct_array.clone(),
4082 Some(NullBuffer::from(vec![true, false])),
4083 )) as ArrayRef,
4084 ),
4085 (
4086 DataType::LargeList(request_field.clone()),
4087 Arc::new(LargeListArray::new(
4088 result_field.clone(),
4089 OffsetBuffer::new(ScalarBuffer::from(vec![0, 3, 3])),
4090 struct_array.clone(),
4091 Some(NullBuffer::from(vec![true, false])),
4092 )) as ArrayRef,
4093 ),
4094 (
4095 DataType::ListView(request_field.clone()),
4096 Arc::new(ListViewArray::new(
4097 result_field.clone(),
4098 ScalarBuffer::from(vec![0, 3]),
4099 ScalarBuffer::from(vec![3, 0]),
4100 struct_array.clone(),
4101 Some(NullBuffer::from(vec![true, false])),
4102 )) as ArrayRef,
4103 ),
4104 (
4105 DataType::LargeListView(request_field),
4106 Arc::new(LargeListViewArray::new(
4107 result_field,
4108 ScalarBuffer::from(vec![0, 3]),
4109 ScalarBuffer::from(vec![3, 0]),
4110 struct_array,
4111 Some(NullBuffer::from(vec![true, false])),
4112 )) as ArrayRef,
4113 ),
4114 ];
4115
4116 for (request_type, expected) in expectations {
4117 let options =
4118 GetOptions::new_with_path(VariantPath::try_from("outer").unwrap().join("list"))
4119 .with_as_type(Some(FieldRef::from(Field::new(
4120 "result",
4121 request_type.clone(),
4122 true,
4123 ))));
4124
4125 let result = variant_get(&variant_array, options).unwrap();
4126 assert_eq!(result.data_type(), expected.data_type());
4127 assert_eq!(&result, &expected);
4128 }
4129
4130 for (idx, expected) in [
4131 (0, vec![Some(1), None]),
4132 (1, vec![None, None]),
4133 (2, vec![Some(3), None]),
4134 ] {
4135 let index_options = GetOptions::new_with_path(
4136 VariantPath::try_from("outer")
4137 .unwrap()
4138 .join("list")
4139 .join(idx),
4140 )
4141 .with_as_type(Some(FieldRef::from(Field::new(
4142 "result",
4143 DataType::Int64,
4144 true,
4145 ))));
4146 let index_result = variant_get(&variant_array, index_options).unwrap();
4147 let index_expected: ArrayRef = Arc::new(Int64Array::from(expected));
4148 assert_eq!(&index_result, &index_expected);
4149 }
4150 }
4151
4152 #[test]
4153 fn test_variant_get_list_like_unsafe_cast_errors_on_element_mismatch() {
4154 let string_array: ArrayRef =
4155 Arc::new(StringArray::from(vec![r#"[1, "two", 3]"#, "[4, 5]"]));
4156 let variant_array = ArrayRef::from(json_to_variant(&string_array).unwrap());
4157 let cast_options = CastOptions {
4158 safe: false,
4159 ..Default::default()
4160 };
4161
4162 let item_field = Arc::new(Field::new("item", DataType::Int64, true));
4163 let request_types = vec![
4164 DataType::List(item_field.clone()),
4165 DataType::LargeList(item_field.clone()),
4166 DataType::ListView(item_field.clone()),
4167 DataType::LargeListView(item_field),
4168 ];
4169
4170 for request_type in request_types {
4171 let options = GetOptions::new()
4172 .with_as_type(Some(FieldRef::from(Field::new(
4173 "result",
4174 request_type.clone(),
4175 true,
4176 ))))
4177 .with_cast_options(cast_options.clone());
4178
4179 let err = variant_get(&variant_array, options).unwrap_err();
4180 assert!(
4181 err.to_string()
4182 .contains("Failed to extract primitive of type Int64")
4183 );
4184 }
4185 }
4186
4187 #[test]
4188 fn test_variant_get_list_like_unsafe_cast_errors_on_non_list() {
4189 let string_array: ArrayRef = Arc::new(StringArray::from(vec!["[1, 2]", "\"not a list\""]));
4190 let variant_array = ArrayRef::from(json_to_variant(&string_array).unwrap());
4191 let cast_options = CastOptions {
4192 safe: false,
4193 ..Default::default()
4194 };
4195 let item_field = Arc::new(Field::new("item", Int64, true));
4196 let data_types = vec![
4197 DataType::List(item_field.clone()),
4198 DataType::LargeList(item_field.clone()),
4199 DataType::ListView(item_field.clone()),
4200 DataType::LargeListView(item_field),
4201 ];
4202
4203 for data_type in data_types {
4204 let options = GetOptions::new()
4205 .with_as_type(Some(FieldRef::from(Field::new("result", data_type, true))))
4206 .with_cast_options(cast_options.clone());
4207
4208 let err = variant_get(&variant_array, options).unwrap_err();
4209 assert!(
4210 err.to_string()
4211 .contains("Failed to extract list from variant"),
4212 );
4213 }
4214 }
4215
4216 #[test]
4217 fn test_variant_get_fixed_size_list_not_implemented() {
4218 let string_array: ArrayRef = Arc::new(StringArray::from(vec!["[1, 2]", "\"not a list\""]));
4219 let variant_array = ArrayRef::from(json_to_variant(&string_array).unwrap());
4220 let item_field = Arc::new(Field::new("item", Int64, true));
4221 for safe in [true, false] {
4222 let options = GetOptions::new()
4223 .with_as_type(Some(FieldRef::from(Field::new(
4224 "result",
4225 DataType::FixedSizeList(item_field.clone(), 2),
4226 true,
4227 ))))
4228 .with_cast_options(CastOptions {
4229 safe,
4230 ..Default::default()
4231 });
4232
4233 let err = variant_get(&variant_array, options).unwrap_err();
4234 assert!(
4235 err.to_string()
4236 .contains("Converting unshredded variant arrays to arrow fixed-size lists")
4237 );
4238 }
4239 }
4240}