1use arrow::{
18 array::{self, Array, ArrayRef, StructArray, make_array},
19 buffer::NullBuffer,
20 compute::CastOptions,
21 datatypes::Field,
22 error::Result,
23};
24use arrow_schema::{ArrowError, DataType, FieldRef};
25use parquet_variant::{VariantPath, VariantPathElement};
26
27use crate::VariantArray;
28use crate::variant_array::BorrowedShreddingState;
29use crate::variant_to_arrow::make_variant_to_arrow_row_builder;
30
31use arrow::array::AsArray;
32use std::sync::Arc;
33
34pub(crate) enum ShreddedPathStep<'a> {
35 Success(BorrowedShreddingState<'a>),
37 Missing,
40 NotShredded,
44}
45
46pub(crate) fn follow_shredded_path_element<'a>(
53 shredding_state: &BorrowedShreddingState<'a>,
54 path_element: &VariantPathElement<'_>,
55 _cast_options: &CastOptions,
56) -> Result<ShreddedPathStep<'a>> {
57 let missing_path_step = || match shredding_state.value_field() {
60 Some(_) => ShreddedPathStep::NotShredded,
61 None => ShreddedPathStep::Missing,
62 };
63
64 let Some(typed_value) = shredding_state.typed_value_field() else {
65 return Ok(missing_path_step());
66 };
67
68 match path_element {
69 VariantPathElement::Field { name } => {
70 let Some(struct_array) = typed_value.as_any().downcast_ref::<StructArray>() else {
73 return Ok(missing_path_step());
75 };
76
77 let Some(field) = struct_array.column_by_name(name) else {
79 return Ok(missing_path_step());
81 };
82
83 let struct_array = field.as_struct_opt().ok_or_else(|| {
84 ArrowError::InvalidArgumentError(format!(
88 "Expected Struct array while following path, got {}",
89 field.data_type(),
90 ))
91 })?;
92
93 let state = BorrowedShreddingState::try_from(struct_array)?;
94 Ok(ShreddedPathStep::Success(state))
95 }
96 VariantPathElement::Index { .. } => {
97 Err(ArrowError::NotYetImplemented(
100 "Pathing into shredded variant array index".into(),
101 ))
102 }
103 }
104}
105
106fn shredded_get_path(
110 input: &VariantArray,
111 path: &[VariantPathElement<'_>],
112 as_field: Option<&Field>,
113 cast_options: &CastOptions,
114) -> Result<ArrayRef> {
115 let make_target_variant =
118 |value: Option<ArrayRef>,
119 typed_value: Option<ArrayRef>,
120 accumulated_nulls: Option<NullBuffer>| {
121 let metadata = input.metadata_field().clone();
122 VariantArray::from_parts(metadata, value, typed_value, accumulated_nulls)
123 };
124
125 let shred_basic_variant =
127 |target: VariantArray, path: VariantPath<'_>, as_field: Option<&Field>| {
128 let as_type = as_field.map(|f| f.data_type());
129 let mut builder = make_variant_to_arrow_row_builder(
130 target.metadata_field(),
131 path,
132 as_type,
133 cast_options,
134 target.len(),
135 )?;
136 for i in 0..target.len() {
137 if target.is_null(i) {
138 builder.append_null()?;
139 } else if !cast_options.safe {
140 let value = target.try_value(i)?;
141 builder.append_value(value)?;
142 } else {
143 let _ = match target.try_value(i) {
144 Ok(v) => builder.append_value(v)?,
145 Err(_) => {
146 builder.append_null()?;
147 false }
149 };
150 }
151 }
152 builder.finish()
153 };
154
155 let mut shredding_state = input.shredding_state().borrow();
158 let mut accumulated_nulls = input.inner().nulls().cloned();
159 let mut path_index = 0;
160 for path_element in path {
161 match follow_shredded_path_element(&shredding_state, path_element, cast_options)? {
162 ShreddedPathStep::Success(state) => {
163 if let Some(typed_value) = shredding_state.typed_value_field() {
165 accumulated_nulls =
166 NullBuffer::union(accumulated_nulls.as_ref(), typed_value.nulls());
167 }
168 shredding_state = state;
169 path_index += 1;
170 continue;
171 }
172 ShreddedPathStep::Missing => {
173 let num_rows = input.len();
174 let arr = match as_field.map(|f| f.data_type()) {
175 Some(data_type) => array::new_null_array(data_type, num_rows),
176 None => Arc::new(array::NullArray::new(num_rows)) as _,
177 };
178 return Ok(arr);
179 }
180 ShreddedPathStep::NotShredded => {
181 let target = make_target_variant(
182 shredding_state.value_field().cloned(),
183 None,
184 accumulated_nulls,
185 );
186 return shred_basic_variant(target, path[path_index..].into(), as_field);
187 }
188 };
189 }
190
191 let target = make_target_variant(
193 shredding_state.value_field().cloned(),
194 shredding_state.typed_value_field().cloned(),
195 accumulated_nulls,
196 );
197
198 let Some(as_field) = as_field else {
200 return Ok(ArrayRef::from(target));
201 };
202
203 if let Some(shredded) = try_perfect_shredding(&target, as_field) {
205 return Ok(shredded);
206 }
207
208 if let DataType::Struct(fields) = as_field.data_type() {
218 if target.typed_value_field().is_none() {
219 return shred_basic_variant(target, VariantPath::default(), Some(as_field));
220 }
221
222 let children = fields
223 .iter()
224 .map(|field| {
225 shredded_get_path(
226 &target,
227 &[VariantPathElement::from(field.name().as_str())],
228 Some(field),
229 cast_options,
230 )
231 })
232 .collect::<Result<Vec<_>>>()?;
233
234 let struct_nulls = target.nulls().cloned();
235
236 return Ok(Arc::new(StructArray::try_new(
237 fields.clone(),
238 children,
239 struct_nulls,
240 )?));
241 }
242
243 shred_basic_variant(target, VariantPath::default(), Some(as_field))
245}
246
247fn try_perfect_shredding(variant_array: &VariantArray, as_field: &Field) -> Option<ArrayRef> {
248 if matches!(as_field.data_type(), DataType::Struct(_)) {
250 return None;
251 }
252 let typed_value = variant_array.typed_value_field()?;
253
254 if typed_value.data_type() == as_field.data_type()
255 && variant_array
256 .value_field()
257 .is_none_or(|v| v.null_count() == v.len())
258 {
259 let parent_nulls = variant_array.nulls();
266
267 let target_array = if parent_nulls.is_none() || typed_value.data_type().is_null() {
269 typed_value.clone()
270 } else {
271 let merged_nulls = NullBuffer::union(parent_nulls, typed_value.nulls());
272 let data = typed_value
273 .to_data()
274 .into_builder()
275 .nulls(merged_nulls)
276 .build()
277 .ok()?;
278 make_array(data)
279 };
280
281 return Some(target_array);
282 }
283
284 None
285}
286
287pub fn variant_get(input: &ArrayRef, options: GetOptions) -> Result<ArrayRef> {
299 let variant_array = VariantArray::try_new(input)?;
300
301 let GetOptions {
302 as_type,
303 path,
304 cast_options,
305 } = options;
306
307 shredded_get_path(&variant_array, &path, as_type.as_deref(), &cast_options)
308}
309
310#[derive(Debug, Clone, Default)]
312pub struct GetOptions<'a> {
313 pub path: VariantPath<'a>,
315 pub as_type: Option<FieldRef>,
319 pub cast_options: CastOptions<'a>,
321}
322
323impl<'a> GetOptions<'a> {
324 pub fn new() -> Self {
326 Default::default()
327 }
328
329 pub fn new_with_path(path: VariantPath<'a>) -> Self {
331 Self {
332 path,
333 as_type: None,
334 cast_options: Default::default(),
335 }
336 }
337
338 pub fn with_as_type(mut self, as_type: Option<FieldRef>) -> Self {
340 self.as_type = as_type;
341 self
342 }
343
344 pub fn with_cast_options(mut self, cast_options: CastOptions<'a>) -> Self {
346 self.cast_options = cast_options;
347 self
348 }
349}
350
351#[cfg(test)]
352mod test {
353 use std::str::FromStr;
354 use std::sync::Arc;
355
356 use super::{GetOptions, variant_get};
357 use crate::variant_array::{ShreddedVariantFieldArray, StructArrayBuilder};
358 use crate::{
359 VariantArray, VariantArrayBuilder, cast_to_variant, json_to_variant, shred_variant,
360 };
361 use arrow::array::{
362 Array, ArrayRef, AsArray, BinaryArray, BinaryViewArray, BooleanArray, Date32Array,
363 Date64Array, Decimal32Array, Decimal64Array, Decimal128Array, Decimal256Array,
364 Float32Array, Float64Array, Int8Array, Int16Array, Int32Array, Int64Array,
365 LargeBinaryArray, LargeListArray, LargeListViewArray, LargeStringArray, ListArray,
366 ListViewArray, NullArray, NullBuilder, StringArray, StringViewArray, StructArray,
367 Time32MillisecondArray, Time32SecondArray, Time64MicrosecondArray, Time64NanosecondArray,
368 };
369 use arrow::buffer::{NullBuffer, OffsetBuffer, ScalarBuffer};
370 use arrow::compute::CastOptions;
371 use arrow::datatypes::DataType::{Int16, Int32, Int64};
372 use arrow::datatypes::i256;
373 use arrow::util::display::FormatOptions;
374 use arrow_schema::DataType::{Boolean, Float32, Float64, Int8};
375 use arrow_schema::{DataType, Field, FieldRef, Fields, IntervalUnit, TimeUnit};
376 use chrono::DateTime;
377 use parquet_variant::{
378 EMPTY_VARIANT_METADATA_BYTES, Variant, VariantDecimal4, VariantDecimal8, VariantDecimal16,
379 VariantDecimalType, VariantPath,
380 };
381
382 fn single_variant_get_test(input_json: &str, path: VariantPath, expected_json: &str) {
383 let input_array_ref: ArrayRef = Arc::new(StringArray::from(vec![Some(input_json)]));
385 let input_variant_array_ref = ArrayRef::from(json_to_variant(&input_array_ref).unwrap());
386
387 let result =
388 variant_get(&input_variant_array_ref, GetOptions::new_with_path(path)).unwrap();
389
390 let expected_array_ref: ArrayRef = Arc::new(StringArray::from(vec![Some(expected_json)]));
392 let expected_variant_array = json_to_variant(&expected_array_ref).unwrap();
393
394 let result_array = VariantArray::try_new(&result).unwrap();
395 assert_eq!(
396 result_array.len(),
397 1,
398 "Expected result array to have length 1"
399 );
400 assert!(
401 result_array.nulls().is_none(),
402 "Expected no nulls in result array"
403 );
404 let result_variant = result_array.value(0);
405 let expected_variant = expected_variant_array.value(0);
406 assert_eq!(
407 result_variant, expected_variant,
408 "Result variant does not match expected variant"
409 );
410 }
411
412 #[test]
413 fn get_primitive_variant_field() {
414 single_variant_get_test(
415 r#"{"some_field": 1234}"#,
416 VariantPath::try_from("some_field").unwrap(),
417 "1234",
418 );
419 }
420
421 #[test]
422 fn get_primitive_variant_list_index() {
423 single_variant_get_test("[1234, 5678]", VariantPath::from(0), "1234");
424 }
425
426 #[test]
427 fn get_primitive_variant_inside_object_of_object() {
428 single_variant_get_test(
429 r#"{"top_level_field": {"inner_field": 1234}}"#,
430 VariantPath::try_from("top_level_field")
431 .unwrap()
432 .join("inner_field"),
433 "1234",
434 );
435 }
436
437 #[test]
438 fn get_primitive_variant_inside_list_of_object() {
439 single_variant_get_test(
440 r#"[{"some_field": 1234}]"#,
441 VariantPath::from(0).join("some_field"),
442 "1234",
443 );
444 }
445
446 #[test]
447 fn get_primitive_variant_inside_object_of_list() {
448 single_variant_get_test(
449 r#"{"some_field": [1234]}"#,
450 VariantPath::try_from("some_field").unwrap().join(0),
451 "1234",
452 );
453 }
454
455 #[test]
456 fn get_complex_variant() {
457 single_variant_get_test(
458 r#"{"top_level_field": {"inner_field": 1234}}"#,
459 VariantPath::try_from("top_level_field").unwrap(),
460 r#"{"inner_field": 1234}"#,
461 );
462 }
463
464 macro_rules! numeric_partially_shredded_test {
466 ($primitive_type:ty, $data_fn:ident) => {
467 let array = $data_fn();
468 let options = GetOptions::new();
469 let result = variant_get(&array, options).unwrap();
470
471 let result = VariantArray::try_new(&result).unwrap();
473 assert_eq!(result.len(), 4);
474
475 assert_eq!(
477 result.value(0),
478 Variant::from(<$primitive_type>::try_from(34u8).unwrap())
479 );
480 assert!(!result.is_valid(1));
481 assert_eq!(result.value(2), Variant::from("n/a"));
482 assert_eq!(
483 result.value(3),
484 Variant::from(<$primitive_type>::try_from(100u8).unwrap())
485 );
486 };
487 }
488
489 macro_rules! partially_shredded_variant_array_gen {
492 ($func_name:ident, $typed_value_array_gen: expr) => {
493 partially_shredded_variant_array_gen!(
494 $func_name,
495 $typed_value_array_gen,
496 Variant::from("n/a")
497 );
498 };
499 ($func_name:ident, $typed_value_array_gen: expr, $fallback_variant:expr) => {
500 fn $func_name() -> ArrayRef {
501 let typed_value: ArrayRef = Arc::new($typed_value_array_gen());
502 let typed_as_variant = cast_to_variant(typed_value.as_ref())
503 .expect("should cast typed array to variant");
504 let mut input_builder = VariantArrayBuilder::new(typed_as_variant.len());
505 input_builder.append_variant(typed_as_variant.value(0));
506 input_builder.append_null();
507 input_builder.append_variant($fallback_variant);
508 input_builder.append_variant(typed_as_variant.value(3));
509
510 let variant_array = shred_variant(&input_builder.build(), typed_value.data_type())
511 .expect("should shred variant array");
512 ArrayRef::from(variant_array)
513 }
514 };
515 }
516
517 macro_rules! numeric_partially_shredded_variant_array_fn {
519 ($func:ident, $array_type:ident, $primitive_type:ty) => {
520 partially_shredded_variant_array_gen!($func, || $array_type::from(vec![
521 Some(<$primitive_type>::try_from(34u8).unwrap()),
522 None,
523 None,
524 Some(<$primitive_type>::try_from(100u8).unwrap()),
525 ]));
526 };
527 }
528
529 numeric_partially_shredded_variant_array_fn!(
530 partially_shredded_int8_variant_array,
531 Int8Array,
532 i8
533 );
534 numeric_partially_shredded_variant_array_fn!(
535 partially_shredded_int16_variant_array,
536 Int16Array,
537 i16
538 );
539 numeric_partially_shredded_variant_array_fn!(
540 partially_shredded_int32_variant_array,
541 Int32Array,
542 i32
543 );
544 numeric_partially_shredded_variant_array_fn!(
545 partially_shredded_int64_variant_array,
546 Int64Array,
547 i64
548 );
549 numeric_partially_shredded_variant_array_fn!(
550 partially_shredded_float32_variant_array,
551 Float32Array,
552 f32
553 );
554 numeric_partially_shredded_variant_array_fn!(
555 partially_shredded_float64_variant_array,
556 Float64Array,
557 f64
558 );
559
560 partially_shredded_variant_array_gen!(partially_shredded_bool_variant_array, || {
561 arrow::array::BooleanArray::from(vec![Some(true), None, None, Some(false)])
562 });
563
564 partially_shredded_variant_array_gen!(
565 partially_shredded_utf8_variant_array,
566 || { StringArray::from(vec![Some("hello"), None, None, Some("world")]) },
567 Variant::from(42i32)
568 );
569
570 partially_shredded_variant_array_gen!(partially_shredded_date32_variant_array, || {
571 Date32Array::from(vec![
572 Some(20348), None,
574 None,
575 Some(20340), ])
577 });
578
579 #[test]
580 fn get_variant_partially_shredded_int8_as_variant() {
581 numeric_partially_shredded_test!(i8, partially_shredded_int8_variant_array);
582 }
583
584 #[test]
585 fn get_variant_partially_shredded_int16_as_variant() {
586 numeric_partially_shredded_test!(i16, partially_shredded_int16_variant_array);
587 }
588
589 #[test]
590 fn get_variant_partially_shredded_int32_as_variant() {
591 numeric_partially_shredded_test!(i32, partially_shredded_int32_variant_array);
592 }
593
594 #[test]
595 fn get_variant_partially_shredded_int64_as_variant() {
596 numeric_partially_shredded_test!(i64, partially_shredded_int64_variant_array);
597 }
598
599 #[test]
600 fn get_variant_partially_shredded_float32_as_variant() {
601 numeric_partially_shredded_test!(f32, partially_shredded_float32_variant_array);
602 }
603
604 #[test]
605 fn get_variant_partially_shredded_float64_as_variant() {
606 numeric_partially_shredded_test!(f64, partially_shredded_float64_variant_array);
607 }
608
609 #[test]
610 fn get_variant_partially_shredded_bool_as_variant() {
611 let array = partially_shredded_bool_variant_array();
612 let options = GetOptions::new();
613 let result = variant_get(&array, options).unwrap();
614
615 let result = VariantArray::try_new(&result).unwrap();
617 assert_eq!(result.len(), 4);
618
619 assert_eq!(result.value(0), Variant::from(true));
621 assert!(!result.is_valid(1));
622 assert_eq!(result.value(2), Variant::from("n/a"));
623 assert_eq!(result.value(3), Variant::from(false));
624 }
625
626 #[test]
627 fn get_variant_partially_shredded_utf8_as_variant() {
628 let array = partially_shredded_utf8_variant_array();
629 let options = GetOptions::new();
630 let result = variant_get(&array, options).unwrap();
631
632 let result = VariantArray::try_new(&result).unwrap();
634 assert_eq!(result.len(), 4);
635
636 assert_eq!(result.value(0), Variant::from("hello"));
638 assert!(!result.is_valid(1));
639 assert_eq!(result.value(2), Variant::from(42i32));
640 assert_eq!(result.value(3), Variant::from("world"));
641 }
642
643 partially_shredded_variant_array_gen!(partially_shredded_binary_view_variant_array, || {
644 BinaryViewArray::from(vec![
645 Some(&[1u8, 2u8, 3u8][..]), None, None, Some(&[4u8, 5u8, 6u8][..]), ])
650 });
651
652 #[test]
653 fn get_variant_partially_shredded_date32_as_variant() {
654 let array = partially_shredded_date32_variant_array();
655 let options = GetOptions::new();
656 let result = variant_get(&array, options).unwrap();
657
658 let result = VariantArray::try_new(&result).unwrap();
660 assert_eq!(result.len(), 4);
661
662 use chrono::NaiveDate;
664 let date1 = NaiveDate::from_ymd_opt(2025, 9, 17).unwrap();
665 let date2 = NaiveDate::from_ymd_opt(2025, 9, 9).unwrap();
666 assert_eq!(result.value(0), Variant::from(date1));
667 assert!(!result.is_valid(1));
668 assert_eq!(result.value(2), Variant::from("n/a"));
669 assert_eq!(result.value(3), Variant::from(date2));
670 }
671
672 #[test]
673 fn get_variant_partially_shredded_binary_view_as_variant() {
674 let array = partially_shredded_binary_view_variant_array();
675 let options = GetOptions::new();
676 let result = variant_get(&array, options).unwrap();
677
678 let result = VariantArray::try_new(&result).unwrap();
680 assert_eq!(result.len(), 4);
681
682 assert_eq!(result.value(0), Variant::from(&[1u8, 2u8, 3u8][..]));
684 assert!(!result.is_valid(1));
685 assert_eq!(result.value(2), Variant::from("n/a"));
686 assert_eq!(result.value(3), Variant::from(&[4u8, 5u8, 6u8][..]));
687 }
688
689 macro_rules! assert_variant_get_as_variant_array_with_default_option {
691 ($variant_array: expr, $array_expected: expr) => {{
692 let options = GetOptions::new();
693 let array = $variant_array;
694 let result = variant_get(&array, options).unwrap();
695 let result = VariantArray::try_new(&result).unwrap();
696
697 assert_eq!(result.len(), $array_expected.len());
698
699 for (idx, item) in $array_expected.into_iter().enumerate() {
700 match item {
701 Some(item) => assert_eq!(result.value(idx), item),
702 None => assert!(result.is_null(idx)),
703 }
704 }
705 }};
706 }
707
708 partially_shredded_variant_array_gen!(
709 partially_shredded_timestamp_micro_ntz_variant_array,
710 || {
711 arrow::array::TimestampMicrosecondArray::from(vec![
712 Some(-456000),
713 None,
714 None,
715 Some(1758602096000000),
716 ])
717 }
718 );
719
720 #[test]
721 fn get_variant_partial_shredded_timestamp_micro_ntz_as_variant() {
722 let array = partially_shredded_timestamp_micro_ntz_variant_array();
723 assert_variant_get_as_variant_array_with_default_option!(
724 array,
725 vec![
726 Some(Variant::from(
727 DateTime::from_timestamp_micros(-456000i64)
728 .unwrap()
729 .naive_utc(),
730 )),
731 None,
732 Some(Variant::from("n/a")),
733 Some(Variant::from(
734 DateTime::parse_from_rfc3339("2025-09-23T12:34:56+08:00")
735 .unwrap()
736 .naive_utc(),
737 )),
738 ]
739 )
740 }
741
742 partially_shredded_variant_array_gen!(partially_shredded_timestamp_micro_variant_array, || {
743 arrow::array::TimestampMicrosecondArray::from(vec![
744 Some(-456000),
745 None,
746 None,
747 Some(1758602096000000),
748 ])
749 .with_timezone("+00:00")
750 });
751
752 #[test]
753 fn get_variant_partial_shredded_timestamp_micro_as_variant() {
754 let array = partially_shredded_timestamp_micro_variant_array();
755 assert_variant_get_as_variant_array_with_default_option!(
756 array,
757 vec![
758 Some(Variant::from(
759 DateTime::from_timestamp_micros(-456000i64)
760 .unwrap()
761 .to_utc(),
762 )),
763 None,
764 Some(Variant::from("n/a")),
765 Some(Variant::from(
766 DateTime::parse_from_rfc3339("2025-09-23T12:34:56+08:00")
767 .unwrap()
768 .to_utc(),
769 )),
770 ]
771 )
772 }
773
774 partially_shredded_variant_array_gen!(
775 partially_shredded_timestamp_nano_ntz_variant_array,
776 || {
777 arrow::array::TimestampNanosecondArray::from(vec![
778 Some(-4999999561),
779 None,
780 None,
781 Some(1758602096000000000),
782 ])
783 }
784 );
785
786 #[test]
787 fn get_variant_partial_shredded_timestamp_nano_ntz_as_variant() {
788 let array = partially_shredded_timestamp_nano_ntz_variant_array();
789 assert_variant_get_as_variant_array_with_default_option!(
790 array,
791 vec![
792 Some(Variant::from(
793 DateTime::from_timestamp(-5, 439).unwrap().naive_utc()
794 )),
795 None,
796 Some(Variant::from("n/a")),
797 Some(Variant::from(
798 DateTime::parse_from_rfc3339("2025-09-23T12:34:56+08:00")
799 .unwrap()
800 .naive_utc()
801 )),
802 ]
803 )
804 }
805
806 partially_shredded_variant_array_gen!(partially_shredded_timestamp_nano_variant_array, || {
807 arrow::array::TimestampNanosecondArray::from(vec![
808 Some(-4999999561),
809 None,
810 None,
811 Some(1758602096000000000),
812 ])
813 .with_timezone("+00:00")
814 });
815
816 #[test]
817 fn get_variant_partial_shredded_timestamp_nano_as_variant() {
818 let array = partially_shredded_timestamp_nano_variant_array();
819 assert_variant_get_as_variant_array_with_default_option!(
820 array,
821 vec![
822 Some(Variant::from(
823 DateTime::from_timestamp(-5, 439).unwrap().to_utc()
824 )),
825 None,
826 Some(Variant::from("n/a")),
827 Some(Variant::from(
828 DateTime::parse_from_rfc3339("2025-09-23T12:34:56+08:00")
829 .unwrap()
830 .to_utc()
831 )),
832 ]
833 )
834 }
835
836 #[test]
838 fn get_variant_shredded_int32_as_int32_safe_cast() {
839 let array = partially_shredded_int32_variant_array();
841 let field = Field::new("typed_value", DataType::Int32, true);
843 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
844 let result = variant_get(&array, options).unwrap();
845 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
846 Some(34),
847 None,
848 None, Some(100),
850 ]));
851 assert_eq!(&result, &expected)
852 }
853
854 #[test]
856 fn get_variant_shredded_int32_as_int32_unsafe_cast() {
857 let array = partially_shredded_int32_variant_array();
859 let field = Field::new("typed_value", DataType::Int32, true);
860 let cast_options = CastOptions {
861 safe: false, ..Default::default()
863 };
864 let options = GetOptions::new()
865 .with_as_type(Some(FieldRef::from(field)))
866 .with_cast_options(cast_options);
867
868 let err = variant_get(&array, options).unwrap_err();
869 assert_eq!(
871 err.to_string(),
872 "Cast error: Failed to extract primitive of type Int32 from variant ShortString(ShortString(\"n/a\")) at path VariantPath([])"
873 );
874 }
875
876 macro_rules! numeric_perfectly_shredded_test {
878 ($primitive_type:ty, $data_fn:ident) => {
879 let array = $data_fn();
880 let options = GetOptions::new();
881 let result = variant_get(&array, options).unwrap();
882
883 let result = VariantArray::try_new(&result).unwrap();
885 assert_eq!(result.len(), 3);
886
887 assert_eq!(
889 result.value(0),
890 Variant::from(<$primitive_type>::try_from(1u8).unwrap())
891 );
892 assert_eq!(
893 result.value(1),
894 Variant::from(<$primitive_type>::try_from(2u8).unwrap())
895 );
896 assert_eq!(
897 result.value(2),
898 Variant::from(<$primitive_type>::try_from(3u8).unwrap())
899 );
900 };
901 }
902
903 #[test]
904 fn get_variant_perfectly_shredded_int8_as_variant() {
905 numeric_perfectly_shredded_test!(i8, perfectly_shredded_int8_variant_array);
906 }
907
908 #[test]
909 fn get_variant_perfectly_shredded_int16_as_variant() {
910 numeric_perfectly_shredded_test!(i16, perfectly_shredded_int16_variant_array);
911 }
912
913 #[test]
914 fn get_variant_perfectly_shredded_int32_as_variant() {
915 numeric_perfectly_shredded_test!(i32, perfectly_shredded_int32_variant_array);
916 }
917
918 #[test]
919 fn get_variant_perfectly_shredded_int64_as_variant() {
920 numeric_perfectly_shredded_test!(i64, perfectly_shredded_int64_variant_array);
921 }
922
923 #[test]
924 fn get_variant_perfectly_shredded_float32_as_variant() {
925 numeric_perfectly_shredded_test!(f32, perfectly_shredded_float32_variant_array);
926 }
927
928 #[test]
929 fn get_variant_perfectly_shredded_float64_as_variant() {
930 numeric_perfectly_shredded_test!(f64, perfectly_shredded_float64_variant_array);
931 }
932
933 #[test]
935 fn get_variant_all_null_as_variant() {
936 let array = all_null_variant_array();
937 let options = GetOptions::new();
938 let result = variant_get(&array, options).unwrap();
939
940 let result = VariantArray::try_new(&result).unwrap();
942 assert_eq!(result.len(), 3);
943
944 assert!(!result.is_valid(0));
946 assert!(!result.is_valid(1));
947 assert!(!result.is_valid(2));
948 }
949
950 #[test]
952 fn get_variant_all_null_as_int32() {
953 let array = all_null_variant_array();
954 let field = Field::new("typed_value", DataType::Int32, true);
956 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
957 let result = variant_get(&array, options).unwrap();
958
959 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
960 Option::<i32>::None,
961 Option::<i32>::None,
962 Option::<i32>::None,
963 ]));
964 assert_eq!(&result, &expected)
965 }
966
967 macro_rules! perfectly_shredded_to_arrow_primitive_test {
968 ($name:ident, $primitive_type:expr, $perfectly_shredded_array_gen_fun:ident, $expected_array:expr) => {
969 #[test]
970 fn $name() {
971 let array = $perfectly_shredded_array_gen_fun();
972 let field = Field::new("typed_value", $primitive_type, true);
973 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
974 let result = variant_get(&array, options).unwrap();
975 let expected_array: ArrayRef = Arc::new($expected_array);
976 assert_eq!(&result, &expected_array);
977 }
978 };
979 }
980
981 perfectly_shredded_to_arrow_primitive_test!(
982 get_variant_perfectly_shredded_int18_as_int8,
983 Int8,
984 perfectly_shredded_int8_variant_array,
985 Int8Array::from(vec![Some(1), Some(2), Some(3)])
986 );
987
988 perfectly_shredded_to_arrow_primitive_test!(
989 get_variant_perfectly_shredded_int16_as_int16,
990 Int16,
991 perfectly_shredded_int16_variant_array,
992 Int16Array::from(vec![Some(1), Some(2), Some(3)])
993 );
994
995 perfectly_shredded_to_arrow_primitive_test!(
996 get_variant_perfectly_shredded_int32_as_int32,
997 Int32,
998 perfectly_shredded_int32_variant_array,
999 Int32Array::from(vec![Some(1), Some(2), Some(3)])
1000 );
1001
1002 perfectly_shredded_to_arrow_primitive_test!(
1003 get_variant_perfectly_shredded_int64_as_int64,
1004 Int64,
1005 perfectly_shredded_int64_variant_array,
1006 Int64Array::from(vec![Some(1), Some(2), Some(3)])
1007 );
1008
1009 perfectly_shredded_to_arrow_primitive_test!(
1010 get_variant_perfectly_shredded_float32_as_float32,
1011 Float32,
1012 perfectly_shredded_float32_variant_array,
1013 Float32Array::from(vec![Some(1.0), Some(2.0), Some(3.0)])
1014 );
1015
1016 perfectly_shredded_to_arrow_primitive_test!(
1017 get_variant_perfectly_shredded_float64_as_float64,
1018 Float64,
1019 perfectly_shredded_float64_variant_array,
1020 Float64Array::from(vec![Some(1.0), Some(2.0), Some(3.0)])
1021 );
1022
1023 perfectly_shredded_to_arrow_primitive_test!(
1024 get_variant_perfectly_shredded_boolean_as_boolean,
1025 Boolean,
1026 perfectly_shredded_bool_variant_array,
1027 BooleanArray::from(vec![Some(true), Some(false), Some(true)])
1028 );
1029
1030 perfectly_shredded_to_arrow_primitive_test!(
1031 get_variant_perfectly_shredded_utf8_as_utf8,
1032 DataType::Utf8,
1033 perfectly_shredded_utf8_variant_array,
1034 StringArray::from(vec![Some("foo"), Some("bar"), Some("baz")])
1035 );
1036
1037 perfectly_shredded_to_arrow_primitive_test!(
1038 get_variant_perfectly_shredded_large_utf8_as_utf8,
1039 DataType::Utf8,
1040 perfectly_shredded_large_utf8_variant_array,
1041 StringArray::from(vec![Some("foo"), Some("bar"), Some("baz")])
1042 );
1043
1044 perfectly_shredded_to_arrow_primitive_test!(
1045 get_variant_perfectly_shredded_utf8_view_as_utf8,
1046 DataType::Utf8,
1047 perfectly_shredded_utf8_view_variant_array,
1048 StringArray::from(vec![Some("foo"), Some("bar"), Some("baz")])
1049 );
1050
1051 macro_rules! perfectly_shredded_variant_array_fn {
1052 ($func:ident, $typed_value_gen:expr) => {
1053 fn $func() -> ArrayRef {
1054 let typed_value: ArrayRef = Arc::new($typed_value_gen());
1057 if let Some(shredded) = cast_to_variant(typed_value.as_ref())
1058 .ok()
1059 .and_then(|unshredded| shred_variant(&unshredded, typed_value.data_type()).ok())
1060 {
1061 return shredded.into();
1062 }
1063
1064 let metadata = BinaryViewArray::from_iter_values(std::iter::repeat_n(
1065 EMPTY_VARIANT_METADATA_BYTES,
1066 typed_value.len(),
1067 ));
1068 VariantArray::from_parts(Arc::new(metadata), None, Some(typed_value), None).into()
1069 }
1070 };
1071 }
1072
1073 perfectly_shredded_variant_array_fn!(perfectly_shredded_utf8_variant_array, || {
1074 StringArray::from(vec![Some("foo"), Some("bar"), Some("baz")])
1075 });
1076
1077 perfectly_shredded_variant_array_fn!(perfectly_shredded_large_utf8_variant_array, || {
1078 LargeStringArray::from(vec![Some("foo"), Some("bar"), Some("baz")])
1079 });
1080
1081 perfectly_shredded_variant_array_fn!(perfectly_shredded_utf8_view_variant_array, || {
1082 StringViewArray::from(vec![Some("foo"), Some("bar"), Some("baz")])
1083 });
1084
1085 perfectly_shredded_variant_array_fn!(perfectly_shredded_bool_variant_array, || {
1086 BooleanArray::from(vec![Some(true), Some(false), Some(true)])
1087 });
1088
1089 macro_rules! numeric_perfectly_shredded_variant_array_fn {
1101 ($func:ident, $array_type:ident, $primitive_type:ty) => {
1102 perfectly_shredded_variant_array_fn!($func, || {
1103 $array_type::from(vec![
1104 Some(<$primitive_type>::try_from(1u8).unwrap()),
1105 Some(<$primitive_type>::try_from(2u8).unwrap()),
1106 Some(<$primitive_type>::try_from(3u8).unwrap()),
1107 ])
1108 });
1109 };
1110 }
1111
1112 numeric_perfectly_shredded_variant_array_fn!(
1113 perfectly_shredded_int8_variant_array,
1114 Int8Array,
1115 i8
1116 );
1117 numeric_perfectly_shredded_variant_array_fn!(
1118 perfectly_shredded_int16_variant_array,
1119 Int16Array,
1120 i16
1121 );
1122 numeric_perfectly_shredded_variant_array_fn!(
1123 perfectly_shredded_int32_variant_array,
1124 Int32Array,
1125 i32
1126 );
1127 numeric_perfectly_shredded_variant_array_fn!(
1128 perfectly_shredded_int64_variant_array,
1129 Int64Array,
1130 i64
1131 );
1132 numeric_perfectly_shredded_variant_array_fn!(
1133 perfectly_shredded_float32_variant_array,
1134 Float32Array,
1135 f32
1136 );
1137 numeric_perfectly_shredded_variant_array_fn!(
1138 perfectly_shredded_float64_variant_array,
1139 Float64Array,
1140 f64
1141 );
1142
1143 perfectly_shredded_variant_array_fn!(
1144 perfectly_shredded_timestamp_micro_ntz_variant_array,
1145 || {
1146 arrow::array::TimestampMicrosecondArray::from(vec![
1147 Some(-456000),
1148 Some(1758602096000001),
1149 Some(1758602096000002),
1150 ])
1151 }
1152 );
1153
1154 perfectly_shredded_to_arrow_primitive_test!(
1155 get_variant_perfectly_shredded_timestamp_micro_ntz_as_timestamp_micro_ntz,
1156 DataType::Timestamp(TimeUnit::Microsecond, None),
1157 perfectly_shredded_timestamp_micro_ntz_variant_array,
1158 arrow::array::TimestampMicrosecondArray::from(vec![
1159 Some(-456000),
1160 Some(1758602096000001),
1161 Some(1758602096000002),
1162 ])
1163 );
1164
1165 perfectly_shredded_to_arrow_primitive_test!(
1167 get_variant_perfectly_shredded_timestamp_micro_ntz_as_nano_ntz,
1168 DataType::Timestamp(TimeUnit::Nanosecond, None),
1169 perfectly_shredded_timestamp_micro_ntz_variant_array,
1170 arrow::array::TimestampNanosecondArray::from(vec![
1171 Some(-456000000),
1172 Some(1758602096000001000),
1173 Some(1758602096000002000)
1174 ])
1175 );
1176
1177 perfectly_shredded_variant_array_fn!(perfectly_shredded_timestamp_micro_variant_array, || {
1178 arrow::array::TimestampMicrosecondArray::from(vec![
1179 Some(-456000),
1180 Some(1758602096000001),
1181 Some(1758602096000002),
1182 ])
1183 .with_timezone("+00:00")
1184 });
1185
1186 perfectly_shredded_to_arrow_primitive_test!(
1187 get_variant_perfectly_shredded_timestamp_micro_as_timestamp_micro,
1188 DataType::Timestamp(TimeUnit::Microsecond, Some(Arc::from("+00:00"))),
1189 perfectly_shredded_timestamp_micro_variant_array,
1190 arrow::array::TimestampMicrosecondArray::from(vec![
1191 Some(-456000),
1192 Some(1758602096000001),
1193 Some(1758602096000002),
1194 ])
1195 .with_timezone("+00:00")
1196 );
1197
1198 perfectly_shredded_to_arrow_primitive_test!(
1200 get_variant_perfectly_shredded_timestamp_micro_as_nano,
1201 DataType::Timestamp(TimeUnit::Nanosecond, Some(Arc::from("+00:00"))),
1202 perfectly_shredded_timestamp_micro_variant_array,
1203 arrow::array::TimestampNanosecondArray::from(vec![
1204 Some(-456000000),
1205 Some(1758602096000001000),
1206 Some(1758602096000002000)
1207 ])
1208 .with_timezone("+00:00")
1209 );
1210
1211 perfectly_shredded_variant_array_fn!(
1212 perfectly_shredded_timestamp_nano_ntz_variant_array,
1213 || {
1214 arrow::array::TimestampNanosecondArray::from(vec![
1215 Some(-4999999561),
1216 Some(1758602096000000001),
1217 Some(1758602096000000002),
1218 ])
1219 }
1220 );
1221
1222 perfectly_shredded_variant_array_fn!(
1223 perfectly_shredded_timestamp_micro_variant_array_for_second_and_milli_second,
1224 || {
1225 arrow::array::TimestampMicrosecondArray::from(vec![
1226 Some(1234), Some(1234000), Some(1234000000), ])
1230 .with_timezone("+00:00")
1231 }
1232 );
1233
1234 perfectly_shredded_to_arrow_primitive_test!(
1237 get_variant_perfectly_shredded_timestamp_micro_as_timestamp_second,
1238 DataType::Timestamp(TimeUnit::Second, Some(Arc::from("+00:00"))),
1239 perfectly_shredded_timestamp_micro_variant_array_for_second_and_milli_second,
1240 arrow::array::TimestampSecondArray::from(vec![
1241 None,
1242 None, Some(1234)
1244 ])
1245 .with_timezone("+00:00")
1246 );
1247
1248 perfectly_shredded_to_arrow_primitive_test!(
1249 get_variant_perfectly_shredded_timestamp_micro_as_timestamp_milli,
1250 DataType::Timestamp(TimeUnit::Millisecond, Some(Arc::from("+00:00"))),
1251 perfectly_shredded_timestamp_micro_variant_array_for_second_and_milli_second,
1252 arrow::array::TimestampMillisecondArray::from(vec![
1253 None, Some(1234),
1255 Some(1234000)
1256 ])
1257 .with_timezone("+00:00")
1258 );
1259
1260 perfectly_shredded_variant_array_fn!(
1261 perfectly_shredded_timestamp_micro_ntz_variant_array_for_second_and_milli_second,
1262 || {
1263 arrow::array::TimestampMicrosecondArray::from(vec![
1264 Some(1234), Some(1234000), Some(1234000000), ])
1268 }
1269 );
1270
1271 perfectly_shredded_to_arrow_primitive_test!(
1274 get_variant_perfectly_shredded_timestamp_micro_ntz_as_timestamp_second,
1275 DataType::Timestamp(TimeUnit::Second, None),
1276 perfectly_shredded_timestamp_micro_ntz_variant_array_for_second_and_milli_second,
1277 arrow::array::TimestampSecondArray::from(vec![
1278 None,
1279 None, Some(1234)
1281 ])
1282 );
1283
1284 perfectly_shredded_to_arrow_primitive_test!(
1285 get_variant_perfectly_shredded_timestamp_micro_ntz_as_timestamp_milli,
1286 DataType::Timestamp(TimeUnit::Millisecond, None),
1287 perfectly_shredded_timestamp_micro_ntz_variant_array_for_second_and_milli_second,
1288 arrow::array::TimestampMillisecondArray::from(vec![
1289 None, Some(1234),
1291 Some(1234000)
1292 ])
1293 );
1294
1295 perfectly_shredded_variant_array_fn!(
1296 perfectly_shredded_timestamp_nano_variant_array_for_second_and_milli_second,
1297 || {
1298 arrow::array::TimestampNanosecondArray::from(vec![
1299 Some(1234000), Some(1234000000), Some(1234000000000), ])
1303 .with_timezone("+00:00")
1304 }
1305 );
1306
1307 perfectly_shredded_to_arrow_primitive_test!(
1310 get_variant_perfectly_shredded_timestamp_nano_as_timestamp_second,
1311 DataType::Timestamp(TimeUnit::Second, Some(Arc::from("+00:00"))),
1312 perfectly_shredded_timestamp_nano_variant_array_for_second_and_milli_second,
1313 arrow::array::TimestampSecondArray::from(vec![
1314 None,
1315 None, Some(1234)
1317 ])
1318 .with_timezone("+00:00")
1319 );
1320
1321 perfectly_shredded_to_arrow_primitive_test!(
1322 get_variant_perfectly_shredded_timestamp_nano_as_timestamp_milli,
1323 DataType::Timestamp(TimeUnit::Millisecond, Some(Arc::from("+00:00"))),
1324 perfectly_shredded_timestamp_nano_variant_array_for_second_and_milli_second,
1325 arrow::array::TimestampMillisecondArray::from(vec![
1326 None, Some(1234),
1328 Some(1234000)
1329 ])
1330 .with_timezone("+00:00")
1331 );
1332
1333 perfectly_shredded_variant_array_fn!(
1334 perfectly_shredded_timestamp_nano_ntz_variant_array_for_second_and_milli_second,
1335 || {
1336 arrow::array::TimestampNanosecondArray::from(vec![
1337 Some(1234000), Some(1234000000), Some(1234000000000), ])
1341 }
1342 );
1343
1344 perfectly_shredded_to_arrow_primitive_test!(
1347 get_variant_perfectly_shredded_timestamp_nano_ntz_as_timestamp_second,
1348 DataType::Timestamp(TimeUnit::Second, None),
1349 perfectly_shredded_timestamp_nano_ntz_variant_array_for_second_and_milli_second,
1350 arrow::array::TimestampSecondArray::from(vec![
1351 None,
1352 None, Some(1234)
1354 ])
1355 );
1356
1357 perfectly_shredded_to_arrow_primitive_test!(
1358 get_variant_perfectly_shredded_timestamp_nano_ntz_as_timestamp_milli,
1359 DataType::Timestamp(TimeUnit::Millisecond, None),
1360 perfectly_shredded_timestamp_nano_ntz_variant_array_for_second_and_milli_second,
1361 arrow::array::TimestampMillisecondArray::from(vec![
1362 None, Some(1234),
1364 Some(1234000)
1365 ])
1366 );
1367
1368 perfectly_shredded_to_arrow_primitive_test!(
1369 get_variant_perfectly_shredded_timestamp_nano_ntz_as_timestamp_nano_ntz,
1370 DataType::Timestamp(TimeUnit::Nanosecond, None),
1371 perfectly_shredded_timestamp_nano_ntz_variant_array,
1372 arrow::array::TimestampNanosecondArray::from(vec![
1373 Some(-4999999561),
1374 Some(1758602096000000001),
1375 Some(1758602096000000002),
1376 ])
1377 );
1378
1379 perfectly_shredded_variant_array_fn!(perfectly_shredded_timestamp_nano_variant_array, || {
1380 arrow::array::TimestampNanosecondArray::from(vec![
1381 Some(-4999999561),
1382 Some(1758602096000000001),
1383 Some(1758602096000000002),
1384 ])
1385 .with_timezone("+00:00")
1386 });
1387
1388 perfectly_shredded_to_arrow_primitive_test!(
1389 get_variant_perfectly_shredded_timestamp_nano_as_timestamp_nano,
1390 DataType::Timestamp(TimeUnit::Nanosecond, Some(Arc::from("+00:00"))),
1391 perfectly_shredded_timestamp_nano_variant_array,
1392 arrow::array::TimestampNanosecondArray::from(vec![
1393 Some(-4999999561),
1394 Some(1758602096000000001),
1395 Some(1758602096000000002),
1396 ])
1397 .with_timezone("+00:00")
1398 );
1399
1400 perfectly_shredded_variant_array_fn!(perfectly_shredded_date_variant_array, || {
1401 Date32Array::from(vec![Some(-12345), Some(17586), Some(20000)])
1402 });
1403
1404 perfectly_shredded_to_arrow_primitive_test!(
1405 get_variant_perfectly_shredded_date_as_date,
1406 DataType::Date32,
1407 perfectly_shredded_date_variant_array,
1408 Date32Array::from(vec![Some(-12345), Some(17586), Some(20000)])
1409 );
1410
1411 perfectly_shredded_to_arrow_primitive_test!(
1412 get_variant_perfectly_shredded_date_as_date64,
1413 DataType::Date64,
1414 perfectly_shredded_date_variant_array,
1415 Date64Array::from(vec![
1416 Some(-1066608000000),
1417 Some(1519430400000),
1418 Some(1728000000000)
1419 ])
1420 );
1421
1422 perfectly_shredded_variant_array_fn!(perfectly_shredded_time_variant_array, || {
1423 Time64MicrosecondArray::from(vec![Some(12345000), Some(87654000), Some(135792000)])
1424 });
1425
1426 perfectly_shredded_to_arrow_primitive_test!(
1427 get_variant_perfectly_shredded_time_as_time,
1428 DataType::Time64(TimeUnit::Microsecond),
1429 perfectly_shredded_time_variant_array,
1430 Time64MicrosecondArray::from(vec![Some(12345000), Some(87654000), Some(135792000)])
1431 );
1432
1433 perfectly_shredded_to_arrow_primitive_test!(
1434 get_variant_perfectly_shredded_time_as_time64_nano,
1435 DataType::Time64(TimeUnit::Nanosecond),
1436 perfectly_shredded_time_variant_array,
1437 Time64NanosecondArray::from(vec![
1438 Some(12345000000),
1439 Some(87654000000),
1440 Some(135792000000)
1441 ])
1442 );
1443
1444 perfectly_shredded_variant_array_fn!(perfectly_shredded_time_variant_array_for_time32, || {
1445 Time64MicrosecondArray::from(vec![
1446 Some(1234), Some(7654000), Some(35792000000), ])
1450 });
1451
1452 perfectly_shredded_to_arrow_primitive_test!(
1453 get_variant_perfectly_shredded_time_as_time32_second,
1454 DataType::Time32(TimeUnit::Second),
1455 perfectly_shredded_time_variant_array_for_time32,
1456 Time32SecondArray::from(vec![
1457 None,
1458 None, Some(35792)
1460 ])
1461 );
1462
1463 perfectly_shredded_to_arrow_primitive_test!(
1464 get_variant_perfectly_shredded_time_as_time32_milli,
1465 DataType::Time32(TimeUnit::Millisecond),
1466 perfectly_shredded_time_variant_array_for_time32,
1467 Time32MillisecondArray::from(vec![
1468 None, Some(7654),
1470 Some(35792000)
1471 ])
1472 );
1473
1474 perfectly_shredded_variant_array_fn!(perfectly_shredded_null_variant_array, || {
1475 let mut builder = NullBuilder::new();
1476 builder.append_nulls(3);
1477 builder.finish()
1478 });
1479
1480 perfectly_shredded_to_arrow_primitive_test!(
1481 get_variant_perfectly_shredded_null_as_null,
1482 DataType::Null,
1483 perfectly_shredded_null_variant_array,
1484 arrow::array::NullArray::new(3)
1485 );
1486
1487 perfectly_shredded_variant_array_fn!(perfectly_shredded_null_variant_array_with_int, || {
1488 Int32Array::from(vec![Some(32), Some(64), Some(48)])
1489 });
1490
1491 perfectly_shredded_to_arrow_primitive_test!(
1493 get_variant_perfectly_shredded_null_with_type_missmatch_in_safe_mode,
1494 DataType::Null,
1495 perfectly_shredded_null_variant_array_with_int,
1496 arrow::array::NullArray::new(3)
1497 );
1498
1499 #[test]
1501 fn get_variant_perfectly_shredded_null_as_null_with_type_missmatch_in_strict_mode() {
1502 let array = perfectly_shredded_null_variant_array_with_int();
1503 let field = Field::new("typed_value", DataType::Null, true);
1504 let options = GetOptions::new()
1505 .with_as_type(Some(FieldRef::from(field)))
1506 .with_cast_options(CastOptions {
1507 safe: false,
1508 format_options: FormatOptions::default(),
1509 });
1510
1511 let result = variant_get(&array, options);
1512
1513 assert!(result.is_err());
1514 let error_msg = format!("{}", result.unwrap_err());
1515 assert!(
1516 error_msg
1517 .contains("Cast error: Failed to extract primitive of type Null from variant Int32(32) at path VariantPath([])"),
1518 "Expected=[Cast error: Failed to extract primitive of type Null from variant Int32(32) at path VariantPath([])],\
1519 Got error message=[{}]",
1520 error_msg
1521 );
1522 }
1523
1524 perfectly_shredded_variant_array_fn!(perfectly_shredded_decimal4_variant_array, || {
1525 Decimal32Array::from(vec![Some(12345), Some(23400), Some(-12342)])
1526 .with_precision_and_scale(5, 2)
1527 .unwrap()
1528 });
1529
1530 perfectly_shredded_to_arrow_primitive_test!(
1531 get_variant_perfectly_shredded_decimal4_as_decimal4,
1532 DataType::Decimal32(5, 2),
1533 perfectly_shredded_decimal4_variant_array,
1534 Decimal32Array::from(vec![Some(12345), Some(23400), Some(-12342)])
1535 .with_precision_and_scale(5, 2)
1536 .unwrap()
1537 );
1538
1539 perfectly_shredded_variant_array_fn!(
1540 perfectly_shredded_decimal8_variant_array_cast2decimal32,
1541 || {
1542 Decimal64Array::from(vec![Some(123456), Some(145678), Some(-123456)])
1543 .with_precision_and_scale(6, 1)
1544 .unwrap()
1545 }
1546 );
1547
1548 perfectly_shredded_to_arrow_primitive_test!(
1552 get_variant_perfectly_shredded_decimal8_through_decimal32_as_decimal8,
1553 DataType::Decimal64(6, 1),
1554 perfectly_shredded_decimal8_variant_array_cast2decimal32,
1555 Decimal64Array::from(vec![Some(123456), Some(145678), Some(-123456)])
1556 .with_precision_and_scale(6, 1)
1557 .unwrap()
1558 );
1559
1560 perfectly_shredded_variant_array_fn!(perfectly_shredded_decimal8_variant_array, || {
1563 Decimal64Array::from(vec![Some(1234567809), Some(1456787000), Some(-1234561203)])
1564 .with_precision_and_scale(10, 1)
1565 .unwrap()
1566 });
1567
1568 perfectly_shredded_to_arrow_primitive_test!(
1569 get_variant_perfectly_shredded_decimal8_as_decimal8,
1570 DataType::Decimal64(10, 1),
1571 perfectly_shredded_decimal8_variant_array,
1572 Decimal64Array::from(vec![Some(1234567809), Some(1456787000), Some(-1234561203)])
1573 .with_precision_and_scale(10, 1)
1574 .unwrap()
1575 );
1576
1577 perfectly_shredded_variant_array_fn!(
1580 perfectly_shredded_decimal16_within_decimal4_variant_array,
1581 || {
1582 Decimal128Array::from(vec![
1583 Some(i128::from(1234589)),
1584 Some(i128::from(2344444)),
1585 Some(i128::from(-1234789)),
1586 ])
1587 .with_precision_and_scale(7, 3)
1588 .unwrap()
1589 }
1590 );
1591
1592 perfectly_shredded_to_arrow_primitive_test!(
1595 get_variant_perfectly_shredded_decimal16_within_decimal4_as_decimal16,
1596 DataType::Decimal128(7, 3),
1597 perfectly_shredded_decimal16_within_decimal4_variant_array,
1598 Decimal128Array::from(vec![
1599 Some(i128::from(1234589)),
1600 Some(i128::from(2344444)),
1601 Some(i128::from(-1234789)),
1602 ])
1603 .with_precision_and_scale(7, 3)
1604 .unwrap()
1605 );
1606
1607 perfectly_shredded_variant_array_fn!(
1608 perfectly_shredded_decimal16_within_decimal8_variant_array,
1609 || {
1610 Decimal128Array::from(vec![Some(1234567809), Some(1456787000), Some(-1234561203)])
1611 .with_precision_and_scale(10, 1)
1612 .unwrap()
1613 }
1614 );
1615
1616 perfectly_shredded_to_arrow_primitive_test!(
1619 get_variant_perfectly_shredded_decimal16_within8_as_decimal16,
1620 DataType::Decimal128(10, 1),
1621 perfectly_shredded_decimal16_within_decimal8_variant_array,
1622 Decimal128Array::from(vec![Some(1234567809), Some(1456787000), Some(-1234561203)])
1623 .with_precision_and_scale(10, 1)
1624 .unwrap()
1625 );
1626
1627 perfectly_shredded_variant_array_fn!(perfectly_shredded_decimal16_variant_array, || {
1628 Decimal128Array::from(vec![
1629 Some(i128::from_str("12345678901234567899").unwrap()),
1630 Some(i128::from_str("23445677483748324300").unwrap()),
1631 Some(i128::from_str("-12345678901234567899").unwrap()),
1632 ])
1633 .with_precision_and_scale(20, 3)
1634 .unwrap()
1635 });
1636
1637 perfectly_shredded_to_arrow_primitive_test!(
1640 get_variant_perfectly_shredded_decimal16_as_decimal16,
1641 DataType::Decimal128(20, 3),
1642 perfectly_shredded_decimal16_variant_array,
1643 Decimal128Array::from(vec![
1644 Some(i128::from_str("12345678901234567899").unwrap()),
1645 Some(i128::from_str("23445677483748324300").unwrap()),
1646 Some(i128::from_str("-12345678901234567899").unwrap())
1647 ])
1648 .with_precision_and_scale(20, 3)
1649 .unwrap()
1650 );
1651
1652 perfectly_shredded_variant_array_fn!(perfectly_shredded_binary_variant_array, || {
1653 BinaryArray::from(vec![
1654 Some(b"Apache" as &[u8]),
1655 Some(b"Arrow-rs" as &[u8]),
1656 Some(b"Parquet-variant" as &[u8]),
1657 ])
1658 });
1659
1660 perfectly_shredded_to_arrow_primitive_test!(
1661 get_variant_perfectly_shredded_binary_as_binary,
1662 DataType::Binary,
1663 perfectly_shredded_binary_variant_array,
1664 BinaryArray::from(vec![
1665 Some(b"Apache" as &[u8]),
1666 Some(b"Arrow-rs" as &[u8]),
1667 Some(b"Parquet-variant" as &[u8]),
1668 ])
1669 );
1670
1671 perfectly_shredded_variant_array_fn!(perfectly_shredded_large_binary_variant_array, || {
1672 LargeBinaryArray::from(vec![
1673 Some(b"Apache" as &[u8]),
1674 Some(b"Arrow-rs" as &[u8]),
1675 Some(b"Parquet-variant" as &[u8]),
1676 ])
1677 });
1678
1679 perfectly_shredded_to_arrow_primitive_test!(
1680 get_variant_perfectly_shredded_large_binary_as_large_binary,
1681 DataType::LargeBinary,
1682 perfectly_shredded_large_binary_variant_array,
1683 LargeBinaryArray::from(vec![
1684 Some(b"Apache" as &[u8]),
1685 Some(b"Arrow-rs" as &[u8]),
1686 Some(b"Parquet-variant" as &[u8]),
1687 ])
1688 );
1689
1690 perfectly_shredded_variant_array_fn!(perfectly_shredded_binary_view_variant_array, || {
1691 BinaryViewArray::from(vec![
1692 Some(b"Apache" as &[u8]),
1693 Some(b"Arrow-rs" as &[u8]),
1694 Some(b"Parquet-variant" as &[u8]),
1695 ])
1696 });
1697
1698 perfectly_shredded_to_arrow_primitive_test!(
1699 get_variant_perfectly_shredded_binary_view_as_binary_view,
1700 DataType::BinaryView,
1701 perfectly_shredded_binary_view_variant_array,
1702 BinaryViewArray::from(vec![
1703 Some(b"Apache" as &[u8]),
1704 Some(b"Arrow-rs" as &[u8]),
1705 Some(b"Parquet-variant" as &[u8]),
1706 ])
1707 );
1708
1709 fn all_null_variant_array() -> ArrayRef {
1726 let nulls = NullBuffer::from(vec![
1727 false, false, false, ]);
1731
1732 let metadata =
1734 BinaryViewArray::from_iter_values(std::iter::repeat_n(EMPTY_VARIANT_METADATA_BYTES, 3));
1735
1736 ArrayRef::from(VariantArray::from_parts(
1737 Arc::new(metadata),
1738 None,
1739 None,
1740 Some(nulls),
1741 ))
1742 }
1743 #[test]
1747 fn test_shredded_object_field_access() {
1748 let array = shredded_object_with_x_field_variant_array();
1749
1750 let options = GetOptions::new_with_path(VariantPath::try_from("x").unwrap());
1752 let result = variant_get(&array, options).unwrap();
1753
1754 let result_variant = VariantArray::try_new(&result).unwrap();
1755 assert_eq!(result_variant.len(), 2);
1756
1757 assert_eq!(result_variant.value(0), Variant::Int32(1));
1759 assert_eq!(result_variant.value(1), Variant::Int32(42));
1761 }
1762
1763 #[test]
1765 fn test_shredded_object_field_as_int32() {
1766 let array = shredded_object_with_x_field_variant_array();
1767
1768 let field = Field::new("x", DataType::Int32, false);
1770 let options = GetOptions::new_with_path(VariantPath::try_from("x").unwrap())
1771 .with_as_type(Some(FieldRef::from(field)));
1772 let result = variant_get(&array, options).unwrap();
1773
1774 let expected: ArrayRef = Arc::new(Int32Array::from(vec![Some(1), Some(42)]));
1776 assert_eq!(&result, &expected);
1777 }
1778
1779 fn shredded_object_with_x_field_variant_array() -> ArrayRef {
1791 let (metadata, y_field_value) = {
1793 let mut builder = parquet_variant::VariantBuilder::new();
1794 let mut obj = builder.new_object();
1795 obj.insert("x", Variant::Int32(42));
1796 obj.insert("y", Variant::from("foo"));
1797 obj.finish();
1798 builder.finish()
1799 };
1800
1801 let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 2));
1803
1804 let empty_object_value = {
1809 let mut builder = parquet_variant::VariantBuilder::new();
1810 let obj = builder.new_object();
1811 obj.finish();
1812 let (_, value) = builder.finish();
1813 value
1814 };
1815
1816 let value_array = BinaryViewArray::from(vec![
1817 Some(y_field_value.as_slice()), Some(empty_object_value.as_slice()), ]);
1820
1821 let x_field_typed_value = Int32Array::from(vec![Some(1), Some(42)]);
1824
1825 let x_field_shredded = ShreddedVariantFieldArray::from_parts(
1827 None,
1828 Some(Arc::new(x_field_typed_value) as ArrayRef),
1829 None,
1830 );
1831
1832 let typed_value_fields = Fields::from(vec![Field::new(
1834 "x",
1835 x_field_shredded.data_type().clone(),
1836 true,
1837 )]);
1838 let typed_value_struct = StructArray::try_new(
1839 typed_value_fields,
1840 vec![ArrayRef::from(x_field_shredded)],
1841 None, )
1843 .unwrap();
1844
1845 ArrayRef::from(VariantArray::from_parts(
1847 Arc::new(metadata_array),
1848 Some(Arc::new(value_array)),
1849 Some(Arc::new(typed_value_struct)),
1850 None,
1851 ))
1852 }
1853
1854 #[test]
1856 fn test_simple_nested_path_support() {
1857 println!("Testing path parsing:");
1859
1860 let path_x = VariantPath::try_from("x").unwrap();
1861 let elements_x: Vec<_> = path_x.iter().collect();
1862 println!(" 'x' -> {} elements: {:?}", elements_x.len(), elements_x);
1863
1864 let path_ax = VariantPath::try_from("a.x").unwrap();
1865 let elements_ax: Vec<_> = path_ax.iter().collect();
1866 println!(
1867 " 'a.x' -> {} elements: {:?}",
1868 elements_ax.len(),
1869 elements_ax
1870 );
1871
1872 let path_ax_alt = VariantPath::try_from("$.a.x").unwrap();
1873 let elements_ax_alt: Vec<_> = path_ax_alt.iter().collect();
1874 println!(
1875 " '$.a.x' -> {} elements: {:?}",
1876 elements_ax_alt.len(),
1877 elements_ax_alt
1878 );
1879
1880 let path_nested = VariantPath::try_from("a").unwrap().join("x");
1881 let elements_nested: Vec<_> = path_nested.iter().collect();
1882 println!(
1883 " VariantPath::try_from('a').unwrap().join('x') -> {} elements: {:?}",
1884 elements_nested.len(),
1885 elements_nested
1886 );
1887
1888 let array = shredded_object_with_x_field_variant_array();
1890
1891 let real_nested_path = VariantPath::try_from("a").unwrap().join("x");
1893 let options = GetOptions::new_with_path(real_nested_path);
1894 let result = variant_get(&array, options);
1895
1896 match result {
1897 Ok(_) => {
1898 println!("Nested path 'a.x' works unexpectedly!");
1899 }
1900 Err(e) => {
1901 println!("Nested path 'a.x' error: {}", e);
1902 if e.to_string().contains("Not yet implemented")
1903 || e.to_string().contains("NotYetImplemented")
1904 {
1905 println!("This is expected - nested paths are not implemented");
1906 return;
1907 }
1908 println!("This shows nested paths need implementation");
1910 }
1911 }
1912 }
1913
1914 #[test]
1918 fn test_depth_0_int32_conversion() {
1919 println!("=== Testing Depth 0: Direct field access ===");
1920
1921 let unshredded_array = create_depth_0_test_data();
1923
1924 let field = Field::new("result", DataType::Int32, true);
1925 let path = VariantPath::try_from("x").unwrap();
1926 let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
1927 let result = variant_get(&unshredded_array, options).unwrap();
1928
1929 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
1930 Some(42), None, None, ]));
1934 assert_eq!(&result, &expected);
1935 println!("Depth 0 (unshredded) passed");
1936
1937 let shredded_array = create_depth_0_shredded_test_data_simple();
1939
1940 let field = Field::new("result", DataType::Int32, true);
1941 let path = VariantPath::try_from("x").unwrap();
1942 let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
1943 let result = variant_get(&shredded_array, options).unwrap();
1944
1945 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
1946 Some(42), None, ]));
1949 assert_eq!(&result, &expected);
1950 println!("Depth 0 (shredded) passed");
1951 }
1952
1953 #[test]
1956 fn test_depth_1_int32_conversion() {
1957 println!("=== Testing Depth 1: Single nested field access ===");
1958
1959 let unshredded_array = create_nested_path_test_data();
1961
1962 let field = Field::new("result", DataType::Int32, true);
1963 let path = VariantPath::try_from("a.x").unwrap(); let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
1965 let result = variant_get(&unshredded_array, options).unwrap();
1966
1967 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
1968 Some(55), None, ]));
1971 assert_eq!(&result, &expected);
1972 println!("Depth 1 (unshredded) passed");
1973
1974 let shredded_array = create_depth_1_shredded_test_data_working();
1976
1977 let field = Field::new("result", DataType::Int32, true);
1978 let path = VariantPath::try_from("a.x").unwrap(); let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
1980 let result = variant_get(&shredded_array, options).unwrap();
1981
1982 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
1983 Some(55), None, ]));
1986 assert_eq!(&result, &expected);
1987 println!("Depth 1 (shredded) passed");
1988 }
1989
1990 #[test]
1993 fn test_depth_2_int32_conversion() {
1994 println!("=== Testing Depth 2: Double nested field access ===");
1995
1996 let unshredded_array = create_depth_2_test_data();
1998
1999 let field = Field::new("result", DataType::Int32, true);
2000 let path = VariantPath::try_from("a.b.x").unwrap(); let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
2002 let result = variant_get(&unshredded_array, options).unwrap();
2003
2004 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
2005 Some(100), None, None, ]));
2009 assert_eq!(&result, &expected);
2010 println!("Depth 2 (unshredded) passed");
2011
2012 let shredded_array = create_depth_2_shredded_test_data_working();
2014
2015 let field = Field::new("result", DataType::Int32, true);
2016 let path = VariantPath::try_from("a.b.x").unwrap(); let options = GetOptions::new_with_path(path).with_as_type(Some(FieldRef::from(field)));
2018 let result = variant_get(&shredded_array, options).unwrap();
2019
2020 let expected: ArrayRef = Arc::new(Int32Array::from(vec![
2021 Some(100), None, None, ]));
2025 assert_eq!(&result, &expected);
2026 println!("Depth 2 (shredded) passed");
2027 }
2028
2029 #[test]
2034 fn test_current_nested_path_functionality() {
2035 let array = shredded_object_with_x_field_variant_array();
2036
2037 let single_path = VariantPath::try_from("x").unwrap();
2039 let field = Field::new("result", DataType::Int32, true);
2040 let options =
2041 GetOptions::new_with_path(single_path).with_as_type(Some(FieldRef::from(field)));
2042 let result = variant_get(&array, options).unwrap();
2043
2044 println!("Single path 'x' works - result: {:?}", result);
2045
2046 let nested_path = VariantPath::try_from("a").unwrap().join("x");
2048 let field = Field::new("result", DataType::Int32, true);
2049 let options =
2050 GetOptions::new_with_path(nested_path).with_as_type(Some(FieldRef::from(field)));
2051 let result = variant_get(&array, options).unwrap();
2052
2053 println!("Nested path 'a.x' result: {:?}", result);
2054 }
2055
2056 fn create_depth_0_test_data() -> ArrayRef {
2059 let mut builder = crate::VariantArrayBuilder::new(3);
2060
2061 {
2063 let json_str = r#"{"x": 42}"#;
2064 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2065 if let Ok(variant_array) = json_to_variant(&string_array) {
2066 builder.append_variant(variant_array.value(0));
2067 } else {
2068 builder.append_null();
2069 }
2070 }
2071
2072 {
2074 let json_str = r#"{"x": "foo"}"#;
2075 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2076 if let Ok(variant_array) = json_to_variant(&string_array) {
2077 builder.append_variant(variant_array.value(0));
2078 } else {
2079 builder.append_null();
2080 }
2081 }
2082
2083 {
2085 let json_str = r#"{"y": 10}"#;
2086 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2087 if let Ok(variant_array) = json_to_variant(&string_array) {
2088 builder.append_variant(variant_array.value(0));
2089 } else {
2090 builder.append_null();
2091 }
2092 }
2093
2094 ArrayRef::from(builder.build())
2095 }
2096
2097 fn create_nested_path_test_data() -> ArrayRef {
2100 let mut builder = crate::VariantArrayBuilder::new(2);
2101
2102 {
2104 let json_str = r#"{"a": {"x": 55}, "b": 42}"#;
2105 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2106 if let Ok(variant_array) = json_to_variant(&string_array) {
2107 builder.append_variant(variant_array.value(0));
2108 } else {
2109 builder.append_null();
2110 }
2111 }
2112
2113 {
2115 let json_str = r#"{"a": {"x": "foo"}, "b": 42}"#;
2116 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2117 if let Ok(variant_array) = json_to_variant(&string_array) {
2118 builder.append_variant(variant_array.value(0));
2119 } else {
2120 builder.append_null();
2121 }
2122 }
2123
2124 ArrayRef::from(builder.build())
2125 }
2126
2127 fn create_depth_2_test_data() -> ArrayRef {
2130 let mut builder = crate::VariantArrayBuilder::new(3);
2131
2132 {
2134 let json_str = r#"{"a": {"b": {"x": 100}}}"#;
2135 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2136 if let Ok(variant_array) = json_to_variant(&string_array) {
2137 builder.append_variant(variant_array.value(0));
2138 } else {
2139 builder.append_null();
2140 }
2141 }
2142
2143 {
2145 let json_str = r#"{"a": {"b": {"x": "bar"}}}"#;
2146 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2147 if let Ok(variant_array) = json_to_variant(&string_array) {
2148 builder.append_variant(variant_array.value(0));
2149 } else {
2150 builder.append_null();
2151 }
2152 }
2153
2154 {
2156 let json_str = r#"{"a": {"b": {"y": 200}}}"#;
2157 let string_array: ArrayRef = Arc::new(StringArray::from(vec![json_str]));
2158 if let Ok(variant_array) = json_to_variant(&string_array) {
2159 builder.append_variant(variant_array.value(0));
2160 } else {
2161 builder.append_null();
2162 }
2163 }
2164
2165 ArrayRef::from(builder.build())
2166 }
2167
2168 fn create_depth_0_shredded_test_data_simple() -> ArrayRef {
2171 let (metadata, string_x_value) = {
2173 let mut builder = parquet_variant::VariantBuilder::new();
2174 let mut obj = builder.new_object();
2175 obj.insert("x", Variant::from("foo"));
2176 obj.finish();
2177 builder.finish()
2178 };
2179
2180 let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 2));
2182
2183 let empty_object_value = {
2187 let mut builder = parquet_variant::VariantBuilder::new();
2188 let obj = builder.new_object();
2189 obj.finish();
2190 let (_, value) = builder.finish();
2191 value
2192 };
2193
2194 let value_array = BinaryViewArray::from(vec![
2195 Some(empty_object_value.as_slice()), Some(string_x_value.as_slice()), ]);
2198
2199 let x_field_typed_value = Int32Array::from(vec![Some(42), None]);
2201
2202 let x_field_shredded = ShreddedVariantFieldArray::from_parts(
2204 None,
2205 Some(Arc::new(x_field_typed_value) as ArrayRef),
2206 None,
2207 );
2208
2209 let typed_value_fields = Fields::from(vec![Field::new(
2211 "x",
2212 x_field_shredded.data_type().clone(),
2213 true,
2214 )]);
2215 let typed_value_struct = StructArray::try_new(
2216 typed_value_fields,
2217 vec![ArrayRef::from(x_field_shredded)],
2218 None,
2219 )
2220 .unwrap();
2221
2222 ArrayRef::from(VariantArray::from_parts(
2224 Arc::new(metadata_array),
2225 Some(Arc::new(value_array)),
2226 Some(Arc::new(typed_value_struct)),
2227 None,
2228 ))
2229 }
2230
2231 fn create_depth_1_shredded_test_data_working() -> ArrayRef {
2236 let (metadata, _) = {
2238 let mut builder = parquet_variant::VariantBuilder::new();
2240 let mut obj = builder.new_object();
2241
2242 let mut a_obj = obj.new_object("a");
2244 a_obj.insert("x", Variant::Int32(55));
2245 a_obj.finish();
2246
2247 obj.insert("b", Variant::Int32(42));
2248 obj.finish();
2249 builder.finish()
2250 };
2251
2252 let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 2));
2253
2254 let empty_object_value = {
2257 let mut builder = parquet_variant::VariantBuilder::new();
2258 let obj = builder.new_object();
2259 obj.finish();
2260 let (_, value) = builder.finish();
2261 value
2262 };
2263
2264 let row1_fallback = {
2267 let mut builder = parquet_variant::VariantBuilder::new();
2268 let mut obj = builder.new_object();
2269 obj.insert("fallback", Variant::from("data"));
2270 obj.finish();
2271 let (_, value) = builder.finish();
2272 value
2273 };
2274
2275 let value_array = BinaryViewArray::from(vec![
2276 Some(empty_object_value.as_slice()), Some(row1_fallback.as_slice()), ]);
2279
2280 let x_typed_value = Int32Array::from(vec![Some(55), None]);
2283 let x_field_shredded = ShreddedVariantFieldArray::from_parts(
2284 None,
2285 Some(Arc::new(x_typed_value) as ArrayRef),
2286 None,
2287 );
2288
2289 let a_value_data = {
2294 let mut builder = parquet_variant::VariantBuilder::new();
2295 let obj = builder.new_object();
2296 obj.finish();
2297 let (_, value) = builder.finish();
2298 value
2299 };
2300 let a_value_array = BinaryViewArray::from(vec![
2301 None, Some(a_value_data.as_slice()), ]);
2304
2305 let a_inner_fields = Fields::from(vec![Field::new(
2306 "x",
2307 x_field_shredded.data_type().clone(),
2308 true,
2309 )]);
2310 let a_inner_typed_value = Arc::new(
2311 StructArray::try_new(a_inner_fields, vec![ArrayRef::from(x_field_shredded)], None)
2312 .unwrap(),
2313 ) as ArrayRef;
2314 let a_field_shredded = ShreddedVariantFieldArray::from_parts(
2315 Some(Arc::new(a_value_array)),
2316 Some(a_inner_typed_value),
2317 None,
2318 );
2319
2320 let typed_value_fields = Fields::from(vec![Field::new(
2322 "a",
2323 a_field_shredded.data_type().clone(),
2324 true,
2325 )]);
2326 let typed_value_struct = StructArray::try_new(
2327 typed_value_fields,
2328 vec![ArrayRef::from(a_field_shredded)],
2329 None,
2330 )
2331 .unwrap();
2332
2333 ArrayRef::from(VariantArray::from_parts(
2335 Arc::new(metadata_array),
2336 Some(Arc::new(value_array)),
2337 Some(Arc::new(typed_value_struct)),
2338 None,
2339 ))
2340 }
2341
2342 fn create_depth_2_shredded_test_data_working() -> ArrayRef {
2348 let (metadata, _) = {
2350 let mut builder = parquet_variant::VariantBuilder::new();
2352 let mut obj = builder.new_object();
2353
2354 let mut a_obj = obj.new_object("a");
2356 let mut b_obj = a_obj.new_object("b");
2357 b_obj.insert("x", Variant::Int32(100));
2358 b_obj.finish();
2359 a_obj.finish();
2360
2361 obj.finish();
2362 builder.finish()
2363 };
2364
2365 let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 3));
2366
2367 let empty_object_value = {
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
2376 let value_array = BinaryViewArray::from(vec![
2378 Some(empty_object_value.as_slice()), Some(empty_object_value.as_slice()), Some(empty_object_value.as_slice()), ]);
2382
2383 let x_typed_value = Int32Array::from(vec![Some(100), None, None]);
2387 let x_field_shredded = ShreddedVariantFieldArray::from_parts(
2388 None,
2389 Some(Arc::new(x_typed_value) as ArrayRef),
2390 None,
2391 );
2392
2393 let b_value_data = {
2395 let mut builder = parquet_variant::VariantBuilder::new();
2396 let obj = builder.new_object();
2397 obj.finish();
2398 let (_, value) = builder.finish();
2399 value
2400 };
2401 let b_value_array = BinaryViewArray::from(vec![
2402 None, Some(b_value_data.as_slice()), Some(b_value_data.as_slice()), ]);
2406
2407 let b_inner_fields = Fields::from(vec![Field::new(
2408 "x",
2409 x_field_shredded.data_type().clone(),
2410 true,
2411 )]);
2412 let b_inner_typed_value = Arc::new(
2413 StructArray::try_new(b_inner_fields, vec![ArrayRef::from(x_field_shredded)], None)
2414 .unwrap(),
2415 ) as ArrayRef;
2416 let b_field_shredded = ShreddedVariantFieldArray::from_parts(
2417 Some(Arc::new(b_value_array)),
2418 Some(b_inner_typed_value),
2419 None,
2420 );
2421
2422 let a_value_data = {
2424 let mut builder = parquet_variant::VariantBuilder::new();
2425 let obj = builder.new_object();
2426 obj.finish();
2427 let (_, value) = builder.finish();
2428 value
2429 };
2430 let a_value_array = BinaryViewArray::from(vec![
2431 None, Some(a_value_data.as_slice()), Some(a_value_data.as_slice()), ]);
2435
2436 let a_inner_fields = Fields::from(vec![Field::new(
2437 "b",
2438 b_field_shredded.data_type().clone(),
2439 true,
2440 )]);
2441 let a_inner_typed_value = Arc::new(
2442 StructArray::try_new(a_inner_fields, vec![ArrayRef::from(b_field_shredded)], None)
2443 .unwrap(),
2444 ) as ArrayRef;
2445 let a_field_shredded = ShreddedVariantFieldArray::from_parts(
2446 Some(Arc::new(a_value_array)),
2447 Some(a_inner_typed_value),
2448 None,
2449 );
2450
2451 let typed_value_fields = Fields::from(vec![Field::new(
2453 "a",
2454 a_field_shredded.data_type().clone(),
2455 true,
2456 )]);
2457 let typed_value_struct = StructArray::try_new(
2458 typed_value_fields,
2459 vec![ArrayRef::from(a_field_shredded)],
2460 None,
2461 )
2462 .unwrap();
2463
2464 ArrayRef::from(VariantArray::from_parts(
2466 Arc::new(metadata_array),
2467 Some(Arc::new(value_array)),
2468 Some(Arc::new(typed_value_struct)),
2469 None,
2470 ))
2471 }
2472
2473 #[test]
2474 fn test_field_path_non_struct_returns_missing_path_step() {
2475 let variant_array = perfectly_shredded_int32_variant_array();
2477
2478 for safe in [true, false] {
2479 let options = GetOptions {
2480 path: VariantPath::try_from("nonexistent_field").unwrap(),
2481 as_type: Some(Arc::new(Field::new("result", DataType::Int32, true))),
2482 cast_options: CastOptions {
2483 safe,
2484 ..Default::default()
2485 },
2486 };
2487
2488 let result_array = variant_get(&variant_array, options).unwrap();
2489 assert_eq!(result_array.len(), 3);
2490 assert!(result_array.is_null(0));
2491 assert!(result_array.is_null(1));
2492 assert!(result_array.is_null(2));
2493 }
2494 }
2495
2496 #[test]
2497 fn test_error_message_boolean_type_display() {
2498 let mut builder = VariantArrayBuilder::new(1);
2499 builder.append_variant(Variant::from("abcd"));
2500 let variant_array: ArrayRef = ArrayRef::from(builder.build());
2501
2502 let options = GetOptions {
2504 path: VariantPath::default(),
2505 as_type: Some(Arc::new(Field::new("result", DataType::Boolean, true))),
2506 cast_options: CastOptions {
2507 safe: false,
2508 ..Default::default()
2509 },
2510 };
2511
2512 let err = variant_get(&variant_array, options).unwrap_err();
2513 let msg = err.to_string();
2514 assert!(msg.contains("Failed to extract primitive of type Boolean"));
2515 }
2516
2517 #[test]
2518 fn test_error_message_numeric_type_display() {
2519 let mut builder = VariantArrayBuilder::new(1);
2520 builder.append_variant(Variant::from("abcd"));
2521 let variant_array: ArrayRef = ArrayRef::from(builder.build());
2522
2523 let options = GetOptions {
2525 path: VariantPath::default(),
2526 as_type: Some(Arc::new(Field::new("result", DataType::Float32, true))),
2527 cast_options: CastOptions {
2528 safe: false,
2529 ..Default::default()
2530 },
2531 };
2532
2533 let err = variant_get(&variant_array, options).unwrap_err();
2534 let msg = err.to_string();
2535 assert!(msg.contains("Failed to extract primitive of type Float32"));
2536 }
2537
2538 #[test]
2539 fn test_error_message_temporal_type_display() {
2540 let mut builder = VariantArrayBuilder::new(1);
2541 builder.append_variant(Variant::BooleanFalse);
2542 let variant_array: ArrayRef = ArrayRef::from(builder.build());
2543
2544 let options = GetOptions {
2546 path: VariantPath::default(),
2547 as_type: Some(Arc::new(Field::new(
2548 "result",
2549 DataType::Timestamp(TimeUnit::Nanosecond, None),
2550 true,
2551 ))),
2552 cast_options: CastOptions {
2553 safe: false,
2554 ..Default::default()
2555 },
2556 };
2557
2558 let err = variant_get(&variant_array, options).unwrap_err();
2559 let msg = err.to_string();
2560 assert!(msg.contains("Failed to extract primitive of type Timestamp(ns)"));
2561 }
2562
2563 #[test]
2564 fn test_null_buffer_union_for_shredded_paths() {
2565 let variant_array = create_depth_1_shredded_test_data_working();
2574
2575 let options = GetOptions {
2580 path: VariantPath::try_from("a.x").unwrap(),
2581 as_type: Some(Arc::new(Field::new("result", DataType::Int32, true))),
2582 cast_options: CastOptions::default(),
2583 };
2584
2585 let result = variant_get(&variant_array, options).unwrap();
2586
2587 assert_eq!(result.len(), variant_array.len());
2589
2590 assert!(!result.is_null(0), "Row 0 should have valid Int32 data");
2594 assert!(
2595 result.is_null(1),
2596 "Row 1 should be null due to type casting failure"
2597 );
2598
2599 let int32_result = result.as_any().downcast_ref::<Int32Array>().unwrap();
2601 assert_eq!(int32_result.value(0), 55); }
2603
2604 #[test]
2605 fn test_struct_null_mask_union_from_children() {
2606 let json_strings = vec![
2611 r#"{"a": 42, "b": "hello"}"#, r#"{"a": "world", "b": 100}"#, r#"{"a": 55, "b": 77}"#, ];
2615
2616 let string_array: Arc<dyn arrow::array::Array> = Arc::new(StringArray::from(json_strings));
2617 let variant_array = json_to_variant(&string_array).unwrap();
2618
2619 let struct_fields = Fields::from(vec![
2622 Field::new("a", DataType::Int32, true),
2623 Field::new("b", DataType::Int32, true),
2624 ]);
2625 let struct_type = DataType::Struct(struct_fields);
2626
2627 let options = GetOptions {
2628 path: VariantPath::default(), as_type: Some(Arc::new(Field::new("result", struct_type, true))),
2630 cast_options: CastOptions::default(),
2631 };
2632
2633 let variant_array_ref = ArrayRef::from(variant_array);
2634 let result = variant_get(&variant_array_ref, options).unwrap();
2635
2636 let struct_result = result.as_struct();
2638 assert_eq!(struct_result.len(), 3);
2639
2640 let field_a = struct_result
2642 .column(0)
2643 .as_any()
2644 .downcast_ref::<Int32Array>()
2645 .unwrap();
2646 let field_b = struct_result
2647 .column(1)
2648 .as_any()
2649 .downcast_ref::<Int32Array>()
2650 .unwrap();
2651
2652 assert!(!field_a.is_null(0));
2655 assert_eq!(field_a.value(0), 42);
2656 assert!(field_b.is_null(0)); assert!(field_a.is_null(1)); assert!(!field_b.is_null(1));
2661 assert_eq!(field_b.value(1), 100);
2662
2663 assert!(!field_a.is_null(2));
2665 assert_eq!(field_a.value(2), 55);
2666 assert!(!field_b.is_null(2));
2667 assert_eq!(field_b.value(2), 77);
2668
2669 assert!(!struct_result.is_null(0)); assert!(!struct_result.is_null(1)); assert!(!struct_result.is_null(2)); }
2676
2677 #[test]
2678 fn test_field_nullability_preservation() {
2679 let json_strings = vec![
2682 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}"#, ];
2692
2693 let string_array: Arc<dyn arrow::array::Array> = Arc::new(StringArray::from(json_strings));
2694 let variant_array = json_to_variant(&string_array).unwrap();
2695
2696 let nullable_field = Arc::new(Field::new("result", DataType::Int32, true));
2698 let options_nullable = GetOptions {
2699 path: VariantPath::try_from("x").unwrap(),
2700 as_type: Some(nullable_field.clone()),
2701 cast_options: CastOptions::default(),
2702 };
2703
2704 let variant_array_ref = ArrayRef::from(variant_array);
2705 let result_nullable = variant_get(&variant_array_ref, options_nullable).unwrap();
2706
2707 let int32_result = result_nullable
2709 .as_any()
2710 .downcast_ref::<Int32Array>()
2711 .unwrap();
2712 assert_eq!(int32_result.len(), 9);
2713
2714 assert!(!int32_result.is_null(0));
2716 assert_eq!(int32_result.value(0), 42);
2717
2718 assert!(int32_result.is_null(1));
2720
2721 assert!(int32_result.is_null(2));
2723
2724 assert!(int32_result.is_null(3));
2726
2727 assert!(int32_result.is_null(4));
2729
2730 assert!(!int32_result.is_null(5));
2733 assert_eq!(int32_result.value(5), 127);
2734
2735 assert!(!int32_result.is_null(6));
2738 assert_eq!(int32_result.value(6), 32767);
2739
2740 assert!(!int32_result.is_null(7));
2743 assert_eq!(int32_result.value(7), 2147483647);
2744
2745 assert!(int32_result.is_null(8));
2748
2749 let non_nullable_field = Arc::new(Field::new("result", DataType::Int32, false));
2751 let options_non_nullable = GetOptions {
2752 path: VariantPath::try_from("x").unwrap(),
2753 as_type: Some(non_nullable_field.clone()),
2754 cast_options: CastOptions::default(), };
2756
2757 let variant_array_2 = json_to_variant(&string_array).unwrap();
2759 let variant_array_ref_2 = ArrayRef::from(variant_array_2);
2760 let result_non_nullable = variant_get(&variant_array_ref_2, options_non_nullable).unwrap();
2761 let int32_result_2 = result_non_nullable
2762 .as_any()
2763 .downcast_ref::<Int32Array>()
2764 .unwrap();
2765
2766 assert_eq!(int32_result_2.len(), 9);
2768
2769 assert!(!int32_result_2.is_null(0));
2771 assert_eq!(int32_result_2.value(0), 42);
2772
2773 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);
2783 assert!(!int32_result_2.is_null(6)); assert_eq!(int32_result_2.value(6), 32767);
2785 assert!(!int32_result_2.is_null(7)); assert_eq!(int32_result_2.value(7), 2147483647);
2787
2788 assert!(int32_result_2.is_null(8)); }
2791
2792 #[test]
2793 fn test_struct_extraction_subset_superset_schema_perfectly_shredded() {
2794 let variant_array = create_comprehensive_shredded_variant();
2796
2797 let struct_fields = Fields::from(vec![
2799 Field::new("a", DataType::Int32, true),
2800 Field::new("b", DataType::Int32, true),
2801 Field::new("d", DataType::Int32, true),
2802 ]);
2803 let struct_type = DataType::Struct(struct_fields);
2804
2805 let options = GetOptions {
2806 path: VariantPath::default(),
2807 as_type: Some(Arc::new(Field::new("result", struct_type, true))),
2808 cast_options: CastOptions::default(),
2809 };
2810
2811 let result = variant_get(&variant_array, options).unwrap();
2812
2813 let struct_result = result.as_any().downcast_ref::<StructArray>().unwrap();
2815 assert_eq!(struct_result.len(), 5);
2816 assert_eq!(struct_result.num_columns(), 3);
2817
2818 let field_a = struct_result
2819 .column(0)
2820 .as_any()
2821 .downcast_ref::<Int32Array>()
2822 .unwrap();
2823 let field_b = struct_result
2824 .column(1)
2825 .as_any()
2826 .downcast_ref::<Int32Array>()
2827 .unwrap();
2828 let field_d = struct_result
2829 .column(2)
2830 .as_any()
2831 .downcast_ref::<Int32Array>()
2832 .unwrap();
2833
2834 assert!(!struct_result.is_null(0));
2836 assert_eq!(field_a.value(0), 1);
2837 assert_eq!(field_b.value(0), 2);
2838 assert!(field_d.is_null(0)); assert!(struct_result.is_null(1));
2842
2843 assert!(!struct_result.is_null(2));
2845 assert!(field_a.is_null(2)); assert_eq!(field_b.value(2), 2);
2847 assert!(field_d.is_null(2)); assert!(!struct_result.is_null(3));
2851 assert_eq!(field_a.value(3), 1);
2852 assert!(field_b.is_null(3)); assert!(field_d.is_null(3)); assert!(!struct_result.is_null(4));
2857 assert!(field_a.is_null(4)); assert!(field_b.is_null(4)); assert!(field_d.is_null(4)); }
2861
2862 #[test]
2863 fn test_nested_struct_extraction_perfectly_shredded() {
2864 let variant_array = create_comprehensive_nested_shredded_variant();
2866 println!("variant_array: {variant_array:?}");
2867
2868 let inner_field = Field::new("inner", DataType::Int32, true);
2870 let inner_type = DataType::Struct(Fields::from(vec![inner_field]));
2871 let outer_field = Field::new("outer", inner_type, true);
2872 let result_type = DataType::Struct(Fields::from(vec![outer_field]));
2873
2874 let options = GetOptions {
2875 path: VariantPath::default(),
2876 as_type: Some(Arc::new(Field::new("result", result_type, true))),
2877 cast_options: CastOptions::default(),
2878 };
2879
2880 let result = variant_get(&variant_array, options).unwrap();
2881 println!("result: {result:?}");
2882
2883 let outer_struct = result.as_any().downcast_ref::<StructArray>().unwrap();
2885 assert_eq!(outer_struct.len(), 4);
2886 assert_eq!(outer_struct.num_columns(), 1);
2887
2888 let inner_struct = outer_struct
2890 .column(0)
2891 .as_any()
2892 .downcast_ref::<StructArray>()
2893 .unwrap();
2894 assert_eq!(inner_struct.num_columns(), 1);
2895
2896 let leaf_field = inner_struct
2898 .column(0)
2899 .as_any()
2900 .downcast_ref::<Int32Array>()
2901 .unwrap();
2902
2903 assert!(!outer_struct.is_null(0));
2905 assert!(!inner_struct.is_null(0));
2906 assert_eq!(leaf_field.value(0), 42);
2907
2908 assert!(!outer_struct.is_null(1));
2910 assert!(!inner_struct.is_null(1)); assert!(leaf_field.is_null(1)); assert!(!outer_struct.is_null(2));
2915 assert!(inner_struct.is_null(2)); assert!(outer_struct.is_null(3));
2919 }
2920
2921 #[test]
2922 fn test_path_based_null_masks_one_step() {
2923 let variant_array = create_comprehensive_nested_shredded_variant();
2925
2926 let path = VariantPath::try_from("outer").unwrap();
2928 let inner_field = Field::new("inner", DataType::Int32, true);
2929 let result_type = DataType::Struct(Fields::from(vec![inner_field]));
2930
2931 let options = GetOptions {
2932 path,
2933 as_type: Some(Arc::new(Field::new("result", result_type, true))),
2934 cast_options: CastOptions::default(),
2935 };
2936
2937 let result = variant_get(&variant_array, options).unwrap();
2938
2939 let outer_result = result.as_any().downcast_ref::<StructArray>().unwrap();
2941 assert_eq!(outer_result.len(), 4);
2942 assert_eq!(outer_result.num_columns(), 1);
2943
2944 let inner_field = outer_result
2946 .column(0)
2947 .as_any()
2948 .downcast_ref::<Int32Array>()
2949 .unwrap();
2950
2951 assert!(!outer_result.is_null(0));
2953 assert_eq!(inner_field.value(0), 42);
2954
2955 assert!(!outer_result.is_null(1));
2957 assert!(inner_field.is_null(1));
2958
2959 assert!(outer_result.is_null(2));
2961
2962 assert!(outer_result.is_null(3));
2964 }
2965
2966 #[test]
2967 fn test_path_based_null_masks_two_steps() {
2968 let variant_array = create_comprehensive_nested_shredded_variant();
2970
2971 let path = VariantPath::try_from("outer").unwrap().join("inner");
2973
2974 let options = GetOptions {
2975 path,
2976 as_type: Some(Arc::new(Field::new("result", DataType::Int32, true))),
2977 cast_options: CastOptions::default(),
2978 };
2979
2980 let result = variant_get(&variant_array, options).unwrap();
2981
2982 let int_result = result.as_any().downcast_ref::<Int32Array>().unwrap();
2984 assert_eq!(int_result.len(), 4);
2985
2986 assert!(!int_result.is_null(0));
2988 assert_eq!(int_result.value(0), 42);
2989
2990 assert!(int_result.is_null(1));
2992
2993 assert!(int_result.is_null(2));
2995
2996 assert!(int_result.is_null(3));
2998 }
2999
3000 #[test]
3001 fn test_struct_extraction_mixed_and_unshredded() {
3002 let variant_array = create_mixed_and_unshredded_variant();
3004
3005 let struct_fields = Fields::from(vec![
3007 Field::new("x", DataType::Int32, true),
3008 Field::new("y", DataType::Int32, true),
3009 ]);
3010 let struct_type = DataType::Struct(struct_fields);
3011
3012 let options = GetOptions {
3013 path: VariantPath::default(),
3014 as_type: Some(Arc::new(Field::new("result", struct_type, true))),
3015 cast_options: CastOptions::default(),
3016 };
3017
3018 let result = variant_get(&variant_array, options).unwrap();
3019
3020 let struct_result = result.as_any().downcast_ref::<StructArray>().unwrap();
3022 assert_eq!(struct_result.len(), 4);
3023 assert_eq!(struct_result.num_columns(), 2);
3024
3025 let field_x = struct_result
3026 .column(0)
3027 .as_any()
3028 .downcast_ref::<Int32Array>()
3029 .unwrap();
3030 let field_y = struct_result
3031 .column(1)
3032 .as_any()
3033 .downcast_ref::<Int32Array>()
3034 .unwrap();
3035
3036 assert_eq!(field_x.value(0), 1);
3038 assert_eq!(field_y.value(0), 42);
3039
3040 assert_eq!(field_x.value(1), 2);
3042 assert!(field_y.is_null(1));
3043
3044 assert_eq!(field_x.value(2), 3);
3046 assert!(field_y.is_null(2));
3047
3048 assert!(struct_result.is_null(3));
3050 }
3051
3052 #[test]
3053 fn test_struct_row_builder_handles_unshredded_nested_structs() {
3054 let json_strings = vec![
3056 r#"{"outer": {"inner": 42}}"#,
3057 r#"{"outer": {"inner": 100}}"#,
3058 ];
3059 let string_array: Arc<dyn Array> = Arc::new(StringArray::from(json_strings));
3060 let variant_array = json_to_variant(&string_array).unwrap();
3061
3062 let inner_fields = Fields::from(vec![Field::new("inner", DataType::Int32, true)]);
3064 let inner_struct_type = DataType::Struct(inner_fields);
3065 let outer_fields = Fields::from(vec![Field::new("outer", inner_struct_type, true)]);
3066 let outer_struct_type = DataType::Struct(outer_fields);
3067
3068 let options = GetOptions {
3069 path: VariantPath::default(),
3070 as_type: Some(Arc::new(Field::new("result", outer_struct_type, true))),
3071 cast_options: CastOptions::default(),
3072 };
3073
3074 let variant_array_ref = ArrayRef::from(variant_array);
3075 let result = variant_get(&variant_array_ref, options).unwrap();
3076
3077 let outer_struct = result.as_struct();
3078 assert_eq!(outer_struct.len(), 2);
3079 assert_eq!(outer_struct.num_columns(), 1);
3080
3081 let inner_struct = outer_struct.column(0).as_struct();
3082 assert_eq!(inner_struct.num_columns(), 1);
3083
3084 let inner_values = inner_struct
3085 .column(0)
3086 .as_any()
3087 .downcast_ref::<Int32Array>()
3088 .unwrap();
3089 assert_eq!(inner_values.value(0), 42);
3090 assert_eq!(inner_values.value(1), 100);
3091 }
3092
3093 #[test]
3094 fn test_unshredded_struct_safe_cast_non_object_rows_are_null() {
3095 let json_strings = vec![r#"{"a": 1, "b": 2}"#, "123", "{}"];
3096 let string_array: Arc<dyn Array> = Arc::new(StringArray::from(json_strings));
3097 let variant_array_ref = ArrayRef::from(json_to_variant(&string_array).unwrap());
3098
3099 let struct_fields = Fields::from(vec![
3100 Field::new("a", DataType::Int32, true),
3101 Field::new("b", DataType::Int32, true),
3102 ]);
3103 let options = GetOptions {
3104 path: VariantPath::default(),
3105 as_type: Some(Arc::new(Field::new(
3106 "result",
3107 DataType::Struct(struct_fields),
3108 true,
3109 ))),
3110 cast_options: CastOptions::default(),
3111 };
3112
3113 let result = variant_get(&variant_array_ref, options).unwrap();
3114 let struct_result = result.as_struct();
3115 let field_a = struct_result
3116 .column(0)
3117 .as_primitive::<arrow::datatypes::Int32Type>();
3118 let field_b = struct_result
3119 .column(1)
3120 .as_primitive::<arrow::datatypes::Int32Type>();
3121
3122 assert!(!struct_result.is_null(0));
3124 assert_eq!(field_a.value(0), 1);
3125 assert_eq!(field_b.value(0), 2);
3126
3127 assert!(struct_result.is_null(1));
3129 assert!(field_a.is_null(1));
3130 assert!(field_b.is_null(1));
3131
3132 assert!(!struct_result.is_null(2));
3134 assert!(field_a.is_null(2));
3135 assert!(field_b.is_null(2));
3136 }
3137
3138 #[test]
3139 fn test_unshredded_struct_strict_cast_non_object_errors() {
3140 let json_strings = vec![r#"{"a": 1, "b": 2}"#, "123"];
3141 let string_array: Arc<dyn Array> = Arc::new(StringArray::from(json_strings));
3142 let variant_array_ref = ArrayRef::from(json_to_variant(&string_array).unwrap());
3143
3144 let struct_fields = Fields::from(vec![
3145 Field::new("a", DataType::Int32, true),
3146 Field::new("b", DataType::Int32, true),
3147 ]);
3148 let options = GetOptions {
3149 path: VariantPath::default(),
3150 as_type: Some(Arc::new(Field::new(
3151 "result",
3152 DataType::Struct(struct_fields),
3153 true,
3154 ))),
3155 cast_options: CastOptions {
3156 safe: false,
3157 ..Default::default()
3158 },
3159 };
3160
3161 let err = variant_get(&variant_array_ref, options).unwrap_err();
3162 assert!(
3163 err.to_string()
3164 .contains("Failed to extract struct from variant")
3165 );
3166 }
3167
3168 fn create_comprehensive_shredded_variant() -> ArrayRef {
3171 let (metadata, _) = {
3172 let mut builder = parquet_variant::VariantBuilder::new();
3173 let obj = builder.new_object();
3174 obj.finish();
3175 builder.finish()
3176 };
3177
3178 let nulls = NullBuffer::from(vec![
3180 true, false, true, true, true, ]);
3186
3187 let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 5));
3188
3189 let a_field_typed_value = Int32Array::from(vec![Some(1), None, None, Some(1), None]);
3192 let a_field_shredded = ShreddedVariantFieldArray::from_parts(
3193 None,
3194 Some(Arc::new(a_field_typed_value) as ArrayRef),
3195 None,
3196 );
3197
3198 let b_field_typed_value = Int32Array::from(vec![Some(2), None, Some(2), None, None]);
3200 let b_field_shredded = ShreddedVariantFieldArray::from_parts(
3201 None,
3202 Some(Arc::new(b_field_typed_value) as ArrayRef),
3203 None,
3204 );
3205
3206 let c_field_typed_value = Int32Array::from(vec![Some(3), None, None, None, None]);
3208 let c_field_shredded = ShreddedVariantFieldArray::from_parts(
3209 None,
3210 Some(Arc::new(c_field_typed_value) as ArrayRef),
3211 None,
3212 );
3213
3214 let typed_value_fields = Fields::from(vec![
3216 Field::new("a", a_field_shredded.data_type().clone(), true),
3217 Field::new("b", b_field_shredded.data_type().clone(), true),
3218 Field::new("c", c_field_shredded.data_type().clone(), true),
3219 ]);
3220 let typed_value_struct = StructArray::try_new(
3221 typed_value_fields,
3222 vec![
3223 ArrayRef::from(a_field_shredded),
3224 ArrayRef::from(b_field_shredded),
3225 ArrayRef::from(c_field_shredded),
3226 ],
3227 None,
3228 )
3229 .unwrap();
3230
3231 ArrayRef::from(VariantArray::from_parts(
3233 Arc::new(metadata_array),
3234 None,
3235 Some(Arc::new(typed_value_struct)),
3236 Some(nulls),
3237 ))
3238 }
3239
3240 fn create_comprehensive_nested_shredded_variant() -> ArrayRef {
3245 let inner_typed_value = Int32Array::from(vec![Some(42), None, None, None]); let inner = ShreddedVariantFieldArray::from_parts(
3249 None,
3250 Some(Arc::new(inner_typed_value) as ArrayRef),
3251 None,
3252 );
3253
3254 let outer_typed_value_nulls = NullBuffer::from(vec![
3255 true, false, false, false, ]);
3260 let outer_typed_value = StructArrayBuilder::new()
3261 .with_field("inner", ArrayRef::from(inner), false)
3262 .with_nulls(outer_typed_value_nulls)
3263 .build();
3264
3265 let outer = ShreddedVariantFieldArray::from_parts(
3266 None,
3267 Some(Arc::new(outer_typed_value) as ArrayRef),
3268 None,
3269 );
3270
3271 let typed_value_nulls = NullBuffer::from(vec![
3272 true, true, false, false, ]);
3277 let typed_value = StructArrayBuilder::new()
3278 .with_field("outer", ArrayRef::from(outer), false)
3279 .with_nulls(typed_value_nulls)
3280 .build();
3281
3282 let metadata_array =
3284 BinaryViewArray::from_iter_values(std::iter::repeat_n(EMPTY_VARIANT_METADATA_BYTES, 4));
3285 let nulls = NullBuffer::from(vec![
3286 true, true, true, false, ]);
3291 ArrayRef::from(VariantArray::from_parts(
3292 Arc::new(metadata_array),
3293 None,
3294 Some(Arc::new(typed_value)),
3295 Some(nulls),
3296 ))
3297 }
3298
3299 fn create_mixed_and_unshredded_variant() -> ArrayRef {
3302 let (metadata, y_field_value) = {
3307 let mut builder = parquet_variant::VariantBuilder::new();
3308 let mut obj = builder.new_object();
3309 obj.insert("y", Variant::from(42));
3310 obj.finish();
3311 builder.finish()
3312 };
3313
3314 let metadata_array = BinaryViewArray::from_iter_values(std::iter::repeat_n(&metadata, 4));
3315
3316 let empty_object_value = {
3323 let mut builder = parquet_variant::VariantBuilder::new();
3324 builder.new_object().finish();
3325 let (_, value) = builder.finish();
3326 value
3327 };
3328
3329 let y_null_value = {
3330 let mut builder = parquet_variant::VariantBuilder::new();
3331 builder.new_object().with_field("y", Variant::Null).finish();
3332 let (_, value) = builder.finish();
3333 value
3334 };
3335
3336 let value_array = BinaryViewArray::from(vec![
3337 Some(y_field_value.as_slice()), Some(empty_object_value.as_slice()), Some(y_null_value.as_slice()), Some(empty_object_value.as_slice()), ]);
3342
3343 let x_field_typed_value = Int32Array::from(vec![Some(1), Some(2), Some(3), Some(0)]);
3346 let x_field_shredded = ShreddedVariantFieldArray::from_parts(
3347 None,
3348 Some(Arc::new(x_field_typed_value) as ArrayRef),
3349 None,
3350 );
3351
3352 let typed_value_struct = StructArrayBuilder::new()
3354 .with_field("x", ArrayRef::from(x_field_shredded), false)
3355 .build();
3356
3357 let variant_nulls = NullBuffer::from(vec![true, true, true, false]); ArrayRef::from(VariantArray::from_parts(
3361 Arc::new(metadata_array),
3362 Some(Arc::new(value_array)),
3363 Some(Arc::new(typed_value_struct)),
3364 Some(variant_nulls),
3365 ))
3366 }
3367
3368 #[test]
3369 fn get_decimal32_rescaled_to_scale2() {
3370 let mut builder = crate::VariantArrayBuilder::new(5);
3372 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();
3376 builder.append_variant(
3377 VariantDecimal8::try_new((VariantDecimal4::MAX_UNSCALED_VALUE as i64) + 1, 3)
3378 .unwrap()
3379 .into(),
3380 ); let variant_array: ArrayRef = ArrayRef::from(builder.build());
3382
3383 let field = Field::new("result", DataType::Decimal32(9, 2), true);
3384 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3385 let result = variant_get(&variant_array, options).unwrap();
3386 let result = result.as_any().downcast_ref::<Decimal32Array>().unwrap();
3387
3388 assert_eq!(result.precision(), 9);
3389 assert_eq!(result.scale(), 2);
3390 assert_eq!(result.value(0), 1234);
3391 assert_eq!(result.value(1), 123);
3392 assert_eq!(result.value(2), 123400);
3393 assert!(result.is_null(3));
3394 assert_eq!(
3395 result.value(4),
3396 VariantDecimal4::MAX_UNSCALED_VALUE / 10 + 1
3397 ); }
3399
3400 #[test]
3401 fn get_decimal32_scale_down_rounding() {
3402 let mut builder = crate::VariantArrayBuilder::new(7);
3403 builder.append_variant(VariantDecimal4::try_new(1235, 0).unwrap().into());
3404 builder.append_variant(VariantDecimal4::try_new(1245, 0).unwrap().into());
3405 builder.append_variant(VariantDecimal4::try_new(-1235, 0).unwrap().into());
3406 builder.append_variant(VariantDecimal4::try_new(-1245, 0).unwrap().into());
3407 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());
3411
3412 let field = Field::new("result", DataType::Decimal32(9, -1), true);
3413 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3414 let result = variant_get(&variant_array, options).unwrap();
3415 let result = result.as_any().downcast_ref::<Decimal32Array>().unwrap();
3416
3417 assert_eq!(result.precision(), 9);
3418 assert_eq!(result.scale(), -1);
3419 assert_eq!(result.value(0), 124);
3420 assert_eq!(result.value(1), 125);
3421 assert_eq!(result.value(2), -124);
3422 assert_eq!(result.value(3), -125);
3423 assert_eq!(result.value(4), 1);
3424 assert!(result.is_valid(5));
3425 assert_eq!(result.value(5), 0);
3426 assert_eq!(result.value(6), 1);
3427 }
3428
3429 #[test]
3430 fn get_decimal32_large_scale_reduction() {
3431 let mut builder = crate::VariantArrayBuilder::new(2);
3432 builder.append_variant(
3433 VariantDecimal4::try_new(-VariantDecimal4::MAX_UNSCALED_VALUE, 0)
3434 .unwrap()
3435 .into(),
3436 );
3437 builder.append_variant(
3438 VariantDecimal4::try_new(VariantDecimal4::MAX_UNSCALED_VALUE, 0)
3439 .unwrap()
3440 .into(),
3441 );
3442 let variant_array: ArrayRef = ArrayRef::from(builder.build());
3443
3444 let field = Field::new("result", DataType::Decimal32(9, -9), true);
3445 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3446 let result = variant_get(&variant_array, options).unwrap();
3447 let result = result.as_any().downcast_ref::<Decimal32Array>().unwrap();
3448
3449 assert_eq!(result.precision(), 9);
3450 assert_eq!(result.scale(), -9);
3451 assert_eq!(result.value(0), -1);
3452 assert_eq!(result.value(1), 1);
3453
3454 let field = Field::new("result", DataType::Decimal32(9, -10), true);
3455 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3456 let result = variant_get(&variant_array, options).unwrap();
3457 let result = result.as_any().downcast_ref::<Decimal32Array>().unwrap();
3458
3459 assert_eq!(result.precision(), 9);
3460 assert_eq!(result.scale(), -10);
3461 assert!(result.is_valid(0));
3462 assert_eq!(result.value(0), 0);
3463 assert!(result.is_valid(1));
3464 assert_eq!(result.value(1), 0);
3465 }
3466
3467 #[test]
3468 fn get_decimal32_precision_overflow_safe() {
3469 let mut builder = crate::VariantArrayBuilder::new(2);
3471 builder.append_variant(
3472 VariantDecimal4::try_new(VariantDecimal4::MAX_UNSCALED_VALUE, 0)
3473 .unwrap()
3474 .into(),
3475 );
3476 builder.append_variant(
3477 VariantDecimal4::try_new(VariantDecimal4::MAX_UNSCALED_VALUE, 9)
3478 .unwrap()
3479 .into(),
3480 ); let variant_array: ArrayRef = ArrayRef::from(builder.build());
3482
3483 let field = Field::new("result", DataType::Decimal32(2, 2), true);
3484 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3485 let result = variant_get(&variant_array, options).unwrap();
3486 let result = result.as_any().downcast_ref::<Decimal32Array>().unwrap();
3487
3488 assert!(result.is_null(0));
3489 assert!(result.is_null(1)); }
3491
3492 #[test]
3493 fn get_decimal32_precision_overflow_unsafe_errors() {
3494 let mut builder = crate::VariantArrayBuilder::new(1);
3495 builder.append_variant(
3496 VariantDecimal4::try_new(VariantDecimal4::MAX_UNSCALED_VALUE, 0)
3497 .unwrap()
3498 .into(),
3499 );
3500 let variant_array: ArrayRef = ArrayRef::from(builder.build());
3501
3502 let field = Field::new("result", DataType::Decimal32(9, 2), true);
3503 let cast_options = CastOptions {
3504 safe: false,
3505 ..Default::default()
3506 };
3507 let options = GetOptions::new()
3508 .with_as_type(Some(FieldRef::from(field)))
3509 .with_cast_options(cast_options);
3510 let err = variant_get(&variant_array, options).unwrap_err();
3511
3512 assert!(
3513 err.to_string().contains(
3514 "Failed to cast to Decimal32(precision=9, scale=2) from variant Decimal4"
3515 )
3516 );
3517 }
3518
3519 #[test]
3520 fn get_decimal64_rescaled_to_scale2() {
3521 let mut builder = crate::VariantArrayBuilder::new(5);
3522 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();
3526 builder.append_variant(
3527 VariantDecimal16::try_new((VariantDecimal8::MAX_UNSCALED_VALUE as i128) + 1, 3)
3528 .unwrap()
3529 .into(),
3530 ); let variant_array: ArrayRef = ArrayRef::from(builder.build());
3532
3533 let field = Field::new("result", DataType::Decimal64(18, 2), true);
3534 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3535 let result = variant_get(&variant_array, options).unwrap();
3536 let result = result.as_any().downcast_ref::<Decimal64Array>().unwrap();
3537
3538 assert_eq!(result.precision(), 18);
3539 assert_eq!(result.scale(), 2);
3540 assert_eq!(result.value(0), 1234);
3541 assert_eq!(result.value(1), 123);
3542 assert_eq!(result.value(2), 123400);
3543 assert!(result.is_null(3));
3544 assert_eq!(
3545 result.value(4),
3546 VariantDecimal8::MAX_UNSCALED_VALUE / 10 + 1
3547 ); }
3549
3550 #[test]
3551 fn get_decimal64_scale_down_rounding() {
3552 let mut builder = crate::VariantArrayBuilder::new(7);
3553 builder.append_variant(VariantDecimal8::try_new(1235, 0).unwrap().into());
3554 builder.append_variant(VariantDecimal8::try_new(1245, 0).unwrap().into());
3555 builder.append_variant(VariantDecimal8::try_new(-1235, 0).unwrap().into());
3556 builder.append_variant(VariantDecimal8::try_new(-1245, 0).unwrap().into());
3557 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());
3561
3562 let field = Field::new("result", DataType::Decimal64(18, -1), true);
3563 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3564 let result = variant_get(&variant_array, options).unwrap();
3565 let result = result.as_any().downcast_ref::<Decimal64Array>().unwrap();
3566
3567 assert_eq!(result.precision(), 18);
3568 assert_eq!(result.scale(), -1);
3569 assert_eq!(result.value(0), 124);
3570 assert_eq!(result.value(1), 125);
3571 assert_eq!(result.value(2), -124);
3572 assert_eq!(result.value(3), -125);
3573 assert_eq!(result.value(4), 1);
3574 assert!(result.is_valid(5));
3575 assert_eq!(result.value(5), 0);
3576 assert_eq!(result.value(6), 1);
3577 }
3578
3579 #[test]
3580 fn get_decimal64_large_scale_reduction() {
3581 let mut builder = crate::VariantArrayBuilder::new(2);
3582 builder.append_variant(
3583 VariantDecimal8::try_new(-VariantDecimal8::MAX_UNSCALED_VALUE, 0)
3584 .unwrap()
3585 .into(),
3586 );
3587 builder.append_variant(
3588 VariantDecimal8::try_new(VariantDecimal8::MAX_UNSCALED_VALUE, 0)
3589 .unwrap()
3590 .into(),
3591 );
3592 let variant_array: ArrayRef = ArrayRef::from(builder.build());
3593
3594 let field = Field::new("result", DataType::Decimal64(18, -18), true);
3595 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3596 let result = variant_get(&variant_array, options).unwrap();
3597 let result = result.as_any().downcast_ref::<Decimal64Array>().unwrap();
3598
3599 assert_eq!(result.precision(), 18);
3600 assert_eq!(result.scale(), -18);
3601 assert_eq!(result.value(0), -1);
3602 assert_eq!(result.value(1), 1);
3603
3604 let field = Field::new("result", DataType::Decimal64(18, -19), true);
3605 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3606 let result = variant_get(&variant_array, options).unwrap();
3607 let result = result.as_any().downcast_ref::<Decimal64Array>().unwrap();
3608
3609 assert_eq!(result.precision(), 18);
3610 assert_eq!(result.scale(), -19);
3611 assert!(result.is_valid(0));
3612 assert_eq!(result.value(0), 0);
3613 assert!(result.is_valid(1));
3614 assert_eq!(result.value(1), 0);
3615 }
3616
3617 #[test]
3618 fn get_decimal64_precision_overflow_safe() {
3619 let mut builder = crate::VariantArrayBuilder::new(2);
3621 builder.append_variant(
3622 VariantDecimal8::try_new(VariantDecimal8::MAX_UNSCALED_VALUE, 0)
3623 .unwrap()
3624 .into(),
3625 );
3626 builder.append_variant(
3627 VariantDecimal8::try_new(VariantDecimal8::MAX_UNSCALED_VALUE, 18)
3628 .unwrap()
3629 .into(),
3630 ); let variant_array: ArrayRef = ArrayRef::from(builder.build());
3632
3633 let field = Field::new("result", DataType::Decimal64(2, 2), true);
3634 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3635 let result = variant_get(&variant_array, options).unwrap();
3636 let result = result.as_any().downcast_ref::<Decimal64Array>().unwrap();
3637
3638 assert!(result.is_null(0));
3639 assert!(result.is_null(1));
3640 }
3641
3642 #[test]
3643 fn get_decimal64_precision_overflow_unsafe_errors() {
3644 let mut builder = crate::VariantArrayBuilder::new(1);
3645 builder.append_variant(
3646 VariantDecimal8::try_new(VariantDecimal8::MAX_UNSCALED_VALUE, 0)
3647 .unwrap()
3648 .into(),
3649 );
3650 let variant_array: ArrayRef = ArrayRef::from(builder.build());
3651
3652 let field = Field::new("result", DataType::Decimal64(18, 2), true);
3653 let cast_options = CastOptions {
3654 safe: false,
3655 ..Default::default()
3656 };
3657 let options = GetOptions::new()
3658 .with_as_type(Some(FieldRef::from(field)))
3659 .with_cast_options(cast_options);
3660 let err = variant_get(&variant_array, options).unwrap_err();
3661
3662 assert!(
3663 err.to_string().contains(
3664 "Failed to cast to Decimal64(precision=18, scale=2) from variant Decimal8"
3665 )
3666 );
3667 }
3668
3669 #[test]
3670 fn get_decimal128_rescaled_to_scale2() {
3671 let mut builder = crate::VariantArrayBuilder::new(4);
3672 builder.append_variant(VariantDecimal16::try_new(1234, 2).unwrap().into());
3673 builder.append_variant(VariantDecimal16::try_new(1234, 3).unwrap().into());
3674 builder.append_variant(VariantDecimal16::try_new(1234, 0).unwrap().into());
3675 builder.append_null();
3676 let variant_array: ArrayRef = ArrayRef::from(builder.build());
3677
3678 let field = Field::new("result", DataType::Decimal128(38, 2), true);
3679 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3680 let result = variant_get(&variant_array, options).unwrap();
3681 let result = result.as_any().downcast_ref::<Decimal128Array>().unwrap();
3682
3683 assert_eq!(result.precision(), 38);
3684 assert_eq!(result.scale(), 2);
3685 assert_eq!(result.value(0), 1234);
3686 assert_eq!(result.value(1), 123);
3687 assert_eq!(result.value(2), 123400);
3688 assert!(result.is_null(3));
3689 }
3690
3691 #[test]
3692 fn get_decimal128_scale_down_rounding() {
3693 let mut builder = crate::VariantArrayBuilder::new(7);
3694 builder.append_variant(VariantDecimal16::try_new(1235, 0).unwrap().into());
3695 builder.append_variant(VariantDecimal16::try_new(1245, 0).unwrap().into());
3696 builder.append_variant(VariantDecimal16::try_new(-1235, 0).unwrap().into());
3697 builder.append_variant(VariantDecimal16::try_new(-1245, 0).unwrap().into());
3698 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());
3702
3703 let field = Field::new("result", DataType::Decimal128(38, -1), true);
3704 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3705 let result = variant_get(&variant_array, options).unwrap();
3706 let result = result.as_any().downcast_ref::<Decimal128Array>().unwrap();
3707
3708 assert_eq!(result.precision(), 38);
3709 assert_eq!(result.scale(), -1);
3710 assert_eq!(result.value(0), 124);
3711 assert_eq!(result.value(1), 125);
3712 assert_eq!(result.value(2), -124);
3713 assert_eq!(result.value(3), -125);
3714 assert_eq!(result.value(4), 1);
3715 assert!(result.is_valid(5));
3716 assert_eq!(result.value(5), 0);
3717 assert_eq!(result.value(6), 1);
3718 }
3719
3720 #[test]
3721 fn get_decimal128_precision_overflow_safe() {
3722 let mut builder = crate::VariantArrayBuilder::new(2);
3724 builder.append_variant(
3725 VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 0)
3726 .unwrap()
3727 .into(),
3728 );
3729 builder.append_variant(
3730 VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 38)
3731 .unwrap()
3732 .into(),
3733 ); let variant_array: ArrayRef = ArrayRef::from(builder.build());
3735
3736 let field = Field::new("result", DataType::Decimal128(2, 2), true);
3737 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3738 let result = variant_get(&variant_array, options).unwrap();
3739 let result = result.as_any().downcast_ref::<Decimal128Array>().unwrap();
3740
3741 assert!(result.is_null(0));
3742 assert!(result.is_null(1)); }
3744
3745 #[test]
3746 fn get_decimal128_precision_overflow_unsafe_errors() {
3747 let mut builder = crate::VariantArrayBuilder::new(1);
3748 builder.append_variant(
3749 VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 0)
3750 .unwrap()
3751 .into(),
3752 );
3753 let variant_array: ArrayRef = ArrayRef::from(builder.build());
3754
3755 let field = Field::new("result", DataType::Decimal128(38, 2), true);
3756 let cast_options = CastOptions {
3757 safe: false,
3758 ..Default::default()
3759 };
3760 let options = GetOptions::new()
3761 .with_as_type(Some(FieldRef::from(field)))
3762 .with_cast_options(cast_options);
3763 let err = variant_get(&variant_array, options).unwrap_err();
3764
3765 assert!(err.to_string().contains(
3766 "Failed to cast to Decimal128(precision=38, scale=2) from variant Decimal16"
3767 ));
3768 }
3769
3770 #[test]
3771 fn get_decimal256_rescaled_to_scale2() {
3772 let mut builder = crate::VariantArrayBuilder::new(4);
3774 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();
3778 let variant_array: ArrayRef = ArrayRef::from(builder.build());
3779
3780 let field = Field::new("result", DataType::Decimal256(76, 2), true);
3781 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3782 let result = variant_get(&variant_array, options).unwrap();
3783 let result = result.as_any().downcast_ref::<Decimal256Array>().unwrap();
3784
3785 assert_eq!(result.precision(), 76);
3786 assert_eq!(result.scale(), 2);
3787 assert_eq!(result.value(0), i256::from_i128(1234));
3788 assert_eq!(result.value(1), i256::from_i128(123));
3789 assert_eq!(result.value(2), i256::from_i128(123400));
3790 assert!(result.is_null(3));
3791 }
3792
3793 #[test]
3794 fn get_decimal256_scale_down_rounding() {
3795 let mut builder = crate::VariantArrayBuilder::new(7);
3796 builder.append_variant(VariantDecimal16::try_new(1235, 0).unwrap().into());
3797 builder.append_variant(VariantDecimal16::try_new(1245, 0).unwrap().into());
3798 builder.append_variant(VariantDecimal16::try_new(-1235, 0).unwrap().into());
3799 builder.append_variant(VariantDecimal16::try_new(-1245, 0).unwrap().into());
3800 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());
3804
3805 let field = Field::new("result", DataType::Decimal256(76, -1), true);
3806 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3807 let result = variant_get(&variant_array, options).unwrap();
3808 let result = result.as_any().downcast_ref::<Decimal256Array>().unwrap();
3809
3810 assert_eq!(result.precision(), 76);
3811 assert_eq!(result.scale(), -1);
3812 assert_eq!(result.value(0), i256::from_i128(124));
3813 assert_eq!(result.value(1), i256::from_i128(125));
3814 assert_eq!(result.value(2), i256::from_i128(-124));
3815 assert_eq!(result.value(3), i256::from_i128(-125));
3816 assert_eq!(result.value(4), i256::from_i128(1));
3817 assert!(result.is_valid(5));
3818 assert_eq!(result.value(5), i256::from_i128(0));
3819 assert_eq!(result.value(6), i256::from_i128(1));
3820 }
3821
3822 #[test]
3823 fn get_decimal256_precision_overflow_safe() {
3824 let mut builder = crate::VariantArrayBuilder::new(2);
3826 builder.append_variant(
3827 VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 1)
3828 .unwrap()
3829 .into(),
3830 );
3831 builder.append_variant(
3832 VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 0)
3833 .unwrap()
3834 .into(),
3835 );
3836 let variant_array: ArrayRef = ArrayRef::from(builder.build());
3837
3838 let field = Field::new("result", DataType::Decimal256(76, 39), true);
3839 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3840 let result = variant_get(&variant_array, options).unwrap();
3841 let result = result.as_any().downcast_ref::<Decimal256Array>().unwrap();
3842
3843 let base = i256::from_i128(10);
3846 let factor = base.checked_pow(38).unwrap();
3847 let expected = i256::from_i128(VariantDecimal16::MAX_UNSCALED_VALUE)
3848 .checked_mul(factor)
3849 .unwrap();
3850 assert_eq!(result.value(0), expected);
3851 assert!(result.is_null(1));
3852 }
3853
3854 #[test]
3855 fn get_decimal256_precision_overflow_unsafe_errors() {
3856 let mut builder = crate::VariantArrayBuilder::new(2);
3858 builder.append_variant(
3859 VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 1)
3860 .unwrap()
3861 .into(),
3862 );
3863 builder.append_variant(
3864 VariantDecimal16::try_new(VariantDecimal16::MAX_UNSCALED_VALUE, 0)
3865 .unwrap()
3866 .into(),
3867 );
3868 let variant_array: ArrayRef = ArrayRef::from(builder.build());
3869
3870 let field = Field::new("result", DataType::Decimal256(76, 39), true);
3871 let cast_options = CastOptions {
3872 safe: false,
3873 ..Default::default()
3874 };
3875 let options = GetOptions::new()
3876 .with_as_type(Some(FieldRef::from(field)))
3877 .with_cast_options(cast_options);
3878 let err = variant_get(&variant_array, options).unwrap_err();
3879
3880 assert!(err.to_string().contains(
3881 "Failed to cast to Decimal256(precision=76, scale=39) from variant Decimal16"
3882 ));
3883 }
3884
3885 #[test]
3886 fn get_non_supported_temporal_types_error() {
3887 let values = vec![None, Some(Variant::Null), Some(Variant::BooleanFalse)];
3888 let variant_array: ArrayRef = ArrayRef::from(VariantArray::from_iter(values));
3889
3890 let test_cases = vec![
3891 FieldRef::from(Field::new(
3892 "result",
3893 DataType::Duration(TimeUnit::Microsecond),
3894 true,
3895 )),
3896 FieldRef::from(Field::new(
3897 "result",
3898 DataType::Interval(IntervalUnit::YearMonth),
3899 true,
3900 )),
3901 ];
3902
3903 for field in test_cases {
3904 let options = GetOptions::new().with_as_type(Some(field));
3905 let err = variant_get(&variant_array, options).unwrap_err();
3906 assert!(
3907 err.to_string()
3908 .contains("Casting Variant to duration/interval types is not supported")
3909 );
3910 }
3911 }
3912
3913 fn invalid_time_variant_array() -> ArrayRef {
3914 let mut builder = VariantArrayBuilder::new(3);
3915 builder.append_variant(Variant::Int64(86401000000));
3917 builder.append_variant(Variant::Int64(86401000000));
3918 builder.append_variant(Variant::Int64(86401000000));
3919 Arc::new(builder.build().into_inner())
3920 }
3921
3922 #[test]
3923 fn test_variant_get_error_when_cast_failure_and_safe_false() {
3924 let variant_array = invalid_time_variant_array();
3925
3926 let field = Field::new("result", DataType::Time64(TimeUnit::Microsecond), true);
3927 let cast_options = CastOptions {
3928 safe: false, ..Default::default()
3930 };
3931 let options = GetOptions::new()
3932 .with_as_type(Some(FieldRef::from(field)))
3933 .with_cast_options(cast_options);
3934 let err = variant_get(&variant_array, options).unwrap_err();
3935 assert!(
3936 err.to_string().contains(
3937 "Cast error: Failed to extract primitive of type Time64(µs) from variant Int64(86401000000) at path VariantPath([])"
3938 ),
3939 "actual: {err}",
3940 );
3941 }
3942
3943 #[test]
3944 fn test_variant_get_return_null_when_cast_failure_and_safe_true() {
3945 let variant_array = invalid_time_variant_array();
3946
3947 let field = Field::new("result", DataType::Time64(TimeUnit::Microsecond), true);
3948 let cast_options = CastOptions {
3949 safe: true, ..Default::default()
3951 };
3952 let options = GetOptions::new()
3953 .with_as_type(Some(FieldRef::from(field)))
3954 .with_cast_options(cast_options);
3955 let result = variant_get(&variant_array, options).unwrap();
3956 assert_eq!(3, result.len());
3957
3958 for i in 0..3 {
3959 assert!(result.is_null(i));
3960 }
3961 }
3962
3963 #[test]
3964 fn test_perfect_shredding_returns_same_arc_ptr() {
3965 let variant_array = perfectly_shredded_int32_variant_array();
3966
3967 let variant_array_ref = VariantArray::try_new(&variant_array).unwrap();
3968 let typed_value_arc = variant_array_ref.typed_value_field().unwrap().clone();
3969
3970 let field = Field::new("result", DataType::Int32, true);
3971 let options = GetOptions::new().with_as_type(Some(FieldRef::from(field)));
3972 let result = variant_get(&variant_array, options).unwrap();
3973
3974 assert!(Arc::ptr_eq(&typed_value_arc, &result));
3975 }
3976
3977 #[test]
3978 fn test_perfect_shredding_three_typed_value_columns() {
3979 let all_nulls_values: Arc<Int32Array> = Arc::new(Int32Array::from(vec![
3981 Option::<i32>::None,
3982 Option::<i32>::None,
3983 Option::<i32>::None,
3984 ]));
3985 let all_nulls_erased: ArrayRef = all_nulls_values.clone();
3986 let all_nulls_field =
3987 ShreddedVariantFieldArray::from_parts(None, Some(all_nulls_erased.clone()), None);
3988 let all_nulls_type = all_nulls_field.data_type().clone();
3989 let all_nulls_struct: ArrayRef = ArrayRef::from(all_nulls_field);
3990
3991 let some_nulls_values: Arc<Int32Array> =
3993 Arc::new(Int32Array::from(vec![Some(10), None, Some(30)]));
3994 let some_nulls_erased: ArrayRef = some_nulls_values.clone();
3995 let some_nulls_field =
3996 ShreddedVariantFieldArray::from_parts(None, Some(some_nulls_erased.clone()), None);
3997 let some_nulls_type = some_nulls_field.data_type().clone();
3998 let some_nulls_struct: ArrayRef = ArrayRef::from(some_nulls_field);
3999
4000 let inner_values: Arc<Int32Array> =
4002 Arc::new(Int32Array::from(vec![Some(111), None, Some(333)]));
4003 let inner_erased: ArrayRef = inner_values.clone();
4004 let inner_field =
4005 ShreddedVariantFieldArray::from_parts(None, Some(inner_erased.clone()), None);
4006 let inner_field_type = inner_field.data_type().clone();
4007 let inner_struct_array: ArrayRef = ArrayRef::from(inner_field);
4008
4009 let nested_struct = Arc::new(
4010 StructArray::try_new(
4011 Fields::from(vec![Field::new("inner", inner_field_type, true)]),
4012 vec![inner_struct_array],
4013 None,
4014 )
4015 .unwrap(),
4016 );
4017 let nested_struct_erased: ArrayRef = nested_struct.clone();
4018 let struct_field =
4019 ShreddedVariantFieldArray::from_parts(None, Some(nested_struct_erased.clone()), None);
4020 let struct_field_type = struct_field.data_type().clone();
4021 let struct_field_struct: ArrayRef = ArrayRef::from(struct_field);
4022
4023 let typed_value_struct = StructArray::try_new(
4025 Fields::from(vec![
4026 Field::new("all_nulls", all_nulls_type, true),
4027 Field::new("some_nulls", some_nulls_type, true),
4028 Field::new("struct_field", struct_field_type, true),
4029 ]),
4030 vec![all_nulls_struct, some_nulls_struct, struct_field_struct],
4031 None,
4032 )
4033 .unwrap();
4034
4035 let metadata = BinaryViewArray::from_iter_values(std::iter::repeat_n(
4036 EMPTY_VARIANT_METADATA_BYTES,
4037 all_nulls_values.len(),
4038 ));
4039 let variant_array: ArrayRef = VariantArray::from_parts(
4040 Arc::new(metadata),
4041 None,
4042 Some(Arc::new(typed_value_struct)),
4043 None,
4044 )
4045 .into();
4046
4047 let all_nulls_field_ref = FieldRef::from(Field::new("result", DataType::Int32, true));
4049 let all_nulls_result = variant_get(
4050 &variant_array,
4051 GetOptions::new_with_path(VariantPath::try_from("all_nulls").unwrap())
4052 .with_as_type(Some(all_nulls_field_ref)),
4053 )
4054 .unwrap();
4055 assert!(Arc::ptr_eq(&all_nulls_result, &all_nulls_erased));
4056
4057 let some_nulls_field_ref = FieldRef::from(Field::new("result", DataType::Int32, true));
4059 let some_nulls_result = variant_get(
4060 &variant_array,
4061 GetOptions::new_with_path(VariantPath::try_from("some_nulls").unwrap())
4062 .with_as_type(Some(some_nulls_field_ref)),
4063 )
4064 .unwrap();
4065 assert!(Arc::ptr_eq(&some_nulls_result, &some_nulls_erased));
4066
4067 let struct_child_fields = Fields::from(vec![Field::new("inner", DataType::Int32, true)]);
4069 let struct_field_ref = FieldRef::from(Field::new(
4070 "result",
4071 DataType::Struct(struct_child_fields.clone()),
4072 true,
4073 ));
4074 let struct_result = variant_get(
4075 &variant_array,
4076 GetOptions::new_with_path(VariantPath::try_from("struct_field").unwrap())
4077 .with_as_type(Some(struct_field_ref)),
4078 )
4079 .unwrap();
4080 let struct_array = struct_result
4081 .as_any()
4082 .downcast_ref::<StructArray>()
4083 .unwrap();
4084 assert_eq!(struct_array.len(), 3);
4085 assert_eq!(struct_array.null_count(), 0);
4086
4087 let inner_values_result = struct_array
4088 .column(0)
4089 .as_any()
4090 .downcast_ref::<Int32Array>()
4091 .unwrap();
4092 assert_eq!(inner_values_result.len(), 3);
4093 assert_eq!(inner_values_result.value(0), 111);
4094 assert!(inner_values_result.is_null(1));
4095 assert_eq!(inner_values_result.value(2), 333);
4096 }
4097
4098 #[test]
4099 fn test_variant_get_list_like_safe_cast() {
4100 let string_array: ArrayRef = Arc::new(StringArray::from(vec![
4101 r#"{"outer":{"list":[1, "two", 3]}}"#,
4102 r#"{"outer":{"list":"not a list"}}"#,
4103 ]));
4104 let variant_array = ArrayRef::from(json_to_variant(&string_array).unwrap());
4105
4106 let element_array: ArrayRef = Arc::new(Int64Array::from(vec![Some(1), None, Some(3)]));
4107 let field = Arc::new(Field::new("item", Int64, true));
4108
4109 let expectations = vec![
4110 (
4111 DataType::List(field.clone()),
4112 Arc::new(ListArray::new(
4113 field.clone(),
4114 OffsetBuffer::new(ScalarBuffer::from(vec![0, 3, 3])),
4115 element_array.clone(),
4116 Some(NullBuffer::from(vec![true, false])),
4117 )) as ArrayRef,
4118 ),
4119 (
4120 DataType::LargeList(field.clone()),
4121 Arc::new(LargeListArray::new(
4122 field.clone(),
4123 OffsetBuffer::new(ScalarBuffer::from(vec![0, 3, 3])),
4124 element_array.clone(),
4125 Some(NullBuffer::from(vec![true, false])),
4126 )) as ArrayRef,
4127 ),
4128 (
4129 DataType::ListView(field.clone()),
4130 Arc::new(ListViewArray::new(
4131 field.clone(),
4132 ScalarBuffer::from(vec![0, 3]),
4133 ScalarBuffer::from(vec![3, 0]),
4134 element_array.clone(),
4135 Some(NullBuffer::from(vec![true, false])),
4136 )) as ArrayRef,
4137 ),
4138 (
4139 DataType::LargeListView(field.clone()),
4140 Arc::new(LargeListViewArray::new(
4141 field,
4142 ScalarBuffer::from(vec![0, 3]),
4143 ScalarBuffer::from(vec![3, 0]),
4144 element_array,
4145 Some(NullBuffer::from(vec![true, false])),
4146 )) as ArrayRef,
4147 ),
4148 ];
4149
4150 for (request_type, expected) in expectations {
4151 let options =
4152 GetOptions::new_with_path(VariantPath::try_from("outer").unwrap().join("list"))
4153 .with_as_type(Some(FieldRef::from(Field::new(
4154 "result",
4155 request_type.clone(),
4156 true,
4157 ))));
4158
4159 let result = variant_get(&variant_array, options).unwrap();
4160 assert_eq!(result.data_type(), expected.data_type());
4161 assert_eq!(&result, &expected);
4162 }
4163
4164 for (idx, expected) in [
4165 (0, vec![Some(1), None]),
4166 (1, vec![None, None]),
4167 (2, vec![Some(3), None]),
4168 ] {
4169 let index_options = GetOptions::new_with_path(
4170 VariantPath::try_from("outer")
4171 .unwrap()
4172 .join("list")
4173 .join(idx),
4174 )
4175 .with_as_type(Some(FieldRef::from(Field::new(
4176 "result",
4177 DataType::Int64,
4178 true,
4179 ))));
4180 let index_result = variant_get(&variant_array, index_options).unwrap();
4181 let index_expected: ArrayRef = Arc::new(Int64Array::from(expected));
4182 assert_eq!(&index_result, &index_expected);
4183 }
4184 }
4185
4186 #[test]
4187 fn test_variant_get_nested_list() {
4188 use arrow::datatypes::Int64Type;
4189
4190 let string_array: ArrayRef = Arc::new(StringArray::from(vec![
4191 r#"[[1, 2], [3]]"#,
4192 r#"[[4], "not a list", [5, 6]]"#,
4193 ]));
4194 let variant_array = ArrayRef::from(json_to_variant(&string_array).unwrap());
4195
4196 let inner_field = Arc::new(Field::new("item", Int64, true));
4197 let outer_field = Arc::new(Field::new(
4198 "item",
4199 DataType::List(inner_field.clone()),
4200 true,
4201 ));
4202 let request_type = DataType::List(outer_field.clone());
4203
4204 let options = GetOptions::new().with_as_type(Some(FieldRef::from(Field::new(
4205 "result",
4206 request_type,
4207 true,
4208 ))));
4209 let result = variant_get(&variant_array, options).unwrap();
4210 let outer = result.as_list::<i32>();
4211
4212 let row0 = outer.value(0);
4214 let row0 = row0.as_list::<i32>();
4215 assert_eq!(row0.len(), 2);
4216 let elem0 = row0.value(0);
4217 assert_eq!(elem0.as_primitive::<Int64Type>().values(), &[1, 2]);
4218 let elem1 = row0.value(1);
4219 assert_eq!(elem1.as_primitive::<Int64Type>().values(), &[3]);
4220
4221 let row1 = outer.value(1);
4223 let row1 = row1.as_list::<i32>();
4224 assert_eq!(row1.len(), 3);
4225 let elem0 = row1.value(0);
4226 assert_eq!(elem0.as_primitive::<Int64Type>().values(), &[4]);
4227 assert!(row1.is_null(1));
4228 let elem2 = row1.value(2);
4229 assert_eq!(elem2.as_primitive::<Int64Type>().values(), &[5, 6]);
4230 }
4231
4232 #[test]
4233 fn test_variant_get_list_like_unsafe_cast_errors_on_element_mismatch() {
4234 let string_array: ArrayRef =
4235 Arc::new(StringArray::from(vec![r#"[1, "two", 3]"#, "[4, 5]"]));
4236 let variant_array = ArrayRef::from(json_to_variant(&string_array).unwrap());
4237 let cast_options = CastOptions {
4238 safe: false,
4239 ..Default::default()
4240 };
4241
4242 let item_field = Arc::new(Field::new("item", DataType::Int64, true));
4243 let request_types = vec![
4244 DataType::List(item_field.clone()),
4245 DataType::LargeList(item_field.clone()),
4246 DataType::ListView(item_field.clone()),
4247 DataType::LargeListView(item_field),
4248 ];
4249
4250 for request_type in request_types {
4251 let options = GetOptions::new()
4252 .with_as_type(Some(FieldRef::from(Field::new(
4253 "result",
4254 request_type.clone(),
4255 true,
4256 ))))
4257 .with_cast_options(cast_options.clone());
4258
4259 let err = variant_get(&variant_array, options).unwrap_err();
4260 assert!(
4261 err.to_string()
4262 .contains("Failed to extract primitive of type Int64")
4263 );
4264 }
4265 }
4266
4267 #[test]
4268 fn test_variant_get_list_like_unsafe_cast_preserves_null_elements() {
4269 let string_array: ArrayRef = Arc::new(StringArray::from(vec![r#"[1, null, 3]"#]));
4270 let variant_array = ArrayRef::from(json_to_variant(&string_array).unwrap());
4271 let cast_options = CastOptions {
4272 safe: false,
4273 ..Default::default()
4274 };
4275 let options = GetOptions::new()
4276 .with_as_type(Some(FieldRef::from(Field::new(
4277 "result",
4278 DataType::List(Arc::new(Field::new("item", DataType::Int64, true))),
4279 true,
4280 ))))
4281 .with_cast_options(cast_options);
4282
4283 let result = variant_get(&variant_array, options).unwrap();
4284 let list_array = result.as_any().downcast_ref::<ListArray>().unwrap();
4285 let values = list_array
4286 .values()
4287 .as_any()
4288 .downcast_ref::<Int64Array>()
4289 .unwrap();
4290
4291 assert_eq!(values.len(), 3);
4292 assert_eq!(values.value(0), 1);
4293 assert!(values.is_null(1));
4294 assert_eq!(values.value(2), 3);
4295 }
4296
4297 #[test]
4298 fn test_variant_get_list_like_unsafe_cast_errors_on_non_list() {
4299 let string_array: ArrayRef = Arc::new(StringArray::from(vec!["[1, 2]", "\"not a list\""]));
4300 let variant_array = ArrayRef::from(json_to_variant(&string_array).unwrap());
4301 let cast_options = CastOptions {
4302 safe: false,
4303 ..Default::default()
4304 };
4305 let item_field = Arc::new(Field::new("item", Int64, true));
4306 let data_types = vec![
4307 DataType::List(item_field.clone()),
4308 DataType::LargeList(item_field.clone()),
4309 DataType::ListView(item_field.clone()),
4310 DataType::LargeListView(item_field),
4311 ];
4312
4313 for data_type in data_types {
4314 let options = GetOptions::new()
4315 .with_as_type(Some(FieldRef::from(Field::new("result", data_type, true))))
4316 .with_cast_options(cast_options.clone());
4317
4318 let err = variant_get(&variant_array, options).unwrap_err();
4319 assert!(
4320 err.to_string()
4321 .contains("Failed to extract list from variant"),
4322 );
4323 }
4324 }
4325
4326 #[test]
4327 fn test_variant_get_fixed_size_list_not_implemented() {
4328 let string_array: ArrayRef = Arc::new(StringArray::from(vec!["[1, 2]", "\"not a list\""]));
4329 let variant_array = ArrayRef::from(json_to_variant(&string_array).unwrap());
4330 let item_field = Arc::new(Field::new("item", Int64, true));
4331 for safe in [true, false] {
4332 let options = GetOptions::new()
4333 .with_as_type(Some(FieldRef::from(Field::new(
4334 "result",
4335 DataType::FixedSizeList(item_field.clone(), 2),
4336 true,
4337 ))))
4338 .with_cast_options(CastOptions {
4339 safe,
4340 ..Default::default()
4341 });
4342
4343 let err = variant_get(&variant_array, options).unwrap_err();
4344 assert!(
4345 err.to_string()
4346 .contains("Converting unshredded variant arrays to arrow fixed-size lists")
4347 );
4348 }
4349 }
4350
4351 macro_rules! perfectly_shredded_preserves_top_level_nulls_test {
4352 ($name:ident, $result_type:expr, $typed_value:expr, $expected_array:expr) => {
4353 perfectly_shredded_preserves_top_level_nulls_test!(
4354 $name,
4355 $result_type,
4356 $typed_value,
4357 Some(NullBuffer::from(vec![true, false, true])),
4358 $expected_array
4359 );
4360 };
4361 ($name:ident, $result_type:expr, $typed_value:expr, $parent_nulls:expr, $expected_array:expr) => {
4362 #[test]
4363 fn $name() {
4364 let metadata = Arc::new(BinaryViewArray::from_iter_values(std::iter::repeat_n(
4365 EMPTY_VARIANT_METADATA_BYTES,
4366 3,
4367 )));
4368 let typed_value: ArrayRef = Arc::new($typed_value);
4369 let variant_array: ArrayRef =
4370 VariantArray::from_parts(metadata, None, Some(typed_value), $parent_nulls)
4371 .into();
4372
4373 let result = variant_get(
4374 &variant_array,
4375 GetOptions::new().with_as_type(Some(FieldRef::from(Field::new(
4376 "result",
4377 $result_type,
4378 true,
4379 )))),
4380 )
4381 .unwrap();
4382
4383 let expected_array: ArrayRef = Arc::new($expected_array);
4384 assert_eq!(&result, &expected_array);
4385 }
4386 };
4387 }
4388
4389 perfectly_shredded_preserves_top_level_nulls_test!(
4390 test_variant_get_perfectly_shredded_integer_preserves_top_level_nulls,
4391 DataType::Int32,
4392 Int32Array::from(vec![Some(0_i32), Some(1_i32), Some(2_i32)]),
4393 Int32Array::from(vec![Some(0_i32), None, Some(2_i32)])
4394 );
4395
4396 perfectly_shredded_preserves_top_level_nulls_test!(
4397 test_variant_get_perfectly_shredded_integer_unions_child_and_top_level_nulls,
4398 DataType::Int32,
4399 Int32Array::from(vec![None, Some(1_i32), Some(2_i32)]),
4400 Some(NullBuffer::from(vec![true, false, true])),
4401 Int32Array::from(vec![None, None, Some(2_i32)])
4402 );
4403
4404 perfectly_shredded_preserves_top_level_nulls_test!(
4405 test_variant_get_perfectly_shredded_null_preserves_top_level_nulls,
4406 DataType::Null,
4407 NullArray::new(3),
4408 NullArray::new(3)
4409 );
4410
4411 perfectly_shredded_preserves_top_level_nulls_test!(
4412 test_variant_get_perfectly_shredded_binary_view_preserves_top_level_nulls,
4413 DataType::BinaryView,
4414 BinaryViewArray::from(vec![
4415 Some(b"Apache" as &[u8]),
4416 Some(b"masked-null" as &[u8]),
4417 Some(b"Parquet-variant" as &[u8]),
4418 ]),
4419 BinaryViewArray::from(vec![
4420 Some(b"Apache" as &[u8]),
4421 None,
4422 Some(b"Parquet-variant" as &[u8]),
4423 ])
4424 );
4425
4426 perfectly_shredded_preserves_top_level_nulls_test!(
4427 test_variant_get_perfectly_shredded_binary_preserves_top_level_nulls,
4428 DataType::Binary,
4429 BinaryArray::from(vec![
4430 Some(b"Apache" as &[u8]),
4431 Some(b"masked-null" as &[u8]),
4432 Some(b"Parquet-variant" as &[u8]),
4433 ]),
4434 BinaryArray::from(vec![
4435 Some(b"Apache" as &[u8]),
4436 None,
4437 Some(b"Parquet-variant" as &[u8]),
4438 ])
4439 );
4440
4441 perfectly_shredded_preserves_top_level_nulls_test!(
4442 test_variant_get_perfectly_shredded_decimal4_preserves_top_level_nulls,
4443 DataType::Decimal32(5, 2),
4444 Decimal32Array::from(vec![Some(12345), Some(23400), Some(-12342)])
4445 .with_precision_and_scale(5, 2)
4446 .unwrap(),
4447 Decimal32Array::from(vec![Some(12345), None, Some(-12342)])
4448 .with_precision_and_scale(5, 2)
4449 .unwrap()
4450 );
4451
4452 perfectly_shredded_preserves_top_level_nulls_test!(
4453 test_variant_get_perfectly_shredded_decimal8_preserves_top_level_nulls,
4454 DataType::Decimal64(10, 1),
4455 Decimal64Array::from(vec![Some(1234567809), Some(1456787000), Some(-1234561203)])
4456 .with_precision_and_scale(10, 1)
4457 .unwrap(),
4458 Decimal64Array::from(vec![Some(1234567809), None, Some(-1234561203)])
4459 .with_precision_and_scale(10, 1)
4460 .unwrap()
4461 );
4462
4463 perfectly_shredded_preserves_top_level_nulls_test!(
4464 test_variant_get_perfectly_shredded_decimal16_preserves_top_level_nulls,
4465 DataType::Decimal128(20, 3),
4466 Decimal128Array::from(vec![
4467 Some(i128::from_str("12345678901234567899").unwrap()),
4468 Some(i128::from_str("23445677483748324300").unwrap()),
4469 Some(i128::from_str("-12345678901234567899").unwrap()),
4470 ])
4471 .with_precision_and_scale(20, 3)
4472 .unwrap(),
4473 Decimal128Array::from(vec![
4474 Some(i128::from_str("12345678901234567899").unwrap()),
4475 None,
4476 Some(i128::from_str("-12345678901234567899").unwrap()),
4477 ])
4478 .with_precision_and_scale(20, 3)
4479 .unwrap()
4480 );
4481}