1#![allow(unused_imports)]
41#![allow(dead_code)]
42
43use std::fmt::Write;
44use std::sync::Arc;
45
46use arrow_array::array;
47use arrow_array::cast::AsArray;
48use arrow_buffer::OffsetBuffer;
49use arrow_schema::TimeUnit;
50use chrono::{DateTime, Timelike as _};
51use itertools::Itertools;
52use thiserror_ext::AsReport;
53
54use super::arrow_schema::IntervalUnit;
55use super::{ArrowIntervalType, arrow_array, arrow_buffer, arrow_cast, arrow_schema};
57use crate::array::*;
59use crate::types::{DataType as RwDataType, Scalar, *};
60use crate::util::iter_util::ZipEqFast;
61
62pub trait ToArrow {
67 fn to_record_batch(
71 &self,
72 schema: arrow_schema::SchemaRef,
73 chunk: &DataChunk,
74 ) -> Result<arrow_array::RecordBatch, ArrayError> {
75 if !chunk.is_vis_compacted() {
77 let c = chunk.clone();
78 return self.to_record_batch(schema, &c.compact_vis());
79 }
80
81 let columns: Vec<_> = chunk
83 .columns()
84 .iter()
85 .zip_eq_fast(schema.fields().iter())
86 .map(|(column, field)| self.to_array(field.data_type(), column))
87 .try_collect()?;
88
89 let opts =
91 arrow_array::RecordBatchOptions::default().with_row_count(Some(chunk.capacity()));
92 arrow_array::RecordBatch::try_new_with_options(schema, columns, &opts)
93 .map_err(ArrayError::to_arrow)
94 }
95
96 fn to_array(
98 &self,
99 data_type: &arrow_schema::DataType,
100 array: &ArrayImpl,
101 ) -> Result<arrow_array::ArrayRef, ArrayError> {
102 let arrow_array = match array {
103 ArrayImpl::Bool(array) => self.bool_to_arrow(array),
104 ArrayImpl::Int16(array) => self.int16_to_arrow(array),
105 ArrayImpl::Int32(array) => self.int32_to_arrow(array),
106 ArrayImpl::Int64(array) => self.int64_to_arrow(array),
107 ArrayImpl::Int256(array) => self.int256_to_arrow(array),
108 ArrayImpl::Float32(array) => self.float32_to_arrow(array),
109 ArrayImpl::Float64(array) => self.float64_to_arrow(array),
110 ArrayImpl::Date(array) => self.date_to_arrow(array),
111 ArrayImpl::Time(array) => self.time_to_arrow(array),
112 ArrayImpl::Timestamp(array) => self.timestamp_to_arrow(array),
113 ArrayImpl::Timestamptz(array) => self.timestamptz_to_arrow(array),
114 ArrayImpl::Interval(array) => self.interval_to_arrow(array),
115 ArrayImpl::Utf8(array) => self.utf8_to_arrow(array),
116 ArrayImpl::Bytea(array) => self.bytea_to_arrow(array),
117 ArrayImpl::Decimal(array) => self.decimal_to_arrow(data_type, array),
118 ArrayImpl::Jsonb(array) => self.jsonb_to_arrow(array),
119 ArrayImpl::Variant(array) => self.variant_to_arrow(array),
120 ArrayImpl::Serial(array) => self.serial_to_arrow(array),
121 ArrayImpl::List(array) => self.list_to_arrow(data_type, array),
122 ArrayImpl::Struct(array) => self.struct_to_arrow(data_type, array),
123 ArrayImpl::Map(array) => self.map_to_arrow(data_type, array),
124 ArrayImpl::Vector(inner) => self.vector_to_arrow(data_type, inner),
125 }?;
126 if arrow_array.data_type() != data_type {
127 arrow_cast::cast(&arrow_array, data_type).map_err(ArrayError::to_arrow)
128 } else {
129 Ok(arrow_array)
130 }
131 }
132
133 #[inline]
134 fn bool_to_arrow(&self, array: &BoolArray) -> Result<arrow_array::ArrayRef, ArrayError> {
135 Ok(Arc::new(arrow_array::BooleanArray::from(array)))
136 }
137
138 #[inline]
139 fn int16_to_arrow(&self, array: &I16Array) -> Result<arrow_array::ArrayRef, ArrayError> {
140 Ok(Arc::new(arrow_array::Int16Array::from(array)))
141 }
142
143 #[inline]
144 fn int32_to_arrow(&self, array: &I32Array) -> Result<arrow_array::ArrayRef, ArrayError> {
145 Ok(Arc::new(arrow_array::Int32Array::from(array)))
146 }
147
148 #[inline]
149 fn int64_to_arrow(&self, array: &I64Array) -> Result<arrow_array::ArrayRef, ArrayError> {
150 Ok(Arc::new(arrow_array::Int64Array::from(array)))
151 }
152
153 #[inline]
154 fn float32_to_arrow(&self, array: &F32Array) -> Result<arrow_array::ArrayRef, ArrayError> {
155 Ok(Arc::new(arrow_array::Float32Array::from(array)))
156 }
157
158 #[inline]
159 fn float64_to_arrow(&self, array: &F64Array) -> Result<arrow_array::ArrayRef, ArrayError> {
160 Ok(Arc::new(arrow_array::Float64Array::from(array)))
161 }
162
163 #[inline]
164 fn utf8_to_arrow(&self, array: &Utf8Array) -> Result<arrow_array::ArrayRef, ArrayError> {
165 Ok(Arc::new(arrow_array::StringArray::from(array)))
166 }
167
168 #[inline]
169 fn int256_to_arrow(&self, array: &Int256Array) -> Result<arrow_array::ArrayRef, ArrayError> {
170 Ok(Arc::new(arrow_array::Decimal256Array::from(array)))
171 }
172
173 #[inline]
174 fn date_to_arrow(&self, array: &DateArray) -> Result<arrow_array::ArrayRef, ArrayError> {
175 Ok(Arc::new(arrow_array::Date32Array::try_from(array)?))
176 }
177
178 #[inline]
179 fn timestamp_to_arrow(
180 &self,
181 array: &TimestampArray,
182 ) -> Result<arrow_array::ArrayRef, ArrayError> {
183 Ok(Arc::new(arrow_array::TimestampMicrosecondArray::try_from(
184 array,
185 )?))
186 }
187
188 #[inline]
189 fn timestamptz_to_arrow(
190 &self,
191 array: &TimestamptzArray,
192 ) -> Result<arrow_array::ArrayRef, ArrayError> {
193 Ok(Arc::new(
194 arrow_array::TimestampMicrosecondArray::try_from(array)?.with_timezone_utc(),
195 ))
196 }
197
198 #[inline]
199 fn time_to_arrow(&self, array: &TimeArray) -> Result<arrow_array::ArrayRef, ArrayError> {
200 Ok(Arc::new(arrow_array::Time64MicrosecondArray::try_from(
201 array,
202 )?))
203 }
204
205 #[inline]
206 fn interval_to_arrow(
207 &self,
208 array: &IntervalArray,
209 ) -> Result<arrow_array::ArrayRef, ArrayError> {
210 Ok(Arc::new(arrow_array::IntervalMonthDayNanoArray::try_from(
211 array,
212 )?))
213 }
214
215 #[inline]
216 fn bytea_to_arrow(&self, array: &BytesArray) -> Result<arrow_array::ArrayRef, ArrayError> {
217 Ok(Arc::new(arrow_array::BinaryArray::from(array)))
218 }
219
220 #[inline]
222 fn decimal_to_arrow(
223 &self,
224 _data_type: &arrow_schema::DataType,
225 array: &DecimalArray,
226 ) -> Result<arrow_array::ArrayRef, ArrayError> {
227 Ok(Arc::new(arrow_array::StringArray::from(array)))
228 }
229
230 #[inline]
232 fn jsonb_to_arrow(&self, array: &JsonbArray) -> Result<arrow_array::ArrayRef, ArrayError> {
233 Ok(Arc::new(arrow_array::StringArray::from(array)))
234 }
235
236 #[inline]
238 fn variant_to_arrow(&self, _array: &VariantArray) -> Result<arrow_array::ArrayRef, ArrayError> {
239 Err(ArrayError::to_arrow(
240 "VARIANT is not supported in Arrow conversion yet",
241 ))
242 }
243
244 #[inline]
245 fn serial_to_arrow(&self, array: &SerialArray) -> Result<arrow_array::ArrayRef, ArrayError> {
246 Ok(Arc::new(arrow_array::Int64Array::from(array)))
247 }
248
249 #[inline]
250 fn list_to_arrow(
251 &self,
252 data_type: &arrow_schema::DataType,
253 array: &ListArray,
254 ) -> Result<arrow_array::ArrayRef, ArrayError> {
255 let arrow_schema::DataType::List(field) = data_type else {
256 return Err(ArrayError::to_arrow("Invalid list type"));
257 };
258 let values = self.to_array(field.data_type(), array.values())?;
259 let offsets = OffsetBuffer::new(array.offsets().iter().map(|&o| o as i32).collect());
260 let nulls = (!array.null_bitmap().all()).then(|| array.null_bitmap().into());
261 Ok(Arc::new(arrow_array::ListArray::new(
262 field.clone(),
263 offsets,
264 values,
265 nulls,
266 )))
267 }
268
269 #[inline]
270 fn vector_to_arrow(
271 &self,
272 data_type: &arrow_schema::DataType,
273 array: &VectorArray,
274 ) -> Result<arrow_array::ArrayRef, ArrayError> {
275 let arrow_schema::DataType::List(field) = data_type else {
276 return Err(ArrayError::to_arrow("Invalid list type"));
277 };
278 if field.data_type() != &arrow_schema::DataType::Float32 {
279 return Err(ArrayError::to_arrow("Invalid list inner type for vector"));
280 }
281 let values = Arc::new(arrow_array::Float32Array::from(
282 array.as_raw_slice().to_vec(),
283 ));
284 let offsets = OffsetBuffer::new(array.offsets().iter().map(|&o| o as i32).collect());
285 let nulls = (!array.null_bitmap().all()).then(|| array.null_bitmap().into());
286 Ok(Arc::new(arrow_array::ListArray::new(
287 field.clone(),
288 offsets,
289 values,
290 nulls,
291 )))
292 }
293
294 #[inline]
295 fn struct_to_arrow(
296 &self,
297 data_type: &arrow_schema::DataType,
298 array: &StructArray,
299 ) -> Result<arrow_array::ArrayRef, ArrayError> {
300 let arrow_schema::DataType::Struct(fields) = data_type else {
301 return Err(ArrayError::to_arrow("Invalid struct type"));
302 };
303 let len = array.len();
307 let child_arrays = array
308 .fields()
309 .zip_eq_fast(fields)
310 .map(|(arr, field)| self.to_array(field.data_type(), arr))
311 .try_collect::<_, _, ArrayError>()?;
312 let nulls = Some(array.null_bitmap().into());
313 Ok(Arc::new(
314 arrow_array::StructArray::try_new_with_length(fields.clone(), child_arrays, nulls, len)
315 .map_err(ArrayError::from_arrow)?,
316 ))
317 }
318
319 #[inline]
320 fn map_to_arrow(
321 &self,
322 data_type: &arrow_schema::DataType,
323 array: &MapArray,
324 ) -> Result<arrow_array::ArrayRef, ArrayError> {
325 let arrow_schema::DataType::Map(field, ordered) = data_type else {
326 return Err(ArrayError::to_arrow("Invalid map type"));
327 };
328 if *ordered {
329 return Err(ArrayError::to_arrow("Sorted map is not supported"));
330 }
331 let values = self
332 .struct_to_arrow(field.data_type(), array.as_struct())?
333 .as_struct()
334 .clone();
335 let offsets = OffsetBuffer::new(array.offsets().iter().map(|&o| o as i32).collect());
336 let nulls = (!array.null_bitmap().all()).then(|| array.null_bitmap().into());
337 Ok(Arc::new(arrow_array::MapArray::new(
338 field.clone(),
339 offsets,
340 values,
341 nulls,
342 *ordered,
343 )))
344 }
345
346 fn to_arrow_field(
351 &self,
352 name: &str,
353 value: &DataType,
354 ) -> Result<arrow_schema::Field, ArrayError> {
355 let data_type = match value {
356 DataType::Boolean => self.bool_type_to_arrow(),
358 DataType::Int16 => self.int16_type_to_arrow(),
359 DataType::Int32 => self.int32_type_to_arrow(),
360 DataType::Int64 => self.int64_type_to_arrow(),
361 DataType::Int256 => self.int256_type_to_arrow(),
362 DataType::Float32 => self.float32_type_to_arrow(),
363 DataType::Float64 => self.float64_type_to_arrow(),
364 DataType::Date => self.date_type_to_arrow(),
365 DataType::Time => self.time_type_to_arrow(),
366 DataType::Timestamp => self.timestamp_type_to_arrow(),
367 DataType::Timestamptz => self.timestamptz_type_to_arrow(),
368 DataType::Interval => self.interval_type_to_arrow(),
369 DataType::Varchar => self.varchar_type_to_arrow(),
370 DataType::Bytea => self.bytea_type_to_arrow(),
371 DataType::Serial => self.serial_type_to_arrow(),
372 DataType::Decimal => return Ok(self.decimal_type_to_arrow(name)),
373 DataType::Jsonb => return Ok(self.jsonb_type_to_arrow(name)),
374 DataType::Variant => {
376 return Err(ArrayError::to_arrow(
377 "VARIANT is not supported in Arrow conversion yet",
378 ));
379 }
380 DataType::Struct(fields) => self.struct_type_to_arrow(fields)?,
381 DataType::List(list) => self.list_type_to_arrow(list)?,
382 DataType::Map(map) => self.map_type_to_arrow(map)?,
383 DataType::Vector(_) => self.vector_type_to_arrow()?,
384 };
385 Ok(arrow_schema::Field::new(name, data_type, true))
386 }
387
388 #[inline]
389 fn bool_type_to_arrow(&self) -> arrow_schema::DataType {
390 arrow_schema::DataType::Boolean
391 }
392
393 #[inline]
394 fn int16_type_to_arrow(&self) -> arrow_schema::DataType {
395 arrow_schema::DataType::Int16
396 }
397
398 #[inline]
399 fn int32_type_to_arrow(&self) -> arrow_schema::DataType {
400 arrow_schema::DataType::Int32
401 }
402
403 #[inline]
404 fn int64_type_to_arrow(&self) -> arrow_schema::DataType {
405 arrow_schema::DataType::Int64
406 }
407
408 #[inline]
409 fn int256_type_to_arrow(&self) -> arrow_schema::DataType {
410 arrow_schema::DataType::Decimal256(arrow_schema::DECIMAL256_MAX_PRECISION, 0)
411 }
412
413 #[inline]
414 fn float32_type_to_arrow(&self) -> arrow_schema::DataType {
415 arrow_schema::DataType::Float32
416 }
417
418 #[inline]
419 fn float64_type_to_arrow(&self) -> arrow_schema::DataType {
420 arrow_schema::DataType::Float64
421 }
422
423 #[inline]
424 fn date_type_to_arrow(&self) -> arrow_schema::DataType {
425 arrow_schema::DataType::Date32
426 }
427
428 #[inline]
429 fn time_type_to_arrow(&self) -> arrow_schema::DataType {
430 arrow_schema::DataType::Time64(arrow_schema::TimeUnit::Microsecond)
431 }
432
433 #[inline]
434 fn timestamp_type_to_arrow(&self) -> arrow_schema::DataType {
435 arrow_schema::DataType::Timestamp(arrow_schema::TimeUnit::Microsecond, None)
436 }
437
438 #[inline]
439 fn timestamptz_type_to_arrow(&self) -> arrow_schema::DataType {
440 arrow_schema::DataType::Timestamp(
441 arrow_schema::TimeUnit::Microsecond,
442 Some("+00:00".into()),
443 )
444 }
445
446 #[inline]
447 fn interval_type_to_arrow(&self) -> arrow_schema::DataType {
448 arrow_schema::DataType::Interval(arrow_schema::IntervalUnit::MonthDayNano)
449 }
450
451 #[inline]
452 fn varchar_type_to_arrow(&self) -> arrow_schema::DataType {
453 arrow_schema::DataType::Utf8
454 }
455
456 #[inline]
457 fn jsonb_type_to_arrow(&self, name: &str) -> arrow_schema::Field {
458 arrow_schema::Field::new(name, arrow_schema::DataType::Utf8, true)
459 .with_metadata([("ARROW:extension:name".into(), "arrowudf.json".into())].into())
460 }
461
462 #[inline]
463 fn bytea_type_to_arrow(&self) -> arrow_schema::DataType {
464 arrow_schema::DataType::Binary
465 }
466
467 #[inline]
468 fn decimal_type_to_arrow(&self, name: &str) -> arrow_schema::Field {
469 arrow_schema::Field::new(name, arrow_schema::DataType::Utf8, true)
470 .with_metadata([("ARROW:extension:name".into(), "arrowudf.decimal".into())].into())
471 }
472
473 #[inline]
474 fn serial_type_to_arrow(&self) -> arrow_schema::DataType {
475 arrow_schema::DataType::Int64
476 }
477
478 #[inline]
479 fn list_type_to_arrow(
480 &self,
481 list_type: &ListType,
482 ) -> Result<arrow_schema::DataType, ArrayError> {
483 Ok(arrow_schema::DataType::List(Arc::new(
484 self.to_arrow_field("item", list_type.elem())?,
485 )))
486 }
487
488 #[inline]
489 fn struct_type_to_arrow(
490 &self,
491 fields: &StructType,
492 ) -> Result<arrow_schema::DataType, ArrayError> {
493 Ok(arrow_schema::DataType::Struct(
494 fields
495 .iter()
496 .map(|(name, ty)| self.to_arrow_field(name, ty))
497 .try_collect::<_, _, ArrayError>()?,
498 ))
499 }
500
501 #[inline]
502 fn map_type_to_arrow(&self, map_type: &MapType) -> Result<arrow_schema::DataType, ArrayError> {
503 let sorted = false;
504 let key = self
506 .to_arrow_field("key", map_type.key())?
507 .with_nullable(false);
508 let value = self.to_arrow_field("value", map_type.value())?;
509 Ok(arrow_schema::DataType::Map(
510 Arc::new(arrow_schema::Field::new(
511 "entries",
512 arrow_schema::DataType::Struct([Arc::new(key), Arc::new(value)].into()),
513 false,
515 )),
516 sorted,
517 ))
518 }
519
520 #[inline]
521 fn vector_type_to_arrow(&self) -> Result<arrow_schema::DataType, ArrayError> {
522 Ok(arrow_schema::DataType::List(Arc::new(
523 self.to_arrow_field("item", &VECTOR_ITEM_TYPE)?,
524 )))
525 }
526}
527
528#[allow(clippy::wrong_self_convention)]
530pub trait FromArrow {
531 fn from_record_batch(&self, batch: &arrow_array::RecordBatch) -> Result<DataChunk, ArrayError> {
533 let mut columns = Vec::with_capacity(batch.num_columns());
534 for (array, field) in batch.columns().iter().zip_eq_fast(batch.schema().fields()) {
535 let column = Arc::new(self.from_array(field, array)?);
536 columns.push(column);
537 }
538 Ok(DataChunk::new(columns, batch.num_rows()))
539 }
540
541 fn from_fields(&self, fields: &arrow_schema::Fields) -> Result<StructType, ArrayError> {
543 Ok(StructType::new(
544 fields
545 .iter()
546 .map(|f| Ok((f.name().clone(), self.from_field(f)?)))
547 .try_collect::<_, Vec<_>, ArrayError>()?,
548 ))
549 }
550
551 fn from_field(&self, field: &arrow_schema::Field) -> Result<DataType, ArrayError> {
553 use arrow_schema::DataType::*;
554 use arrow_schema::IntervalUnit::*;
555 use arrow_schema::TimeUnit::*;
556
557 if let Some(type_name) = field.metadata().get("ARROW:extension:name") {
559 return self.from_extension_type(type_name, field.data_type());
560 }
561
562 Ok(match field.data_type() {
563 Boolean => DataType::Boolean,
564 Int16 => DataType::Int16,
565 Int32 => DataType::Int32,
566 Int64 => DataType::Int64,
567 Int8 => DataType::Int16,
568 UInt8 => DataType::Int16,
569 UInt16 => DataType::Int32,
570 UInt32 => DataType::Int64,
571 UInt64 => DataType::Decimal,
572 Float16 => DataType::Float32,
573 Float32 => DataType::Float32,
574 Float64 => DataType::Float64,
575 Decimal128(_, _) => DataType::Decimal,
576 Decimal256(_, _) => DataType::Int256,
577 Date32 => DataType::Date,
578 Time32(Second) | Time32(Millisecond) | Time64(Microsecond) | Time64(Nanosecond) => {
579 DataType::Time
580 }
581 Timestamp(Microsecond, None) => DataType::Timestamp,
582 Timestamp(Microsecond, Some(_)) => DataType::Timestamptz,
583 Timestamp(Second, None) => DataType::Timestamp,
584 Timestamp(Second, Some(_)) => DataType::Timestamptz,
585 Timestamp(Millisecond, None) => DataType::Timestamp,
586 Timestamp(Millisecond, Some(_)) => DataType::Timestamptz,
587 Timestamp(Nanosecond, None) => DataType::Timestamp,
588 Timestamp(Nanosecond, Some(_)) => DataType::Timestamptz,
589 Interval(MonthDayNano) => DataType::Interval,
590 Utf8 => DataType::Varchar,
591 Utf8View => DataType::Varchar,
592 Binary => DataType::Bytea,
593 FixedSizeBinary(_) => self.from_fixed_size_binary()?,
596 LargeUtf8 => self.from_large_utf8()?,
597 LargeBinary => self.from_large_binary()?,
598 List(field) => DataType::list(self.from_field(field)?),
599 Struct(fields) => DataType::Struct(self.from_fields(fields)?),
600 Map(field, _is_sorted) => {
601 let entries = self.from_field(field)?;
602 DataType::Map(MapType::try_from_entries(entries).map_err(|e| {
603 ArrayError::from_arrow(format!("invalid arrow map field: {field:?}, err: {e}"))
604 })?)
605 }
606 t => {
607 return Err(ArrayError::from_arrow(format!(
608 "unsupported arrow data type: {t:?}"
609 )));
610 }
611 })
612 }
613
614 fn from_large_utf8(&self) -> Result<DataType, ArrayError> {
616 Ok(DataType::Varchar)
617 }
618
619 fn from_large_binary(&self) -> Result<DataType, ArrayError> {
621 Ok(DataType::Bytea)
622 }
623
624 fn from_fixed_size_binary(&self) -> Result<DataType, ArrayError> {
626 Ok(DataType::Bytea)
627 }
628
629 fn from_extension_type(
631 &self,
632 type_name: &str,
633 physical_type: &arrow_schema::DataType,
634 ) -> Result<DataType, ArrayError> {
635 match (type_name, physical_type) {
636 ("arrowudf.decimal", arrow_schema::DataType::Utf8) => Ok(DataType::Decimal),
637 ("arrowudf.json", arrow_schema::DataType::Utf8) => Ok(DataType::Jsonb),
638 _ => Err(ArrayError::from_arrow(format!(
639 "unsupported extension type: {type_name:?}"
640 ))),
641 }
642 }
643
644 fn from_array(
649 &self,
650 expected_field: &arrow_schema::Field,
651 array: &arrow_array::ArrayRef,
652 ) -> Result<ArrayImpl, ArrayError> {
653 use arrow_schema::DataType::*;
654 use arrow_schema::IntervalUnit::*;
655 use arrow_schema::TimeUnit::*;
656
657 if let Some(type_name) = expected_field.metadata().get("ARROW:extension:name") {
659 return self.from_extension_array(type_name, array);
660 }
661
662 match array.data_type() {
663 Boolean => self.from_bool_array(array.as_any().downcast_ref().unwrap()),
664 Int8 => self.from_int8_array(array.as_any().downcast_ref().unwrap()),
665 Int16 => self.from_int16_array(array.as_any().downcast_ref().unwrap()),
666 Int32 => self.from_int32_array(array.as_any().downcast_ref().unwrap()),
667 Int64 => self.from_int64_array(array.as_any().downcast_ref().unwrap()),
668 UInt8 => self.from_uint8_array(array.as_any().downcast_ref().unwrap()),
669 UInt16 => self.from_uint16_array(array.as_any().downcast_ref().unwrap()),
670 UInt32 => self.from_uint32_array(array.as_any().downcast_ref().unwrap()),
671
672 UInt64 => self.from_uint64_array(array.as_any().downcast_ref().unwrap()),
673 Decimal128(_, _) => self.from_decimal128_array(array.as_any().downcast_ref().unwrap()),
674 Decimal256(_, _) => self.from_int256_array(array.as_any().downcast_ref().unwrap()),
675 Float16 => self.from_float16_array(array.as_any().downcast_ref().unwrap()),
676 Float32 => self.from_float32_array(array.as_any().downcast_ref().unwrap()),
677 Float64 => self.from_float64_array(array.as_any().downcast_ref().unwrap()),
678 Date32 => self.from_date32_array(array.as_any().downcast_ref().unwrap()),
679 Time32(Second) => self.from_time32s_array(array.as_any().downcast_ref().unwrap()),
680 Time32(Millisecond) => self.from_time32ms_array(array.as_any().downcast_ref().unwrap()),
681 Time64(Microsecond) => self.from_time64us_array(array.as_any().downcast_ref().unwrap()),
682 Time64(Nanosecond) => self.from_time64ns_array(array.as_any().downcast_ref().unwrap()),
683 Timestamp(Second, None) => {
684 self.from_timestampsecond_array(array.as_any().downcast_ref().unwrap())
685 }
686 Timestamp(Second, Some(_)) => {
687 self.from_timestampsecond_some_array(array.as_any().downcast_ref().unwrap())
688 }
689 Timestamp(Millisecond, None) => {
690 self.from_timestampms_array(array.as_any().downcast_ref().unwrap())
691 }
692 Timestamp(Millisecond, Some(_)) => {
693 self.from_timestampms_some_array(array.as_any().downcast_ref().unwrap())
694 }
695 Timestamp(Microsecond, None) => {
696 self.from_timestampus_array(array.as_any().downcast_ref().unwrap())
697 }
698 Timestamp(Microsecond, Some(_)) => {
699 self.from_timestampus_some_array(array.as_any().downcast_ref().unwrap())
700 }
701 Timestamp(Nanosecond, None) => {
702 self.from_timestampns_array(array.as_any().downcast_ref().unwrap())
703 }
704 Timestamp(Nanosecond, Some(_)) => {
705 self.from_timestampns_some_array(array.as_any().downcast_ref().unwrap())
706 }
707 Interval(MonthDayNano) => {
708 self.from_interval_array(array.as_any().downcast_ref().unwrap())
709 }
710 Utf8 => self.from_utf8_array(array.as_any().downcast_ref().unwrap()),
711 Utf8View => self.from_utf8_view_array(array.as_any().downcast_ref().unwrap()),
712 Binary => self.from_binary_array(array.as_any().downcast_ref().unwrap()),
713 FixedSizeBinary(_) => {
714 self.from_fixed_size_binary_array(array.as_any().downcast_ref().unwrap())
715 }
716 LargeUtf8 => self.from_large_utf8_array(array.as_any().downcast_ref().unwrap()),
717 LargeBinary => self.from_large_binary_array(array.as_any().downcast_ref().unwrap()),
718 List(_) => self.from_list_array(expected_field, array.as_any().downcast_ref().unwrap()),
719 Struct(_) => {
720 self.from_struct_array(expected_field, array.as_any().downcast_ref().unwrap())
721 }
722 Map(_, _) => {
723 self.from_map_array(expected_field, array.as_any().downcast_ref().unwrap())
724 }
725 t => Err(ArrayError::from_arrow(format!(
726 "unsupported arrow data type: {t:?}",
727 ))),
728 }
729 }
730
731 fn from_extension_array(
733 &self,
734 type_name: &str,
735 array: &arrow_array::ArrayRef,
736 ) -> Result<ArrayImpl, ArrayError> {
737 match type_name {
738 "arrowudf.decimal" => {
739 let array: &arrow_array::StringArray =
740 array.as_any().downcast_ref().ok_or_else(|| {
741 ArrayError::from_arrow(
742 "expected string array for `arrowudf.decimal`".to_owned(),
743 )
744 })?;
745 Ok(ArrayImpl::Decimal(array.try_into()?))
746 }
747 "arrowudf.json" => {
748 let array: &arrow_array::StringArray =
749 array.as_any().downcast_ref().ok_or_else(|| {
750 ArrayError::from_arrow(
751 "expected string array for `arrowudf.json`".to_owned(),
752 )
753 })?;
754 Ok(ArrayImpl::Jsonb(array.try_into()?))
755 }
756 _ => Err(ArrayError::from_arrow(format!(
757 "unsupported extension type: {type_name:?}"
758 ))),
759 }
760 }
761
762 fn from_bool_array(&self, array: &arrow_array::BooleanArray) -> Result<ArrayImpl, ArrayError> {
763 Ok(ArrayImpl::Bool(array.into()))
764 }
765
766 fn from_int16_array(&self, array: &arrow_array::Int16Array) -> Result<ArrayImpl, ArrayError> {
767 Ok(ArrayImpl::Int16(array.into()))
768 }
769
770 fn from_int8_array(&self, array: &arrow_array::Int8Array) -> Result<ArrayImpl, ArrayError> {
771 Ok(ArrayImpl::Int16(array.into()))
772 }
773
774 fn from_uint8_array(&self, array: &arrow_array::UInt8Array) -> Result<ArrayImpl, ArrayError> {
775 Ok(ArrayImpl::Int16(array.into()))
776 }
777
778 fn from_uint16_array(&self, array: &arrow_array::UInt16Array) -> Result<ArrayImpl, ArrayError> {
779 Ok(ArrayImpl::Int32(array.into()))
780 }
781
782 fn from_uint32_array(&self, array: &arrow_array::UInt32Array) -> Result<ArrayImpl, ArrayError> {
783 Ok(ArrayImpl::Int64(array.into()))
784 }
785
786 fn from_int32_array(&self, array: &arrow_array::Int32Array) -> Result<ArrayImpl, ArrayError> {
787 Ok(ArrayImpl::Int32(array.into()))
788 }
789
790 fn from_int64_array(&self, array: &arrow_array::Int64Array) -> Result<ArrayImpl, ArrayError> {
791 Ok(ArrayImpl::Int64(array.into()))
792 }
793
794 fn from_int256_array(
795 &self,
796 array: &arrow_array::Decimal256Array,
797 ) -> Result<ArrayImpl, ArrayError> {
798 Ok(ArrayImpl::Int256(array.into()))
799 }
800
801 fn from_decimal128_array(
802 &self,
803 array: &arrow_array::Decimal128Array,
804 ) -> Result<ArrayImpl, ArrayError> {
805 Ok(ArrayImpl::Decimal(array.try_into()?))
806 }
807
808 fn from_uint64_array(&self, array: &arrow_array::UInt64Array) -> Result<ArrayImpl, ArrayError> {
809 Ok(ArrayImpl::Decimal(array.try_into()?))
810 }
811
812 fn from_float16_array(
813 &self,
814 array: &arrow_array::Float16Array,
815 ) -> Result<ArrayImpl, ArrayError> {
816 Ok(ArrayImpl::Float32(array.try_into()?))
817 }
818
819 fn from_float32_array(
820 &self,
821 array: &arrow_array::Float32Array,
822 ) -> Result<ArrayImpl, ArrayError> {
823 Ok(ArrayImpl::Float32(array.into()))
824 }
825
826 fn from_float64_array(
827 &self,
828 array: &arrow_array::Float64Array,
829 ) -> Result<ArrayImpl, ArrayError> {
830 Ok(ArrayImpl::Float64(array.into()))
831 }
832
833 fn from_date32_array(&self, array: &arrow_array::Date32Array) -> Result<ArrayImpl, ArrayError> {
834 Ok(ArrayImpl::Date(array.try_into()?))
835 }
836
837 fn from_time32s_array(
838 &self,
839 array: &arrow_array::Time32SecondArray,
840 ) -> Result<ArrayImpl, ArrayError> {
841 Ok(ArrayImpl::Time(array.try_into()?))
842 }
843
844 fn from_time32ms_array(
845 &self,
846 array: &arrow_array::Time32MillisecondArray,
847 ) -> Result<ArrayImpl, ArrayError> {
848 Ok(ArrayImpl::Time(array.try_into()?))
849 }
850
851 fn from_time64us_array(
852 &self,
853 array: &arrow_array::Time64MicrosecondArray,
854 ) -> Result<ArrayImpl, ArrayError> {
855 Ok(ArrayImpl::Time(array.try_into()?))
856 }
857
858 fn from_time64ns_array(
859 &self,
860 array: &arrow_array::Time64NanosecondArray,
861 ) -> Result<ArrayImpl, ArrayError> {
862 Ok(ArrayImpl::Time(array.try_into()?))
863 }
864
865 fn from_timestampsecond_array(
866 &self,
867 array: &arrow_array::TimestampSecondArray,
868 ) -> Result<ArrayImpl, ArrayError> {
869 Ok(ArrayImpl::Timestamp(array.try_into()?))
870 }
871 fn from_timestampsecond_some_array(
872 &self,
873 array: &arrow_array::TimestampSecondArray,
874 ) -> Result<ArrayImpl, ArrayError> {
875 Ok(ArrayImpl::Timestamptz(array.try_into()?))
876 }
877
878 fn from_timestampms_array(
879 &self,
880 array: &arrow_array::TimestampMillisecondArray,
881 ) -> Result<ArrayImpl, ArrayError> {
882 Ok(ArrayImpl::Timestamp(array.try_into()?))
883 }
884
885 fn from_timestampms_some_array(
886 &self,
887 array: &arrow_array::TimestampMillisecondArray,
888 ) -> Result<ArrayImpl, ArrayError> {
889 Ok(ArrayImpl::Timestamptz(array.try_into()?))
890 }
891
892 fn from_timestampus_array(
893 &self,
894 array: &arrow_array::TimestampMicrosecondArray,
895 ) -> Result<ArrayImpl, ArrayError> {
896 Ok(ArrayImpl::Timestamp(array.try_into()?))
897 }
898
899 fn from_timestampus_some_array(
900 &self,
901 array: &arrow_array::TimestampMicrosecondArray,
902 ) -> Result<ArrayImpl, ArrayError> {
903 Ok(ArrayImpl::Timestamptz(array.try_into()?))
904 }
905
906 fn from_timestampns_array(
907 &self,
908 array: &arrow_array::TimestampNanosecondArray,
909 ) -> Result<ArrayImpl, ArrayError> {
910 Ok(ArrayImpl::Timestamp(array.try_into()?))
911 }
912
913 fn from_timestampns_some_array(
914 &self,
915 array: &arrow_array::TimestampNanosecondArray,
916 ) -> Result<ArrayImpl, ArrayError> {
917 Ok(ArrayImpl::Timestamptz(array.try_into()?))
918 }
919
920 fn from_interval_array(
921 &self,
922 array: &arrow_array::IntervalMonthDayNanoArray,
923 ) -> Result<ArrayImpl, ArrayError> {
924 Ok(ArrayImpl::Interval(array.try_into()?))
925 }
926
927 fn from_utf8_array(&self, array: &arrow_array::StringArray) -> Result<ArrayImpl, ArrayError> {
928 Ok(ArrayImpl::Utf8(array.into()))
929 }
930
931 fn from_utf8_view_array(
932 &self,
933 array: &arrow_array::StringViewArray,
934 ) -> Result<ArrayImpl, ArrayError> {
935 Ok(ArrayImpl::Utf8(array.into()))
936 }
937
938 fn from_binary_array(&self, array: &arrow_array::BinaryArray) -> Result<ArrayImpl, ArrayError> {
939 Ok(ArrayImpl::Bytea(array.into()))
940 }
941
942 fn from_large_utf8_array(
943 &self,
944 array: &arrow_array::LargeStringArray,
945 ) -> Result<ArrayImpl, ArrayError> {
946 Ok(ArrayImpl::Utf8(array.into()))
947 }
948
949 fn from_large_binary_array(
950 &self,
951 array: &arrow_array::LargeBinaryArray,
952 ) -> Result<ArrayImpl, ArrayError> {
953 Ok(ArrayImpl::Bytea(array.into()))
954 }
955
956 fn from_fixed_size_binary_array(
957 &self,
958 array: &arrow_array::FixedSizeBinaryArray,
959 ) -> Result<ArrayImpl, ArrayError> {
960 Ok(ArrayImpl::Bytea(array.iter().collect()))
961 }
962
963 fn from_list_array(
967 &self,
968 expected_field: &arrow_schema::Field,
969 array: &arrow_array::ListArray,
970 ) -> Result<ArrayImpl, ArrayError> {
971 use arrow_array::Array;
972 let elem_field = match (expected_field.data_type(), array.data_type()) {
973 (arrow_schema::DataType::List(elem), _) | (_, arrow_schema::DataType::List(elem)) => {
974 elem
975 }
976 _ => unreachable!("a list array must have a list data type"),
977 };
978 Ok(ArrayImpl::List(ListArray {
979 value: Box::new(self.from_array(elem_field, array.values())?),
980 bitmap: match array.nulls() {
981 Some(nulls) => nulls.iter().collect(),
982 None => Bitmap::ones(array.len()),
983 },
984 offsets: array.offsets().iter().map(|o| *o as u32).collect(),
985 }))
986 }
987
988 fn from_struct_array(
1001 &self,
1002 expected_field: &arrow_schema::Field,
1003 array: &arrow_array::StructArray,
1004 ) -> Result<ArrayImpl, ArrayError> {
1005 use std::collections::HashMap;
1006
1007 use arrow_array::Array;
1008
1009 let arrow_schema::DataType::Struct(actual_fields) = array.data_type() else {
1010 unreachable!("a struct array must have a struct data type");
1011 };
1012 let expected_fields = match expected_field.data_type() {
1013 arrow_schema::DataType::Struct(fields) => fields,
1014 _ => actual_fields,
1015 };
1016
1017 let len = array.len();
1018 let decode_positionally = |fields: &arrow_schema::Fields| {
1019 array
1020 .columns()
1021 .iter()
1022 .zip_eq_fast(fields)
1023 .map(|(column, field)| self.from_array(field, column).map(Arc::new))
1024 .try_collect()
1025 };
1026 let names_aligned = expected_fields.len() == actual_fields.len()
1029 && expected_fields
1030 .iter()
1031 .zip_eq_fast(actual_fields.iter())
1032 .all(|(e, a)| e.name() == a.name());
1033 let columns: Vec<Arc<ArrayImpl>> = if names_aligned {
1034 decode_positionally(expected_fields)?
1035 } else {
1036 let mut actual_name_to_index = HashMap::new();
1039 for (idx, f) in actual_fields.iter().enumerate() {
1040 actual_name_to_index.entry(f.name().as_str()).or_insert(idx);
1041 }
1042 if expected_fields
1043 .iter()
1044 .all(|f| actual_name_to_index.contains_key(f.name().as_str()))
1045 {
1046 expected_fields
1047 .iter()
1048 .map(|expected_field| {
1049 let idx = actual_name_to_index[expected_field.name().as_str()];
1050 self.from_array(expected_field, &array.columns()[idx])
1051 .map(Arc::new)
1052 })
1053 .try_collect()?
1054 } else if expected_fields.len() == actual_fields.len() {
1055 decode_positionally(expected_fields)?
1058 } else {
1059 let names =
1060 |fields: &arrow_schema::Fields| fields.iter().map(|f| f.name()).join(", ");
1061 return Err(ArrayError::from_arrow(format!(
1062 "unable to align struct fields: expected [{}], actual [{}]",
1063 names(expected_fields),
1064 names(actual_fields),
1065 )));
1066 }
1067 };
1068
1069 Ok(ArrayImpl::Struct(StructArray::new(
1070 StructType::new(
1071 expected_fields
1072 .iter()
1073 .zip_eq_fast(columns.iter())
1074 .map(|(f, c)| (f.name().clone(), c.data_type())),
1075 ),
1076 columns,
1077 (0..len).map(|i| array.is_valid(i)).collect(),
1078 )))
1079 }
1080
1081 fn from_map_array(
1084 &self,
1085 expected_field: &arrow_schema::Field,
1086 array: &arrow_array::MapArray,
1087 ) -> Result<ArrayImpl, ArrayError> {
1088 use arrow_array::Array;
1089 let expected_entries = match (expected_field.data_type(), array.data_type()) {
1090 (arrow_schema::DataType::Map(entries, _), _)
1091 | (_, arrow_schema::DataType::Map(entries, _)) => entries,
1092 _ => unreachable!("a map array must have a map data type"),
1093 };
1094 let struct_array = self.from_struct_array(expected_entries, array.entries())?;
1095 MapType::try_from_entries(struct_array.data_type())
1098 .map_err(|e| ArrayError::from_arrow(format!("invalid arrow map array: {e}")))?;
1099 let list_array = ListArray {
1100 value: Box::new(struct_array),
1101 bitmap: match array.nulls() {
1102 Some(nulls) => nulls.iter().collect(),
1103 None => Bitmap::ones(array.len()),
1104 },
1105 offsets: array.offsets().iter().map(|o| *o as u32).collect(),
1106 };
1107
1108 Ok(ArrayImpl::Map(MapArray { inner: list_array }))
1109 }
1110}
1111
1112impl From<&Bitmap> for arrow_buffer::NullBuffer {
1113 fn from(bitmap: &Bitmap) -> Self {
1114 bitmap.iter().collect()
1115 }
1116}
1117
1118macro_rules! converts {
1120 ($ArrayType:ty, $ArrowType:ty) => {
1121 impl From<&$ArrayType> for $ArrowType {
1122 fn from(array: &$ArrayType) -> Self {
1123 array.iter().collect()
1124 }
1125 }
1126 impl From<&$ArrowType> for $ArrayType {
1127 fn from(array: &$ArrowType) -> Self {
1128 array.iter().collect()
1129 }
1130 }
1131 impl From<&[$ArrowType]> for $ArrayType {
1132 fn from(arrays: &[$ArrowType]) -> Self {
1133 arrays.iter().flat_map(|a| a.iter()).collect()
1134 }
1135 }
1136 };
1137 ($ArrayType:ty, $ArrowType:ty, @map) => {
1139 impl From<&$ArrayType> for $ArrowType {
1140 fn from(array: &$ArrayType) -> Self {
1141 array.iter().map(|o| o.map(|v| v.into_arrow())).collect()
1142 }
1143 }
1144 impl From<&$ArrowType> for $ArrayType {
1145 fn from(array: &$ArrowType) -> Self {
1146 array
1147 .iter()
1148 .map(|o| {
1149 o.map(|v| {
1150 <<$ArrayType as Array>::RefItem<'_> as FromIntoArrow>::from_arrow(v)
1151 })
1152 })
1153 .collect()
1154 }
1155 }
1156 impl From<&[$ArrowType]> for $ArrayType {
1157 fn from(arrays: &[$ArrowType]) -> Self {
1158 arrays
1159 .iter()
1160 .flat_map(|a| a.iter())
1161 .map(|o| {
1162 o.map(|v| {
1163 <<$ArrayType as Array>::RefItem<'_> as FromIntoArrow>::from_arrow(v)
1164 })
1165 })
1166 .collect()
1167 }
1168 }
1169 };
1170 ($ArrayType:ty, $ArrowType:ty, @try_map) => {
1172 impl TryFrom<&$ArrayType> for $ArrowType {
1173 type Error = ArrayError;
1174
1175 fn try_from(array: &$ArrayType) -> Result<Self, Self::Error> {
1176 let mut builder = <$ArrowType>::builder(array.len());
1179 for o in array.iter() {
1180 builder.append_option(o.map(|v| v.try_into_arrow()).transpose()?);
1181 }
1182 Ok(builder.finish())
1183 }
1184 }
1185 impl TryFrom<&$ArrowType> for $ArrayType {
1186 type Error = ArrayError;
1187
1188 fn try_from(array: &$ArrowType) -> Result<Self, Self::Error> {
1189 use arrow_array::Array as _;
1190
1191 let mut builder = <$ArrayType as Array>::Builder::new(array.len());
1192 for o in array.iter() {
1193 builder.append(
1194 o.map(<<$ArrayType as Array>::RefItem<'_> as TryFromIntoArrow>::try_from_arrow)
1195 .transpose()?,
1196 );
1197 }
1198 Ok(builder.finish())
1199 }
1200 }
1201 };
1202}
1203
1204macro_rules! converts_with_type {
1206 ($ArrayType:ty, $ArrowType:ty, $FromType:ty, $ToType:ty) => {
1207 impl From<&$ArrayType> for $ArrowType {
1208 fn from(array: &$ArrayType) -> Self {
1209 let values: Vec<Option<$ToType>> =
1210 array.iter().map(|x| x.map(|v| v as $ToType)).collect();
1211 <$ArrowType>::from_iter(values)
1212 }
1213 }
1214
1215 impl From<&$ArrowType> for $ArrayType {
1216 fn from(array: &$ArrowType) -> Self {
1217 let values: Vec<Option<$FromType>> =
1218 array.iter().map(|x| x.map(|v| v as $FromType)).collect();
1219 <$ArrayType>::from_iter(values)
1220 }
1221 }
1222
1223 impl From<&[$ArrowType]> for $ArrayType {
1224 fn from(arrays: &[$ArrowType]) -> Self {
1225 let values: Vec<Option<$FromType>> = arrays
1226 .iter()
1227 .flat_map(|a| a.iter().map(|x| x.map(|v| v as $FromType)))
1228 .collect();
1229 <$ArrayType>::from_iter(values)
1230 }
1231 }
1232 };
1233}
1234
1235macro_rules! converts_with_time_unit {
1236 ($ArrayType:ty, $ArrowType:ident, $time_unit:ident) => {
1237 impl TryFrom<&$ArrayType> for arrow_array::$ArrowType {
1238 type Error = ArrayError;
1239
1240 fn try_from(array: &$ArrayType) -> Result<Self, Self::Error> {
1241 let mut builder = arrow_array::$ArrowType::builder(array.len());
1242 for o in array.iter() {
1243 builder.append_option(
1244 o.map(|v| into_arrow_temporal_value(v, TimeUnit::$time_unit))
1245 .transpose()?,
1246 );
1247 }
1248 Ok(builder.finish())
1249 }
1250 }
1251
1252 impl TryFrom<&arrow_array::$ArrowType> for $ArrayType {
1253 type Error = ArrayError;
1254
1255 fn try_from(array: &arrow_array::$ArrowType) -> Result<Self, Self::Error> {
1256 Self::try_from(std::slice::from_ref(array))
1257 }
1258 }
1259
1260 impl TryFrom<&[arrow_array::$ArrowType]> for $ArrayType {
1261 type Error = ArrayError;
1262
1263 fn try_from(arrays: &[arrow_array::$ArrowType]) -> Result<Self, Self::Error> {
1264 use arrow_array::Array as _;
1265
1266 let mut builder =
1267 <$ArrayType as Array>::Builder::new(arrays.iter().map(|a| a.len()).sum());
1268 for o in arrays.iter().flat_map(|a| a.iter()) {
1269 builder.append(
1270 o.map(|v| try_from_arrow_temporal_value(v, TimeUnit::$time_unit))
1271 .transpose()?,
1272 );
1273 }
1274 Ok(builder.finish())
1275 }
1276 }
1277 };
1278}
1279
1280converts!(BoolArray, arrow_array::BooleanArray);
1281converts!(I16Array, arrow_array::Int16Array);
1282converts!(I32Array, arrow_array::Int32Array);
1283converts!(I64Array, arrow_array::Int64Array);
1284converts!(F32Array, arrow_array::Float32Array, @map);
1285converts!(F64Array, arrow_array::Float64Array, @map);
1286converts!(BytesArray, arrow_array::BinaryArray);
1287converts!(BytesArray, arrow_array::LargeBinaryArray);
1288converts!(Utf8Array, arrow_array::StringArray);
1289converts!(Utf8Array, arrow_array::LargeStringArray);
1290converts!(Utf8Array, arrow_array::StringViewArray);
1291converts!(DateArray, arrow_array::Date32Array, @try_map);
1292converts!(IntervalArray, arrow_array::IntervalMonthDayNanoArray, @try_map);
1293converts!(SerialArray, arrow_array::Int64Array, @map);
1294
1295converts_with_type!(I16Array, arrow_array::Int8Array, i16, i8);
1296converts_with_type!(I16Array, arrow_array::UInt8Array, i16, u8);
1297converts_with_type!(I32Array, arrow_array::UInt16Array, i32, u16);
1298converts_with_type!(I64Array, arrow_array::UInt32Array, i64, u32);
1299
1300converts_with_time_unit!(TimeArray, Time32SecondArray, Second);
1301converts_with_time_unit!(TimeArray, Time32MillisecondArray, Millisecond);
1302converts_with_time_unit!(TimeArray, Time64MicrosecondArray, Microsecond);
1303converts_with_time_unit!(TimeArray, Time64NanosecondArray, Nanosecond);
1304
1305converts_with_time_unit!(TimestampArray, TimestampSecondArray, Second);
1306converts_with_time_unit!(TimestampArray, TimestampMillisecondArray, Millisecond);
1307converts_with_time_unit!(TimestampArray, TimestampMicrosecondArray, Microsecond);
1308converts_with_time_unit!(TimestampArray, TimestampNanosecondArray, Nanosecond);
1309
1310converts_with_time_unit!(TimestamptzArray, TimestampSecondArray, Second);
1311converts_with_time_unit!(TimestamptzArray, TimestampMillisecondArray, Millisecond);
1312converts_with_time_unit!(TimestamptzArray, TimestampMicrosecondArray, Microsecond);
1313converts_with_time_unit!(TimestamptzArray, TimestampNanosecondArray, Nanosecond);
1314
1315trait FromIntoArrow {
1317 type ArrowType;
1319 fn from_arrow(value: Self::ArrowType) -> Self;
1320 fn into_arrow(self) -> Self::ArrowType;
1321}
1322
1323trait TryFromIntoArrow: Sized {
1326 type ArrowType;
1328 fn try_from_arrow(value: Self::ArrowType) -> Result<Self, ArrayError>;
1329 fn try_into_arrow(self) -> Result<Self::ArrowType, ArrayError>;
1330}
1331
1332trait TemporalArrowConvert<ArrowNative>: Sized {
1335 fn try_from_arrow_with_time_unit(
1336 value: ArrowNative,
1337 time_unit: TimeUnit,
1338 ) -> Result<Self, ArrayError>;
1339 fn into_arrow_with_time_unit(self, time_unit: TimeUnit) -> Result<ArrowNative, ArrayError>;
1340}
1341
1342fn try_from_arrow_temporal_value<Value, ArrowNative>(
1343 value: ArrowNative,
1344 time_unit: TimeUnit,
1345) -> Result<Value, ArrayError>
1346where
1347 Value: TemporalArrowConvert<ArrowNative>,
1348{
1349 Value::try_from_arrow_with_time_unit(value, time_unit)
1350}
1351
1352fn into_arrow_temporal_value<Value, ArrowNative>(
1353 value: Value,
1354 time_unit: TimeUnit,
1355) -> Result<ArrowNative, ArrayError>
1356where
1357 Value: TemporalArrowConvert<ArrowNative>,
1358{
1359 value.into_arrow_with_time_unit(time_unit)
1360}
1361
1362impl FromIntoArrow for Serial {
1363 type ArrowType = i64;
1364
1365 fn from_arrow(value: Self::ArrowType) -> Self {
1366 value.into()
1367 }
1368
1369 fn into_arrow(self) -> Self::ArrowType {
1370 self.into()
1371 }
1372}
1373
1374impl FromIntoArrow for F32 {
1375 type ArrowType = f32;
1376
1377 fn from_arrow(value: Self::ArrowType) -> Self {
1378 value.into()
1379 }
1380
1381 fn into_arrow(self) -> Self::ArrowType {
1382 self.into()
1383 }
1384}
1385
1386impl FromIntoArrow for F64 {
1387 type ArrowType = f64;
1388
1389 fn from_arrow(value: Self::ArrowType) -> Self {
1390 value.into()
1391 }
1392
1393 fn into_arrow(self) -> Self::ArrowType {
1394 self.into()
1395 }
1396}
1397
1398impl TryFromIntoArrow for Date {
1399 type ArrowType = i32;
1400
1401 #[allow(deprecated)]
1402 fn try_from_arrow(value: Self::ArrowType) -> Result<Self, ArrayError> {
1403 arrow_array::types::Date32Type::to_naive_date_opt(value)
1404 .map(Date)
1405 .ok_or_else(|| ArrayError::from_arrow(format!("invalid Arrow date {value}")))
1406 }
1407
1408 fn try_into_arrow(self) -> Result<Self::ArrowType, ArrayError> {
1409 Ok(arrow_array::types::Date32Type::from_naive_date(self.0))
1410 }
1411}
1412
1413impl TemporalArrowConvert<i32> for Time {
1415 fn try_from_arrow_with_time_unit(value: i32, time_unit: TimeUnit) -> Result<Self, ArrayError> {
1416 u32::try_from(value)
1417 .ok()
1418 .and_then(|v| match time_unit {
1419 TimeUnit::Second => Time::with_secs_nano(v, 0).ok(),
1420 TimeUnit::Millisecond => Time::with_milli(v).ok(),
1421 unit => unreachable!("{unit:?} is not a Time32 unit"),
1422 })
1423 .ok_or_else(|| invalid_arrow_temporal_value(value, time_unit))
1424 }
1425
1426 fn into_arrow_with_time_unit(self, time_unit: TimeUnit) -> Result<i32, ArrayError> {
1427 Ok(match time_unit {
1428 TimeUnit::Second => self.0.num_seconds_from_midnight() as i32,
1429 TimeUnit::Millisecond => {
1430 (self.0.num_seconds_from_midnight() * 1_000 + self.0.nanosecond() / 1_000_000)
1431 as i32
1432 }
1433 unit => unreachable!("{unit:?} is not a Time32 unit"),
1434 })
1435 }
1436}
1437
1438impl TemporalArrowConvert<i64> for Time {
1442 fn try_from_arrow_with_time_unit(value: i64, time_unit: TimeUnit) -> Result<Self, ArrayError> {
1443 u64::try_from(value)
1444 .ok()
1445 .and_then(|v| match time_unit {
1446 TimeUnit::Microsecond => Time::with_micro(v).ok(),
1447 TimeUnit::Nanosecond => Time::with_micro(v / 1_000).ok(),
1448 unit => unreachable!("{unit:?} is not a Time64 unit"),
1449 })
1450 .ok_or_else(|| invalid_arrow_temporal_value(value, time_unit))
1451 }
1452
1453 fn into_arrow_with_time_unit(self, time_unit: TimeUnit) -> Result<i64, ArrayError> {
1454 Ok(match time_unit {
1455 TimeUnit::Microsecond => self.micros_of_day() as i64,
1456 TimeUnit::Nanosecond => self.nanos_of_day() as i64,
1457 unit => unreachable!("{unit:?} is not a Time64 unit"),
1458 })
1459 }
1460}
1461
1462impl TemporalArrowConvert<i64> for Timestamp {
1463 fn try_from_arrow_with_time_unit(value: i64, time_unit: TimeUnit) -> Result<Self, ArrayError> {
1464 match time_unit {
1465 TimeUnit::Second => Timestamp::with_secs_nsecs(value, 0)
1466 .map_err(|_| invalid_arrow_temporal_value(value, time_unit)),
1467 TimeUnit::Millisecond => Timestamp::with_millis(value)
1468 .map_err(|_| invalid_arrow_temporal_value(value, time_unit)),
1469 TimeUnit::Microsecond => Timestamp::with_micros(value)
1470 .map_err(|_| invalid_arrow_temporal_value(value, time_unit)),
1471 TimeUnit::Nanosecond => Ok(Timestamp::with_nanos(value)),
1472 }
1473 }
1474
1475 fn into_arrow_with_time_unit(self, time_unit: TimeUnit) -> Result<i64, ArrayError> {
1476 match time_unit {
1477 TimeUnit::Second => Ok(self.0.and_utc().timestamp()),
1478 TimeUnit::Millisecond => Ok(self.0.and_utc().timestamp_millis()),
1479 TimeUnit::Microsecond => Ok(self.0.and_utc().timestamp_micros()),
1480 TimeUnit::Nanosecond => self
1481 .0
1482 .and_utc()
1483 .timestamp_nanos_opt()
1484 .ok_or_else(|| arrow_temporal_value_overflow(self, time_unit)),
1485 }
1486 }
1487}
1488
1489impl TemporalArrowConvert<i64> for Timestamptz {
1490 fn try_from_arrow_with_time_unit(value: i64, time_unit: TimeUnit) -> Result<Self, ArrayError> {
1491 match time_unit {
1492 TimeUnit::Second => Timestamptz::from_secs(value)
1493 .ok_or_else(|| invalid_arrow_temporal_value(value, time_unit)),
1494 TimeUnit::Millisecond => Timestamptz::from_millis(value)
1495 .ok_or_else(|| invalid_arrow_temporal_value(value, time_unit)),
1496 TimeUnit::Microsecond => Timestamptz::from_micros(value)
1497 .ok_or_else(|| invalid_arrow_temporal_value(value, time_unit)),
1498 TimeUnit::Nanosecond => Ok(Timestamptz::from_nanos(value)),
1499 }
1500 }
1501
1502 fn into_arrow_with_time_unit(self, time_unit: TimeUnit) -> Result<i64, ArrayError> {
1503 match time_unit {
1504 TimeUnit::Second => Ok(self.timestamp()),
1505 TimeUnit::Millisecond => Ok(self.timestamp_millis()),
1506 TimeUnit::Microsecond => Ok(self.timestamp_micros()),
1507 TimeUnit::Nanosecond => self
1508 .timestamp_nanos()
1509 .ok_or_else(|| arrow_temporal_value_overflow(self, time_unit)),
1510 }
1511 }
1512}
1513
1514fn invalid_arrow_temporal_value<T: std::fmt::Display>(value: T, time_unit: TimeUnit) -> ArrayError {
1515 ArrayError::from_arrow(format!(
1516 "invalid Arrow temporal value {value} for unit {time_unit:?}"
1517 ))
1518}
1519
1520fn arrow_temporal_value_overflow<T: std::fmt::Display>(
1521 value: T,
1522 time_unit: TimeUnit,
1523) -> ArrayError {
1524 ArrayError::to_arrow(format!(
1525 "temporal value {value} overflows Arrow unit {time_unit:?}"
1526 ))
1527}
1528
1529impl TryFromIntoArrow for Interval {
1530 type ArrowType = ArrowIntervalType;
1531
1532 fn try_from_arrow(value: Self::ArrowType) -> Result<Self, ArrayError> {
1534 Ok(Interval::from_month_day_usec(
1535 value.months,
1536 value.days,
1537 value.nanoseconds / 1_000,
1538 ))
1539 }
1540
1541 fn try_into_arrow(self) -> Result<Self::ArrowType, ArrayError> {
1542 Ok(ArrowIntervalType {
1543 months: self.months(),
1544 days: self.days(),
1545 nanoseconds: self.usecs().checked_mul(1_000).ok_or_else(|| {
1546 ArrayError::to_arrow(format!(
1547 "interval with {} microseconds is out of range for Arrow",
1548 self.usecs()
1549 ))
1550 })?,
1551 })
1552 }
1553}
1554
1555impl From<&DecimalArray> for arrow_array::LargeBinaryArray {
1556 fn from(array: &DecimalArray) -> Self {
1557 let mut builder =
1558 arrow_array::builder::LargeBinaryBuilder::with_capacity(array.len(), array.len() * 8);
1559 for value in array.iter() {
1560 builder.append_option(value.map(|d| d.to_string()));
1561 }
1562 builder.finish()
1563 }
1564}
1565
1566impl From<&DecimalArray> for arrow_array::StringArray {
1567 fn from(array: &DecimalArray) -> Self {
1568 let mut builder =
1569 arrow_array::builder::StringBuilder::with_capacity(array.len(), array.len() * 8);
1570 for value in array.iter() {
1571 builder.append_option(value.map(|d| d.to_string()));
1572 }
1573 builder.finish()
1574 }
1575}
1576
1577impl TryFrom<&arrow_array::Decimal128Array> for DecimalArray {
1579 type Error = ArrayError;
1580
1581 fn try_from(array: &arrow_array::Decimal128Array) -> Result<Self, Self::Error> {
1582 if array.scale() < 0 {
1583 bail!("support negative scale for arrow decimal")
1584 }
1585
1586 let precision = array.precision();
1589 let max_value = 10_i128.pow(precision as u32) - 1;
1590
1591 let from_arrow = |value| {
1592 const NAN: i128 = i128::MIN + 1;
1593 let res = match value {
1594 NAN => Decimal::NaN,
1596 v if v == max_value => Decimal::PositiveInf,
1597 v if v == -max_value => Decimal::NegativeInf,
1598 i128::MAX => Decimal::PositiveInf, i128::MIN => Decimal::NegativeInf, _ => Decimal::truncated_i128_and_scale(value, array.scale() as u32)
1601 .ok_or_else(|| ArrayError::from_arrow("decimal overflow"))?,
1602 };
1603 Ok(res)
1604 };
1605 array
1606 .iter()
1607 .map(|o| o.map(from_arrow).transpose())
1608 .collect::<Result<Self, Self::Error>>()
1609 }
1610}
1611
1612impl TryFrom<&arrow_array::UInt64Array> for DecimalArray {
1614 type Error = ArrayError;
1615
1616 fn try_from(array: &arrow_array::UInt64Array) -> Result<Self, Self::Error> {
1617 let from_arrow = |value| {
1618 let res = Decimal::from(value);
1620 Ok(res)
1621 };
1622
1623 array
1625 .iter()
1626 .map(|o| o.map(from_arrow).transpose())
1627 .collect::<Result<Self, Self::Error>>()
1628 }
1629}
1630
1631impl TryFrom<&arrow_array::Float16Array> for F32Array {
1632 type Error = ArrayError;
1633
1634 fn try_from(array: &arrow_array::Float16Array) -> Result<Self, Self::Error> {
1635 let from_arrow = |value| Ok(f32::from(value));
1636
1637 array
1638 .iter()
1639 .map(|o| o.map(from_arrow).transpose())
1640 .collect::<Result<Self, Self::Error>>()
1641 }
1642}
1643
1644impl TryFrom<&arrow_array::LargeBinaryArray> for DecimalArray {
1645 type Error = ArrayError;
1646
1647 fn try_from(array: &arrow_array::LargeBinaryArray) -> Result<Self, Self::Error> {
1648 array
1649 .iter()
1650 .map(|o| {
1651 o.map(|s| {
1652 let s = std::str::from_utf8(s)
1653 .map_err(|_| ArrayError::from_arrow(format!("invalid decimal: {s:?}")))?;
1654 s.parse()
1655 .map_err(|_| ArrayError::from_arrow(format!("invalid decimal: {s:?}")))
1656 })
1657 .transpose()
1658 })
1659 .try_collect()
1660 }
1661}
1662
1663impl TryFrom<&arrow_array::StringArray> for DecimalArray {
1664 type Error = ArrayError;
1665
1666 fn try_from(array: &arrow_array::StringArray) -> Result<Self, Self::Error> {
1667 array
1668 .iter()
1669 .map(|o| {
1670 o.map(|s| {
1671 s.parse()
1672 .map_err(|_| ArrayError::from_arrow(format!("invalid decimal: {s:?}")))
1673 })
1674 .transpose()
1675 })
1676 .try_collect()
1677 }
1678}
1679
1680impl From<&JsonbArray> for arrow_array::StringArray {
1681 fn from(array: &JsonbArray) -> Self {
1682 let mut builder =
1683 arrow_array::builder::StringBuilder::with_capacity(array.len(), array.len() * 16);
1684 for value in array.iter() {
1685 match value {
1686 Some(jsonb) => {
1687 write!(&mut builder, "{}", jsonb).unwrap();
1688 builder.append_value("");
1689 }
1690 None => builder.append_null(),
1691 }
1692 }
1693 builder.finish()
1694 }
1695}
1696
1697impl TryFrom<&arrow_array::StringArray> for JsonbArray {
1698 type Error = ArrayError;
1699
1700 fn try_from(array: &arrow_array::StringArray) -> Result<Self, Self::Error> {
1701 array
1702 .iter()
1703 .map(|o| {
1704 o.map(|s| {
1705 s.parse()
1706 .map_err(|_| ArrayError::from_arrow(format!("invalid json: {s}")))
1707 })
1708 .transpose()
1709 })
1710 .try_collect()
1711 }
1712}
1713
1714impl From<&IntervalArray> for arrow_array::StringArray {
1715 fn from(array: &IntervalArray) -> Self {
1716 let mut builder =
1717 arrow_array::builder::StringBuilder::with_capacity(array.len(), array.len() * 16);
1718 for value in array.iter() {
1719 match value {
1720 Some(interval) => {
1721 write!(&mut builder, "{}", interval).unwrap();
1722 builder.append_value("");
1723 }
1724 None => builder.append_null(),
1725 }
1726 }
1727 builder.finish()
1728 }
1729}
1730
1731impl From<&JsonbArray> for arrow_array::LargeStringArray {
1732 fn from(array: &JsonbArray) -> Self {
1733 let mut builder =
1734 arrow_array::builder::LargeStringBuilder::with_capacity(array.len(), array.len() * 16);
1735 for value in array.iter() {
1736 match value {
1737 Some(jsonb) => {
1738 write!(&mut builder, "{}", jsonb).unwrap();
1739 builder.append_value("");
1740 }
1741 None => builder.append_null(),
1742 }
1743 }
1744 builder.finish()
1745 }
1746}
1747
1748impl TryFrom<&arrow_array::LargeStringArray> for JsonbArray {
1749 type Error = ArrayError;
1750
1751 fn try_from(array: &arrow_array::LargeStringArray) -> Result<Self, Self::Error> {
1752 array
1753 .iter()
1754 .map(|o| {
1755 o.map(|s| {
1756 s.parse()
1757 .map_err(|_| ArrayError::from_arrow(format!("invalid json: {s}")))
1758 })
1759 .transpose()
1760 })
1761 .try_collect()
1762 }
1763}
1764
1765impl From<arrow_buffer::i256> for Int256 {
1766 fn from(value: arrow_buffer::i256) -> Self {
1767 let buffer = value.to_be_bytes();
1768 Int256::from_be_bytes(buffer)
1769 }
1770}
1771
1772impl<'a> From<Int256Ref<'a>> for arrow_buffer::i256 {
1773 fn from(val: Int256Ref<'a>) -> Self {
1774 let buffer = val.to_be_bytes();
1775 arrow_buffer::i256::from_be_bytes(buffer)
1776 }
1777}
1778
1779impl From<&Int256Array> for arrow_array::Decimal256Array {
1780 fn from(array: &Int256Array) -> Self {
1781 array
1782 .iter()
1783 .map(|o| o.map(arrow_buffer::i256::from))
1784 .collect()
1785 }
1786}
1787
1788impl From<&arrow_array::Decimal256Array> for Int256Array {
1789 fn from(array: &arrow_array::Decimal256Array) -> Self {
1790 let values = array.iter().map(|o| o.map(Int256::from)).collect_vec();
1791
1792 values
1793 .iter()
1794 .map(|i| i.as_ref().map(|v| v.as_scalar_ref()))
1795 .collect()
1796 }
1797}
1798
1799pub fn is_parquet_field_match_source_schema(
1807 arrow_field: &arrow_schema::Field,
1808 rw_data_type: &crate::types::DataType,
1809) -> bool {
1810 use arrow_schema::extension::ExtensionType as _;
1811
1812 if arrow_field.extension_type_name() == Some(parquet_variant_compute::VariantType::NAME) {
1817 return matches!(arrow_field.data_type(), arrow_schema::DataType::Struct(_))
1818 && matches!(rw_data_type, crate::types::DataType::Variant);
1819 }
1820 is_parquet_schema_match_source_schema(arrow_field.data_type(), rw_data_type)
1821}
1822
1823pub fn is_parquet_schema_match_source_schema(
1842 arrow_data_type: &arrow_schema::DataType,
1843 rw_data_type: &crate::types::DataType,
1844) -> bool {
1845 use arrow_schema::DataType as ArrowType;
1846
1847 use crate::types::{DataType as RwType, MapType, StructType};
1848
1849 match (arrow_data_type, rw_data_type) {
1850 (ArrowType::Boolean, RwType::Boolean)
1852 | (ArrowType::Int8 | ArrowType::Int16 | ArrowType::UInt8, RwType::Int16)
1853 | (ArrowType::Int32 | ArrowType::UInt16, RwType::Int32)
1854 | (ArrowType::Int64 | ArrowType::UInt32, RwType::Int64)
1855 | (ArrowType::UInt64 | ArrowType::Decimal128(_, _), RwType::Decimal)
1856 | (ArrowType::Decimal256(_, _), RwType::Int256)
1857 | (ArrowType::Float16 | ArrowType::Float32, RwType::Float32)
1858 | (ArrowType::Float64, RwType::Float64)
1859 | (ArrowType::Timestamp(_, None), RwType::Timestamp)
1860 | (ArrowType::Timestamp(_, Some(_)), RwType::Timestamptz)
1861 | (ArrowType::Date32, RwType::Date)
1862 | (
1863 ArrowType::Time32(arrow_schema::TimeUnit::Second | arrow_schema::TimeUnit::Millisecond)
1864 | ArrowType::Time64(
1865 arrow_schema::TimeUnit::Microsecond | arrow_schema::TimeUnit::Nanosecond,
1866 ),
1867 RwType::Time,
1868 )
1869 | (ArrowType::Interval(arrow_schema::IntervalUnit::MonthDayNano), RwType::Interval)
1870 | (ArrowType::Utf8 | ArrowType::LargeUtf8 | ArrowType::Utf8View, RwType::Varchar)
1871 | (
1872 ArrowType::Binary | ArrowType::LargeBinary | ArrowType::FixedSizeBinary(_),
1873 RwType::Bytea,
1874 ) => true,
1875
1876 (ArrowType::Struct(arrow_fields), RwType::Struct(rw_struct)) => {
1880 if arrow_fields.len() < rw_struct.len() {
1881 return false;
1882 }
1883 for (rw_name, rw_ty) in rw_struct.iter() {
1884 let mut candidates = arrow_fields.iter().filter(|f| f.name() == rw_name);
1885 let Some(arrow_field) = candidates.next() else {
1886 return false;
1887 };
1888 if candidates.next().is_some() {
1891 return false;
1892 }
1893 if !is_parquet_field_match_source_schema(arrow_field, rw_ty) {
1894 return false;
1895 }
1896 }
1897 true
1898 }
1899 (ArrowType::List(arrow_field), RwType::List(rw_list_ty)) => {
1902 is_parquet_field_match_source_schema(arrow_field, rw_list_ty.elem())
1903 }
1904 (ArrowType::Map(arrow_field, _), RwType::Map(rw_map_ty)) => {
1908 if let ArrowType::Struct(fields) = arrow_field.data_type() {
1909 if fields.len() != 2 {
1910 return false;
1911 }
1912 let key_field = &fields[0];
1913 let value_field = &fields[1];
1914 if key_field.name() != "key" || value_field.name() != "value" {
1915 return false;
1916 }
1917 let (rw_key_ty, rw_value_ty) = (rw_map_ty.key(), rw_map_ty.value());
1918 is_parquet_field_match_source_schema(key_field, rw_key_ty)
1919 && is_parquet_field_match_source_schema(value_field, rw_value_ty)
1920 } else {
1921 false
1922 }
1923 }
1924 _ => false,
1926 }
1927}
1928#[cfg(test)]
1929mod tests {
1930
1931 use arrow_schema::{DataType as ArrowType, Field as ArrowField};
1932
1933 use super::*;
1934 use crate::array::arrow::IcebergArrowConvert;
1935 use crate::types::{DataType as RwType, MapType, StructType};
1936
1937 struct Dummy;
1939 impl FromArrow for Dummy {}
1940
1941 fn variant_field(name: &str) -> ArrowField {
1942 use std::collections::HashMap;
1943 ArrowField::new(
1944 name,
1945 ArrowType::Struct(
1946 vec![
1947 ArrowField::new("metadata", ArrowType::Binary, false),
1948 ArrowField::new("value", ArrowType::Binary, true),
1949 ]
1950 .into(),
1951 ),
1952 true,
1953 )
1954 .with_metadata(HashMap::from([(
1955 "ARROW:extension:name".to_owned(),
1956 "arrow.parquet.variant".to_owned(),
1957 )]))
1958 }
1959
1960 #[test]
1961 fn test_variant_field_schema_match() {
1962 let variant = variant_field("v");
1963
1964 assert!(is_parquet_field_match_source_schema(
1965 &variant,
1966 &RwType::Variant
1967 ));
1968 assert!(!is_parquet_schema_match_source_schema(
1969 variant.data_type(),
1970 &RwType::Variant
1971 ));
1972 let rw_physical = RwType::Struct(StructType::new(vec![
1975 ("metadata".to_owned(), RwType::Bytea),
1976 ("value".to_owned(), RwType::Bytea),
1977 ]));
1978 assert!(!is_parquet_field_match_source_schema(
1979 &variant,
1980 &rw_physical
1981 ));
1982
1983 let arrow_struct = ArrowField::new(
1985 "s",
1986 ArrowType::Struct(vec![variant_field("v")].into()),
1987 true,
1988 );
1989 let rw_struct = RwType::Struct(StructType::new(vec![("v".to_owned(), RwType::Variant)]));
1990 assert!(is_parquet_field_match_source_schema(
1991 &arrow_struct,
1992 &rw_struct
1993 ));
1994
1995 let arrow_list = ArrowField::new(
1996 "l",
1997 ArrowType::List(Arc::new(variant_field("element"))),
1998 true,
1999 );
2000 assert!(is_parquet_field_match_source_schema(
2001 &arrow_list,
2002 &RwType::list(RwType::Variant)
2003 ));
2004
2005 let arrow_map = ArrowField::new(
2006 "m",
2007 ArrowType::Map(
2008 Arc::new(ArrowField::new(
2009 "entries",
2010 ArrowType::Struct(
2011 vec![
2012 ArrowField::new("key", ArrowType::Utf8, false),
2013 variant_field("value"),
2014 ]
2015 .into(),
2016 ),
2017 false,
2018 )),
2019 false,
2020 ),
2021 true,
2022 );
2023 assert!(is_parquet_field_match_source_schema(
2024 &arrow_map,
2025 &RwType::Map(MapType::from_kv(RwType::Varchar, RwType::Variant))
2026 ));
2027 }
2028
2029 #[test]
2030 fn test_variant_ext_under_list_map_rejects_physical_struct() {
2031 let physical = RwType::Struct(StructType::new(vec![
2032 ("metadata".to_owned(), RwType::Bytea),
2033 ("value".to_owned(), RwType::Bytea),
2034 ]));
2035
2036 let list_field = ArrowField::new(
2040 "l",
2041 ArrowType::List(Arc::new(variant_field("element"))),
2042 true,
2043 );
2044 assert!(!is_parquet_field_match_source_schema(
2045 &list_field,
2046 &RwType::list(physical.clone())
2047 ));
2048 assert!(is_parquet_field_match_source_schema(
2049 &list_field,
2050 &RwType::list(RwType::Variant)
2051 ));
2052
2053 let map_field = ArrowField::new(
2055 "m",
2056 ArrowType::Map(
2057 Arc::new(ArrowField::new(
2058 "entries",
2059 ArrowType::Struct(
2060 vec![
2061 ArrowField::new("key", ArrowType::Utf8, false),
2062 variant_field("value"),
2063 ]
2064 .into(),
2065 ),
2066 false,
2067 )),
2068 false,
2069 ),
2070 true,
2071 );
2072 assert!(!is_parquet_field_match_source_schema(
2073 &map_field,
2074 &RwType::Map(MapType::from_kv(RwType::Varchar, physical))
2075 ));
2076 assert!(is_parquet_field_match_source_schema(
2077 &map_field,
2078 &RwType::Map(MapType::from_kv(RwType::Varchar, RwType::Variant))
2079 ));
2080 }
2081
2082 #[test]
2083 fn test_variant_ext_nested_under_list_rejects_physical_struct() {
2084 let list_field = ArrowField::new(
2086 "l",
2087 ArrowType::List(Arc::new(ArrowField::new(
2088 "element",
2089 ArrowType::Struct(vec![variant_field("v")].into()),
2090 true,
2091 ))),
2092 true,
2093 );
2094 let physical = RwType::Struct(StructType::new(vec![
2095 ("metadata".to_owned(), RwType::Bytea),
2096 ("value".to_owned(), RwType::Bytea),
2097 ]));
2098 let elem_physical = RwType::Struct(StructType::new(vec![("v".to_owned(), physical)]));
2099 assert!(!is_parquet_field_match_source_schema(
2100 &list_field,
2101 &RwType::list(elem_physical)
2102 ));
2103 let elem_variant = RwType::Struct(StructType::new(vec![("v".to_owned(), RwType::Variant)]));
2104 assert!(is_parquet_field_match_source_schema(
2105 &list_field,
2106 &RwType::list(elem_variant)
2107 ));
2108 }
2109
2110 #[test]
2111 fn test_variant_ext_declared_as_scalar_rejects_match() {
2112 let v = variant_field("v");
2114 assert!(!is_parquet_field_match_source_schema(&v, &RwType::Varchar));
2115 assert!(!is_parquet_field_match_source_schema(&v, &RwType::Bytea));
2116 assert!(is_parquet_field_match_source_schema(&v, &RwType::Variant));
2117 }
2118
2119 #[test]
2120 fn test_nested_struct_reorder_and_superset_decode_by_declared() {
2121 let inner: arrow_array::ArrayRef = Arc::new(arrow_array::StructArray::from(vec![
2123 (
2124 Arc::new(ArrowField::new("b", ArrowType::Utf8, true)),
2125 Arc::new(arrow_array::StringArray::from(vec![Some("x")])) as arrow_array::ArrayRef,
2126 ),
2127 (
2128 Arc::new(ArrowField::new("a", ArrowType::Int32, true)),
2129 Arc::new(arrow_array::Int32Array::from(vec![Some(1)])) as arrow_array::ArrayRef,
2130 ),
2131 (
2132 Arc::new(ArrowField::new("c", ArrowType::Int32, true)),
2133 Arc::new(arrow_array::Int32Array::from(vec![Some(9)])) as arrow_array::ArrayRef,
2134 ),
2135 ]));
2136 let st: arrow_array::ArrayRef = Arc::new(arrow_array::StructArray::from(vec![(
2137 Arc::new(ArrowField::new("inner", inner.data_type().clone(), true)),
2138 inner,
2139 )]));
2140
2141 let declared_field = ArrowField::new(
2142 "st",
2143 ArrowType::Struct(
2144 vec![ArrowField::new(
2145 "inner",
2146 ArrowType::Struct(
2147 vec![
2148 ArrowField::new("a", ArrowType::Int32, true),
2149 ArrowField::new("b", ArrowType::Utf8, true),
2150 ]
2151 .into(),
2152 ),
2153 true,
2154 )]
2155 .into(),
2156 ),
2157 true,
2158 );
2159 let converted = IcebergArrowConvert
2160 .array_from_arrow_array(&declared_field, &st)
2161 .unwrap();
2162
2163 assert_eq!(
2164 converted.data_type(),
2165 RwType::Struct(StructType::new(vec![(
2166 "inner",
2167 RwType::Struct(StructType::new(vec![
2168 ("a", RwType::Int32),
2169 ("b", RwType::Varchar),
2170 ])),
2171 )])),
2172 );
2173 let ArrayImpl::Struct(s) = &converted else {
2174 panic!("expected RW struct");
2175 };
2176 assert_eq!(
2177 s.value_at(0).unwrap().to_owned_scalar(),
2178 StructValue::new(vec![Some(ScalarImpl::Struct(StructValue::new(vec![
2179 Some(ScalarImpl::Int32(1)),
2180 Some(ScalarImpl::Utf8("x".into())),
2181 ])))]),
2182 );
2183 }
2184
2185 #[test]
2186 fn test_variant_ext_grandchild_decodes_as_physical_struct() {
2187 let v_child: arrow_array::ArrayRef = Arc::new(arrow_array::StructArray::from(vec![
2189 (
2190 Arc::new(ArrowField::new("metadata", ArrowType::Binary, false)),
2191 Arc::new(arrow_array::BinaryArray::from_iter_values([
2192 &[1_u8, 0, 0][..]
2193 ])) as arrow_array::ArrayRef,
2194 ),
2195 (
2196 Arc::new(ArrowField::new("value", ArrowType::Binary, true)),
2197 Arc::new(arrow_array::BinaryArray::from_iter_values([&[9_u8][..]]))
2198 as arrow_array::ArrayRef,
2199 ),
2200 ]));
2201 let mid: arrow_array::ArrayRef = Arc::new(arrow_array::StructArray::from(vec![(
2202 Arc::new(variant_field("v")),
2203 v_child,
2204 )]));
2205 let s: arrow_array::ArrayRef = Arc::new(arrow_array::StructArray::from(vec![(
2206 Arc::new(ArrowField::new("mid", mid.data_type().clone(), true)),
2207 mid,
2208 )]));
2209
2210 let declared = RwType::Struct(StructType::new(vec![(
2212 "mid".to_owned(),
2213 RwType::Struct(StructType::new(vec![(
2214 "v".to_owned(),
2215 RwType::Struct(StructType::new(vec![
2216 ("metadata".to_owned(), RwType::Bytea),
2217 ("value".to_owned(), RwType::Bytea),
2218 ])),
2219 )])),
2220 )]));
2221 let declared_field = IcebergArrowConvert.to_arrow_field("s", &declared).unwrap();
2222
2223 let converted = IcebergArrowConvert
2224 .array_from_arrow_array(&declared_field, &s)
2225 .unwrap();
2226 assert_eq!(
2228 converted.data_type(),
2229 RwType::Struct(StructType::new(vec![(
2230 "mid",
2231 RwType::Struct(StructType::new(vec![(
2232 "v",
2233 RwType::Struct(StructType::new(vec![
2234 ("metadata", RwType::Bytea),
2235 ("value", RwType::Bytea),
2236 ])),
2237 )])),
2238 )])),
2239 );
2240 }
2241
2242 #[test]
2243 fn test_struct_schema_match() {
2244 let arrow_struct = ArrowType::Struct(
2247 vec![
2248 ArrowField::new("f1", ArrowType::Float64, true),
2249 ArrowField::new("f2", ArrowType::Utf8, true),
2250 ]
2251 .into(),
2252 );
2253 let rw_struct = RwType::Struct(StructType::new(vec![
2255 ("f1".to_owned(), RwType::Float64),
2256 ("f2".to_owned(), RwType::Varchar),
2257 ]));
2258 assert!(is_parquet_schema_match_source_schema(
2259 &arrow_struct,
2260 &rw_struct
2261 ));
2262
2263 let arrow_struct_superset = ArrowType::Struct(
2265 vec![
2266 ArrowField::new("f1", ArrowType::Float64, true),
2267 ArrowField::new("f2", ArrowType::Utf8, true),
2268 ArrowField::new("f3", ArrowType::Int32, true),
2269 ]
2270 .into(),
2271 );
2272 assert!(is_parquet_schema_match_source_schema(
2273 &arrow_struct_superset,
2274 &rw_struct
2275 ));
2276
2277 let arrow_struct_reordered = ArrowType::Struct(
2279 vec![
2280 ArrowField::new("f2", ArrowType::Utf8, true),
2281 ArrowField::new("f1", ArrowType::Float64, true),
2282 ]
2283 .into(),
2284 );
2285 assert!(is_parquet_schema_match_source_schema(
2286 &arrow_struct_reordered,
2287 &rw_struct
2288 ));
2289
2290 let arrow_struct2 = ArrowType::Struct(
2292 vec![
2293 ArrowField::new("f1", ArrowType::Float64, true),
2294 ArrowField::new("f3", ArrowType::Utf8, true),
2295 ]
2296 .into(),
2297 );
2298 assert!(!is_parquet_schema_match_source_schema(
2299 &arrow_struct2,
2300 &rw_struct
2301 ));
2302 }
2303
2304 #[test]
2305 fn test_struct_duplicate_sibling_names_reject_match() {
2306 let rw_struct = RwType::Struct(StructType::new(vec![("f1".to_owned(), RwType::Float64)]));
2307
2308 for dup_type in [ArrowType::Float64, ArrowType::Utf8] {
2311 let arrow_struct = ArrowType::Struct(
2312 vec![
2313 ArrowField::new("f1", ArrowType::Float64, true),
2314 ArrowField::new("f1", dup_type, true),
2315 ]
2316 .into(),
2317 );
2318 assert!(!is_parquet_schema_match_source_schema(
2319 &arrow_struct,
2320 &rw_struct
2321 ));
2322 }
2323
2324 let arrow_struct = ArrowType::Struct(
2326 vec![
2327 ArrowField::new("f1", ArrowType::Float64, true),
2328 ArrowField::new("extra", ArrowType::Int32, true),
2329 ArrowField::new("extra", ArrowType::Utf8, true),
2330 ]
2331 .into(),
2332 );
2333 assert!(is_parquet_schema_match_source_schema(
2334 &arrow_struct,
2335 &rw_struct
2336 ));
2337 }
2338
2339 #[test]
2340 fn test_struct_projection_from_arrow() {
2341 use itertools::Itertools;
2342
2343 let actual_fields: arrow_schema::Fields = vec![
2345 ArrowField::new("foo", ArrowType::Int32, true),
2346 ArrowField::new("bar", ArrowType::Utf8, true),
2347 ArrowField::new("baz", ArrowType::Int32, true),
2348 ]
2349 .into();
2350 let foo: arrow_array::ArrayRef =
2351 Arc::new(arrow_array::Int32Array::from(vec![Some(10), Some(20)]));
2352 let bar: arrow_array::ArrayRef =
2353 Arc::new(arrow_array::StringArray::from(vec![Some("a"), Some("b")]));
2354 let baz: arrow_array::ArrayRef =
2355 Arc::new(arrow_array::Int32Array::from(vec![Some(100), Some(200)]));
2356 let actual_struct = arrow_array::StructArray::new(actual_fields, vec![foo, bar, baz], None);
2357 let actual_struct_ref: arrow_array::ArrayRef = Arc::new(actual_struct);
2358
2359 let expected_field = ArrowField::new(
2361 "s",
2362 ArrowType::Struct(
2363 vec![
2364 ArrowField::new("foo", ArrowType::Int32, true),
2365 ArrowField::new("bar", ArrowType::Utf8, true),
2366 ]
2367 .into(),
2368 ),
2369 true,
2370 );
2371
2372 let array_impl = Dummy
2373 .from_array(&expected_field, &actual_struct_ref)
2374 .unwrap();
2375
2376 let ArrayImpl::Struct(s) = array_impl else {
2377 panic!("expected RW StructArray");
2378 };
2379
2380 let DataType::Struct(st) = s.data_type() else {
2381 panic!("expected RW struct type");
2382 };
2383 assert_eq!(st.len(), 2);
2384 assert_eq!(st.iter().map(|(n, _)| n).collect_vec(), vec!["foo", "bar"]);
2385
2386 let v0 = s.value_at(0).unwrap().to_owned_scalar();
2387 let v1 = s.value_at(1).unwrap().to_owned_scalar();
2388 assert_eq!(
2389 v0,
2390 StructValue::new(vec![
2391 Some(ScalarImpl::Int32(10)),
2392 Some(ScalarImpl::Utf8("a".into()))
2393 ])
2394 );
2395 assert_eq!(
2396 v1,
2397 StructValue::new(vec![
2398 Some(ScalarImpl::Int32(20)),
2399 Some(ScalarImpl::Utf8("b".into()))
2400 ])
2401 );
2402 }
2403
2404 fn build_list_of_struct(
2406 elem_fields: arrow_schema::Fields,
2407 columns: Vec<arrow_array::ArrayRef>,
2408 ) -> arrow_array::ArrayRef {
2409 use std::sync::Arc;
2410 let elem_struct = arrow_array::StructArray::new(elem_fields.clone(), columns, None);
2411 Arc::new(arrow_array::ListArray::new(
2412 Arc::new(ArrowField::new(
2413 "element",
2414 ArrowType::Struct(elem_fields),
2415 true,
2416 )),
2417 arrow_buffer::OffsetBuffer::new(vec![0, 2].into()),
2418 Arc::new(elem_struct),
2419 None,
2420 ))
2421 }
2422
2423 #[test]
2424 fn test_list_element_struct_decodes_by_declared_field() {
2425 let file_array = build_list_of_struct(
2428 vec![
2429 ArrowField::new("b", ArrowType::Utf8, true),
2430 ArrowField::new("a", ArrowType::Int32, true),
2431 ArrowField::new("extra", ArrowType::Int32, true),
2432 ]
2433 .into(),
2434 vec![
2435 Arc::new(arrow_array::StringArray::from(vec![Some("x"), Some("y")])),
2436 Arc::new(arrow_array::Int32Array::from(vec![Some(1), Some(2)])),
2437 Arc::new(arrow_array::Int32Array::from(vec![Some(9), Some(8)])),
2438 ],
2439 );
2440 let declared_elem: arrow_schema::Fields = vec![
2442 ArrowField::new("a", ArrowType::Int32, true),
2443 ArrowField::new("b", ArrowType::Utf8, true),
2444 ]
2445 .into();
2446 let declared_field = ArrowField::new(
2447 "l",
2448 ArrowType::List(Arc::new(ArrowField::new(
2449 "element",
2450 ArrowType::Struct(declared_elem),
2451 true,
2452 ))),
2453 true,
2454 );
2455
2456 let converted = Dummy.from_array(&declared_field, &file_array).unwrap();
2457 assert_eq!(
2458 converted.data_type(),
2459 RwType::list(RwType::Struct(StructType::new(vec![
2460 ("a", RwType::Int32),
2461 ("b", RwType::Varchar),
2462 ])))
2463 );
2464 let ArrayImpl::List(list) = &converted else {
2465 panic!("expected list array");
2466 };
2467 let ArrayImpl::Struct(elems) = list.values() else {
2468 panic!("expected struct elements");
2469 };
2470 assert_eq!(
2471 elems.value_at(0).unwrap().to_owned_scalar(),
2472 StructValue::new(vec![
2473 Some(ScalarImpl::Int32(1)),
2474 Some(ScalarImpl::Utf8("x".into())),
2475 ])
2476 );
2477 assert_eq!(
2478 elems.value_at(1).unwrap().to_owned_scalar(),
2479 StructValue::new(vec![
2480 Some(ScalarImpl::Int32(2)),
2481 Some(ScalarImpl::Utf8("y".into())),
2482 ])
2483 );
2484 }
2485
2486 fn decode_struct(
2488 declared_fields: Vec<arrow_schema::Field>,
2489 actual: arrow_array::StructArray,
2490 ) -> Result<ArrayImpl, ArrayError> {
2491 let declared = ArrowField::new("s", ArrowType::Struct(declared_fields.into()), true);
2492 let array: arrow_array::ArrayRef = Arc::new(actual);
2493 Dummy.from_array(&declared, &array)
2494 }
2495
2496 #[test]
2497 fn test_struct_name_mismatch_same_arity_decodes_positionally() {
2498 let actual_fields: arrow_schema::Fields = vec![
2501 ArrowField::new("total", ArrowType::Int32, true),
2502 ArrowField::new("count", ArrowType::Utf8, true),
2503 ]
2504 .into();
2505 let array = arrow_array::StructArray::new(
2506 actual_fields,
2507 vec![
2508 Arc::new(arrow_array::Int32Array::from(vec![Some(42)])),
2509 Arc::new(arrow_array::StringArray::from(vec![Some("x")])),
2510 ],
2511 None,
2512 );
2513
2514 let converted = decode_struct(
2515 vec![
2516 ArrowField::new("sum", ArrowType::Int32, true),
2517 ArrowField::new("cnt", ArrowType::Utf8, true),
2518 ],
2519 array,
2520 )
2521 .unwrap();
2522 assert_eq!(
2523 converted.data_type(),
2524 RwType::Struct(StructType::new(vec![
2525 ("sum", RwType::Int32),
2526 ("cnt", RwType::Varchar),
2527 ]))
2528 );
2529 let ArrayImpl::Struct(structs) = &converted else {
2530 panic!("expected struct array");
2531 };
2532 assert_eq!(
2533 structs.value_at(0).unwrap().to_owned_scalar(),
2534 StructValue::new(vec![
2535 Some(ScalarImpl::Int32(42)),
2536 Some(ScalarImpl::Utf8("x".into())),
2537 ])
2538 );
2539 }
2540
2541 #[test]
2542 fn test_struct_unalignable_fields_error() {
2543 let array = arrow_array::StructArray::new(
2546 vec![ArrowField::new("a", ArrowType::Int32, true)].into(),
2547 vec![Arc::new(arrow_array::Int32Array::from(vec![Some(1)]))],
2548 None,
2549 );
2550
2551 let err = decode_struct(
2552 vec![
2553 ArrowField::new("a", ArrowType::Int32, true),
2554 ArrowField::new("b", ArrowType::Utf8, true),
2555 ],
2556 array,
2557 )
2558 .unwrap_err();
2559 assert!(
2560 err.to_string()
2561 .contains("unable to align struct fields: expected [a, b], actual [a]"),
2562 "unexpected error: {err}"
2563 );
2564 }
2565
2566 #[test]
2567 fn test_struct_child_type_divergence_stamped_honestly() {
2568 let array = arrow_array::StructArray::new(
2571 vec![ArrowField::new("a", ArrowType::Utf8, true)].into(),
2572 vec![Arc::new(arrow_array::StringArray::from(vec![Some("oops")]))],
2573 None,
2574 );
2575
2576 let converted =
2577 decode_struct(vec![ArrowField::new("a", ArrowType::Int64, true)], array).unwrap();
2578 assert_eq!(
2579 converted.data_type(),
2580 RwType::Struct(StructType::new(vec![("a", RwType::Varchar)]))
2581 );
2582 }
2583
2584 #[test]
2585 fn test_struct_child_decodes_despite_lossy_expected_field() {
2586 let array = arrow_array::StructArray::new(
2590 vec![ArrowField::new("a", ArrowType::Int16, true)].into(),
2591 vec![Arc::new(arrow_array::Int16Array::from(vec![
2592 Some(7),
2593 Some(-3),
2594 ]))],
2595 None,
2596 );
2597
2598 let converted =
2599 decode_struct(vec![ArrowField::new("a", ArrowType::Int32, true)], array).unwrap();
2600 assert_eq!(
2601 converted.data_type(),
2602 RwType::Struct(StructType::new(vec![("a", RwType::Int16)]))
2603 );
2604 let ArrayImpl::Struct(structs) = &converted else {
2605 panic!("expected struct array");
2606 };
2607 assert_eq!(
2608 structs.value_at(0).unwrap().to_owned_scalar(),
2609 StructValue::new(vec![Some(ScalarImpl::Int16(7))])
2610 );
2611 }
2612
2613 #[test]
2614 fn test_struct_duplicate_sibling_names_decode_first_occurrence() {
2615 let actual_fields: arrow_schema::Fields = vec![
2618 ArrowField::new("a", ArrowType::Int32, true),
2619 ArrowField::new("a", ArrowType::Utf8, true),
2620 ArrowField::new("b", ArrowType::Utf8, true),
2621 ]
2622 .into();
2623 let array = arrow_array::StructArray::new(
2624 actual_fields,
2625 vec![
2626 Arc::new(arrow_array::Int32Array::from(vec![Some(1)])),
2627 Arc::new(arrow_array::StringArray::from(vec![Some("dup")])),
2628 Arc::new(arrow_array::StringArray::from(vec![Some("x")])),
2629 ],
2630 None,
2631 );
2632
2633 let converted = decode_struct(
2634 vec![
2635 ArrowField::new("a", ArrowType::Int32, true),
2636 ArrowField::new("b", ArrowType::Utf8, true),
2637 ],
2638 array,
2639 )
2640 .unwrap();
2641 let ArrayImpl::Struct(structs) = &converted else {
2642 panic!("expected struct array");
2643 };
2644 assert_eq!(
2645 structs.value_at(0).unwrap().to_owned_scalar(),
2646 StructValue::new(vec![
2647 Some(ScalarImpl::Int32(1)),
2648 Some(ScalarImpl::Utf8("x".into())),
2649 ])
2650 );
2651 }
2652
2653 #[test]
2654 fn test_extension_decode_follows_declared_field_under_list() {
2655 let json_meta: std::collections::HashMap<String, String> = [(
2656 "ARROW:extension:name".to_owned(),
2657 "arrowudf.json".to_owned(),
2658 )]
2659 .into();
2660 let strings: arrow_array::ArrayRef = Arc::new(arrow_array::StringArray::from(vec![
2661 Some(r#"{"k":1}"#),
2662 Some("2"),
2663 ]));
2664 let make_list = |elem_field: ArrowField, values: arrow_array::ArrayRef| {
2665 Arc::new(arrow_array::ListArray::new(
2666 Arc::new(elem_field),
2667 arrow_buffer::OffsetBuffer::new(vec![0, 2].into()),
2668 values,
2669 None,
2670 )) as arrow_array::ArrayRef
2671 };
2672 let plain_elem = ArrowField::new("element", ArrowType::Utf8, true);
2673 let json_elem = plain_elem.clone().with_metadata(json_meta);
2674
2675 let file_json = make_list(json_elem.clone(), strings.clone());
2677 let declared_plain =
2678 ArrowField::new("l", ArrowType::List(Arc::new(plain_elem.clone())), true);
2679 let converted = Dummy.from_array(&declared_plain, &file_json).unwrap();
2680 assert_eq!(converted.data_type(), RwType::list(RwType::Varchar));
2681
2682 let file_plain = make_list(plain_elem, strings);
2684 let declared_json = ArrowField::new("l", ArrowType::List(Arc::new(json_elem)), true);
2685 let converted = Dummy.from_array(&declared_json, &file_plain).unwrap();
2686 assert_eq!(converted.data_type(), RwType::list(RwType::Jsonb));
2687 }
2688
2689 #[test]
2690 fn test_map_value_struct_decodes_by_declared_field() {
2691 let value_fields: arrow_schema::Fields = vec![
2694 ArrowField::new("y", ArrowType::Int32, true),
2695 ArrowField::new("x", ArrowType::Int32, true),
2696 ]
2697 .into();
2698 let entries_fields: arrow_schema::Fields = vec![
2699 ArrowField::new("key", ArrowType::Utf8, false),
2700 ArrowField::new("value", ArrowType::Struct(value_fields.clone()), true),
2701 ]
2702 .into();
2703 let value_struct = arrow_array::StructArray::new(
2704 value_fields,
2705 vec![
2706 Arc::new(arrow_array::Int32Array::from(vec![Some(7)])),
2707 Arc::new(arrow_array::Int32Array::from(vec![Some(42)])),
2708 ],
2709 None,
2710 );
2711 let entries = arrow_array::StructArray::new(
2712 entries_fields.clone(),
2713 vec![
2714 Arc::new(arrow_array::StringArray::from(vec![Some("k")])),
2715 Arc::new(value_struct),
2716 ],
2717 None,
2718 );
2719 let file_map: arrow_array::ArrayRef = Arc::new(arrow_array::MapArray::new(
2720 Arc::new(ArrowField::new(
2721 "entries",
2722 ArrowType::Struct(entries_fields),
2723 false,
2724 )),
2725 arrow_buffer::OffsetBuffer::new(vec![0, 1].into()),
2726 entries,
2727 None,
2728 false,
2729 ));
2730
2731 let declared_value =
2732 ArrowType::Struct(vec![ArrowField::new("x", ArrowType::Int32, true)].into());
2733 let declared_field = ArrowField::new(
2734 "m",
2735 ArrowType::Map(
2736 Arc::new(ArrowField::new(
2737 "entries",
2738 ArrowType::Struct(
2739 vec![
2740 ArrowField::new("key", ArrowType::Utf8, false),
2741 ArrowField::new("value", declared_value, true),
2742 ]
2743 .into(),
2744 ),
2745 false,
2746 )),
2747 false,
2748 ),
2749 true,
2750 );
2751
2752 let converted = Dummy.from_array(&declared_field, &file_map).unwrap();
2753 assert_eq!(
2754 converted.data_type(),
2755 RwType::Map(MapType::from_kv(
2756 RwType::Varchar,
2757 RwType::Struct(StructType::new(vec![("x", RwType::Int32)])),
2758 ))
2759 );
2760 let ArrayImpl::Map(map) = &converted else {
2761 panic!("expected map array");
2762 };
2763 let ArrayImpl::Struct(entries) = map.inner.values() else {
2764 panic!("expected struct entries");
2765 };
2766 assert_eq!(
2767 entries.value_at(0).unwrap().to_owned_scalar(),
2768 StructValue::new(vec![
2769 Some(ScalarImpl::Utf8("k".into())),
2770 Some(ScalarImpl::Struct(StructValue::new(vec![Some(
2771 ScalarImpl::Int32(42)
2772 )]))),
2773 ])
2774 );
2775 }
2776
2777 #[test]
2778 fn test_map_invalid_key_type_errors() {
2779 let entries_fields: arrow_schema::Fields = vec![
2782 ArrowField::new("key", ArrowType::Float64, false),
2783 ArrowField::new("value", ArrowType::Int32, true),
2784 ]
2785 .into();
2786 let entries = arrow_array::StructArray::new(
2787 entries_fields.clone(),
2788 vec![
2789 Arc::new(arrow_array::Float64Array::from(vec![Some(1.5)])),
2790 Arc::new(arrow_array::Int32Array::from(vec![Some(42)])),
2791 ],
2792 None,
2793 );
2794 let entries_field = Arc::new(ArrowField::new(
2795 "entries",
2796 ArrowType::Struct(entries_fields),
2797 false,
2798 ));
2799 let file_map: arrow_array::ArrayRef = Arc::new(arrow_array::MapArray::new(
2800 entries_field.clone(),
2801 arrow_buffer::OffsetBuffer::new(vec![0, 1].into()),
2802 entries,
2803 None,
2804 false,
2805 ));
2806 let field = ArrowField::new("m", ArrowType::Map(entries_field, false), true);
2807
2808 let err = Dummy.from_array(&field, &file_map).unwrap_err();
2809 assert!(
2810 err.to_string().contains("invalid map key type"),
2811 "unexpected error: {err}"
2812 );
2813 }
2814
2815 #[test]
2816 fn test_list_schema_match() {
2817 let arrow_list =
2819 ArrowType::List(Box::new(ArrowField::new("item", ArrowType::Float64, true)).into());
2820 let rw_list = RwType::Float64.list();
2822 assert!(is_parquet_schema_match_source_schema(&arrow_list, &rw_list));
2823
2824 let rw_list2 = RwType::Int32.list();
2825 assert!(!is_parquet_schema_match_source_schema(
2826 &arrow_list,
2827 &rw_list2
2828 ));
2829 }
2830
2831 #[test]
2832 fn test_map_schema_match() {
2833 let arrow_map = ArrowType::Map(
2835 Arc::new(ArrowField::new(
2836 "entries",
2837 ArrowType::Struct(
2838 vec![
2839 ArrowField::new("key", ArrowType::Utf8, false),
2840 ArrowField::new("value", ArrowType::Int32, true),
2841 ]
2842 .into(),
2843 ),
2844 false,
2845 )),
2846 false,
2847 );
2848 let rw_map = RwType::Map(MapType::from_kv(RwType::Varchar, RwType::Int32));
2850 assert!(is_parquet_schema_match_source_schema(&arrow_map, &rw_map));
2851
2852 let rw_map2 = RwType::Map(MapType::from_kv(RwType::Int32, RwType::Int32));
2854 assert!(!is_parquet_schema_match_source_schema(&arrow_map, &rw_map2));
2855
2856 let rw_map3 = RwType::Map(MapType::from_kv(RwType::Varchar, RwType::Float64));
2858 assert!(!is_parquet_schema_match_source_schema(&arrow_map, &rw_map3));
2859
2860 let arrow_map2 = ArrowType::Map(
2862 Arc::new(ArrowField::new(
2863 "entries",
2864 ArrowType::Struct(
2865 vec![
2866 ArrowField::new("k", ArrowType::Utf8, false),
2867 ArrowField::new("value", ArrowType::Int32, true),
2868 ]
2869 .into(),
2870 ),
2871 false,
2872 )),
2873 false,
2874 );
2875 assert!(!is_parquet_schema_match_source_schema(&arrow_map2, &rw_map));
2876 }
2877
2878 #[test]
2879 fn bool() {
2880 let array = BoolArray::from_iter([None, Some(false), Some(true)]);
2881 let arrow = arrow_array::BooleanArray::from(&array);
2882 assert_eq!(BoolArray::from(&arrow), array);
2883 }
2884
2885 #[test]
2886 fn i16() {
2887 let array = I16Array::from_iter([None, Some(-7), Some(25)]);
2888 let arrow = arrow_array::Int16Array::from(&array);
2889 assert_eq!(I16Array::from(&arrow), array);
2890 }
2891
2892 #[test]
2893 fn i32() {
2894 let array = I32Array::from_iter([None, Some(-7), Some(25)]);
2895 let arrow = arrow_array::Int32Array::from(&array);
2896 assert_eq!(I32Array::from(&arrow), array);
2897 }
2898
2899 #[test]
2900 fn i64() {
2901 let array = I64Array::from_iter([None, Some(-7), Some(25)]);
2902 let arrow = arrow_array::Int64Array::from(&array);
2903 assert_eq!(I64Array::from(&arrow), array);
2904 }
2905
2906 #[test]
2907 fn f32() {
2908 let array = F32Array::from_iter([None, Some(-7.0), Some(25.0)]);
2909 let arrow = arrow_array::Float32Array::from(&array);
2910 assert_eq!(F32Array::from(&arrow), array);
2911 }
2912
2913 #[test]
2914 fn f64() {
2915 let array = F64Array::from_iter([None, Some(-7.0), Some(25.0)]);
2916 let arrow = arrow_array::Float64Array::from(&array);
2917 assert_eq!(F64Array::from(&arrow), array);
2918 }
2919
2920 #[test]
2921 fn int8() {
2922 let array: PrimitiveArray<i16> = I16Array::from_iter([None, Some(-128), Some(127)]);
2923 let arr = arrow_array::Int8Array::from(vec![None, Some(-128), Some(127)]);
2924 let converted: PrimitiveArray<i16> = (&arr).into();
2925 assert_eq!(converted, array);
2926 }
2927
2928 #[test]
2929 fn uint8() {
2930 let array: PrimitiveArray<i16> = I16Array::from_iter([None, Some(7), Some(25)]);
2931 let arr = arrow_array::UInt8Array::from(vec![None, Some(7), Some(25)]);
2932 let converted: PrimitiveArray<i16> = (&arr).into();
2933 assert_eq!(converted, array);
2934 }
2935
2936 #[test]
2937 fn uint16() {
2938 let array: PrimitiveArray<i32> = I32Array::from_iter([None, Some(7), Some(65535)]);
2939 let arr = arrow_array::UInt16Array::from(vec![None, Some(7), Some(65535)]);
2940 let converted: PrimitiveArray<i32> = (&arr).into();
2941 assert_eq!(converted, array);
2942 }
2943
2944 #[test]
2945 fn uint32() {
2946 let array: PrimitiveArray<i64> = I64Array::from_iter([None, Some(7), Some(4294967295)]);
2947 let arr = arrow_array::UInt32Array::from(vec![None, Some(7), Some(4294967295)]);
2948 let converted: PrimitiveArray<i64> = (&arr).into();
2949 assert_eq!(converted, array);
2950 }
2951
2952 #[test]
2953 fn uint64() {
2954 let array: PrimitiveArray<Decimal> = DecimalArray::from_iter([
2955 None,
2956 Some(Decimal::Normalized("7".parse().unwrap())),
2957 Some(Decimal::Normalized("18446744073709551615".parse().unwrap())),
2958 ]);
2959 let arr = arrow_array::UInt64Array::from(vec![None, Some(7), Some(18446744073709551615)]);
2960 let converted: PrimitiveArray<Decimal> = (&arr).try_into().unwrap();
2961 assert_eq!(converted, array);
2962 }
2963
2964 #[test]
2965 fn date() {
2966 let array = DateArray::from_iter([
2967 None,
2968 Date::with_days_since_ce(12345).ok(),
2969 Date::with_days_since_ce(-12345).ok(),
2970 ]);
2971 let arrow = arrow_array::Date32Array::try_from(&array).unwrap();
2972 assert_eq!(DateArray::try_from(&arrow).unwrap(), array);
2973 }
2974
2975 #[test]
2976 fn time() {
2977 let array = TimeArray::from_iter([None, Time::with_micro(24 * 3600 * 1_000_000 - 1).ok()]);
2978 let arrow = arrow_array::Time64MicrosecondArray::try_from(&array).unwrap();
2979 assert_eq!(TimeArray::try_from(&arrow).unwrap(), array);
2980 }
2981
2982 #[test]
2983 fn time_arrow_units_round_trip() {
2984 let second_array = TimeArray::from_iter([
2985 None,
2986 Time::with_secs_nano(1, 0).ok(),
2987 Time::with_secs_nano(2, 0).ok(),
2988 ]);
2989 let arrow = arrow_array::Time32SecondArray::try_from(&second_array).unwrap();
2990 assert_eq!(
2991 arrow,
2992 arrow_array::Time32SecondArray::from(vec![None, Some(1), Some(2)])
2993 );
2994 assert_eq!(TimeArray::try_from(&arrow).unwrap(), second_array);
2995
2996 let millisecond_array = TimeArray::from_iter([
2997 None,
2998 Time::with_secs_nano(1, 0).ok(),
2999 Time::with_secs_nano(2, 123_000_000).ok(),
3000 ]);
3001 let arrow = arrow_array::Time32MillisecondArray::try_from(&millisecond_array).unwrap();
3002 assert_eq!(
3003 arrow,
3004 arrow_array::Time32MillisecondArray::from(vec![None, Some(1_000), Some(2_123)])
3005 );
3006 assert_eq!(TimeArray::try_from(&arrow).unwrap(), millisecond_array);
3007
3008 let microsecond_array = TimeArray::from_iter([
3009 None,
3010 Time::with_secs_nano(1, 0).ok(),
3011 Time::with_secs_nano(2, 123_456_000).ok(),
3012 ]);
3013 let arrow = arrow_array::Time64MicrosecondArray::try_from(µsecond_array).unwrap();
3014 assert_eq!(
3015 arrow,
3016 arrow_array::Time64MicrosecondArray::from(vec![None, Some(1_000_000), Some(2_123_456)])
3017 );
3018 assert_eq!(TimeArray::try_from(&arrow).unwrap(), microsecond_array);
3019
3020 let nanosecond_array = TimeArray::from_iter([
3021 None,
3022 Time::with_secs_nano(1, 0).ok(),
3023 Time::with_secs_nano(2, 123_456_000).ok(),
3024 ]);
3025 let arrow = arrow_array::Time64NanosecondArray::try_from(&nanosecond_array).unwrap();
3026 assert_eq!(
3027 arrow,
3028 arrow_array::Time64NanosecondArray::from(vec![
3029 None,
3030 Some(1_000_000_000),
3031 Some(2_123_456_000)
3032 ])
3033 );
3034 assert_eq!(TimeArray::try_from(&arrow).unwrap(), nanosecond_array);
3035 }
3036
3037 #[test]
3038 fn time_arrow_units_truncate_sub_unit_precision() {
3039 let array = TimeArray::from_iter([Time::with_secs_nano(2, 123_456_789).ok()]);
3040
3041 assert_eq!(
3042 arrow_array::Time32SecondArray::try_from(&array).unwrap(),
3043 arrow_array::Time32SecondArray::from(vec![Some(2)])
3044 );
3045 assert_eq!(
3046 arrow_array::Time32MillisecondArray::try_from(&array).unwrap(),
3047 arrow_array::Time32MillisecondArray::from(vec![Some(2_123)])
3048 );
3049 assert_eq!(
3050 arrow_array::Time64MicrosecondArray::try_from(&array).unwrap(),
3051 arrow_array::Time64MicrosecondArray::from(vec![Some(2_123_456)])
3052 );
3053
3054 let arrow = arrow_array::Time64NanosecondArray::from(vec![Some(2_123_456_789)]);
3056 assert_eq!(
3057 TimeArray::try_from(&arrow).unwrap(),
3058 TimeArray::from_iter([Time::with_secs_nano(2, 123_456_000).ok()])
3059 );
3060 }
3061
3062 #[test]
3063 fn time_arrow_units_from_arrow() {
3064 use std::sync::Arc;
3065
3066 struct Dummy;
3067 impl FromArrow for Dummy {}
3068
3069 for arrow_type in [
3070 ArrowType::Time32(arrow_schema::TimeUnit::Second),
3071 ArrowType::Time32(arrow_schema::TimeUnit::Millisecond),
3072 ArrowType::Time64(arrow_schema::TimeUnit::Microsecond),
3073 ArrowType::Time64(arrow_schema::TimeUnit::Nanosecond),
3074 ] {
3075 let field = ArrowField::new("t", arrow_type, true);
3076 assert!(is_parquet_schema_match_source_schema(
3077 field.data_type(),
3078 &RwType::Time
3079 ));
3080 assert_eq!(Dummy.from_field(&field).unwrap(), RwType::Time);
3081 }
3082
3083 for arrow_type in [
3084 ArrowType::Time32(arrow_schema::TimeUnit::Microsecond),
3085 ArrowType::Time32(arrow_schema::TimeUnit::Nanosecond),
3086 ArrowType::Time64(arrow_schema::TimeUnit::Second),
3087 ArrowType::Time64(arrow_schema::TimeUnit::Millisecond),
3088 ] {
3089 let field = ArrowField::new("t", arrow_type, true);
3090 assert!(!is_parquet_schema_match_source_schema(
3091 field.data_type(),
3092 &RwType::Time
3093 ));
3094 assert_from_arrow_error(Dummy.from_field(&field));
3095 }
3096
3097 let cases: Vec<(arrow_array::ArrayRef, TimeArray)> = vec![
3098 (
3099 Arc::new(arrow_array::Time32SecondArray::from(vec![
3100 None,
3101 Some(1),
3102 Some(2),
3103 ])),
3104 TimeArray::from_iter([
3105 None,
3106 Time::with_secs_nano(1, 0).ok(),
3107 Time::with_secs_nano(2, 0).ok(),
3108 ]),
3109 ),
3110 (
3111 Arc::new(arrow_array::Time32MillisecondArray::from(vec![
3112 None,
3113 Some(1_000),
3114 Some(2_123),
3115 ])),
3116 TimeArray::from_iter([
3117 None,
3118 Time::with_secs_nano(1, 0).ok(),
3119 Time::with_secs_nano(2, 123_000_000).ok(),
3120 ]),
3121 ),
3122 (
3123 Arc::new(arrow_array::Time64MicrosecondArray::from(vec![
3124 None,
3125 Some(1_000_000),
3126 Some(2_123_456),
3127 ])),
3128 TimeArray::from_iter([
3129 None,
3130 Time::with_secs_nano(1, 0).ok(),
3131 Time::with_secs_nano(2, 123_456_000).ok(),
3132 ]),
3133 ),
3134 (
3135 Arc::new(arrow_array::Time64NanosecondArray::from(vec![
3136 None,
3137 Some(1_000_000_000),
3138 Some(2_123_456_789),
3139 ])),
3140 TimeArray::from_iter([
3141 None,
3142 Time::with_secs_nano(1, 0).ok(),
3143 Time::with_secs_nano(2, 123_456_000).ok(),
3144 ]),
3145 ),
3146 ];
3147
3148 for (array, expected) in cases {
3149 let field = ArrowField::new("t", array.data_type().clone(), true);
3150 let ArrayImpl::Time(actual) = Dummy.from_array(&field, &array).unwrap() else {
3151 panic!("expected RW TimeArray");
3152 };
3153 assert_eq!(actual, expected);
3154 }
3155 }
3156
3157 #[test]
3158 fn time_arrow_units_reject_invalid_values() {
3159 use std::sync::Arc;
3160
3161 struct Dummy;
3162 impl FromArrow for Dummy {}
3163
3164 let cases: Vec<arrow_array::ArrayRef> = vec![
3165 Arc::new(arrow_array::Time32SecondArray::from(vec![Some(-1)])),
3166 Arc::new(arrow_array::Time32SecondArray::from(vec![Some(86_400)])),
3167 Arc::new(arrow_array::Time32MillisecondArray::from(vec![Some(-1)])),
3168 Arc::new(arrow_array::Time32MillisecondArray::from(vec![Some(
3169 86_400_000,
3170 )])),
3171 Arc::new(arrow_array::Time64MicrosecondArray::from(vec![Some(-1)])),
3172 Arc::new(arrow_array::Time64MicrosecondArray::from(vec![Some(
3173 86_400_000_000,
3174 )])),
3175 Arc::new(arrow_array::Time64NanosecondArray::from(vec![Some(-1)])),
3176 Arc::new(arrow_array::Time64NanosecondArray::from(vec![Some(
3177 86_400_000_000_000,
3178 )])),
3179 Arc::new(arrow_array::Time64MicrosecondArray::from(vec![Some(
3181 4_294_967_296_000_000,
3182 )])),
3183 Arc::new(arrow_array::Time64NanosecondArray::from(vec![Some(
3184 4_294_967_296_000_000_000,
3185 )])),
3186 ];
3187
3188 for array in cases {
3189 let field = ArrowField::new("t", array.data_type().clone(), true);
3190 assert_from_arrow_error(Dummy.from_array(&field, &array));
3191 }
3192 }
3193
3194 #[test]
3195 fn timestamp() {
3196 let array =
3197 TimestampArray::from_iter([None, Timestamp::with_micros(123456789012345678).ok()]);
3198 let arrow = arrow_array::TimestampMicrosecondArray::try_from(&array).unwrap();
3199 assert_eq!(TimestampArray::try_from(&arrow).unwrap(), array);
3200 }
3201
3202 #[test]
3203 fn timestamp_nanosecond_export_rejects_out_of_range_values() {
3204 let timestamp_array =
3206 TimestampArray::from_iter([Timestamp::with_micros(9_300_000_000_000_000).ok()]);
3207 let err = arrow_array::TimestampNanosecondArray::try_from(×tamp_array).unwrap_err();
3208 assert!(matches!(err, ArrayError::ToArrow(_)), "got {err:?}");
3209
3210 let timestamptz_array =
3211 TimestamptzArray::from_iter([Timestamptz::from_micros(9_300_000_000_000_000).unwrap()]);
3212 let err = arrow_array::TimestampNanosecondArray::try_from(×tamptz_array).unwrap_err();
3213 assert!(matches!(err, ArrayError::ToArrow(_)), "got {err:?}");
3214 }
3215
3216 #[test]
3217 fn timestamp_arrow_units_reject_invalid_values() {
3218 let invalid_second = arrow_array::TimestampSecondArray::from(vec![Some(i64::MAX)]);
3219 let invalid_millisecond =
3220 arrow_array::TimestampMillisecondArray::from(vec![Some(i64::MAX)]);
3221 let invalid_microsecond =
3222 arrow_array::TimestampMicrosecondArray::from(vec![Some(i64::MAX)]);
3223
3224 assert_from_arrow_error(TimestampArray::try_from(&invalid_second));
3225 assert_from_arrow_error(TimestampArray::try_from(&invalid_millisecond));
3226 assert_from_arrow_error(TimestampArray::try_from(&invalid_microsecond));
3227 }
3228
3229 #[test]
3230 fn timestamptz_arrow_units_reject_invalid_values() {
3231 let invalid_second = arrow_array::TimestampSecondArray::from(vec![Some(i64::MAX)]);
3232 let invalid_millisecond =
3233 arrow_array::TimestampMillisecondArray::from(vec![Some(i64::MAX)]);
3234 let invalid_microsecond =
3235 arrow_array::TimestampMicrosecondArray::from(vec![Some(i64::MAX)]);
3236 let unrepresentable_second =
3238 arrow_array::TimestampSecondArray::from(vec![Some(9_000_000_000_000)]);
3239
3240 assert_from_arrow_error(TimestamptzArray::try_from(&invalid_second));
3241 assert_from_arrow_error(TimestamptzArray::try_from(&invalid_millisecond));
3242 assert_from_arrow_error(TimestamptzArray::try_from(&invalid_microsecond));
3243 assert_from_arrow_error(TimestamptzArray::try_from(&unrepresentable_second));
3244 }
3245
3246 #[test]
3247 fn date_rejects_out_of_range_arrow_value() {
3248 let valid = arrow_array::Date32Array::from(vec![Some(0), None]);
3249 assert_eq!(
3250 DateArray::try_from(&valid).unwrap(),
3251 DateArray::from_iter([Date::with_days_since_unix_epoch(0).ok(), None])
3252 );
3253
3254 let out_of_range = arrow_array::Date32Array::from(vec![Some(1_000_000_000)]);
3256 assert_from_arrow_error(DateArray::try_from(&out_of_range));
3257 }
3258
3259 #[test]
3260 fn interval_rejects_out_of_range_microseconds() {
3261 let array = IntervalArray::from_iter([Interval::from_month_day_usec(0, 0, i64::MAX)]);
3262 let err = arrow_array::IntervalMonthDayNanoArray::try_from(&array).unwrap_err();
3263 assert!(matches!(err, ArrayError::ToArrow(_)), "got {err:?}");
3264 }
3265
3266 #[test]
3267 fn interval_truncates_sub_microsecond_nanos() {
3268 let arrow = arrow_array::IntervalMonthDayNanoArray::from(vec![
3269 Some(ArrowIntervalType::new(0, 0, 1_999)),
3270 Some(ArrowIntervalType::new(0, 0, -1)),
3271 Some(ArrowIntervalType::new(0, 0, -1_999)),
3272 ]);
3273 assert_eq!(
3274 IntervalArray::try_from(&arrow).unwrap(),
3275 IntervalArray::from_iter([
3276 Interval::from_month_day_usec(0, 0, 1),
3277 Interval::from_month_day_usec(0, 0, 0),
3278 Interval::from_month_day_usec(0, 0, -1),
3279 ])
3280 );
3281 }
3282
3283 fn assert_from_arrow_error<T>(result: Result<T, ArrayError>) {
3284 match result {
3285 Err(ArrayError::FromArrow(_)) => {}
3286 Err(err) => panic!("expected FromArrow error, got {err:?}"),
3287 Ok(_) => panic!("expected FromArrow error, got Ok"),
3288 }
3289 }
3290
3291 #[test]
3292 fn interval() {
3293 let array = IntervalArray::from_iter([
3294 None,
3295 Some(Interval::from_month_day_usec(
3296 1_000_000,
3297 1_000,
3298 1_000_000_000,
3299 )),
3300 Some(Interval::from_month_day_usec(
3301 -1_000_000,
3302 -1_000,
3303 -1_000_000_000,
3304 )),
3305 ]);
3306 let arrow = arrow_array::IntervalMonthDayNanoArray::try_from(&array).unwrap();
3307 assert_eq!(IntervalArray::try_from(&arrow).unwrap(), array);
3308 }
3309
3310 #[test]
3311 fn string() {
3312 let array = Utf8Array::from_iter([None, Some("array"), Some("arrow")]);
3313 let arrow = arrow_array::StringArray::from(&array);
3314 assert_eq!(Utf8Array::from(&arrow), array);
3315 }
3316
3317 #[test]
3318 fn utf8_view_from_arrow_and_schema_match() {
3319 let field = ArrowField::new("v", ArrowType::Utf8View, true);
3320 assert!(is_parquet_field_match_source_schema(
3321 &field,
3322 &RwType::Varchar
3323 ));
3324 assert_eq!(Dummy.from_field(&field).unwrap(), RwType::Varchar);
3325
3326 let array: arrow_array::ArrayRef = Arc::new(arrow_array::StringViewArray::from(vec![
3327 None,
3328 Some("inline"),
3329 Some("a string longer than twelve bytes"),
3330 ]));
3331 let ArrayImpl::Utf8(actual) = Dummy.from_array(&field, &array).unwrap() else {
3332 panic!("expected RW Utf8Array");
3333 };
3334 assert_eq!(
3335 actual,
3336 Utf8Array::from_iter([
3337 None,
3338 Some("inline"),
3339 Some("a string longer than twelve bytes"),
3340 ])
3341 );
3342
3343 let arrow_struct = ArrowType::Struct(vec![field].into());
3344 let rw_struct = RwType::Struct(StructType::new(vec![("v", RwType::Varchar)]));
3345 assert!(is_parquet_schema_match_source_schema(
3346 &arrow_struct,
3347 &rw_struct
3348 ));
3349 }
3350
3351 #[test]
3352 fn binary() {
3353 let array = BytesArray::from_iter([None, Some("array".as_bytes())]);
3354 let arrow = arrow_array::BinaryArray::from(&array);
3355 assert_eq!(BytesArray::from(&arrow), array);
3356 }
3357
3358 #[test]
3359 fn fixed_size_binary() {
3360 let uuid = [
3361 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc,
3362 0xde, 0xf0,
3363 ];
3364 let arrow_array = arrow_array::FixedSizeBinaryArray::try_from_sparse_iter_with_size(
3365 [None, Some(uuid)].into_iter(),
3366 16,
3367 )
3368 .unwrap();
3369 let field =
3370 arrow_schema::Field::new("u", arrow_schema::DataType::FixedSizeBinary(16), true);
3371
3372 assert_eq!(Dummy.from_field(&field).unwrap(), DataType::Bytea);
3373
3374 let rw_array = Dummy
3375 .from_array(&field, &(Arc::new(arrow_array) as arrow_array::ArrayRef))
3376 .unwrap();
3377 let expected = BytesArray::from_iter([None, Some(uuid.as_slice())]);
3378 assert_eq!(rw_array.as_bytea(), &expected);
3379 }
3380
3381 #[test]
3382 fn decimal() {
3383 let array = DecimalArray::from_iter([
3384 None,
3385 Some(Decimal::NaN),
3386 Some(Decimal::PositiveInf),
3387 Some(Decimal::NegativeInf),
3388 Some(Decimal::Normalized("123.4".parse().unwrap())),
3389 Some(Decimal::Normalized("123.456".parse().unwrap())),
3390 ]);
3391 let arrow = arrow_array::LargeBinaryArray::from(&array);
3392 assert_eq!(DecimalArray::try_from(&arrow).unwrap(), array);
3393
3394 let arrow = arrow_array::StringArray::from(&array);
3395 assert_eq!(DecimalArray::try_from(&arrow).unwrap(), array);
3396 }
3397
3398 #[test]
3399 fn jsonb() {
3400 let array = JsonbArray::from_iter([
3401 None,
3402 Some("null".parse().unwrap()),
3403 Some("false".parse().unwrap()),
3404 Some("1".parse().unwrap()),
3405 Some("[1, 2, 3]".parse().unwrap()),
3406 Some(r#"{ "a": 1, "b": null }"#.parse().unwrap()),
3407 ]);
3408 let arrow = arrow_array::LargeStringArray::from(&array);
3409 assert_eq!(JsonbArray::try_from(&arrow).unwrap(), array);
3410
3411 let arrow = arrow_array::StringArray::from(&array);
3412 assert_eq!(JsonbArray::try_from(&arrow).unwrap(), array);
3413 }
3414
3415 #[test]
3416 fn int256() {
3417 let values = [
3418 None,
3419 Some(Int256::from(1)),
3420 Some(Int256::from(i64::MAX)),
3421 Some(Int256::from(i64::MAX) * Int256::from(i64::MAX)),
3422 Some(Int256::from(i64::MAX) * Int256::from(i64::MAX) * Int256::from(i64::MAX)),
3423 Some(
3424 Int256::from(i64::MAX)
3425 * Int256::from(i64::MAX)
3426 * Int256::from(i64::MAX)
3427 * Int256::from(i64::MAX),
3428 ),
3429 Some(Int256::min_value()),
3430 Some(Int256::max_value()),
3431 ];
3432
3433 let array =
3434 Int256Array::from_iter(values.iter().map(|r| r.as_ref().map(|x| x.as_scalar_ref())));
3435 let arrow = arrow_array::Decimal256Array::from(&array);
3436 assert_eq!(Int256Array::from(&arrow), array);
3437 }
3438}