1use arrow::array::{
6 Array, AsArray, FixedSizeListArray, GenericBinaryArray, GenericListArray, GenericListViewArray,
7 GenericStringArray, ListLikeArray, OffsetSizeTrait, PrimitiveArray,
8};
9use arrow::compute::{CastOptions, kernels::cast};
10use arrow::datatypes::{
11 self as datatypes, ArrowNativeType, ArrowPrimitiveType, ArrowTemporalType, ArrowTimestampType,
12 DecimalType, RunEndIndexType,
13};
14use arrow::temporal_conversions::{as_date, as_datetime, as_time};
15use arrow_schema::{ArrowError, DataType, TimeUnit};
16use chrono::{DateTime, TimeZone, Utc};
17use parquet_variant::{
18 ObjectFieldBuilder, Variant, VariantBuilderExt, VariantDecimal4, VariantDecimal8,
19 VariantDecimal16, VariantDecimalType,
20};
21use std::collections::HashMap;
22
23pub(crate) enum ArrowToVariantRowBuilder<'a> {
29 Null(NullArrowToVariantBuilder),
30 Boolean(BooleanArrowToVariantBuilder<'a>),
31 PrimitiveInt8(PrimitiveArrowToVariantBuilder<'a, datatypes::Int8Type>),
32 PrimitiveInt16(PrimitiveArrowToVariantBuilder<'a, datatypes::Int16Type>),
33 PrimitiveInt32(PrimitiveArrowToVariantBuilder<'a, datatypes::Int32Type>),
34 PrimitiveInt64(PrimitiveArrowToVariantBuilder<'a, datatypes::Int64Type>),
35 PrimitiveUInt8(PrimitiveArrowToVariantBuilder<'a, datatypes::UInt8Type>),
36 PrimitiveUInt16(PrimitiveArrowToVariantBuilder<'a, datatypes::UInt16Type>),
37 PrimitiveUInt32(PrimitiveArrowToVariantBuilder<'a, datatypes::UInt32Type>),
38 PrimitiveUInt64(PrimitiveArrowToVariantBuilder<'a, datatypes::UInt64Type>),
39 PrimitiveFloat16(PrimitiveArrowToVariantBuilder<'a, datatypes::Float16Type>),
40 PrimitiveFloat32(PrimitiveArrowToVariantBuilder<'a, datatypes::Float32Type>),
41 PrimitiveFloat64(PrimitiveArrowToVariantBuilder<'a, datatypes::Float64Type>),
42 Decimal32(DecimalArrowToVariantBuilder<'a, datatypes::Decimal32Type, VariantDecimal4>),
43 Decimal64(DecimalArrowToVariantBuilder<'a, datatypes::Decimal64Type, VariantDecimal8>),
44 Decimal128(DecimalArrowToVariantBuilder<'a, datatypes::Decimal128Type, VariantDecimal16>),
45 Decimal256(Decimal256ArrowToVariantBuilder<'a>),
46 TimestampSecond(TimestampArrowToVariantBuilder<'a, datatypes::TimestampSecondType>),
47 TimestampMillisecond(TimestampArrowToVariantBuilder<'a, datatypes::TimestampMillisecondType>),
48 TimestampMicrosecond(TimestampArrowToVariantBuilder<'a, datatypes::TimestampMicrosecondType>),
49 TimestampNanosecond(TimestampArrowToVariantBuilder<'a, datatypes::TimestampNanosecondType>),
50 Date32(DateArrowToVariantBuilder<'a, datatypes::Date32Type>),
51 Date64(DateArrowToVariantBuilder<'a, datatypes::Date64Type>),
52 Time32Second(TimeArrowToVariantBuilder<'a, datatypes::Time32SecondType>),
53 Time32Millisecond(TimeArrowToVariantBuilder<'a, datatypes::Time32MillisecondType>),
54 Time64Microsecond(TimeArrowToVariantBuilder<'a, datatypes::Time64MicrosecondType>),
55 Time64Nanosecond(TimeArrowToVariantBuilder<'a, datatypes::Time64NanosecondType>),
56 Binary(BinaryArrowToVariantBuilder<'a, i32>),
57 LargeBinary(BinaryArrowToVariantBuilder<'a, i64>),
58 BinaryView(BinaryViewArrowToVariantBuilder<'a>),
59 FixedSizeBinary(FixedSizeBinaryArrowToVariantBuilder<'a>),
60 Utf8(StringArrowToVariantBuilder<'a, i32>),
61 LargeUtf8(StringArrowToVariantBuilder<'a, i64>),
62 Utf8View(StringViewArrowToVariantBuilder<'a>),
63 List(ListArrowToVariantBuilder<'a, GenericListArray<i32>>),
64 LargeList(ListArrowToVariantBuilder<'a, GenericListArray<i64>>),
65 ListView(ListArrowToVariantBuilder<'a, GenericListViewArray<i32>>),
66 LargeListView(ListArrowToVariantBuilder<'a, GenericListViewArray<i64>>),
67 FixedSizeList(ListArrowToVariantBuilder<'a, FixedSizeListArray>),
68 Struct(StructArrowToVariantBuilder<'a>),
69 Map(MapArrowToVariantBuilder<'a>),
70 Union(UnionArrowToVariantBuilder<'a>),
71 Dictionary(DictionaryArrowToVariantBuilder<'a>),
72 RunEndEncodedInt16(RunEndEncodedArrowToVariantBuilder<'a, datatypes::Int16Type>),
73 RunEndEncodedInt32(RunEndEncodedArrowToVariantBuilder<'a, datatypes::Int32Type>),
74 RunEndEncodedInt64(RunEndEncodedArrowToVariantBuilder<'a, datatypes::Int64Type>),
75}
76
77impl ArrowToVariantRowBuilder<'_> {
78 pub fn append_row(
80 &mut self,
81 builder: &mut impl VariantBuilderExt,
82 index: usize,
83 ) -> Result<(), ArrowError> {
84 use ArrowToVariantRowBuilder::*;
85 match self {
86 Null(b) => b.append_row(builder, index),
87 Boolean(b) => b.append_row(builder, index),
88 PrimitiveInt8(b) => b.append_row(builder, index),
89 PrimitiveInt16(b) => b.append_row(builder, index),
90 PrimitiveInt32(b) => b.append_row(builder, index),
91 PrimitiveInt64(b) => b.append_row(builder, index),
92 PrimitiveUInt8(b) => b.append_row(builder, index),
93 PrimitiveUInt16(b) => b.append_row(builder, index),
94 PrimitiveUInt32(b) => b.append_row(builder, index),
95 PrimitiveUInt64(b) => b.append_row(builder, index),
96 PrimitiveFloat16(b) => b.append_row(builder, index),
97 PrimitiveFloat32(b) => b.append_row(builder, index),
98 PrimitiveFloat64(b) => b.append_row(builder, index),
99 Decimal32(b) => b.append_row(builder, index),
100 Decimal64(b) => b.append_row(builder, index),
101 Decimal128(b) => b.append_row(builder, index),
102 Decimal256(b) => b.append_row(builder, index),
103 TimestampSecond(b) => b.append_row(builder, index),
104 TimestampMillisecond(b) => b.append_row(builder, index),
105 TimestampMicrosecond(b) => b.append_row(builder, index),
106 TimestampNanosecond(b) => b.append_row(builder, index),
107 Date32(b) => b.append_row(builder, index),
108 Date64(b) => b.append_row(builder, index),
109 Time32Second(b) => b.append_row(builder, index),
110 Time32Millisecond(b) => b.append_row(builder, index),
111 Time64Microsecond(b) => b.append_row(builder, index),
112 Time64Nanosecond(b) => b.append_row(builder, index),
113 Binary(b) => b.append_row(builder, index),
114 LargeBinary(b) => b.append_row(builder, index),
115 BinaryView(b) => b.append_row(builder, index),
116 FixedSizeBinary(b) => b.append_row(builder, index),
117 Utf8(b) => b.append_row(builder, index),
118 LargeUtf8(b) => b.append_row(builder, index),
119 Utf8View(b) => b.append_row(builder, index),
120 List(b) => b.append_row(builder, index),
121 LargeList(b) => b.append_row(builder, index),
122 ListView(b) => b.append_row(builder, index),
123 LargeListView(b) => b.append_row(builder, index),
124 FixedSizeList(b) => b.append_row(builder, index),
125 Struct(b) => b.append_row(builder, index),
126 Map(b) => b.append_row(builder, index),
127 Union(b) => b.append_row(builder, index),
128 Dictionary(b) => b.append_row(builder, index),
129 RunEndEncodedInt16(b) => b.append_row(builder, index),
130 RunEndEncodedInt32(b) => b.append_row(builder, index),
131 RunEndEncodedInt64(b) => b.append_row(builder, index),
132 }
133 }
134}
135
136pub(crate) fn make_arrow_to_variant_row_builder<'a>(
138 data_type: &'a DataType,
139 array: &'a dyn Array,
140 options: &'a CastOptions,
141) -> Result<ArrowToVariantRowBuilder<'a>, ArrowError> {
142 use ArrowToVariantRowBuilder::*;
143 let builder =
144 match data_type {
145 DataType::Null => Null(NullArrowToVariantBuilder),
146 DataType::Boolean => Boolean(BooleanArrowToVariantBuilder::new(array)),
147 DataType::Int8 => PrimitiveInt8(PrimitiveArrowToVariantBuilder::new(array)),
148 DataType::Int16 => PrimitiveInt16(PrimitiveArrowToVariantBuilder::new(array)),
149 DataType::Int32 => PrimitiveInt32(PrimitiveArrowToVariantBuilder::new(array)),
150 DataType::Int64 => PrimitiveInt64(PrimitiveArrowToVariantBuilder::new(array)),
151 DataType::UInt8 => PrimitiveUInt8(PrimitiveArrowToVariantBuilder::new(array)),
152 DataType::UInt16 => PrimitiveUInt16(PrimitiveArrowToVariantBuilder::new(array)),
153 DataType::UInt32 => PrimitiveUInt32(PrimitiveArrowToVariantBuilder::new(array)),
154 DataType::UInt64 => PrimitiveUInt64(PrimitiveArrowToVariantBuilder::new(array)),
155 DataType::Float16 => PrimitiveFloat16(PrimitiveArrowToVariantBuilder::new(array)),
156 DataType::Float32 => PrimitiveFloat32(PrimitiveArrowToVariantBuilder::new(array)),
157 DataType::Float64 => PrimitiveFloat64(PrimitiveArrowToVariantBuilder::new(array)),
158 DataType::Decimal32(_, scale) => {
159 Decimal32(DecimalArrowToVariantBuilder::new(array, options, *scale))
160 }
161 DataType::Decimal64(_, scale) => {
162 Decimal64(DecimalArrowToVariantBuilder::new(array, options, *scale))
163 }
164 DataType::Decimal128(_, scale) => {
165 Decimal128(DecimalArrowToVariantBuilder::new(array, options, *scale))
166 }
167 DataType::Decimal256(_, scale) => {
168 Decimal256(Decimal256ArrowToVariantBuilder::new(array, options, *scale))
169 }
170 DataType::Timestamp(time_unit, time_zone) => {
171 match time_unit {
172 TimeUnit::Second => TimestampSecond(TimestampArrowToVariantBuilder::new(
173 array,
174 options,
175 time_zone.is_some(),
176 )),
177 TimeUnit::Millisecond => TimestampMillisecond(
178 TimestampArrowToVariantBuilder::new(array, options, time_zone.is_some()),
179 ),
180 TimeUnit::Microsecond => TimestampMicrosecond(
181 TimestampArrowToVariantBuilder::new(array, options, time_zone.is_some()),
182 ),
183 TimeUnit::Nanosecond => TimestampNanosecond(
184 TimestampArrowToVariantBuilder::new(array, options, time_zone.is_some()),
185 ),
186 }
187 }
188 DataType::Date32 => Date32(DateArrowToVariantBuilder::new(array, options)),
189 DataType::Date64 => Date64(DateArrowToVariantBuilder::new(array, options)),
190 DataType::Time32(time_unit) => match time_unit {
191 TimeUnit::Second => Time32Second(TimeArrowToVariantBuilder::new(array, options)),
192 TimeUnit::Millisecond => {
193 Time32Millisecond(TimeArrowToVariantBuilder::new(array, options))
194 }
195 _ => {
196 return Err(ArrowError::CastError(format!(
197 "Unsupported Time32 unit: {time_unit:?}"
198 )));
199 }
200 },
201 DataType::Time64(time_unit) => match time_unit {
202 TimeUnit::Microsecond => {
203 Time64Microsecond(TimeArrowToVariantBuilder::new(array, options))
204 }
205 TimeUnit::Nanosecond => {
206 Time64Nanosecond(TimeArrowToVariantBuilder::new(array, options))
207 }
208 _ => {
209 return Err(ArrowError::CastError(format!(
210 "Unsupported Time64 unit: {time_unit:?}"
211 )));
212 }
213 },
214 DataType::Duration(_) | DataType::Interval(_) => {
215 return Err(ArrowError::InvalidArgumentError(
216 "Casting duration/interval types to Variant is not supported. \
217 The Variant format does not define duration/interval types."
218 .to_string(),
219 ));
220 }
221 DataType::Binary => Binary(BinaryArrowToVariantBuilder::new(array)),
222 DataType::LargeBinary => LargeBinary(BinaryArrowToVariantBuilder::new(array)),
223 DataType::BinaryView => BinaryView(BinaryViewArrowToVariantBuilder::new(array)),
224 DataType::FixedSizeBinary(_) => {
225 FixedSizeBinary(FixedSizeBinaryArrowToVariantBuilder::new(array))
226 }
227 DataType::Utf8 => Utf8(StringArrowToVariantBuilder::new(array)),
228 DataType::LargeUtf8 => LargeUtf8(StringArrowToVariantBuilder::new(array)),
229 DataType::Utf8View => Utf8View(StringViewArrowToVariantBuilder::new(array)),
230 DataType::List(_) => List(ListArrowToVariantBuilder::new(array.as_list(), options)?),
231 DataType::LargeList(_) => {
232 LargeList(ListArrowToVariantBuilder::new(array.as_list(), options)?)
233 }
234 DataType::ListView(_) => ListView(ListArrowToVariantBuilder::new(
235 array.as_list_view(),
236 options,
237 )?),
238 DataType::LargeListView(_) => LargeListView(ListArrowToVariantBuilder::new(
239 array.as_list_view(),
240 options,
241 )?),
242 DataType::FixedSizeList(_, _) => FixedSizeList(ListArrowToVariantBuilder::new(
243 array.as_fixed_size_list(),
244 options,
245 )?),
246 DataType::Struct(_) => Struct(StructArrowToVariantBuilder::new(
247 array.as_struct(),
248 options,
249 )?),
250 DataType::Map(_, _) => Map(MapArrowToVariantBuilder::new(array, options)?),
251 DataType::Union(_, _) => Union(UnionArrowToVariantBuilder::new(array, options)?),
252 DataType::Dictionary(_, _) => {
253 Dictionary(DictionaryArrowToVariantBuilder::new(array, options)?)
254 }
255 DataType::RunEndEncoded(run_ends, _) => match run_ends.data_type() {
256 DataType::Int16 => {
257 RunEndEncodedInt16(RunEndEncodedArrowToVariantBuilder::new(array, options)?)
258 }
259 DataType::Int32 => {
260 RunEndEncodedInt32(RunEndEncodedArrowToVariantBuilder::new(array, options)?)
261 }
262 DataType::Int64 => {
263 RunEndEncodedInt64(RunEndEncodedArrowToVariantBuilder::new(array, options)?)
264 }
265 _ => {
266 return Err(ArrowError::CastError(format!(
267 "Unsupported run ends type: {}",
268 run_ends.data_type()
269 )));
270 }
271 },
272 };
273 Ok(builder)
274}
275
276macro_rules! define_row_builder {
304 (
305 struct $name:ident<$lifetime:lifetime $(, $generic:ident $( : $bound:path )? )*>
306 $( where $where_path:path: $where_bound:path $(,)? )?
307 $({ $( $field:ident: $field_type:ty ),+ $(,)? })?,
308 |$array_param:ident| -> $array_type:ty { $init_expr:expr }
309 $(, |$value:ident| $(-> Option<$option_ty:ty>)? $value_transform:expr )?
310 ) => {
311 pub(crate) struct $name<$lifetime $(, $generic: $( $bound )? )*>
312 $( where $where_path: $where_bound )?
313 {
314 array: &$lifetime $array_type,
315 $( $( $field: $field_type, )+ )?
316 _phantom: std::marker::PhantomData<($( $generic, )*)>, }
318
319 impl<$lifetime $(, $generic: $( $bound )? )*> $name<$lifetime $(, $generic)*>
320 $( where $where_path: $where_bound )?
321 {
322 pub(crate) fn new($array_param: &$lifetime dyn Array $( $(, $field: $field_type )+ )?) -> Self {
323 Self {
324 array: $init_expr,
325 $( $( $field, )+ )?
326 _phantom: std::marker::PhantomData,
327 }
328 }
329
330 fn append_row(&self, builder: &mut impl VariantBuilderExt, index: usize) -> Result<(), ArrowError> {
331 if self.array.is_null(index) {
332 builder.append_null();
333 } else {
334 $(
343 #[expect(unused)]
344 $( let $field = &self.$field; )+
345 )?
346
347 let value = self.array.value(index);
349 $(
350 let $value = value;
351 let value = $value_transform;
352 $(
353 let Some(value): Option<$option_ty> = value else {
355 return if self.options.safe {
356 builder.append_value(Variant::Null);
359 Ok(())
360 } else {
361 Err(ArrowError::ComputeError(format!(
362 "Failed to convert value at index {index}: conversion failed",
363 )))
364 };
365 };
366 )?
367 )?
368 builder.append_value(value);
369 }
370 Ok(())
371 }
372 }
373 };
374}
375
376define_row_builder!(
377 struct BooleanArrowToVariantBuilder<'a>,
378 |array| -> arrow::array::BooleanArray { array.as_boolean() }
379);
380
381define_row_builder!(
382 struct PrimitiveArrowToVariantBuilder<'a, T: ArrowPrimitiveType>
383 where T::Native: Into<Variant<'a, 'a>>,
384 |array| -> PrimitiveArray<T> { array.as_primitive() }
385);
386
387define_row_builder!(
388 struct DecimalArrowToVariantBuilder<'a, A: DecimalType, V>
389 where
390 V: VariantDecimalType<Native = A::Native>,
391 {
392 options: &'a CastOptions<'a>,
393 scale: i8,
394 },
395 |array| -> PrimitiveArray<A> { array.as_primitive() },
396 |value| -> Option<_> { V::try_new_with_signed_scale(value, *scale).ok() }
397);
398
399define_row_builder!(
401 struct Decimal256ArrowToVariantBuilder<'a> {
402 options: &'a CastOptions<'a>,
403 scale: i8,
404 },
405 |array| -> arrow::array::Decimal256Array { array.as_primitive() },
406 |value| -> Option<_> {
407 let value = value.to_i128();
408 value.and_then(|v| VariantDecimal16::try_new_with_signed_scale(v, *scale).ok())
409 }
410);
411
412define_row_builder!(
413 struct TimestampArrowToVariantBuilder<'a, T: ArrowTimestampType> {
414 options: &'a CastOptions<'a>,
415 has_time_zone: bool,
416 },
417 |array| -> PrimitiveArray<T> { array.as_primitive() },
418 |value| -> Option<_> {
419 as_datetime::<T>(value).map(|naive_datetime| {
421 if *has_time_zone {
422 let utc_dt: DateTime<Utc> = Utc.from_utc_datetime(&naive_datetime);
424 Variant::from(utc_dt) } else {
426 Variant::from(naive_datetime) }
429 })
430 }
431);
432
433define_row_builder!(
434 struct DateArrowToVariantBuilder<'a, T: ArrowTemporalType>
435 where
436 i64: From<T::Native>,
437 {
438 options: &'a CastOptions<'a>,
439 },
440 |array| -> PrimitiveArray<T> { array.as_primitive() },
441 |value| -> Option<_> {
442 let date_value = i64::from(value);
443 as_date::<T>(date_value)
444 }
445);
446
447define_row_builder!(
448 struct TimeArrowToVariantBuilder<'a, T: ArrowTemporalType>
449 where
450 i64: From<T::Native>,
451 {
452 options: &'a CastOptions<'a>,
453 },
454 |array| -> PrimitiveArray<T> { array.as_primitive() },
455 |value| -> Option<_> {
456 let time_value = i64::from(value);
457 as_time::<T>(time_value)
458 }
459);
460
461define_row_builder!(
462 struct BinaryArrowToVariantBuilder<'a, O: OffsetSizeTrait>,
463 |array| -> GenericBinaryArray<O> { array.as_binary() }
464);
465
466define_row_builder!(
467 struct BinaryViewArrowToVariantBuilder<'a>,
468 |array| -> arrow::array::BinaryViewArray { array.as_byte_view() }
469);
470
471define_row_builder!(
472 struct FixedSizeBinaryArrowToVariantBuilder<'a>,
473 |array| -> arrow::array::FixedSizeBinaryArray { array.as_fixed_size_binary() }
474);
475
476define_row_builder!(
477 struct StringArrowToVariantBuilder<'a, O: OffsetSizeTrait>,
478 |array| -> GenericStringArray<O> { array.as_string() }
479);
480
481define_row_builder!(
482 struct StringViewArrowToVariantBuilder<'a>,
483 |array| -> arrow::array::StringViewArray { array.as_string_view() }
484);
485
486pub(crate) struct NullArrowToVariantBuilder;
488
489impl NullArrowToVariantBuilder {
490 fn append_row(
491 &self,
492 builder: &mut impl VariantBuilderExt,
493 _index: usize,
494 ) -> Result<(), ArrowError> {
495 builder.append_null();
496 Ok(())
497 }
498}
499
500pub(crate) struct ListArrowToVariantBuilder<'a, L: ListLikeArray> {
503 list_array: &'a L,
504 values_builder: Box<ArrowToVariantRowBuilder<'a>>,
505}
506
507impl<'a, L: ListLikeArray> ListArrowToVariantBuilder<'a, L> {
508 pub(crate) fn new(array: &'a L, options: &'a CastOptions) -> Result<Self, ArrowError> {
509 let values = array.values();
510 let values_builder =
511 make_arrow_to_variant_row_builder(values.data_type(), values, options)?;
512
513 Ok(Self {
514 list_array: array,
515 values_builder: Box::new(values_builder),
516 })
517 }
518
519 fn append_row(
520 &mut self,
521 builder: &mut impl VariantBuilderExt,
522 index: usize,
523 ) -> Result<(), ArrowError> {
524 if self.list_array.is_null(index) {
525 builder.append_null();
526 return Ok(());
527 }
528
529 let range = self.list_array.element_range(index);
530
531 let mut list_builder = builder.try_new_list()?;
532 for value_index in range {
533 self.values_builder
534 .append_row(&mut list_builder, value_index)?;
535 }
536 list_builder.finish();
537 Ok(())
538 }
539}
540
541pub(crate) struct StructArrowToVariantBuilder<'a> {
543 struct_array: &'a arrow::array::StructArray,
544 field_builders: Vec<(&'a str, ArrowToVariantRowBuilder<'a>)>,
545}
546
547impl<'a> StructArrowToVariantBuilder<'a> {
548 pub(crate) fn new(
549 struct_array: &'a arrow::array::StructArray,
550 options: &'a CastOptions,
551 ) -> Result<Self, ArrowError> {
552 let mut field_builders = Vec::new();
553
554 for (field_name, field_array) in struct_array
556 .column_names()
557 .iter()
558 .zip(struct_array.columns().iter())
559 {
560 let field_builder = make_arrow_to_variant_row_builder(
561 field_array.data_type(),
562 field_array.as_ref(),
563 options,
564 )?;
565 field_builders.push((*field_name, field_builder));
566 }
567
568 Ok(Self {
569 struct_array,
570 field_builders,
571 })
572 }
573
574 fn append_row(
575 &mut self,
576 builder: &mut impl VariantBuilderExt,
577 index: usize,
578 ) -> Result<(), ArrowError> {
579 if self.struct_array.is_null(index) {
580 builder.append_null();
581 } else {
582 let mut obj_builder = builder.try_new_object()?;
584
585 for (field_name, row_builder) in &mut self.field_builders {
587 let mut field_builder = ObjectFieldBuilder::new(field_name, &mut obj_builder);
588 row_builder.append_row(&mut field_builder, index)?;
589 }
590
591 obj_builder.finish();
592 }
593 Ok(())
594 }
595}
596
597pub(crate) struct MapArrowToVariantBuilder<'a> {
599 map_array: &'a arrow::array::MapArray,
600 key_strings: arrow::array::StringArray,
601 values_builder: Box<ArrowToVariantRowBuilder<'a>>,
602}
603
604impl<'a> MapArrowToVariantBuilder<'a> {
605 pub(crate) fn new(array: &'a dyn Array, options: &'a CastOptions) -> Result<Self, ArrowError> {
606 let map_array = array.as_map();
607
608 let keys = cast(map_array.keys(), &DataType::Utf8)?;
610 let key_strings = keys.as_string::<i32>().clone();
611
612 let values = map_array.values();
614 let values_builder =
615 make_arrow_to_variant_row_builder(values.data_type(), values.as_ref(), options)?;
616
617 Ok(Self {
618 map_array,
619 key_strings,
620 values_builder: Box::new(values_builder),
621 })
622 }
623
624 fn append_row(
625 &mut self,
626 builder: &mut impl VariantBuilderExt,
627 index: usize,
628 ) -> Result<(), ArrowError> {
629 if self.map_array.is_null(index) {
631 builder.append_null();
632 return Ok(());
633 }
634
635 let offsets = self.map_array.offsets();
636 let start = offsets[index].as_usize();
637 let end = offsets[index + 1].as_usize();
638
639 let mut object_builder = builder.try_new_object()?;
641
642 for kv_index in start..end {
644 let key = self.key_strings.value(kv_index);
645 let mut field_builder = ObjectFieldBuilder::new(key, &mut object_builder);
646 self.values_builder
647 .append_row(&mut field_builder, kv_index)?;
648 }
649
650 object_builder.finish();
651 Ok(())
652 }
653}
654
655pub(crate) struct UnionArrowToVariantBuilder<'a> {
659 union_array: &'a arrow::array::UnionArray,
660 child_builders: HashMap<i8, Box<ArrowToVariantRowBuilder<'a>>>,
661}
662
663impl<'a> UnionArrowToVariantBuilder<'a> {
664 pub(crate) fn new(array: &'a dyn Array, options: &'a CastOptions) -> Result<Self, ArrowError> {
665 let union_array = array.as_union();
666 let type_ids = union_array.type_ids();
667
668 let mut child_builders = HashMap::new();
670 for &type_id in type_ids {
671 let child_array = union_array.child(type_id);
672 let child_builder = make_arrow_to_variant_row_builder(
673 child_array.data_type(),
674 child_array.as_ref(),
675 options,
676 )?;
677 child_builders.insert(type_id, Box::new(child_builder));
678 }
679
680 Ok(Self {
681 union_array,
682 child_builders,
683 })
684 }
685
686 fn append_row(
687 &mut self,
688 builder: &mut impl VariantBuilderExt,
689 index: usize,
690 ) -> Result<(), ArrowError> {
691 let type_id = self.union_array.type_id(index);
692 let value_offset = self.union_array.value_offset(index);
693
694 match self.child_builders.get_mut(&type_id) {
696 Some(child_builder) => child_builder.append_row(builder, value_offset)?,
697 None => builder.append_null(),
698 }
699
700 Ok(())
701 }
702}
703
704pub(crate) struct DictionaryArrowToVariantBuilder<'a> {
706 keys: &'a dyn Array, normalized_keys: Vec<usize>,
708 values_builder: Box<ArrowToVariantRowBuilder<'a>>,
709}
710
711impl<'a> DictionaryArrowToVariantBuilder<'a> {
712 pub(crate) fn new(array: &'a dyn Array, options: &'a CastOptions) -> Result<Self, ArrowError> {
713 let dict_array = array.as_any_dictionary();
714 let values = dict_array.values();
715 let values_builder =
716 make_arrow_to_variant_row_builder(values.data_type(), values.as_ref(), options)?;
717
718 let normalized_keys = match values.len() {
720 0 => Vec::new(),
721 _ => dict_array.normalized_keys(),
722 };
723
724 Ok(Self {
725 keys: dict_array.keys(),
726 normalized_keys,
727 values_builder: Box::new(values_builder),
728 })
729 }
730
731 fn append_row(
732 &mut self,
733 builder: &mut impl VariantBuilderExt,
734 index: usize,
735 ) -> Result<(), ArrowError> {
736 if self.keys.is_null(index) {
737 builder.append_null();
738 } else {
739 let normalized_key = self.normalized_keys[index];
740 self.values_builder.append_row(builder, normalized_key)?;
741 }
742 Ok(())
743 }
744}
745
746pub(crate) struct RunEndEncodedArrowToVariantBuilder<'a, R: RunEndIndexType> {
748 run_array: &'a arrow::array::RunArray<R>,
749 values_builder: Box<ArrowToVariantRowBuilder<'a>>,
750
751 run_ends: &'a [R::Native],
752 run_number: usize, run_start: usize, }
755
756impl<'a, R: RunEndIndexType> RunEndEncodedArrowToVariantBuilder<'a, R> {
757 pub(crate) fn new(array: &'a dyn Array, options: &'a CastOptions) -> Result<Self, ArrowError> {
758 let Some(run_array) = array.as_run_opt() else {
759 return Err(ArrowError::CastError("Expected RunArray".to_string()));
760 };
761
762 let values = run_array.values();
763 let values_builder =
764 make_arrow_to_variant_row_builder(values.data_type(), values.as_ref(), options)?;
765
766 Ok(Self {
767 run_array,
768 values_builder: Box::new(values_builder),
769 run_ends: run_array.run_ends().values(),
770 run_number: 0,
771 run_start: 0,
772 })
773 }
774
775 fn set_run_for_index(&mut self, index: usize) -> Result<(), ArrowError> {
776 if index >= self.run_start {
777 let Some(run_end) = self.run_ends.get(self.run_number) else {
778 return Err(ArrowError::CastError(format!(
779 "Index {index} beyond run array"
780 )));
781 };
782 if index < run_end.as_usize() {
783 return Ok(());
784 }
785 if index == run_end.as_usize() {
786 self.run_number += 1;
787 self.run_start = run_end.as_usize();
788 return Ok(());
789 }
790 }
791
792 let run_number = self
794 .run_ends
795 .partition_point(|&run_end| run_end.as_usize() <= index);
796 if run_number >= self.run_ends.len() {
797 return Err(ArrowError::CastError(format!(
798 "Index {index} beyond run array"
799 )));
800 }
801 self.run_number = run_number;
802 self.run_start = match run_number {
803 0 => 0,
804 _ => self.run_ends[run_number - 1].as_usize(),
805 };
806 Ok(())
807 }
808
809 fn append_row(
810 &mut self,
811 builder: &mut impl VariantBuilderExt,
812 index: usize,
813 ) -> Result<(), ArrowError> {
814 self.set_run_for_index(index)?;
815
816 if self.run_array.values().is_null(self.run_number) {
818 builder.append_null();
819 return Ok(());
820 }
821
822 self.values_builder.append_row(builder, self.run_number)?;
824
825 Ok(())
826 }
827}
828
829#[cfg(test)]
830mod tests {
831 use super::*;
832 use crate::{VariantArray, VariantArrayBuilder};
833 use arrow::array::{ArrayRef, BooleanArray, Int32Array, StringArray};
834 use arrow::datatypes::Int32Type;
835 use std::sync::Arc;
836
837 fn execute_row_builder_test(array: &dyn Array) -> VariantArray {
839 execute_row_builder_test_with_options(
840 array,
841 CastOptions {
842 safe: false,
843 ..Default::default()
844 },
845 )
846 }
847
848 fn execute_row_builder_test_with_options(
850 array: &dyn Array,
851 options: CastOptions,
852 ) -> VariantArray {
853 let mut row_builder =
854 make_arrow_to_variant_row_builder(array.data_type(), array, &options).unwrap();
855
856 let mut array_builder = VariantArrayBuilder::new(array.len());
857
858 for i in 0..array.len() {
860 row_builder.append_row(&mut array_builder, i).unwrap();
861 }
862
863 let variant_array = array_builder.build();
864 assert_eq!(variant_array.len(), array.len());
865 variant_array
866 }
867
868 fn test_row_builder_basic(array: &dyn Array, expected_values: Vec<Option<Variant>>) {
871 test_row_builder_basic_with_options(
872 array,
873 expected_values,
874 CastOptions {
875 safe: false,
876 ..Default::default()
877 },
878 );
879 }
880
881 fn test_row_builder_basic_with_options(
883 array: &dyn Array,
884 expected_values: Vec<Option<Variant>>,
885 options: CastOptions,
886 ) {
887 let variant_array = execute_row_builder_test_with_options(array, options);
888
889 for (i, expected) in expected_values.iter().enumerate() {
891 match expected {
892 Some(variant) => {
893 assert_eq!(variant_array.value(i), *variant, "Mismatch at index {i}")
894 }
895 None => assert!(variant_array.is_null(i), "Expected null at index {i}"),
896 }
897 }
898 }
899
900 #[test]
901 fn test_primitive_row_builder() {
902 let int_array = Int32Array::from(vec![Some(42), None, Some(100)]);
903 test_row_builder_basic(
904 &int_array,
905 vec![Some(Variant::Int32(42)), None, Some(Variant::Int32(100))],
906 );
907 }
908
909 #[test]
910 fn test_string_row_builder() {
911 let string_array = StringArray::from(vec![Some("hello"), None, Some("world")]);
912 test_row_builder_basic(
913 &string_array,
914 vec![
915 Some(Variant::from("hello")),
916 None,
917 Some(Variant::from("world")),
918 ],
919 );
920 }
921
922 #[test]
923 fn test_boolean_row_builder() {
924 let bool_array = BooleanArray::from(vec![Some(true), None, Some(false)]);
925 test_row_builder_basic(
926 &bool_array,
927 vec![Some(Variant::from(true)), None, Some(Variant::from(false))],
928 );
929 }
930
931 #[test]
932 fn test_struct_row_builder() {
933 use arrow::array::{ArrayRef, Int32Array, StringArray, StructArray};
934 use arrow_schema::{DataType, Field};
935 use std::sync::Arc;
936
937 let int_field = Field::new("id", DataType::Int32, true);
939 let string_field = Field::new("name", DataType::Utf8, true);
940
941 let int_array = Int32Array::from(vec![Some(1), None, Some(3)]);
942 let string_array = StringArray::from(vec![Some("Alice"), Some("Bob"), None]);
943
944 let struct_array = StructArray::try_new(
945 vec![int_field, string_field].into(),
946 vec![
947 Arc::new(int_array) as ArrayRef,
948 Arc::new(string_array) as ArrayRef,
949 ],
950 None,
951 )
952 .unwrap();
953
954 let variant_array = execute_row_builder_test(&struct_array);
955
956 let first_variant = variant_array.value(0);
958 assert_eq!(first_variant.get_object_field("id"), Some(Variant::from(1)));
959 assert_eq!(
960 first_variant.get_object_field("name"),
961 Some(Variant::from("Alice"))
962 );
963
964 let second_variant = variant_array.value(1);
966 assert_eq!(second_variant.get_object_field("id"), None); assert_eq!(
968 second_variant.get_object_field("name"),
969 Some(Variant::from("Bob"))
970 );
971
972 let third_variant = variant_array.value(2);
974 assert_eq!(third_variant.get_object_field("id"), Some(Variant::from(3)));
975 assert_eq!(third_variant.get_object_field("name"), None); }
977
978 #[test]
979 fn test_run_end_encoded_row_builder() {
980 use arrow::array::{Int32Array, RunArray};
981 use arrow::datatypes::Int32Type;
982
983 let values = StringArray::from(vec!["A", "B", "C"]);
987 let run_ends = Int32Array::from(vec![2, 5, 6]);
988 let run_array = RunArray::<Int32Type>::try_new(&run_ends, &values).unwrap();
989
990 let variant_array = execute_row_builder_test(&run_array);
991
992 assert_eq!(variant_array.value(0), Variant::from("A")); assert_eq!(variant_array.value(1), Variant::from("A")); assert_eq!(variant_array.value(2), Variant::from("B")); assert_eq!(variant_array.value(3), Variant::from("B")); assert_eq!(variant_array.value(4), Variant::from("B")); assert_eq!(variant_array.value(5), Variant::from("C")); }
1000
1001 #[test]
1002 fn test_run_end_encoded_random_access() {
1003 use arrow::array::{Int32Array, RunArray};
1004 use arrow::datatypes::Int32Type;
1005
1006 let values = StringArray::from(vec!["A", "B", "C"]);
1008 let run_ends = Int32Array::from(vec![2, 5, 6]);
1009 let run_array = RunArray::<Int32Type>::try_new(&run_ends, &values).unwrap();
1010
1011 let options = CastOptions {
1012 safe: false,
1013 ..Default::default()
1014 };
1015 let mut row_builder =
1016 make_arrow_to_variant_row_builder(run_array.data_type(), &run_array, &options).unwrap();
1017
1018 let access_pattern = [0, 5, 2, 4, 1, 3]; let expected_values = ["A", "C", "B", "B", "A", "B"];
1021
1022 for (i, &index) in access_pattern.iter().enumerate() {
1023 let mut array_builder = VariantArrayBuilder::new(1);
1024 row_builder.append_row(&mut array_builder, index).unwrap();
1025 let variant_array = array_builder.build();
1026 assert_eq!(variant_array.value(0), Variant::from(expected_values[i]));
1027 }
1028 }
1029
1030 #[test]
1031 fn test_run_end_encoded_with_nulls() {
1032 use arrow::array::{Int32Array, RunArray};
1033 use arrow::datatypes::Int32Type;
1034
1035 let values = StringArray::from(vec![Some("A"), None, Some("B")]);
1037 let run_ends = Int32Array::from(vec![2, 4, 5]);
1038 let run_array = RunArray::<Int32Type>::try_new(&run_ends, &values).unwrap();
1039
1040 let options = CastOptions {
1041 safe: false,
1042 ..Default::default()
1043 };
1044 let mut row_builder =
1045 make_arrow_to_variant_row_builder(run_array.data_type(), &run_array, &options).unwrap();
1046 let mut array_builder = VariantArrayBuilder::new(5);
1047
1048 for i in 0..5 {
1050 row_builder.append_row(&mut array_builder, i).unwrap();
1051 }
1052
1053 let variant_array = array_builder.build();
1054 assert_eq!(variant_array.len(), 5);
1055
1056 assert_eq!(variant_array.value(0), Variant::from("A")); assert_eq!(variant_array.value(1), Variant::from("A")); assert!(variant_array.is_null(2)); assert!(variant_array.is_null(3)); assert_eq!(variant_array.value(4), Variant::from("B")); }
1063
1064 #[test]
1065 fn test_dictionary_row_builder() {
1066 use arrow::array::{DictionaryArray, Int32Array};
1067 use arrow::datatypes::Int32Type;
1068
1069 let values = StringArray::from(vec!["apple", "banana", "cherry"]);
1071 let keys = Int32Array::from(vec![0, 1, 0, 2, 1]);
1072 let dict_array = DictionaryArray::<Int32Type>::try_new(keys, Arc::new(values)).unwrap();
1073
1074 let variant_array = execute_row_builder_test(&dict_array);
1075
1076 assert_eq!(variant_array.value(0), Variant::from("apple")); assert_eq!(variant_array.value(1), Variant::from("banana")); assert_eq!(variant_array.value(2), Variant::from("apple")); assert_eq!(variant_array.value(3), Variant::from("cherry")); assert_eq!(variant_array.value(4), Variant::from("banana")); }
1083
1084 #[test]
1085 fn test_dictionary_with_nulls() {
1086 use arrow::array::{DictionaryArray, Int32Array};
1087 use arrow::datatypes::Int32Type;
1088
1089 let values = StringArray::from(vec!["x", "y", "z"]);
1091 let keys = Int32Array::from(vec![Some(0), None, Some(1), None, Some(2)]);
1092 let dict_array = DictionaryArray::<Int32Type>::try_new(keys, Arc::new(values)).unwrap();
1093
1094 let options = CastOptions {
1095 safe: false,
1096 ..Default::default()
1097 };
1098 let mut row_builder =
1099 make_arrow_to_variant_row_builder(dict_array.data_type(), &dict_array, &options)
1100 .unwrap();
1101 let mut array_builder = VariantArrayBuilder::new(5);
1102
1103 for i in 0..5 {
1105 row_builder.append_row(&mut array_builder, i).unwrap();
1106 }
1107
1108 let variant_array = array_builder.build();
1109 assert_eq!(variant_array.len(), 5);
1110
1111 assert_eq!(variant_array.value(0), Variant::from("x")); assert!(variant_array.is_null(1)); assert_eq!(variant_array.value(2), Variant::from("y")); assert!(variant_array.is_null(3)); assert_eq!(variant_array.value(4), Variant::from("z")); }
1118
1119 #[test]
1120 fn test_dictionary_random_access() {
1121 use arrow::array::{DictionaryArray, Int32Array};
1122 use arrow::datatypes::Int32Type;
1123
1124 let values = StringArray::from(vec!["red", "green", "blue"]);
1126 let keys = Int32Array::from(vec![0, 1, 2, 0, 1, 2]);
1127 let dict_array = DictionaryArray::<Int32Type>::try_new(keys, Arc::new(values)).unwrap();
1128
1129 let options = CastOptions {
1130 safe: false,
1131 ..Default::default()
1132 };
1133 let mut row_builder =
1134 make_arrow_to_variant_row_builder(dict_array.data_type(), &dict_array, &options)
1135 .unwrap();
1136
1137 let access_pattern = [5, 0, 3, 1, 4, 2]; let expected_values = ["blue", "red", "red", "green", "green", "blue"];
1140
1141 for (i, &index) in access_pattern.iter().enumerate() {
1142 let mut array_builder = VariantArrayBuilder::new(1);
1143 row_builder.append_row(&mut array_builder, index).unwrap();
1144 let variant_array = array_builder.build();
1145 assert_eq!(variant_array.value(0), Variant::from(expected_values[i]));
1146 }
1147 }
1148
1149 #[test]
1150 fn test_nested_dictionary() {
1151 use arrow::array::{DictionaryArray, Int32Array, StructArray};
1152 use arrow::datatypes::{Field, Int32Type};
1153
1154 let id_array = Int32Array::from(vec![1, 2, 3]);
1156 let name_array = StringArray::from(vec!["Alice", "Bob", "Charlie"]);
1157 let struct_array = StructArray::from(vec![
1158 (
1159 Arc::new(Field::new("id", DataType::Int32, false)),
1160 Arc::new(id_array) as ArrayRef,
1161 ),
1162 (
1163 Arc::new(Field::new("name", DataType::Utf8, false)),
1164 Arc::new(name_array) as ArrayRef,
1165 ),
1166 ]);
1167
1168 let keys = Int32Array::from(vec![0, 1, 0, 2, 1]);
1169 let dict_array =
1170 DictionaryArray::<Int32Type>::try_new(keys, Arc::new(struct_array)).unwrap();
1171
1172 let options = CastOptions {
1173 safe: false,
1174 ..Default::default()
1175 };
1176 let mut row_builder =
1177 make_arrow_to_variant_row_builder(dict_array.data_type(), &dict_array, &options)
1178 .unwrap();
1179 let mut array_builder = VariantArrayBuilder::new(5);
1180
1181 for i in 0..5 {
1183 row_builder.append_row(&mut array_builder, i).unwrap();
1184 }
1185
1186 let variant_array = array_builder.build();
1187 assert_eq!(variant_array.len(), 5);
1188
1189 let first_variant = variant_array.value(0);
1191 assert_eq!(first_variant.get_object_field("id"), Some(Variant::from(1)));
1192 assert_eq!(
1193 first_variant.get_object_field("name"),
1194 Some(Variant::from("Alice"))
1195 );
1196
1197 let second_variant = variant_array.value(1);
1198 assert_eq!(
1199 second_variant.get_object_field("id"),
1200 Some(Variant::from(2))
1201 );
1202 assert_eq!(
1203 second_variant.get_object_field("name"),
1204 Some(Variant::from("Bob"))
1205 );
1206
1207 let third_variant = variant_array.value(2);
1209 assert_eq!(third_variant.get_object_field("id"), Some(Variant::from(1)));
1210 assert_eq!(
1211 third_variant.get_object_field("name"),
1212 Some(Variant::from("Alice"))
1213 );
1214 }
1215
1216 #[test]
1217 fn test_list_row_builder() {
1218 use arrow::array::ListArray;
1219
1220 let data = vec![
1222 Some(vec![Some(1), Some(2)]),
1223 Some(vec![Some(3), Some(4), Some(5)]),
1224 None,
1225 Some(vec![]),
1226 ];
1227 let list_array = ListArray::from_iter_primitive::<Int32Type, _, _>(data);
1228
1229 let variant_array = execute_row_builder_test(&list_array);
1230
1231 let row0 = variant_array.value(0);
1233 let list0 = row0.as_list().unwrap();
1234 assert_eq!(list0.len(), 2);
1235 assert_eq!(list0.get(0), Some(Variant::from(1)));
1236 assert_eq!(list0.get(1), Some(Variant::from(2)));
1237
1238 let row1 = variant_array.value(1);
1240 let list1 = row1.as_list().unwrap();
1241 assert_eq!(list1.len(), 3);
1242 assert_eq!(list1.get(0), Some(Variant::from(3)));
1243 assert_eq!(list1.get(1), Some(Variant::from(4)));
1244 assert_eq!(list1.get(2), Some(Variant::from(5)));
1245
1246 assert!(variant_array.is_null(2));
1248
1249 let row3 = variant_array.value(3);
1251 let list3 = row3.as_list().unwrap();
1252 assert_eq!(list3.len(), 0);
1253 }
1254
1255 #[test]
1256 fn test_sliced_list_row_builder() {
1257 use arrow::array::ListArray;
1258
1259 let data = vec![
1261 Some(vec![Some(1), Some(2)]),
1262 Some(vec![Some(3), Some(4), Some(5)]),
1263 Some(vec![Some(6)]),
1264 ];
1265 let list_array = ListArray::from_iter_primitive::<Int32Type, _, _>(data);
1266
1267 let sliced_array = list_array.slice(1, 1);
1269
1270 let options = CastOptions {
1271 safe: false,
1272 ..Default::default()
1273 };
1274 let mut row_builder =
1275 make_arrow_to_variant_row_builder(sliced_array.data_type(), &sliced_array, &options)
1276 .unwrap();
1277 let mut variant_array_builder = VariantArrayBuilder::new(sliced_array.len());
1278
1279 row_builder
1281 .append_row(&mut variant_array_builder, 0)
1282 .unwrap();
1283 let variant_array = variant_array_builder.build();
1284
1285 assert_eq!(variant_array.len(), 1);
1287
1288 let row0 = variant_array.value(0);
1290 let list0 = row0.as_list().unwrap();
1291 assert_eq!(list0.len(), 3);
1292 assert_eq!(list0.get(0), Some(Variant::from(3)));
1293 assert_eq!(list0.get(1), Some(Variant::from(4)));
1294 assert_eq!(list0.get(2), Some(Variant::from(5)));
1295 }
1296
1297 #[test]
1298 fn test_nested_list_row_builder() {
1299 use arrow::array::ListArray;
1300 use arrow::datatypes::Field;
1301
1302 let inner_field = Arc::new(Field::new("item", DataType::Int32, true));
1304 let inner_list_field = Arc::new(Field::new("item", DataType::List(inner_field), true));
1305
1306 let values_data = vec![Some(vec![Some(1), Some(2)]), Some(vec![Some(3)])];
1307 let values_list = ListArray::from_iter_primitive::<Int32Type, _, _>(values_data);
1308
1309 let outer_offsets = arrow::buffer::OffsetBuffer::new(vec![0i32, 2, 2].into());
1310 let outer_list = ListArray::new(
1311 inner_list_field,
1312 outer_offsets,
1313 Arc::new(values_list),
1314 Some(arrow::buffer::NullBuffer::from(vec![true, false])),
1315 );
1316
1317 let options = CastOptions {
1318 safe: false,
1319 ..Default::default()
1320 };
1321 let mut row_builder =
1322 make_arrow_to_variant_row_builder(outer_list.data_type(), &outer_list, &options)
1323 .unwrap();
1324 let mut variant_array_builder = VariantArrayBuilder::new(outer_list.len());
1325
1326 for i in 0..outer_list.len() {
1327 row_builder
1328 .append_row(&mut variant_array_builder, i)
1329 .unwrap();
1330 }
1331
1332 let variant_array = variant_array_builder.build();
1333
1334 assert_eq!(variant_array.len(), 2);
1336
1337 let row0 = variant_array.value(0);
1339 let outer_list0 = row0.as_list().unwrap();
1340 assert_eq!(outer_list0.len(), 2);
1341
1342 let inner_list0_0 = outer_list0.get(0).unwrap();
1343 let inner_list0_0 = inner_list0_0.as_list().unwrap();
1344 assert_eq!(inner_list0_0.len(), 2);
1345 assert_eq!(inner_list0_0.get(0), Some(Variant::from(1)));
1346 assert_eq!(inner_list0_0.get(1), Some(Variant::from(2)));
1347
1348 let inner_list0_1 = outer_list0.get(1).unwrap();
1349 let inner_list0_1 = inner_list0_1.as_list().unwrap();
1350 assert_eq!(inner_list0_1.len(), 1);
1351 assert_eq!(inner_list0_1.get(0), Some(Variant::from(3)));
1352
1353 assert!(variant_array.is_null(1));
1355 }
1356
1357 #[test]
1358 fn test_map_row_builder() {
1359 use arrow::array::{Int32Array, MapArray, StringArray, StructArray};
1360 use arrow::buffer::{NullBuffer, OffsetBuffer};
1361 use arrow::datatypes::{DataType, Field, Fields};
1362 use std::sync::Arc;
1363
1364 let keys = StringArray::from(vec!["key1", "key2", "key3"]);
1366 let values = Int32Array::from(vec![1, 2, 3]);
1367 let entries_fields = Fields::from(vec![
1368 Field::new(Field::MAP_KEY_FIELD_DEFAULT_NAME, DataType::Utf8, false),
1369 Field::new(Field::MAP_VALUE_FIELD_DEFAULT_NAME, DataType::Int32, true),
1370 ]);
1371 let entries = StructArray::new(
1372 entries_fields.clone(),
1373 vec![Arc::new(keys), Arc::new(values)],
1374 None, );
1376
1377 let offsets = OffsetBuffer::new(vec![0, 1, 1, 1, 3].into());
1383
1384 let null_buffer = Some(NullBuffer::from(vec![true, true, false, true]));
1386
1387 let map_field = Arc::new(Field::new(
1389 Field::MAP_ENTRIES_FIELD_DEFAULT_NAME,
1390 DataType::Struct(entries_fields),
1391 false, ));
1393
1394 let map_array = MapArray::try_new(
1396 map_field,
1397 offsets,
1398 entries,
1399 null_buffer,
1400 false, )
1402 .unwrap();
1403
1404 let variant_array = execute_row_builder_test(&map_array);
1405
1406 let map0 = variant_array.value(0);
1408 let obj0 = map0.as_object().unwrap();
1409 assert_eq!(obj0.len(), 1);
1410 assert_eq!(obj0.get("key1"), Some(Variant::from(1)));
1411
1412 let map1 = variant_array.value(1);
1414 let obj1 = map1.as_object().unwrap();
1415 assert_eq!(obj1.len(), 0); assert!(variant_array.is_null(2));
1419
1420 let map3 = variant_array.value(3);
1422 let obj3 = map3.as_object().unwrap();
1423 assert_eq!(obj3.len(), 2);
1424 assert_eq!(obj3.get("key2"), Some(Variant::from(2)));
1425 assert_eq!(obj3.get("key3"), Some(Variant::from(3)));
1426 }
1427
1428 #[test]
1429 fn test_union_sparse_row_builder() {
1430 use arrow::array::{Float64Array, Int32Array, StringArray, UnionArray};
1431 use arrow::buffer::ScalarBuffer;
1432 use arrow::datatypes::{DataType, Field, UnionFields};
1433 use std::sync::Arc;
1434
1435 let int_array = Int32Array::from(vec![Some(1), None, None, None, Some(34), None]);
1437 let float_array = Float64Array::from(vec![None, Some(3.2), None, Some(32.5), None, None]);
1438 let string_array = StringArray::from(vec![None, None, Some("hello"), None, None, None]);
1439 let type_ids = [0, 1, 2, 1, 0, 0].into_iter().collect::<ScalarBuffer<i8>>();
1440
1441 let union_fields = UnionFields::from_fields(vec![
1442 Field::new("int_field", DataType::Int32, false),
1443 Field::new("float_field", DataType::Float64, false),
1444 Field::new("string_field", DataType::Utf8, false),
1445 ]);
1446
1447 let children: Vec<Arc<dyn Array>> = vec![
1448 Arc::new(int_array),
1449 Arc::new(float_array),
1450 Arc::new(string_array),
1451 ];
1452
1453 let union_array = UnionArray::try_new(
1454 union_fields,
1455 type_ids,
1456 None, children,
1458 )
1459 .unwrap();
1460
1461 let variant_array = execute_row_builder_test(&union_array);
1462 assert_eq!(variant_array.value(0), Variant::Int32(1));
1463 assert_eq!(variant_array.value(1), Variant::Double(3.2));
1464 assert_eq!(variant_array.value(2), Variant::from("hello"));
1465 assert_eq!(variant_array.value(3), Variant::Double(32.5));
1466 assert_eq!(variant_array.value(4), Variant::Int32(34));
1467 assert!(variant_array.is_null(5));
1468 }
1469
1470 #[test]
1471 fn test_union_dense_row_builder() {
1472 use arrow::array::{Float64Array, Int32Array, StringArray, UnionArray};
1473 use arrow::buffer::ScalarBuffer;
1474 use arrow::datatypes::{DataType, Field, UnionFields};
1475 use std::sync::Arc;
1476
1477 let int_array = Int32Array::from(vec![Some(1), Some(34), None]);
1479 let float_array = Float64Array::from(vec![3.2, 32.5]);
1480 let string_array = StringArray::from(vec!["hello"]);
1481 let type_ids = [0, 1, 2, 1, 0, 0].into_iter().collect::<ScalarBuffer<i8>>();
1482 let offsets = [0, 0, 0, 1, 1, 2]
1483 .into_iter()
1484 .collect::<ScalarBuffer<i32>>();
1485
1486 let union_fields = UnionFields::from_fields(vec![
1487 Field::new("int_field", DataType::Int32, false),
1488 Field::new("float_field", DataType::Float64, false),
1489 Field::new("string_field", DataType::Utf8, false),
1490 ]);
1491
1492 let children: Vec<Arc<dyn Array>> = vec![
1493 Arc::new(int_array),
1494 Arc::new(float_array),
1495 Arc::new(string_array),
1496 ];
1497
1498 let union_array = UnionArray::try_new(
1499 union_fields,
1500 type_ids,
1501 Some(offsets), children,
1503 )
1504 .unwrap();
1505
1506 let options = CastOptions {
1508 safe: false,
1509 ..Default::default()
1510 };
1511 let mut row_builder =
1512 make_arrow_to_variant_row_builder(union_array.data_type(), &union_array, &options)
1513 .unwrap();
1514
1515 let mut variant_builder = VariantArrayBuilder::new(union_array.len());
1516 for i in 0..union_array.len() {
1517 row_builder.append_row(&mut variant_builder, i).unwrap();
1518 }
1519 let variant_array = variant_builder.build();
1520
1521 assert_eq!(variant_array.len(), 6);
1522 assert_eq!(variant_array.value(0), Variant::Int32(1));
1523 assert_eq!(variant_array.value(1), Variant::Double(3.2));
1524 assert_eq!(variant_array.value(2), Variant::from("hello"));
1525 assert_eq!(variant_array.value(3), Variant::Double(32.5));
1526 assert_eq!(variant_array.value(4), Variant::Int32(34));
1527 assert!(variant_array.is_null(5));
1528 }
1529
1530 #[test]
1531 fn test_union_sparse_type_ids_row_builder() {
1532 use arrow::array::{Int32Array, StringArray, UnionArray};
1533 use arrow::buffer::ScalarBuffer;
1534 use arrow::datatypes::{DataType, Field, UnionFields};
1535 use std::sync::Arc;
1536
1537 let int_array = Int32Array::from(vec![Some(42), None]);
1539 let string_array = StringArray::from(vec![None, Some("test")]);
1540 let type_ids = [1, 3].into_iter().collect::<ScalarBuffer<i8>>();
1541
1542 let union_fields = UnionFields::try_new(
1543 vec![1, 3], vec![
1545 Field::new("int_field", DataType::Int32, false),
1546 Field::new("string_field", DataType::Utf8, false),
1547 ],
1548 )
1549 .unwrap();
1550
1551 let children: Vec<Arc<dyn Array>> = vec![Arc::new(int_array), Arc::new(string_array)];
1552
1553 let union_array = UnionArray::try_new(
1554 union_fields,
1555 type_ids,
1556 None, children,
1558 )
1559 .unwrap();
1560
1561 let options = CastOptions {
1563 safe: false,
1564 ..Default::default()
1565 };
1566 let mut row_builder =
1567 make_arrow_to_variant_row_builder(union_array.data_type(), &union_array, &options)
1568 .unwrap();
1569
1570 let mut variant_builder = VariantArrayBuilder::new(union_array.len());
1571 for i in 0..union_array.len() {
1572 row_builder.append_row(&mut variant_builder, i).unwrap();
1573 }
1574 let variant_array = variant_builder.build();
1575
1576 assert_eq!(variant_array.len(), 2);
1578
1579 assert_eq!(variant_array.value(0), Variant::Int32(42));
1581
1582 assert_eq!(variant_array.value(1), Variant::from("test"));
1584 }
1585
1586 #[test]
1587 fn test_decimal32_row_builder() {
1588 use arrow::array::Decimal32Array;
1589 use parquet_variant::VariantDecimal4;
1590
1591 let decimal_array = Decimal32Array::from(vec![Some(1234), None, Some(-5678)])
1593 .with_precision_and_scale(9, 2)
1594 .unwrap();
1595
1596 test_row_builder_basic(
1597 &decimal_array,
1598 vec![
1599 Some(Variant::from(VariantDecimal4::try_new(1234, 2).unwrap())),
1600 None,
1601 Some(Variant::from(VariantDecimal4::try_new(-5678, 2).unwrap())),
1602 ],
1603 );
1604 }
1605
1606 #[test]
1607 fn test_decimal128_row_builder() {
1608 use arrow::array::Decimal128Array;
1609 use parquet_variant::VariantDecimal16;
1610
1611 let decimal_array = Decimal128Array::from(vec![Some(123), None, Some(456)])
1613 .with_precision_and_scale(10, -2)
1614 .unwrap();
1615
1616 test_row_builder_basic(
1617 &decimal_array,
1618 vec![
1619 Some(Variant::from(VariantDecimal16::try_new(12300, 0).unwrap())),
1620 None,
1621 Some(Variant::from(VariantDecimal16::try_new(45600, 0).unwrap())),
1622 ],
1623 );
1624 }
1625
1626 #[test]
1627 fn test_decimal256_overflow_row_builder() {
1628 use arrow::array::Decimal256Array;
1629 use arrow::datatypes::i256;
1630
1631 let large_value = i256::from_i128(i128::MAX) + i256::from(1); let decimal_array = Decimal256Array::from(vec![Some(large_value), Some(i256::from(123))])
1634 .with_precision_and_scale(76, 3)
1635 .unwrap();
1636
1637 test_row_builder_basic_with_options(
1638 &decimal_array,
1639 vec![
1640 Some(Variant::Null), Some(Variant::from(VariantDecimal16::try_new(123, 3).unwrap())),
1642 ],
1643 CastOptions::default(),
1644 );
1645 }
1646
1647 #[test]
1648 fn test_binary_row_builder() {
1649 use arrow::array::BinaryArray;
1650
1651 let binary_data = vec![
1652 Some(b"hello".as_slice()),
1653 None,
1654 Some(b"\x00\x01\x02\xFF".as_slice()),
1655 Some(b"".as_slice()), ];
1657 let binary_array = BinaryArray::from(binary_data);
1658
1659 test_row_builder_basic(
1660 &binary_array,
1661 vec![
1662 Some(Variant::from(b"hello".as_slice())),
1663 None,
1664 Some(Variant::from([0x00, 0x01, 0x02, 0xFF].as_slice())),
1665 Some(Variant::from([].as_slice())),
1666 ],
1667 );
1668 }
1669
1670 #[test]
1671 fn test_binary_view_row_builder() {
1672 use arrow::array::BinaryViewArray;
1673
1674 let binary_data = vec![
1675 Some(b"short".as_slice()),
1676 None,
1677 Some(b"this is a longer binary view that exceeds inline storage".as_slice()),
1678 ];
1679 let binary_view_array = BinaryViewArray::from(binary_data);
1680
1681 test_row_builder_basic(
1682 &binary_view_array,
1683 vec![
1684 Some(Variant::from(b"short".as_slice())),
1685 None,
1686 Some(Variant::from(
1687 b"this is a longer binary view that exceeds inline storage".as_slice(),
1688 )),
1689 ],
1690 );
1691 }
1692
1693 #[test]
1694 fn test_fixed_size_binary_row_builder() {
1695 use arrow::array::FixedSizeBinaryArray;
1696
1697 let binary_data = vec![
1698 Some([0x01, 0x02, 0x03, 0x04]),
1699 None,
1700 Some([0xFF, 0xFE, 0xFD, 0xFC]),
1701 ];
1702 let fixed_binary_array =
1703 FixedSizeBinaryArray::try_from_sparse_iter_with_size(binary_data.into_iter(), 4)
1704 .unwrap();
1705
1706 test_row_builder_basic(
1707 &fixed_binary_array,
1708 vec![
1709 Some(Variant::from([0x01, 0x02, 0x03, 0x04].as_slice())),
1710 None,
1711 Some(Variant::from([0xFF, 0xFE, 0xFD, 0xFC].as_slice())),
1712 ],
1713 );
1714 }
1715
1716 #[test]
1717 fn test_utf8_view_row_builder() {
1718 use arrow::array::StringViewArray;
1719
1720 let string_data = vec![
1721 Some("short"),
1722 None,
1723 Some("this is a much longer string that will be stored out-of-line in the buffer"),
1724 ];
1725 let string_view_array = StringViewArray::from(string_data);
1726
1727 test_row_builder_basic(
1728 &string_view_array,
1729 vec![
1730 Some(Variant::from("short")),
1731 None,
1732 Some(Variant::from(
1733 "this is a much longer string that will be stored out-of-line in the buffer",
1734 )),
1735 ],
1736 );
1737 }
1738
1739 #[test]
1740 fn test_timestamp_second_row_builder() {
1741 use arrow::array::TimestampSecondArray;
1742
1743 let timestamp_data = vec![
1744 Some(1609459200), None,
1746 Some(1640995200), ];
1748 let timestamp_array = TimestampSecondArray::from(timestamp_data);
1749
1750 let expected_naive1 = DateTime::from_timestamp(1609459200, 0).unwrap().naive_utc();
1751 let expected_naive2 = DateTime::from_timestamp(1640995200, 0).unwrap().naive_utc();
1752
1753 test_row_builder_basic(
1754 ×tamp_array,
1755 vec![
1756 Some(Variant::from(expected_naive1)),
1757 None,
1758 Some(Variant::from(expected_naive2)),
1759 ],
1760 );
1761 }
1762
1763 #[test]
1764 fn test_timestamp_with_timezone_row_builder() {
1765 use arrow::array::TimestampMicrosecondArray;
1766 use chrono::DateTime;
1767
1768 let timestamp_data = vec![
1769 Some(1609459200000000), None,
1771 Some(1640995200000000), ];
1773 let timezone = "UTC".to_string();
1774 let timestamp_array =
1775 TimestampMicrosecondArray::from(timestamp_data).with_timezone(timezone);
1776
1777 let expected_utc1 = DateTime::from_timestamp(1609459200, 0).unwrap();
1778 let expected_utc2 = DateTime::from_timestamp(1640995200, 0).unwrap();
1779
1780 test_row_builder_basic(
1781 ×tamp_array,
1782 vec![
1783 Some(Variant::from(expected_utc1)),
1784 None,
1785 Some(Variant::from(expected_utc2)),
1786 ],
1787 );
1788 }
1789
1790 #[test]
1791 fn test_timestamp_nanosecond_precision_row_builder() {
1792 use arrow::array::TimestampNanosecondArray;
1793
1794 let timestamp_data = vec![
1795 Some(1609459200123456789), None,
1797 Some(1609459200000000000), ];
1799 let timestamp_array = TimestampNanosecondArray::from(timestamp_data);
1800
1801 let expected_with_nanos = DateTime::from_timestamp(1609459200, 123456789)
1802 .unwrap()
1803 .naive_utc();
1804 let expected_no_nanos = DateTime::from_timestamp(1609459200, 0).unwrap().naive_utc();
1805
1806 test_row_builder_basic(
1807 ×tamp_array,
1808 vec![
1809 Some(Variant::from(expected_with_nanos)),
1810 None,
1811 Some(Variant::from(expected_no_nanos)),
1812 ],
1813 );
1814 }
1815
1816 #[test]
1817 fn test_timestamp_millisecond_row_builder() {
1818 use arrow::array::TimestampMillisecondArray;
1819
1820 let timestamp_data = vec![
1821 Some(1609459200123), None,
1823 Some(1609459200000), ];
1825 let timestamp_array = TimestampMillisecondArray::from(timestamp_data);
1826
1827 let expected_with_millis = DateTime::from_timestamp(1609459200, 123000000)
1828 .unwrap()
1829 .naive_utc();
1830 let expected_no_millis = DateTime::from_timestamp(1609459200, 0).unwrap().naive_utc();
1831
1832 test_row_builder_basic(
1833 ×tamp_array,
1834 vec![
1835 Some(Variant::from(expected_with_millis)),
1836 None,
1837 Some(Variant::from(expected_no_millis)),
1838 ],
1839 );
1840 }
1841
1842 #[test]
1843 fn test_date32_row_builder() {
1844 use arrow::array::Date32Array;
1845 use chrono::NaiveDate;
1846
1847 let date_data = vec![
1848 Some(0), None,
1850 Some(19723), Some(-719162), ];
1853 let date_array = Date32Array::from(date_data);
1854
1855 let expected_epoch = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap();
1856 let expected_2024 = NaiveDate::from_ymd_opt(2024, 1, 1).unwrap();
1857 let expected_min = NaiveDate::from_ymd_opt(1, 1, 1).unwrap();
1858
1859 test_row_builder_basic(
1860 &date_array,
1861 vec![
1862 Some(Variant::from(expected_epoch)),
1863 None,
1864 Some(Variant::from(expected_2024)),
1865 Some(Variant::from(expected_min)),
1866 ],
1867 );
1868 }
1869
1870 #[test]
1871 fn test_date64_row_builder() {
1872 use arrow::array::Date64Array;
1873 use chrono::NaiveDate;
1874
1875 let date_data = vec![
1877 Some(0), None,
1879 Some(1704067200000), Some(86400000), ];
1882 let date_array = Date64Array::from(date_data);
1883
1884 let expected_epoch = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap();
1885 let expected_2024 = NaiveDate::from_ymd_opt(2024, 1, 1).unwrap();
1886 let expected_next_day = NaiveDate::from_ymd_opt(1970, 1, 2).unwrap();
1887
1888 test_row_builder_basic(
1889 &date_array,
1890 vec![
1891 Some(Variant::from(expected_epoch)),
1892 None,
1893 Some(Variant::from(expected_2024)),
1894 Some(Variant::from(expected_next_day)),
1895 ],
1896 );
1897 }
1898
1899 #[test]
1900 fn test_time32_second_row_builder() {
1901 use arrow::array::Time32SecondArray;
1902 use chrono::NaiveTime;
1903
1904 let time_data = vec![
1906 Some(0), None,
1908 Some(3661), Some(86399), ];
1911 let time_array = Time32SecondArray::from(time_data);
1912
1913 let expected_midnight = NaiveTime::from_hms_opt(0, 0, 0).unwrap();
1914 let expected_time = NaiveTime::from_hms_opt(1, 1, 1).unwrap();
1915 let expected_last = NaiveTime::from_hms_opt(23, 59, 59).unwrap();
1916
1917 test_row_builder_basic(
1918 &time_array,
1919 vec![
1920 Some(Variant::from(expected_midnight)),
1921 None,
1922 Some(Variant::from(expected_time)),
1923 Some(Variant::from(expected_last)),
1924 ],
1925 );
1926 }
1927
1928 #[test]
1929 fn test_time32_millisecond_row_builder() {
1930 use arrow::array::Time32MillisecondArray;
1931 use chrono::NaiveTime;
1932
1933 let time_data = vec![
1935 Some(0), None,
1937 Some(3661123), Some(86399999), ];
1940 let time_array = Time32MillisecondArray::from(time_data);
1941
1942 let expected_midnight = NaiveTime::from_hms_milli_opt(0, 0, 0, 0).unwrap();
1943 let expected_time = NaiveTime::from_hms_milli_opt(1, 1, 1, 123).unwrap();
1944 let expected_last = NaiveTime::from_hms_milli_opt(23, 59, 59, 999).unwrap();
1945
1946 test_row_builder_basic(
1947 &time_array,
1948 vec![
1949 Some(Variant::from(expected_midnight)),
1950 None,
1951 Some(Variant::from(expected_time)),
1952 Some(Variant::from(expected_last)),
1953 ],
1954 );
1955 }
1956
1957 #[test]
1958 fn test_time64_microsecond_row_builder() {
1959 use arrow::array::Time64MicrosecondArray;
1960 use chrono::NaiveTime;
1961
1962 let time_data = vec![
1964 Some(0), None,
1966 Some(3661123456), Some(86399999999), ];
1969 let time_array = Time64MicrosecondArray::from(time_data);
1970
1971 let expected_midnight = NaiveTime::from_hms_micro_opt(0, 0, 0, 0).unwrap();
1972 let expected_time = NaiveTime::from_hms_micro_opt(1, 1, 1, 123456).unwrap();
1973 let expected_last = NaiveTime::from_hms_micro_opt(23, 59, 59, 999999).unwrap();
1974
1975 test_row_builder_basic(
1976 &time_array,
1977 vec![
1978 Some(Variant::from(expected_midnight)),
1979 None,
1980 Some(Variant::from(expected_time)),
1981 Some(Variant::from(expected_last)),
1982 ],
1983 );
1984 }
1985
1986 #[test]
1987 fn test_time64_nanosecond_row_builder() {
1988 use arrow::array::Time64NanosecondArray;
1989 use chrono::NaiveTime;
1990
1991 let time_data = vec![
1993 Some(0), None,
1995 Some(3661123456789), Some(86399999999999), ];
1998 let time_array = Time64NanosecondArray::from(time_data);
1999
2000 let expected_midnight = NaiveTime::from_hms_nano_opt(0, 0, 0, 0).unwrap();
2001 let expected_time = NaiveTime::from_hms_micro_opt(1, 1, 1, 123456).unwrap();
2003 let expected_last = NaiveTime::from_hms_micro_opt(23, 59, 59, 999999).unwrap();
2004
2005 test_row_builder_basic(
2006 &time_array,
2007 vec![
2008 Some(Variant::from(expected_midnight)),
2009 None,
2010 Some(Variant::from(expected_time)),
2011 Some(Variant::from(expected_last)),
2012 ],
2013 );
2014 }
2015}