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