parquet_variant_compute/
cast_to_variant.rs

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