1use crate::arrow_to_variant::make_arrow_to_variant_row_builder;
19use crate::{VariantArray, VariantArrayBuilder};
20use arrow::array::Array;
21use arrow::compute::CastOptions;
22use arrow_schema::ArrowError;
23
24pub fn cast_to_variant_with_options(
58 input: &dyn Array,
59 options: &CastOptions,
60) -> Result<VariantArray, ArrowError> {
61 if input.null_count() == input.len() {
63 let mut array_builder = VariantArrayBuilder::new(input.len());
64 array_builder.append_nulls(input.len());
65 return Ok(array_builder.build());
66 }
67
68 let mut row_builder = make_arrow_to_variant_row_builder(input.data_type(), input, options)?;
70
71 let mut array_builder = VariantArrayBuilder::new(input.len());
73
74 for i in 0..input.len() {
76 row_builder.append_row(&mut array_builder, i)?;
77 }
78
79 Ok(array_builder.build())
80}
81
82pub fn cast_to_variant(input: &dyn Array) -> Result<VariantArray, ArrowError> {
88 cast_to_variant_with_options(
89 input,
90 &CastOptions {
91 safe: false,
92 ..Default::default()
93 },
94 )
95}
96
97#[cfg(test)]
98mod tests {
99 use super::*;
100 use arrow::array::{
101 ArrayRef, BinaryArray, BooleanArray, Date32Array, Date64Array, Decimal32Array,
102 Decimal64Array, Decimal128Array, Decimal256Array, DictionaryArray,
103 DurationMicrosecondArray, DurationMillisecondArray, DurationNanosecondArray,
104 DurationSecondArray, FixedSizeBinaryBuilder, FixedSizeListBuilder, Float16Array,
105 Float32Array, Float64Array, GenericByteBuilder, GenericByteViewBuilder, Int8Array,
106 Int16Array, Int32Array, Int64Array, IntervalDayTimeArray, IntervalMonthDayNanoArray,
107 IntervalYearMonthArray, LargeListArray, LargeListViewBuilder, LargeStringArray, ListArray,
108 ListViewBuilder, MapArray, NullArray, StringArray, StringRunBuilder, StringViewArray,
109 StructArray, Time32MillisecondArray, Time32SecondArray, Time64MicrosecondArray,
110 Time64NanosecondArray, TimestampMicrosecondArray, TimestampMillisecondArray,
111 TimestampNanosecondArray, TimestampSecondArray, UInt8Array, UInt16Array, UInt32Array,
112 UInt64Array, UnionArray,
113 };
114 use arrow::buffer::{NullBuffer, OffsetBuffer, ScalarBuffer};
115 use arrow::datatypes::{
116 BinaryType, BinaryViewType, Date32Type, Date64Type, Int8Type, Int32Type, Int64Type,
117 IntervalDayTime, IntervalMonthDayNano, LargeBinaryType, i256,
118 };
119 use arrow::temporal_conversions::timestamp_s_to_datetime;
120 use arrow_schema::{
121 DECIMAL32_MAX_PRECISION, DECIMAL64_MAX_PRECISION, DECIMAL128_MAX_PRECISION,
122 };
123 use arrow_schema::{DataType, Field, Fields, UnionFields};
124 use chrono::{DateTime, NaiveDate, NaiveTime};
125 use half::f16;
126 use parquet_variant::{
127 Variant, VariantBuilder, VariantBuilderExt, VariantDecimal4, VariantDecimal8,
128 VariantDecimal16,
129 };
130 use std::{sync::Arc, vec};
131
132 macro_rules! max_unscaled_value {
133 (32, $precision:expr) => {
134 (u32::pow(10, $precision as u32) - 1) as i32
135 };
136 (64, $precision:expr) => {
137 (u64::pow(10, $precision as u32) - 1) as i64
138 };
139 (128, $precision:expr) => {
140 (u128::pow(10, $precision as u32) - 1) as i128
141 };
142 }
143
144 #[test]
145 fn test_cast_to_variant_null() {
146 run_test(Arc::new(NullArray::new(2)), vec![None, None])
147 }
148
149 #[test]
150 fn test_cast_to_variant_bool() {
151 run_test(
152 Arc::new(BooleanArray::from(vec![Some(true), None, Some(false)])),
153 vec![
154 Some(Variant::BooleanTrue),
155 None,
156 Some(Variant::BooleanFalse),
157 ],
158 );
159 }
160
161 #[test]
162 fn test_cast_to_variant_int8() {
163 run_test(
164 Arc::new(Int8Array::from(vec![
165 Some(i8::MIN),
166 None,
167 Some(-1),
168 Some(1),
169 Some(i8::MAX),
170 ])),
171 vec![
172 Some(Variant::Int8(i8::MIN)),
173 None,
174 Some(Variant::Int8(-1)),
175 Some(Variant::Int8(1)),
176 Some(Variant::Int8(i8::MAX)),
177 ],
178 )
179 }
180
181 #[test]
182 fn test_cast_to_variant_int16() {
183 run_test(
184 Arc::new(Int16Array::from(vec![
185 Some(i16::MIN),
186 None,
187 Some(-1),
188 Some(1),
189 Some(i16::MAX),
190 ])),
191 vec![
192 Some(Variant::Int16(i16::MIN)),
193 None,
194 Some(Variant::Int16(-1)),
195 Some(Variant::Int16(1)),
196 Some(Variant::Int16(i16::MAX)),
197 ],
198 )
199 }
200
201 #[test]
202 fn test_cast_to_variant_int32() {
203 run_test(
204 Arc::new(Int32Array::from(vec![
205 Some(i32::MIN),
206 None,
207 Some(-1),
208 Some(1),
209 Some(i32::MAX),
210 ])),
211 vec![
212 Some(Variant::Int32(i32::MIN)),
213 None,
214 Some(Variant::Int32(-1)),
215 Some(Variant::Int32(1)),
216 Some(Variant::Int32(i32::MAX)),
217 ],
218 )
219 }
220
221 #[test]
222 fn test_cast_to_variant_int64() {
223 run_test(
224 Arc::new(Int64Array::from(vec![
225 Some(i64::MIN),
226 None,
227 Some(-1),
228 Some(1),
229 Some(i64::MAX),
230 ])),
231 vec![
232 Some(Variant::Int64(i64::MIN)),
233 None,
234 Some(Variant::Int64(-1)),
235 Some(Variant::Int64(1)),
236 Some(Variant::Int64(i64::MAX)),
237 ],
238 )
239 }
240
241 #[test]
242 fn test_cast_to_variant_uint8() {
243 run_test(
244 Arc::new(UInt8Array::from(vec![
245 Some(0),
246 None,
247 Some(1),
248 Some(127),
249 Some(u8::MAX),
250 ])),
251 vec![
252 Some(Variant::Int8(0)),
253 None,
254 Some(Variant::Int8(1)),
255 Some(Variant::Int8(127)),
256 Some(Variant::Int16(255)), ],
258 )
259 }
260
261 #[test]
262 fn test_cast_to_variant_uint16() {
263 run_test(
264 Arc::new(UInt16Array::from(vec![
265 Some(0),
266 None,
267 Some(1),
268 Some(32767),
269 Some(u16::MAX),
270 ])),
271 vec![
272 Some(Variant::Int16(0)),
273 None,
274 Some(Variant::Int16(1)),
275 Some(Variant::Int16(32767)),
276 Some(Variant::Int32(65535)), ],
278 )
279 }
280
281 #[test]
282 fn test_cast_to_variant_uint32() {
283 run_test(
284 Arc::new(UInt32Array::from(vec![
285 Some(0),
286 None,
287 Some(1),
288 Some(2147483647),
289 Some(u32::MAX),
290 ])),
291 vec![
292 Some(Variant::Int32(0)),
293 None,
294 Some(Variant::Int32(1)),
295 Some(Variant::Int32(2147483647)),
296 Some(Variant::Int64(4294967295)), ],
298 )
299 }
300
301 #[test]
302 fn test_cast_to_variant_uint64() {
303 run_test(
304 Arc::new(UInt64Array::from(vec![
305 Some(0),
306 None,
307 Some(1),
308 Some(9223372036854775807),
309 Some(u64::MAX),
310 ])),
311 vec![
312 Some(Variant::Int64(0)),
313 None,
314 Some(Variant::Int64(1)),
315 Some(Variant::Int64(9223372036854775807)),
316 Some(Variant::Decimal16(
317 VariantDecimal16::try_from(18446744073709551615).unwrap(),
319 )),
320 ],
321 )
322 }
323
324 #[test]
325 fn test_cast_to_variant_float16() {
326 run_test(
327 Arc::new(Float16Array::from(vec![
328 Some(f16::MIN),
329 None,
330 Some(f16::from_f32(-1.5)),
331 Some(f16::from_f32(0.0)),
332 Some(f16::from_f32(1.5)),
333 Some(f16::MAX),
334 ])),
335 vec![
336 Some(Variant::Float(f16::MIN.into())),
337 None,
338 Some(Variant::Float(-1.5)),
339 Some(Variant::Float(0.0)),
340 Some(Variant::Float(1.5)),
341 Some(Variant::Float(f16::MAX.into())),
342 ],
343 )
344 }
345
346 #[test]
347 fn test_cast_to_variant_float32() {
348 run_test(
349 Arc::new(Float32Array::from(vec![
350 Some(f32::MIN),
351 None,
352 Some(-1.5),
353 Some(0.0),
354 Some(1.5),
355 Some(f32::MAX),
356 ])),
357 vec![
358 Some(Variant::Float(f32::MIN)),
359 None,
360 Some(Variant::Float(-1.5)),
361 Some(Variant::Float(0.0)),
362 Some(Variant::Float(1.5)),
363 Some(Variant::Float(f32::MAX)),
364 ],
365 )
366 }
367
368 #[test]
369 fn test_cast_to_variant_float64() {
370 run_test(
371 Arc::new(Float64Array::from(vec![
372 Some(f64::MIN),
373 None,
374 Some(-1.5),
375 Some(0.0),
376 Some(1.5),
377 Some(f64::MAX),
378 ])),
379 vec![
380 Some(Variant::Double(f64::MIN)),
381 None,
382 Some(Variant::Double(-1.5)),
383 Some(Variant::Double(0.0)),
384 Some(Variant::Double(1.5)),
385 Some(Variant::Double(f64::MAX)),
386 ],
387 )
388 }
389
390 #[test]
391 fn test_cast_to_variant_decimal32() {
392 run_test(
393 Arc::new(
394 Decimal32Array::from(vec![
395 Some(i32::MIN),
396 Some(-max_unscaled_value!(32, DECIMAL32_MAX_PRECISION) - 1), Some(-max_unscaled_value!(32, DECIMAL32_MAX_PRECISION)), None,
399 Some(-123),
400 Some(0),
401 Some(123),
402 Some(max_unscaled_value!(32, DECIMAL32_MAX_PRECISION)), Some(max_unscaled_value!(32, DECIMAL32_MAX_PRECISION) + 1), Some(i32::MAX),
405 ])
406 .with_precision_and_scale(DECIMAL32_MAX_PRECISION, 3)
407 .unwrap(),
408 ),
409 vec![
410 Some(Variant::Null),
411 Some(Variant::Null),
412 Some(
413 VariantDecimal4::try_new(-max_unscaled_value!(32, DECIMAL32_MAX_PRECISION), 3)
414 .unwrap()
415 .into(),
416 ),
417 None,
418 Some(VariantDecimal4::try_new(-123, 3).unwrap().into()),
419 Some(VariantDecimal4::try_new(0, 3).unwrap().into()),
420 Some(VariantDecimal4::try_new(123, 3).unwrap().into()),
421 Some(
422 VariantDecimal4::try_new(max_unscaled_value!(32, DECIMAL32_MAX_PRECISION), 3)
423 .unwrap()
424 .into(),
425 ),
426 Some(Variant::Null),
427 Some(Variant::Null),
428 ],
429 )
430 }
431
432 #[test]
433 fn test_cast_to_variant_decimal32_negative_scale() {
434 run_test(
435 Arc::new(
436 Decimal32Array::from(vec![
437 Some(i32::MIN),
438 Some(-max_unscaled_value!(32, DECIMAL32_MAX_PRECISION - 3) - 1), Some(-max_unscaled_value!(32, DECIMAL32_MAX_PRECISION - 3)), None,
441 Some(-123),
442 Some(0),
443 Some(123),
444 Some(max_unscaled_value!(32, DECIMAL32_MAX_PRECISION - 3)), Some(max_unscaled_value!(32, DECIMAL32_MAX_PRECISION - 3) + 1), Some(i32::MAX),
447 ])
448 .with_precision_and_scale(DECIMAL32_MAX_PRECISION, -3)
449 .unwrap(),
450 ),
451 vec![
452 Some(Variant::Null),
453 Some(Variant::Null),
454 Some(
455 VariantDecimal4::try_new(
456 -max_unscaled_value!(32, DECIMAL32_MAX_PRECISION - 3) * 1000,
457 0,
458 )
459 .unwrap()
460 .into(),
461 ),
462 None,
463 Some(VariantDecimal4::try_new(-123_000, 0).unwrap().into()),
464 Some(VariantDecimal4::try_new(0, 0).unwrap().into()),
465 Some(VariantDecimal4::try_new(123_000, 0).unwrap().into()),
466 Some(
467 VariantDecimal4::try_new(
468 max_unscaled_value!(32, DECIMAL32_MAX_PRECISION - 3) * 1000,
469 0,
470 )
471 .unwrap()
472 .into(),
473 ),
474 Some(Variant::Null),
475 Some(Variant::Null),
476 ],
477 )
478 }
479
480 #[test]
481 fn test_cast_to_variant_decimal32_overflow_strict_mode() {
482 run_test_in_strict_mode(
483 Arc::new(
484 Decimal32Array::from(vec![Some(i32::MIN)])
485 .with_precision_and_scale(DECIMAL32_MAX_PRECISION, 3)
486 .unwrap(),
487 ),
488 Err(ArrowError::ComputeError(
489 "Failed to convert value at index 0: conversion failed".to_string(),
490 )),
491 );
492 }
493
494 #[test]
495 fn test_cast_to_variant_decimal64() {
496 run_test(
497 Arc::new(
498 Decimal64Array::from(vec![
499 Some(i64::MIN),
500 Some(-max_unscaled_value!(64, DECIMAL64_MAX_PRECISION) - 1), Some(-max_unscaled_value!(64, DECIMAL64_MAX_PRECISION)), None,
503 Some(-123),
504 Some(0),
505 Some(123),
506 Some(max_unscaled_value!(64, DECIMAL64_MAX_PRECISION)), Some(max_unscaled_value!(64, DECIMAL64_MAX_PRECISION) + 1), Some(i64::MAX),
509 ])
510 .with_precision_and_scale(DECIMAL64_MAX_PRECISION, 3)
511 .unwrap(),
512 ),
513 vec![
514 Some(Variant::Null),
515 Some(Variant::Null),
516 Some(
517 VariantDecimal8::try_new(-max_unscaled_value!(64, DECIMAL64_MAX_PRECISION), 3)
518 .unwrap()
519 .into(),
520 ),
521 None,
522 Some(VariantDecimal8::try_new(-123, 3).unwrap().into()),
523 Some(VariantDecimal8::try_new(0, 3).unwrap().into()),
524 Some(VariantDecimal8::try_new(123, 3).unwrap().into()),
525 Some(
526 VariantDecimal8::try_new(max_unscaled_value!(64, DECIMAL64_MAX_PRECISION), 3)
527 .unwrap()
528 .into(),
529 ),
530 Some(Variant::Null),
531 Some(Variant::Null),
532 ],
533 )
534 }
535
536 #[test]
537 fn test_cast_to_variant_decimal64_negative_scale() {
538 run_test(
539 Arc::new(
540 Decimal64Array::from(vec![
541 Some(i64::MIN),
542 Some(-max_unscaled_value!(64, DECIMAL64_MAX_PRECISION - 3) - 1), Some(-max_unscaled_value!(64, DECIMAL64_MAX_PRECISION - 3)), None,
545 Some(-123),
546 Some(0),
547 Some(123),
548 Some(max_unscaled_value!(64, DECIMAL64_MAX_PRECISION - 3)), Some(max_unscaled_value!(64, DECIMAL64_MAX_PRECISION - 3) + 1), Some(i64::MAX),
551 ])
552 .with_precision_and_scale(DECIMAL64_MAX_PRECISION, -3)
553 .unwrap(),
554 ),
555 vec![
556 Some(Variant::Null),
557 Some(Variant::Null),
558 Some(
559 VariantDecimal8::try_new(
560 -max_unscaled_value!(64, DECIMAL64_MAX_PRECISION - 3) * 1000,
561 0,
562 )
563 .unwrap()
564 .into(),
565 ),
566 None,
567 Some(VariantDecimal8::try_new(-123_000, 0).unwrap().into()),
568 Some(VariantDecimal8::try_new(0, 0).unwrap().into()),
569 Some(VariantDecimal8::try_new(123_000, 0).unwrap().into()),
570 Some(
571 VariantDecimal8::try_new(
572 max_unscaled_value!(64, DECIMAL64_MAX_PRECISION - 3) * 1000,
573 0,
574 )
575 .unwrap()
576 .into(),
577 ),
578 Some(Variant::Null),
579 Some(Variant::Null),
580 ],
581 )
582 }
583
584 #[test]
585 fn test_cast_to_variant_decimal64_overflow_strict_mode() {
586 run_test_in_strict_mode(
587 Arc::new(
588 Decimal64Array::from(vec![Some(i64::MAX)])
589 .with_precision_and_scale(DECIMAL64_MAX_PRECISION, 3)
590 .unwrap(),
591 ),
592 Err(ArrowError::ComputeError(
593 "Failed to convert value at index 0: conversion failed".to_string(),
594 )),
595 );
596 }
597
598 #[test]
599 fn test_cast_to_variant_decimal128() {
600 run_test(
601 Arc::new(
602 Decimal128Array::from(vec![
603 Some(i128::MIN),
604 Some(-max_unscaled_value!(128, DECIMAL128_MAX_PRECISION) - 1), Some(-max_unscaled_value!(128, DECIMAL128_MAX_PRECISION)), None,
607 Some(-123),
608 Some(0),
609 Some(123),
610 Some(max_unscaled_value!(128, DECIMAL128_MAX_PRECISION)), Some(max_unscaled_value!(128, DECIMAL128_MAX_PRECISION) + 1), Some(i128::MAX),
613 ])
614 .with_precision_and_scale(DECIMAL128_MAX_PRECISION, 3)
615 .unwrap(),
616 ),
617 vec![
618 Some(Variant::Null),
619 Some(Variant::Null),
620 Some(
621 VariantDecimal16::try_new(
622 -max_unscaled_value!(128, DECIMAL128_MAX_PRECISION),
623 3,
624 )
625 .unwrap()
626 .into(),
627 ),
628 None,
629 Some(VariantDecimal16::try_new(-123, 3).unwrap().into()),
630 Some(VariantDecimal16::try_new(0, 3).unwrap().into()),
631 Some(VariantDecimal16::try_new(123, 3).unwrap().into()),
632 Some(
633 VariantDecimal16::try_new(
634 max_unscaled_value!(128, DECIMAL128_MAX_PRECISION),
635 3,
636 )
637 .unwrap()
638 .into(),
639 ),
640 Some(Variant::Null),
641 Some(Variant::Null),
642 ],
643 )
644 }
645
646 #[test]
647 fn test_cast_to_variant_decimal128_negative_scale() {
648 run_test(
649 Arc::new(
650 Decimal128Array::from(vec![
651 Some(i128::MIN),
652 Some(-max_unscaled_value!(128, DECIMAL128_MAX_PRECISION - 3) - 1), Some(-max_unscaled_value!(128, DECIMAL128_MAX_PRECISION - 3)), None,
655 Some(-123),
656 Some(0),
657 Some(123),
658 Some(max_unscaled_value!(128, DECIMAL128_MAX_PRECISION - 3)), Some(max_unscaled_value!(128, DECIMAL128_MAX_PRECISION - 3) + 1), Some(i128::MAX),
661 ])
662 .with_precision_and_scale(DECIMAL128_MAX_PRECISION, -3)
663 .unwrap(),
664 ),
665 vec![
666 Some(Variant::Null),
667 Some(Variant::Null),
668 Some(
669 VariantDecimal16::try_new(
670 -max_unscaled_value!(128, DECIMAL128_MAX_PRECISION - 3) * 1000,
671 0,
672 )
673 .unwrap()
674 .into(),
675 ),
676 None,
677 Some(VariantDecimal16::try_new(-123_000, 0).unwrap().into()),
678 Some(VariantDecimal16::try_new(0, 0).unwrap().into()),
679 Some(VariantDecimal16::try_new(123_000, 0).unwrap().into()),
680 Some(
681 VariantDecimal16::try_new(
682 max_unscaled_value!(128, DECIMAL128_MAX_PRECISION - 3) * 1000,
683 0,
684 )
685 .unwrap()
686 .into(),
687 ),
688 Some(Variant::Null),
689 Some(Variant::Null),
690 ],
691 )
692 }
693
694 #[test]
695 fn test_cast_to_variant_decimal128_overflow_strict_mode() {
696 run_test_in_strict_mode(
697 Arc::new(
698 Decimal128Array::from(vec![Some(
699 -max_unscaled_value!(128, DECIMAL128_MAX_PRECISION) - 1,
700 )])
701 .with_precision_and_scale(DECIMAL128_MAX_PRECISION, 3)
702 .unwrap(),
703 ),
704 Err(ArrowError::ComputeError(
705 "Failed to convert value at index 0: conversion failed".to_string(),
706 )),
707 );
708 }
709
710 #[test]
711 fn test_cast_to_variant_decimal256() {
712 run_test(
713 Arc::new(
714 Decimal256Array::from(vec![
715 Some(i256::MIN),
716 Some(i256::from_i128(
717 -max_unscaled_value!(128, DECIMAL128_MAX_PRECISION) - 1,
718 )), Some(i256::from_i128(-max_unscaled_value!(
720 128,
721 DECIMAL128_MAX_PRECISION
722 ))), None,
724 Some(i256::from_i128(-123)),
725 Some(i256::from_i128(0)),
726 Some(i256::from_i128(123)),
727 Some(i256::from_i128(max_unscaled_value!(
728 128,
729 DECIMAL128_MAX_PRECISION
730 ))), Some(i256::from_i128(
732 max_unscaled_value!(128, DECIMAL128_MAX_PRECISION) + 1,
733 )), Some(i256::MAX),
735 ])
736 .with_precision_and_scale(DECIMAL128_MAX_PRECISION, 3)
737 .unwrap(),
738 ),
739 vec![
740 Some(Variant::Null),
741 Some(Variant::Null),
742 Some(
743 VariantDecimal16::try_new(
744 -max_unscaled_value!(128, DECIMAL128_MAX_PRECISION),
745 3,
746 )
747 .unwrap()
748 .into(),
749 ),
750 None,
751 Some(VariantDecimal16::try_new(-123, 3).unwrap().into()),
752 Some(VariantDecimal16::try_new(0, 3).unwrap().into()),
753 Some(VariantDecimal16::try_new(123, 3).unwrap().into()),
754 Some(
755 VariantDecimal16::try_new(
756 max_unscaled_value!(128, DECIMAL128_MAX_PRECISION),
757 3,
758 )
759 .unwrap()
760 .into(),
761 ),
762 Some(Variant::Null),
763 Some(Variant::Null),
764 ],
765 )
766 }
767
768 #[test]
769 fn test_cast_to_variant_decimal256_negative_scale() {
770 run_test(
771 Arc::new(
772 Decimal256Array::from(vec![
773 Some(i256::MIN),
774 Some(i256::from_i128(
775 -max_unscaled_value!(128, DECIMAL128_MAX_PRECISION - 3) - 1,
776 )), Some(i256::from_i128(-max_unscaled_value!(
778 128,
779 DECIMAL128_MAX_PRECISION - 3
780 ))), None,
782 Some(i256::from_i128(-123)),
783 Some(i256::from_i128(0)),
784 Some(i256::from_i128(123)),
785 Some(i256::from_i128(max_unscaled_value!(
786 128,
787 DECIMAL128_MAX_PRECISION - 3
788 ))), Some(i256::from_i128(
790 max_unscaled_value!(128, DECIMAL128_MAX_PRECISION - 3) + 1,
791 )), Some(i256::MAX),
793 ])
794 .with_precision_and_scale(DECIMAL128_MAX_PRECISION, -3)
795 .unwrap(),
796 ),
797 vec![
798 Some(Variant::Null),
799 Some(Variant::Null),
800 Some(
801 VariantDecimal16::try_new(
802 -max_unscaled_value!(128, DECIMAL128_MAX_PRECISION - 3) * 1000,
803 0,
804 )
805 .unwrap()
806 .into(),
807 ),
808 None,
809 Some(VariantDecimal16::try_new(-123_000, 0).unwrap().into()),
810 Some(VariantDecimal16::try_new(0, 0).unwrap().into()),
811 Some(VariantDecimal16::try_new(123_000, 0).unwrap().into()),
812 Some(
813 VariantDecimal16::try_new(
814 max_unscaled_value!(128, DECIMAL128_MAX_PRECISION - 3) * 1000,
815 0,
816 )
817 .unwrap()
818 .into(),
819 ),
820 Some(Variant::Null),
821 Some(Variant::Null),
822 ],
823 )
824 }
825
826 #[test]
827 fn test_cast_to_variant_decimal256_overflow_strict_mode() {
828 run_test_in_strict_mode(
829 Arc::new(
830 Decimal256Array::from(vec![Some(i256::from_i128(
831 max_unscaled_value!(128, DECIMAL128_MAX_PRECISION) + 1,
832 ))])
833 .with_precision_and_scale(DECIMAL128_MAX_PRECISION, 3)
834 .unwrap(),
835 ),
836 Err(ArrowError::ComputeError(
837 "Failed to convert value at index 0: conversion failed".to_string(),
838 )),
839 );
840 }
841
842 #[test]
843 fn test_cast_to_variant_timestamp() {
844 let run_array_tests =
845 |microseconds: i64, array_ntz: Arc<dyn Array>, array_tz: Arc<dyn Array>| {
846 let timestamp = DateTime::from_timestamp_nanos(microseconds * 1000);
847 run_test(
848 array_tz,
849 vec![Some(Variant::TimestampMicros(timestamp)), None],
850 );
851 run_test(
852 array_ntz,
853 vec![
854 Some(Variant::TimestampNtzMicros(timestamp.naive_utc())),
855 None,
856 ],
857 );
858 };
859
860 let nanosecond = 1234567890;
861 let microsecond = 1234567;
862 let millisecond = 1234;
863 let second = 1;
864
865 let second_array = TimestampSecondArray::from(vec![Some(second), None]);
866 run_array_tests(
867 second * 1000 * 1000,
868 Arc::new(second_array.clone()),
869 Arc::new(second_array.with_timezone("+01:00".to_string())),
870 );
871
872 let millisecond_array = TimestampMillisecondArray::from(vec![Some(millisecond), None]);
873 run_array_tests(
874 millisecond * 1000,
875 Arc::new(millisecond_array.clone()),
876 Arc::new(millisecond_array.with_timezone("+01:00".to_string())),
877 );
878
879 let microsecond_array = TimestampMicrosecondArray::from(vec![Some(microsecond), None]);
880 run_array_tests(
881 microsecond,
882 Arc::new(microsecond_array.clone()),
883 Arc::new(microsecond_array.with_timezone("+01:00".to_string())),
884 );
885
886 let timestamp = DateTime::from_timestamp_nanos(nanosecond);
887 let nanosecond_array = TimestampNanosecondArray::from(vec![Some(nanosecond), None]);
888 run_test(
889 Arc::new(nanosecond_array.clone()),
890 vec![
891 Some(Variant::TimestampNtzNanos(timestamp.naive_utc())),
892 None,
893 ],
894 );
895 run_test(
896 Arc::new(nanosecond_array.with_timezone("+01:00".to_string())),
897 vec![Some(Variant::TimestampNanos(timestamp)), None],
898 );
899 }
900
901 #[test]
902 fn test_cast_to_variant_timestamp_overflow_strict_mode() {
903 let ts_array = TimestampSecondArray::from(vec![Some(i64::MAX), Some(0), Some(1609459200)])
904 .with_timezone_opt(None::<&str>);
905
906 let values = Arc::new(ts_array);
907 run_test_in_strict_mode(
908 values,
909 Err(ArrowError::ComputeError(
910 "Failed to convert value at index 0: conversion failed".to_string(),
911 )),
912 );
913 }
914
915 #[test]
916 fn test_cast_to_variant_timestamp_overflow_non_strict_mode() {
917 let ts_array = TimestampSecondArray::from(vec![Some(i64::MAX), Some(0), Some(1609459200)])
918 .with_timezone_opt(None::<&str>);
919
920 let values = Arc::new(ts_array);
921 run_test(
922 values,
923 vec![
924 Some(Variant::Null), Some(Variant::TimestampNtzMicros(
926 timestamp_s_to_datetime(0).unwrap(),
927 )),
928 Some(Variant::TimestampNtzMicros(
929 timestamp_s_to_datetime(1609459200).unwrap(),
930 )),
931 ],
932 );
933 }
934
935 #[test]
936 fn test_cast_to_variant_date() {
937 run_test(
939 Arc::new(Date32Array::from(vec![
940 Some(Date32Type::from_naive_date(NaiveDate::MIN)),
941 None,
942 Some(Date32Type::from_naive_date(
943 NaiveDate::from_ymd_opt(2025, 8, 1).unwrap(),
944 )),
945 Some(Date32Type::from_naive_date(NaiveDate::MAX)),
946 ])),
947 vec![
948 Some(Variant::Date(NaiveDate::MIN)),
949 None,
950 Some(Variant::Date(NaiveDate::from_ymd_opt(2025, 8, 1).unwrap())),
951 Some(Variant::Date(NaiveDate::MAX)),
952 ],
953 );
954
955 run_test(
957 Arc::new(Date64Array::from(vec![
958 Some(Date64Type::from_naive_date(NaiveDate::MIN)),
959 None,
960 Some(Date64Type::from_naive_date(
961 NaiveDate::from_ymd_opt(2025, 8, 1).unwrap(),
962 )),
963 Some(Date64Type::from_naive_date(NaiveDate::MAX)),
964 ])),
965 vec![
966 Some(Variant::Date(NaiveDate::MIN)),
967 None,
968 Some(Variant::Date(NaiveDate::from_ymd_opt(2025, 8, 1).unwrap())),
969 Some(Variant::Date(NaiveDate::MAX)),
970 ],
971 );
972 }
973
974 #[test]
975 fn test_cast_to_variant_date64_strict_mode() {
976 let date64_values = Date64Array::from(vec![Some(i64::MAX), Some(0), Some(i64::MIN)]);
977
978 let values = Arc::new(date64_values);
979 run_test_in_strict_mode(
980 values,
981 Err(ArrowError::ComputeError(
982 "Failed to convert value at index 0: conversion failed".to_string(),
983 )),
984 );
985 }
986
987 #[test]
988 fn test_cast_to_variant_date64_non_strict_mode() {
989 let date64_values = Date64Array::from(vec![Some(i64::MAX), Some(0), Some(i64::MIN)]);
990
991 let values = Arc::new(date64_values);
992 run_test(
993 values,
994 vec![
995 Some(Variant::Null),
996 Some(Variant::Date(Date64Type::to_naive_date_opt(0).unwrap())),
997 Some(Variant::Null),
998 ],
999 );
1000 }
1001
1002 #[test]
1003 fn test_cast_to_variant_time32_second() {
1004 let array: Time32SecondArray = vec![Some(1), Some(86_399), None].into();
1005 let values = Arc::new(array);
1006 run_test(
1007 values,
1008 vec![
1009 Some(Variant::Time(
1010 NaiveTime::from_num_seconds_from_midnight_opt(1, 0).unwrap(),
1011 )),
1012 Some(Variant::Time(
1013 NaiveTime::from_num_seconds_from_midnight_opt(86_399, 0).unwrap(),
1014 )),
1015 None,
1016 ],
1017 )
1018 }
1019
1020 #[test]
1021 fn test_cast_to_variant_time32_millisecond() {
1022 let array: Time32MillisecondArray = vec![Some(123_456), Some(456_000), None].into();
1023 let values = Arc::new(array);
1024 run_test(
1025 values,
1026 vec![
1027 Some(Variant::Time(
1028 NaiveTime::from_num_seconds_from_midnight_opt(123, 456_000_000).unwrap(),
1029 )),
1030 Some(Variant::Time(
1031 NaiveTime::from_num_seconds_from_midnight_opt(456, 0).unwrap(),
1032 )),
1033 None,
1034 ],
1035 )
1036 }
1037
1038 #[test]
1039 fn test_cast_to_variant_time64_micro() {
1040 let array: Time64MicrosecondArray = vec![Some(1), Some(123_456_789), None].into();
1041 let values = Arc::new(array);
1042 run_test(
1043 values,
1044 vec![
1045 Some(Variant::Time(
1046 NaiveTime::from_num_seconds_from_midnight_opt(0, 1_000).unwrap(),
1047 )),
1048 Some(Variant::Time(
1049 NaiveTime::from_num_seconds_from_midnight_opt(123, 456_789_000).unwrap(),
1050 )),
1051 None,
1052 ],
1053 )
1054 }
1055
1056 #[test]
1057 fn test_cast_to_variant_time64_nano() {
1058 let array: Time64NanosecondArray =
1059 vec![Some(1), Some(1001), Some(123_456_789_012), None].into();
1060 run_test(
1061 Arc::new(array),
1062 vec![
1064 Some(Variant::Time(
1065 NaiveTime::from_num_seconds_from_midnight_opt(0, 0).unwrap(),
1066 )),
1067 Some(Variant::Time(
1068 NaiveTime::from_num_seconds_from_midnight_opt(0, 1_000).unwrap(),
1069 )),
1070 Some(Variant::Time(
1071 NaiveTime::from_num_seconds_from_midnight_opt(123, 456_789_000).unwrap(),
1072 )),
1073 None,
1074 ],
1075 )
1076 }
1077
1078 #[test]
1079 fn test_cast_to_variant_time32_strict_mode() {
1080 let time32_array = Time32SecondArray::from(vec![Some(90000), Some(3600), Some(-1)]);
1081
1082 let values = Arc::new(time32_array);
1083 run_test_in_strict_mode(
1084 values,
1085 Err(ArrowError::ComputeError(
1086 "Failed to convert value at index 0: conversion failed".to_string(),
1087 )),
1088 );
1089 }
1090
1091 #[test]
1092 fn test_cast_to_variant_time32_non_strict_mode() {
1093 let time32_array = Time32SecondArray::from(vec![Some(90000), Some(3600), Some(-1)]);
1094
1095 let values = Arc::new(time32_array);
1096 run_test(
1097 values,
1098 vec![
1099 Some(Variant::Null),
1100 Some(Variant::Time(
1101 NaiveTime::from_num_seconds_from_midnight_opt(3600, 0).unwrap(),
1102 )),
1103 Some(Variant::Null),
1104 ],
1105 );
1106 }
1107
1108 #[test]
1109 fn test_cast_to_variant_duration_or_interval_errors() {
1110 let arrays: Vec<Box<dyn Array>> = vec![
1111 Box::new(DurationSecondArray::from(vec![Some(10), None, Some(-5)])),
1113 Box::new(DurationMillisecondArray::from(vec![
1114 Some(10),
1115 None,
1116 Some(-5),
1117 ])),
1118 Box::new(DurationMicrosecondArray::from(vec![
1119 Some(10),
1120 None,
1121 Some(-5),
1122 ])),
1123 Box::new(DurationNanosecondArray::from(vec![
1124 Some(10),
1125 None,
1126 Some(-5),
1127 ])),
1128 Box::new(IntervalYearMonthArray::from(vec![Some(12), None, Some(-6)])),
1130 Box::new(IntervalDayTimeArray::from(vec![
1131 Some(IntervalDayTime::new(12, 0)),
1132 None,
1133 Some(IntervalDayTime::new(-6, 0)),
1134 ])),
1135 Box::new(IntervalMonthDayNanoArray::from(vec![
1136 Some(IntervalMonthDayNano::new(12, 0, 0)),
1137 None,
1138 Some(IntervalMonthDayNano::new(-6, 0, 0)),
1139 ])),
1140 ];
1141
1142 for array in arrays {
1143 let result = cast_to_variant(array.as_ref());
1144 assert!(result.is_err());
1145 match result.unwrap_err() {
1146 ArrowError::InvalidArgumentError(msg) => {
1147 assert!(
1148 msg.contains("Casting duration/interval types to Variant is not supported")
1149 );
1150 assert!(
1151 msg.contains("The Variant format does not define duration/interval types")
1152 );
1153 }
1154 _ => panic!("Expected InvalidArgumentError"),
1155 }
1156 }
1157 }
1158
1159 #[test]
1160 fn test_cast_to_variant_binary() {
1161 let mut builder = GenericByteBuilder::<BinaryType>::new();
1163 builder.append_value(b"hello");
1164 builder.append_value(b"");
1165 builder.append_null();
1166 builder.append_value(b"world");
1167 let binary_array = builder.finish();
1168 run_test(
1169 Arc::new(binary_array),
1170 vec![
1171 Some(Variant::Binary(b"hello")),
1172 Some(Variant::Binary(b"")),
1173 None,
1174 Some(Variant::Binary(b"world")),
1175 ],
1176 );
1177
1178 let mut builder = GenericByteBuilder::<LargeBinaryType>::new();
1180 builder.append_value(b"hello");
1181 builder.append_value(b"");
1182 builder.append_null();
1183 builder.append_value(b"world");
1184 let large_binary_array = builder.finish();
1185 run_test(
1186 Arc::new(large_binary_array),
1187 vec![
1188 Some(Variant::Binary(b"hello")),
1189 Some(Variant::Binary(b"")),
1190 None,
1191 Some(Variant::Binary(b"world")),
1192 ],
1193 );
1194
1195 let mut builder = GenericByteViewBuilder::<BinaryViewType>::new();
1197 builder.append_value(b"hello");
1198 builder.append_value(b"");
1199 builder.append_null();
1200 builder.append_value(b"world");
1201 let byte_view_array = builder.finish();
1202 run_test(
1203 Arc::new(byte_view_array),
1204 vec![
1205 Some(Variant::Binary(b"hello")),
1206 Some(Variant::Binary(b"")),
1207 None,
1208 Some(Variant::Binary(b"world")),
1209 ],
1210 );
1211 }
1212
1213 #[test]
1214 fn test_cast_to_variant_fixed_size_binary() {
1215 let v1 = vec![1, 2];
1216 let v2 = vec![3, 4];
1217 let v3 = vec![5, 6];
1218
1219 let mut builder = FixedSizeBinaryBuilder::new(2);
1220 builder.append_value(&v1).unwrap();
1221 builder.append_value(&v2).unwrap();
1222 builder.append_null();
1223 builder.append_value(&v3).unwrap();
1224 let array = builder.finish();
1225
1226 run_test(
1227 Arc::new(array),
1228 vec![
1229 Some(Variant::Binary(&v1)),
1230 Some(Variant::Binary(&v2)),
1231 None,
1232 Some(Variant::Binary(&v3)),
1233 ],
1234 );
1235 }
1236
1237 #[test]
1238 fn test_cast_to_variant_utf8() {
1239 let short_strings = vec![Some("hello"), Some(""), None, Some("world"), Some("test")];
1241 let string_array = StringArray::from(short_strings.clone());
1242
1243 run_test(
1244 Arc::new(string_array),
1245 vec![
1246 Some(Variant::from("hello")),
1247 Some(Variant::from("")),
1248 None,
1249 Some(Variant::from("world")),
1250 Some(Variant::from("test")),
1251 ],
1252 );
1253
1254 let long_string = "a".repeat(100); let long_strings = vec![Some(long_string.clone()), None, Some("short".to_string())];
1257 let string_array = StringArray::from(long_strings);
1258
1259 run_test(
1260 Arc::new(string_array),
1261 vec![
1262 Some(Variant::from(long_string.as_str())),
1263 None,
1264 Some(Variant::from("short")),
1265 ],
1266 );
1267 }
1268
1269 #[test]
1270 fn test_cast_to_variant_large_utf8() {
1271 let short_strings = vec![Some("hello"), Some(""), None, Some("world")];
1273 let string_array = LargeStringArray::from(short_strings.clone());
1274
1275 run_test(
1276 Arc::new(string_array),
1277 vec![
1278 Some(Variant::from("hello")),
1279 Some(Variant::from("")),
1280 None,
1281 Some(Variant::from("world")),
1282 ],
1283 );
1284
1285 let long_string = "b".repeat(100); let long_strings = vec![Some(long_string.clone()), None, Some("short".to_string())];
1288 let string_array = LargeStringArray::from(long_strings);
1289
1290 run_test(
1291 Arc::new(string_array),
1292 vec![
1293 Some(Variant::from(long_string.as_str())),
1294 None,
1295 Some(Variant::from("short")),
1296 ],
1297 );
1298 }
1299
1300 #[test]
1301 fn test_cast_to_variant_utf8_view() {
1302 let short_strings = vec![Some("hello"), Some(""), None, Some("world")];
1304 let string_view_array = StringViewArray::from(short_strings.clone());
1305
1306 run_test(
1307 Arc::new(string_view_array),
1308 vec![
1309 Some(Variant::from("hello")),
1310 Some(Variant::from("")),
1311 None,
1312 Some(Variant::from("world")),
1313 ],
1314 );
1315
1316 let long_string = "c".repeat(100); let long_strings = vec![Some(long_string.clone()), None, Some("short".to_string())];
1319 let string_view_array = StringViewArray::from(long_strings);
1320
1321 run_test(
1322 Arc::new(string_view_array),
1323 vec![
1324 Some(Variant::from(long_string.as_str())),
1325 None,
1326 Some(Variant::from("short")),
1327 ],
1328 );
1329 }
1330
1331 #[test]
1332 fn test_cast_to_variant_list() {
1333 let data = vec![Some(vec![Some(0), Some(1), Some(2)]), None];
1335 let list_array = ListArray::from_iter_primitive::<Int32Type, _, _>(data);
1336
1337 let (metadata, value) = {
1339 let mut builder = VariantBuilder::new();
1340 let mut list = builder.new_list();
1341 list.append_value(0);
1342 list.append_value(1);
1343 list.append_value(2);
1344 list.finish();
1345 builder.finish()
1346 };
1347 let variant = Variant::new(&metadata, &value);
1348
1349 run_test(Arc::new(list_array), vec![Some(variant), None]);
1350 }
1351
1352 #[test]
1353 fn test_cast_to_variant_sliced_list() {
1354 let data = vec![
1356 Some(vec![Some(0), Some(1), Some(2)]),
1357 Some(vec![Some(3), Some(4), Some(5)]),
1358 None,
1359 ];
1360 let list_array = ListArray::from_iter_primitive::<Int32Type, _, _>(data);
1361
1362 let (metadata, value) = {
1364 let mut builder = VariantBuilder::new();
1365 let mut list = builder.new_list();
1366 list.append_value(3);
1367 list.append_value(4);
1368 list.append_value(5);
1369 list.finish();
1370 builder.finish()
1371 };
1372 let variant = Variant::new(&metadata, &value);
1373
1374 run_test(Arc::new(list_array.slice(1, 2)), vec![Some(variant), None]);
1375 }
1376
1377 #[test]
1378 fn test_cast_to_variant_large_list() {
1379 let data = vec![Some(vec![Some(0), Some(1), Some(2)]), None];
1381 let large_list_array = LargeListArray::from_iter_primitive::<Int64Type, _, _>(data);
1382
1383 let (metadata, value) = {
1385 let mut builder = VariantBuilder::new();
1386 let mut list = builder.new_list();
1387 list.append_value(0i64);
1388 list.append_value(1i64);
1389 list.append_value(2i64);
1390 list.finish();
1391 builder.finish()
1392 };
1393 let variant = Variant::new(&metadata, &value);
1394
1395 run_test(Arc::new(large_list_array), vec![Some(variant), None]);
1396 }
1397
1398 #[test]
1399 fn test_cast_to_variant_sliced_large_list() {
1400 let data = vec![
1402 Some(vec![Some(0), Some(1), Some(2)]),
1403 Some(vec![Some(3), Some(4), Some(5)]),
1404 None,
1405 ];
1406 let large_list_array = ListArray::from_iter_primitive::<Int64Type, _, _>(data);
1407
1408 let (metadata, value) = {
1410 let mut builder = VariantBuilder::new();
1411 let mut list = builder.new_list();
1412 list.append_value(3i64);
1413 list.append_value(4i64);
1414 list.append_value(5i64);
1415 list.finish();
1416 builder.finish()
1417 };
1418 let variant = Variant::new(&metadata, &value);
1419
1420 run_test(
1421 Arc::new(large_list_array.slice(1, 2)),
1422 vec![Some(variant), None],
1423 );
1424 }
1425
1426 #[test]
1427 fn test_cast_to_variant_list_view() {
1428 let mut builder = ListViewBuilder::new(Int32Array::builder(0));
1430 builder.append_value(&Int32Array::from(vec![Some(0), None, Some(2)]));
1431 builder.append_value(&Int32Array::from(vec![Some(3), Some(4)]));
1432 builder.append_null();
1433 builder.append_value(&Int32Array::from(vec![None, None]));
1434 let list_view_array = builder.finish();
1435
1436 let (metadata, value) = {
1438 let mut builder = VariantBuilder::new();
1439 let mut list = builder.new_list();
1440 list.append_value(0i32);
1441 list.append_null();
1442 list.append_value(2i32);
1443 list.finish();
1444 builder.finish()
1445 };
1446 let variant0 = Variant::new(&metadata, &value);
1447
1448 let (metadata, value) = {
1449 let mut builder = VariantBuilder::new();
1450 let mut list = builder.new_list();
1451 list.append_value(3i32);
1452 list.append_value(4i32);
1453 list.finish();
1454 builder.finish()
1455 };
1456 let variant1 = Variant::new(&metadata, &value);
1457
1458 let (metadata, value) = {
1459 let mut builder = VariantBuilder::new();
1460 let mut list = builder.new_list();
1461 list.append_null();
1462 list.append_null();
1463 list.finish();
1464 builder.finish()
1465 };
1466 let variant3 = Variant::new(&metadata, &value);
1467
1468 run_test(
1469 Arc::new(list_view_array),
1470 vec![Some(variant0), Some(variant1), None, Some(variant3)],
1471 );
1472 }
1473
1474 #[test]
1475 fn test_cast_to_variant_sliced_list_view() {
1476 let mut builder = ListViewBuilder::new(Int32Array::builder(0));
1478 builder.append_value(&Int32Array::from(vec![Some(0), Some(1), Some(2)]));
1479 builder.append_value(&Int32Array::from(vec![Some(3), None]));
1480 builder.append_null();
1481 let list_view_array = builder.finish();
1482
1483 let (metadata, value) = {
1485 let mut builder = VariantBuilder::new();
1486 let mut list = builder.new_list();
1487 list.append_value(3i32);
1488 list.append_null();
1489 list.finish();
1490 builder.finish()
1491 };
1492 let variant = Variant::new(&metadata, &value);
1493
1494 run_test(
1495 Arc::new(list_view_array.slice(1, 2)),
1496 vec![Some(variant), None],
1497 );
1498 }
1499
1500 #[test]
1501 fn test_cast_to_variant_large_list_view() {
1502 let mut builder = LargeListViewBuilder::new(Int64Array::builder(0));
1504 builder.append_value(&Int64Array::from(vec![Some(0), None, Some(2)]));
1505 builder.append_value(&Int64Array::from(vec![Some(3), Some(4)]));
1506 builder.append_null();
1507 builder.append_value(&Int64Array::from(vec![None, None]));
1508 let large_list_view_array = builder.finish();
1509
1510 let (metadata, value) = {
1512 let mut builder = VariantBuilder::new();
1513 let mut list = builder.new_list();
1514 list.append_value(0i64);
1515 list.append_null();
1516 list.append_value(2i64);
1517 list.finish();
1518 builder.finish()
1519 };
1520 let variant0 = Variant::new(&metadata, &value);
1521
1522 let (metadata, value) = {
1523 let mut builder = VariantBuilder::new();
1524 let mut list = builder.new_list();
1525 list.append_value(3i64);
1526 list.append_value(4i64);
1527 list.finish();
1528 builder.finish()
1529 };
1530 let variant1 = Variant::new(&metadata, &value);
1531
1532 let (metadata, value) = {
1533 let mut builder = VariantBuilder::new();
1534 let mut list = builder.new_list();
1535 list.append_null();
1536 list.append_null();
1537 list.finish();
1538 builder.finish()
1539 };
1540 let variant3 = Variant::new(&metadata, &value);
1541
1542 run_test(
1543 Arc::new(large_list_view_array),
1544 vec![Some(variant0), Some(variant1), None, Some(variant3)],
1545 );
1546 }
1547
1548 #[test]
1549 fn test_cast_to_variant_sliced_large_list_view() {
1550 let mut builder = LargeListViewBuilder::new(Int64Array::builder(0));
1552 builder.append_value(&Int64Array::from(vec![Some(0), Some(1), Some(2)]));
1553 builder.append_value(&Int64Array::from(vec![Some(3), None]));
1554 builder.append_null();
1555 let large_list_view_array = builder.finish();
1556
1557 let (metadata, value) = {
1559 let mut builder = VariantBuilder::new();
1560 let mut list = builder.new_list();
1561 list.append_value(3i64);
1562 list.append_null();
1563 list.finish();
1564 builder.finish()
1565 };
1566 let variant = Variant::new(&metadata, &value);
1567
1568 run_test(
1569 Arc::new(large_list_view_array.slice(1, 2)),
1570 vec![Some(variant), None],
1571 );
1572 }
1573
1574 #[test]
1575 fn test_cast_to_variant_fixed_size_list() {
1576 let mut builder = FixedSizeListBuilder::new(Int32Array::builder(0), 2);
1577 builder.values().append_value(0);
1578 builder.values().append_value(1);
1579 builder.append(true); builder.values().append_null();
1582 builder.values().append_value(3);
1583 builder.append(true); builder.values().append_value(4);
1586 builder.values().append_null();
1587 builder.append(false); builder.values().append_nulls(2);
1590 builder.append(true); let fixed_size_list_array = builder.finish();
1593
1594 let (metadata, value) = {
1596 let mut builder = VariantBuilder::new();
1597 let mut list = builder.new_list();
1598 list.append_value(0i32);
1599 list.append_value(1i32);
1600 list.finish();
1601 builder.finish()
1602 };
1603 let variant0 = Variant::new(&metadata, &value);
1604
1605 let (metadata, value) = {
1606 let mut builder = VariantBuilder::new();
1607 let mut list = builder.new_list();
1608 list.append_null();
1609 list.append_value(3i32);
1610 list.finish();
1611 builder.finish()
1612 };
1613 let variant1 = Variant::new(&metadata, &value);
1614
1615 let (metadata, value) = {
1616 let mut builder = VariantBuilder::new();
1617 let mut list = builder.new_list();
1618 list.append_null();
1619 list.append_null();
1620 list.finish();
1621 builder.finish()
1622 };
1623 let variant3 = Variant::new(&metadata, &value);
1624
1625 run_test(
1626 Arc::new(fixed_size_list_array),
1627 vec![Some(variant0), Some(variant1), None, Some(variant3)],
1628 );
1629 }
1630
1631 #[test]
1632 fn test_cast_to_variant_sliced_fixed_size_list() {
1633 let mut builder = FixedSizeListBuilder::new(Int64Array::builder(0), 2);
1635 builder.values().append_value(0);
1636 builder.values().append_value(1);
1637 builder.append(true); builder.values().append_null();
1640 builder.values().append_value(3);
1641 builder.append(true); builder.values().append_value(4);
1644 builder.values().append_null();
1645 builder.append(false); let fixed_size_list_array = builder.finish();
1648
1649 let (metadata, value) = {
1651 let mut builder = VariantBuilder::new();
1652 let mut list = builder.new_list();
1653 list.append_null();
1654 list.append_value(3i64);
1655 list.finish();
1656 builder.finish()
1657 };
1658 let variant = Variant::new(&metadata, &value);
1659
1660 run_test(
1661 Arc::new(fixed_size_list_array.slice(1, 2)),
1662 vec![Some(variant), None],
1663 );
1664 }
1665
1666 #[test]
1667 fn test_cast_to_variant_struct() {
1668 let id_array = Int64Array::from(vec![Some(1001), Some(1002), None, Some(1003)]);
1670 let age_array = Int32Array::from(vec![Some(25), Some(30), Some(35), None]);
1671
1672 let fields = Fields::from(vec![
1673 Field::new("id", DataType::Int64, true),
1674 Field::new("age", DataType::Int32, true),
1675 ]);
1676
1677 let struct_array = StructArray::new(
1678 fields,
1679 vec![Arc::new(id_array), Arc::new(age_array)],
1680 None, );
1682
1683 let result = cast_to_variant(&struct_array).unwrap();
1684 assert_eq!(result.len(), 4);
1685
1686 let variant1 = result.value(0);
1688 let obj1 = variant1.as_object().unwrap();
1689 assert_eq!(obj1.get("id"), Some(Variant::from(1001i64)));
1690 assert_eq!(obj1.get("age"), Some(Variant::from(25i32)));
1691
1692 let variant2 = result.value(1);
1694 let obj2 = variant2.as_object().unwrap();
1695 assert_eq!(obj2.get("id"), Some(Variant::from(1002i64)));
1696 assert_eq!(obj2.get("age"), Some(Variant::from(30i32)));
1697
1698 let variant3 = result.value(2);
1700 let obj3 = variant3.as_object().unwrap();
1701 assert_eq!(obj3.get("id"), None);
1702 assert_eq!(obj3.get("age"), Some(Variant::from(35i32)));
1703
1704 let variant4 = result.value(3);
1706 let obj4 = variant4.as_object().unwrap();
1707 assert_eq!(obj4.get("id"), Some(Variant::from(1003i64)));
1708 assert_eq!(obj4.get("age"), None);
1709 }
1710
1711 #[test]
1712 fn test_cast_to_variant_struct_with_nulls() {
1713 let id_array = Int64Array::from(vec![Some(1001), Some(1002)]);
1715 let age_array = Int32Array::from(vec![Some(25), Some(30)]);
1716
1717 let fields = Fields::from(vec![
1718 Field::new("id", DataType::Int64, false),
1719 Field::new("age", DataType::Int32, false),
1720 ]);
1721
1722 let null_buffer = NullBuffer::from(vec![true, false]);
1724
1725 let struct_array = StructArray::new(
1726 fields,
1727 vec![Arc::new(id_array), Arc::new(age_array)],
1728 Some(null_buffer),
1729 );
1730
1731 let result = cast_to_variant(&struct_array).unwrap();
1732 assert_eq!(result.len(), 2);
1733
1734 assert!(!result.is_null(0));
1736 let variant1 = result.value(0);
1737 let obj1 = variant1.as_object().unwrap();
1738 assert_eq!(obj1.get("id"), Some(Variant::from(1001i64)));
1739 assert_eq!(obj1.get("age"), Some(Variant::from(25i32)));
1740
1741 assert!(result.is_null(1));
1743 }
1744
1745 #[test]
1746 fn test_cast_to_variant_struct_performance() {
1747 let size = 1000;
1750
1751 let id_array = Int64Array::from((0..size).map(|i| Some(i as i64)).collect::<Vec<_>>());
1752 let age_array = Int32Array::from(
1753 (0..size)
1754 .map(|i| Some((i % 100) as i32))
1755 .collect::<Vec<_>>(),
1756 );
1757 let score_array =
1758 Float64Array::from((0..size).map(|i| Some(i as f64 * 0.1)).collect::<Vec<_>>());
1759
1760 let fields = Fields::from(vec![
1761 Field::new("id", DataType::Int64, false),
1762 Field::new("age", DataType::Int32, false),
1763 Field::new("score", DataType::Float64, false),
1764 ]);
1765
1766 let struct_array = StructArray::new(
1767 fields,
1768 vec![
1769 Arc::new(id_array),
1770 Arc::new(age_array),
1771 Arc::new(score_array),
1772 ],
1773 None,
1774 );
1775
1776 let result = cast_to_variant(&struct_array).unwrap();
1777 assert_eq!(result.len(), size);
1778
1779 let variant0 = result.value(0);
1781 let obj0 = variant0.as_object().unwrap();
1782 assert_eq!(obj0.get("id"), Some(Variant::from(0i64)));
1783 assert_eq!(obj0.get("age"), Some(Variant::from(0i32)));
1784 assert_eq!(obj0.get("score"), Some(Variant::from(0.0f64)));
1785
1786 let variant999 = result.value(999);
1787 let obj999 = variant999.as_object().unwrap();
1788 assert_eq!(obj999.get("id"), Some(Variant::from(999i64)));
1789 assert_eq!(obj999.get("age"), Some(Variant::from(99i32))); assert_eq!(obj999.get("score"), Some(Variant::from(99.9f64)));
1791 }
1792
1793 #[test]
1794 fn test_cast_to_variant_struct_performance_large() {
1795 let size = 10000;
1797 let num_fields = 10;
1798
1799 let mut field_arrays: Vec<ArrayRef> = Vec::new();
1801 let mut fields = Vec::new();
1802
1803 for field_idx in 0..num_fields {
1804 match field_idx % 4 {
1805 0 => {
1806 let array = Int64Array::from(
1808 (0..size)
1809 .map(|i| Some(i as i64 + field_idx as i64))
1810 .collect::<Vec<_>>(),
1811 );
1812 field_arrays.push(Arc::new(array));
1813 fields.push(Field::new(
1814 format!("int_field_{}", field_idx),
1815 DataType::Int64,
1816 false,
1817 ));
1818 }
1819 1 => {
1820 let array = Int32Array::from(
1822 (0..size)
1823 .map(|i| Some((i % 1000) as i32 + field_idx as i32))
1824 .collect::<Vec<_>>(),
1825 );
1826 field_arrays.push(Arc::new(array));
1827 fields.push(Field::new(
1828 format!("int32_field_{}", field_idx),
1829 DataType::Int32,
1830 false,
1831 ));
1832 }
1833 2 => {
1834 let array = Float64Array::from(
1836 (0..size)
1837 .map(|i| Some(i as f64 * 0.1 + field_idx as f64))
1838 .collect::<Vec<_>>(),
1839 );
1840 field_arrays.push(Arc::new(array));
1841 fields.push(Field::new(
1842 format!("float_field_{}", field_idx),
1843 DataType::Float64,
1844 false,
1845 ));
1846 }
1847 _ => {
1848 let binary_data: Vec<Option<&[u8]>> = (0..size)
1850 .map(|i| {
1851 match i % 3 {
1853 0 => Some(b"test_data_0" as &[u8]),
1854 1 => Some(b"test_data_1" as &[u8]),
1855 _ => Some(b"test_data_2" as &[u8]),
1856 }
1857 })
1858 .collect();
1859 let array = BinaryArray::from(binary_data);
1860 field_arrays.push(Arc::new(array));
1861 fields.push(Field::new(
1862 format!("binary_field_{}", field_idx),
1863 DataType::Binary,
1864 false,
1865 ));
1866 }
1867 }
1868 }
1869
1870 let struct_array = StructArray::new(Fields::from(fields), field_arrays, None);
1871
1872 let result = cast_to_variant(&struct_array).unwrap();
1873 assert_eq!(result.len(), size);
1874
1875 for sample_idx in [0, size / 4, size / 2, size - 1] {
1877 let variant = result.value(sample_idx);
1878 let obj = variant.as_object().unwrap();
1879
1880 assert_eq!(obj.len(), num_fields);
1882
1883 if let Some(int_field_0) = obj.get("int_field_0") {
1885 assert_eq!(int_field_0, Variant::from(sample_idx as i64));
1886 }
1887 if let Some(float_field_2) = obj.get("float_field_2") {
1888 assert_eq!(float_field_2, Variant::from(sample_idx as f64 * 0.1 + 2.0));
1889 }
1890 }
1891 }
1892
1893 #[test]
1894 fn test_cast_to_variant_nested_struct() {
1895 let id_array = Int64Array::from(vec![Some(1001), Some(1002)]);
1897 let x_array = Float64Array::from(vec![Some(40.7), Some(37.8)]);
1898 let y_array = Float64Array::from(vec![Some(-74.0), Some(-122.4)]);
1899
1900 let location_fields = Fields::from(vec![
1902 Field::new("x", DataType::Float64, true),
1903 Field::new("y", DataType::Float64, true),
1904 ]);
1905 let location_struct = StructArray::new(
1906 location_fields.clone(),
1907 vec![Arc::new(x_array), Arc::new(y_array)],
1908 None,
1909 );
1910
1911 let person_fields = Fields::from(vec![
1913 Field::new("id", DataType::Int64, true),
1914 Field::new("location", DataType::Struct(location_fields), true),
1915 ]);
1916 let person_struct = StructArray::new(
1917 person_fields,
1918 vec![Arc::new(id_array), Arc::new(location_struct)],
1919 None,
1920 );
1921
1922 let result = cast_to_variant(&person_struct).unwrap();
1923 assert_eq!(result.len(), 2);
1924
1925 let variant1 = result.value(0);
1927 let obj1 = variant1.as_object().unwrap();
1928 assert_eq!(obj1.get("id"), Some(Variant::from(1001i64)));
1929
1930 let location_variant1 = obj1.get("location").unwrap();
1931 let location_obj1 = location_variant1.as_object().unwrap();
1932 assert_eq!(location_obj1.get("x"), Some(Variant::from(40.7f64)));
1933 assert_eq!(location_obj1.get("y"), Some(Variant::from(-74.0f64)));
1934
1935 let variant2 = result.value(1);
1937 let obj2 = variant2.as_object().unwrap();
1938 assert_eq!(obj2.get("id"), Some(Variant::from(1002i64)));
1939
1940 let location_variant2 = obj2.get("location").unwrap();
1941 let location_obj2 = location_variant2.as_object().unwrap();
1942 assert_eq!(location_obj2.get("x"), Some(Variant::from(37.8f64)));
1943 assert_eq!(location_obj2.get("y"), Some(Variant::from(-122.4f64)));
1944 }
1945
1946 #[test]
1947 fn test_cast_to_variant_map() {
1948 let keys = vec!["key1", "key2", "key3"];
1949 let values_data = Int32Array::from(vec![1, 2, 3]);
1950 let entry_offsets = vec![0, 1, 3];
1951 let map_array =
1952 MapArray::new_from_strings(keys.clone().into_iter(), &values_data, &entry_offsets)
1953 .unwrap();
1954
1955 let result = cast_to_variant(&map_array).unwrap();
1956 let variant1 = result.value(0);
1958 assert_eq!(
1959 variant1.as_object().unwrap().get("key1").unwrap(),
1960 Variant::from(1)
1961 );
1962
1963 let variant2 = result.value(1);
1965 assert_eq!(
1966 variant2.as_object().unwrap().get("key2").unwrap(),
1967 Variant::from(2)
1968 );
1969 assert_eq!(
1970 variant2.as_object().unwrap().get("key3").unwrap(),
1971 Variant::from(3)
1972 );
1973 }
1974
1975 #[test]
1976 fn test_cast_to_variant_map_with_nulls_and_empty() {
1977 use arrow::array::{Int32Array, MapArray, StringArray, StructArray};
1978 use arrow::buffer::{NullBuffer, OffsetBuffer};
1979 use arrow::datatypes::{DataType, Field, Fields};
1980 use std::sync::Arc;
1981
1982 let keys = StringArray::from(vec!["key1", "key2", "key3"]);
1984 let values = Int32Array::from(vec![1, 2, 3]);
1985 let entries_fields = Fields::from(vec![
1986 Field::new("key", DataType::Utf8, false),
1987 Field::new("value", DataType::Int32, true),
1988 ]);
1989 let entries = StructArray::new(
1990 entries_fields.clone(),
1991 vec![Arc::new(keys), Arc::new(values)],
1992 None,
1993 );
1994
1995 let offsets = OffsetBuffer::new(vec![0, 1, 1, 1, 3].into());
1997
1998 let null_buffer = Some(NullBuffer::from(vec![true, true, false, true]));
2000
2001 let map_field = Arc::new(Field::new(
2002 "entries",
2003 DataType::Struct(entries_fields),
2004 false,
2005 ));
2006
2007 let map_array = MapArray::try_new(map_field, offsets, entries, null_buffer, false).unwrap();
2008
2009 let result = cast_to_variant(&map_array).unwrap();
2010
2011 let variant0 = result.value(0);
2013 assert_eq!(
2014 variant0.as_object().unwrap().get("key1").unwrap(),
2015 Variant::from(1)
2016 );
2017
2018 let variant1 = result.value(1);
2020 let obj1 = variant1.as_object().unwrap();
2021 assert_eq!(obj1.len(), 0); assert!(result.is_null(2));
2025
2026 let variant3 = result.value(3);
2028 assert_eq!(
2029 variant3.as_object().unwrap().get("key2").unwrap(),
2030 Variant::from(2)
2031 );
2032 assert_eq!(
2033 variant3.as_object().unwrap().get("key3").unwrap(),
2034 Variant::from(3)
2035 );
2036 }
2037
2038 #[test]
2039 fn test_cast_to_variant_map_with_non_string_keys() {
2040 let offsets = OffsetBuffer::new(vec![0, 1, 3].into());
2041 let fields = Fields::from(vec![
2042 Field::new("key", DataType::Int32, false),
2043 Field::new("values", DataType::Int32, false),
2044 ]);
2045 let columns = vec![
2046 Arc::new(Int32Array::from(vec![1, 2, 3])) as _,
2047 Arc::new(Int32Array::from(vec![1, 2, 3])) as _,
2048 ];
2049
2050 let entries = StructArray::new(fields.clone(), columns, None);
2051 let field = Arc::new(Field::new("entries", DataType::Struct(fields), false));
2052
2053 let map_array = MapArray::new(field.clone(), offsets.clone(), entries.clone(), None, false);
2054
2055 let result = cast_to_variant(&map_array).unwrap();
2056
2057 let variant1 = result.value(0);
2058 assert_eq!(
2059 variant1.as_object().unwrap().get("1").unwrap(),
2060 Variant::from(1)
2061 );
2062
2063 let variant2 = result.value(1);
2064 assert_eq!(
2065 variant2.as_object().unwrap().get("2").unwrap(),
2066 Variant::from(2)
2067 );
2068 assert_eq!(
2069 variant2.as_object().unwrap().get("3").unwrap(),
2070 Variant::from(3)
2071 );
2072 }
2073
2074 #[test]
2075 fn test_cast_to_variant_union_sparse() {
2076 let int_array = Int32Array::from(vec![Some(1), None, None, None, Some(34), None]);
2078 let float_array = Float64Array::from(vec![None, Some(3.2), None, Some(32.5), None, None]);
2079 let string_array = StringArray::from(vec![None, None, Some("hello"), None, None, None]);
2080 let type_ids = [0, 1, 2, 1, 0, 0].into_iter().collect::<ScalarBuffer<i8>>();
2081
2082 let union_fields = UnionFields::from_fields(vec![
2083 Field::new("int_field", DataType::Int32, false),
2084 Field::new("float_field", DataType::Float64, false),
2085 Field::new("string_field", DataType::Utf8, false),
2086 ]);
2087
2088 let children: Vec<Arc<dyn Array>> = vec![
2089 Arc::new(int_array),
2090 Arc::new(float_array),
2091 Arc::new(string_array),
2092 ];
2093
2094 let union_array = UnionArray::try_new(
2095 union_fields,
2096 type_ids,
2097 None, children,
2099 )
2100 .unwrap();
2101
2102 run_test(
2103 Arc::new(union_array),
2104 vec![
2105 Some(Variant::Int32(1)),
2106 Some(Variant::Double(3.2)),
2107 Some(Variant::from("hello")),
2108 Some(Variant::Double(32.5)),
2109 Some(Variant::Int32(34)),
2110 None,
2111 ],
2112 );
2113 }
2114
2115 #[test]
2116 fn test_cast_to_variant_union_dense() {
2117 let int_array = Int32Array::from(vec![Some(1), Some(34), None]);
2119 let float_array = Float64Array::from(vec![3.2, 32.5]);
2120 let string_array = StringArray::from(vec!["hello"]);
2121 let type_ids = [0, 1, 2, 1, 0, 0].into_iter().collect::<ScalarBuffer<i8>>();
2122 let offsets = [0, 0, 0, 1, 1, 2]
2123 .into_iter()
2124 .collect::<ScalarBuffer<i32>>();
2125
2126 let union_fields = UnionFields::from_fields(vec![
2127 Field::new("int_field", DataType::Int32, false),
2128 Field::new("float_field", DataType::Float64, false),
2129 Field::new("string_field", DataType::Utf8, false),
2130 ]);
2131
2132 let children: Vec<Arc<dyn Array>> = vec![
2133 Arc::new(int_array),
2134 Arc::new(float_array),
2135 Arc::new(string_array),
2136 ];
2137
2138 let union_array = UnionArray::try_new(
2139 union_fields,
2140 type_ids,
2141 Some(offsets), children,
2143 )
2144 .unwrap();
2145
2146 run_test(
2147 Arc::new(union_array),
2148 vec![
2149 Some(Variant::Int32(1)),
2150 Some(Variant::Double(3.2)),
2151 Some(Variant::from("hello")),
2152 Some(Variant::Double(32.5)),
2153 Some(Variant::Int32(34)),
2154 None,
2155 ],
2156 );
2157 }
2158
2159 #[test]
2160 fn test_cast_to_variant_dictionary() {
2161 let values = StringArray::from(vec!["apple", "banana", "cherry", "date"]);
2162 let keys = Int32Array::from(vec![Some(0), Some(1), None, Some(2), Some(0), Some(3)]);
2163 let dict_array = DictionaryArray::<Int32Type>::try_new(keys, Arc::new(values)).unwrap();
2164
2165 run_test(
2166 Arc::new(dict_array),
2167 vec![
2168 Some(Variant::from("apple")),
2169 Some(Variant::from("banana")),
2170 None,
2171 Some(Variant::from("cherry")),
2172 Some(Variant::from("apple")),
2173 Some(Variant::from("date")),
2174 ],
2175 );
2176 }
2177
2178 #[test]
2179 fn test_cast_to_variant_dictionary_with_nulls() {
2180 let values = StringArray::from(vec![Some("a"), None, Some("c")]);
2182 let keys = Int8Array::from(vec![Some(0), Some(1), Some(2), Some(0)]);
2183 let dict_array = DictionaryArray::<Int8Type>::try_new(keys, Arc::new(values)).unwrap();
2184
2185 run_test(
2186 Arc::new(dict_array),
2187 vec![
2188 Some(Variant::from("a")),
2189 None, Some(Variant::from("c")),
2191 Some(Variant::from("a")),
2192 ],
2193 );
2194 }
2195
2196 #[test]
2197 fn test_cast_to_variant_run_end_encoded() {
2198 let mut builder = StringRunBuilder::<Int32Type>::new();
2199 builder.append_value("apple");
2200 builder.append_value("apple");
2201 builder.append_value("banana");
2202 builder.append_value("banana");
2203 builder.append_value("banana");
2204 builder.append_value("cherry");
2205 let run_array = builder.finish();
2206
2207 run_test(
2208 Arc::new(run_array),
2209 vec![
2210 Some(Variant::from("apple")),
2211 Some(Variant::from("apple")),
2212 Some(Variant::from("banana")),
2213 Some(Variant::from("banana")),
2214 Some(Variant::from("banana")),
2215 Some(Variant::from("cherry")),
2216 ],
2217 );
2218 }
2219
2220 #[test]
2221 fn test_cast_to_variant_run_end_encoded_with_nulls() {
2222 use arrow::array::StringRunBuilder;
2223 use arrow::datatypes::Int32Type;
2224
2225 let mut builder = StringRunBuilder::<Int32Type>::new();
2227 builder.append_value("apple");
2228 builder.append_null();
2229 builder.append_value("banana");
2230 builder.append_value("banana");
2231 builder.append_null();
2232 builder.append_null();
2233 let run_array = builder.finish();
2234
2235 run_test(
2236 Arc::new(run_array),
2237 vec![
2238 Some(Variant::from("apple")),
2239 None,
2240 Some(Variant::from("banana")),
2241 Some(Variant::from("banana")),
2242 None,
2243 None,
2244 ],
2245 );
2246 }
2247
2248 fn run_test_with_options(
2252 values: ArrayRef,
2253 expected: Vec<Option<Variant>>,
2254 options: CastOptions,
2255 ) {
2256 let variant_array = cast_to_variant_with_options(&values, &options).unwrap();
2257 assert_eq!(variant_array.len(), expected.len());
2258 for (i, expected_value) in expected.iter().enumerate() {
2259 match expected_value {
2260 Some(value) => {
2261 assert!(!variant_array.is_null(i), "Expected non-null at index {i}");
2262 assert_eq!(variant_array.value(i), *value, "mismatch at index {i}");
2263 }
2264 None => {
2265 assert!(variant_array.is_null(i), "Expected null at index {i}");
2266 }
2267 }
2268 }
2269 }
2270
2271 fn run_test(values: ArrayRef, expected: Vec<Option<Variant>>) {
2272 run_test_with_options(values, expected, CastOptions::default());
2273 }
2274
2275 fn run_test_in_strict_mode(
2276 values: ArrayRef,
2277 expected: Result<Vec<Option<Variant>>, ArrowError>,
2278 ) {
2279 let options = CastOptions {
2280 safe: false,
2281 ..Default::default()
2282 };
2283 match expected {
2284 Ok(expected) => run_test_with_options(values, expected, options),
2285 Err(_) => {
2286 let result = cast_to_variant_with_options(values.as_ref(), &options);
2287 assert!(result.is_err());
2288 assert_eq!(
2289 result.unwrap_err().to_string(),
2290 expected.unwrap_err().to_string()
2291 );
2292 }
2293 }
2294 }
2295}