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