Skip to main content

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