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