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