1use crate::arrow::array_reader::{ArrayReader, read_records, skip_records};
19use crate::arrow::record_reader::RecordReader;
20use crate::arrow::schema::parquet_to_arrow_field;
21use crate::basic::Type as PhysicalType;
22use crate::column::page::PageIterator;
23use crate::data_type::{DataType, Int96};
24use crate::errors::Result;
25use crate::schema::types::ColumnDescPtr;
26use arrow_array::{
27 Array, ArrayRef, BooleanArray, Date64Array, Decimal64Array, Decimal128Array, Decimal256Array,
28 Float32Array, Float64Array, Int8Array, Int16Array, Int32Array, Int64Array, PrimitiveArray,
29 UInt8Array, UInt16Array, builder::PrimitiveDictionaryBuilder, cast::AsArray, downcast_integer,
30 types::*,
31};
32use arrow_array::{
33 TimestampMicrosecondArray, TimestampMillisecondArray, TimestampNanosecondArray,
34 TimestampSecondArray, UInt32Array, UInt64Array,
35};
36use arrow_buffer::{BooleanBuffer, Buffer, NullBuffer, ScalarBuffer, i256};
37use arrow_schema::{DataType as ArrowType, TimeUnit};
38use std::any::Any;
39use std::sync::Arc;
40
41pub trait IntoBuffer {
43 fn into_buffer(self, target_type: &ArrowType) -> Buffer;
44}
45
46macro_rules! native_buffer {
47 ($($t:ty),*) => {
48 $(impl IntoBuffer for Vec<$t> {
49 fn into_buffer(self, _target_type: &ArrowType) -> Buffer {
50 Buffer::from_vec(self)
51 }
52 })*
53 };
54}
55native_buffer!(i8, i16, i32, i64, u8, u16, u32, u64, f32, f64);
56
57impl IntoBuffer for Vec<bool> {
58 fn into_buffer(self, _target_type: &ArrowType) -> Buffer {
59 BooleanBuffer::from(self.as_slice()).into_inner()
60 }
61}
62
63impl IntoBuffer for Vec<Int96> {
64 fn into_buffer(self, target_type: &ArrowType) -> Buffer {
65 let mut builder = Vec::with_capacity(self.len());
66 match target_type {
67 ArrowType::Timestamp(TimeUnit::Second, _) => {
68 builder.extend(self.iter().map(|x| x.to_seconds()));
69 }
70 ArrowType::Timestamp(TimeUnit::Millisecond, _) => {
71 builder.extend(self.iter().map(|x| x.to_millis()));
72 }
73 ArrowType::Timestamp(TimeUnit::Microsecond, _) => {
74 builder.extend(self.iter().map(|x| x.to_micros()));
75 }
76 ArrowType::Timestamp(TimeUnit::Nanosecond, _) => {
77 builder.extend(self.iter().map(|x| x.to_nanos()));
78 }
79 _ => unreachable!("Invalid target_type for Int96."),
80 }
81 Buffer::from_vec(builder)
82 }
83}
84
85pub struct PrimitiveArrayReader<T>
88where
89 T: DataType,
90 T::T: Copy + Default,
91 Vec<T::T>: IntoBuffer,
92{
93 data_type: ArrowType,
94 pages: Box<dyn PageIterator>,
95 def_levels_buffer: Option<Vec<i16>>,
96 rep_levels_buffer: Option<Vec<i16>>,
97 record_reader: RecordReader<T>,
98}
99
100impl<T> PrimitiveArrayReader<T>
101where
102 T: DataType,
103 T::T: Copy + Default,
104 Vec<T::T>: IntoBuffer,
105{
106 pub fn new(
113 pages: Box<dyn PageIterator>,
114 column_desc: ColumnDescPtr,
115 arrow_type: Option<ArrowType>,
116 batch_size: usize,
117 padding_threshold: Option<i16>,
118 ) -> Result<Self> {
119 let data_type = match arrow_type {
121 Some(t) => t,
122 None => parquet_to_arrow_field(column_desc.as_ref())?
123 .data_type()
124 .clone(),
125 };
126
127 let mut record_reader = RecordReader::<T>::new(column_desc, batch_size);
128 if let Some(threshold) = padding_threshold {
129 record_reader.set_padding_threshold(threshold);
130 }
131
132 Ok(Self {
133 data_type,
134 pages,
135 def_levels_buffer: None,
136 rep_levels_buffer: None,
137 record_reader,
138 })
139 }
140}
141
142impl<T> ArrayReader for PrimitiveArrayReader<T>
144where
145 T: DataType,
146 T::T: Copy + Default,
147 Vec<T::T>: IntoBuffer,
148{
149 fn as_any(&self) -> &dyn Any {
150 self
151 }
152
153 fn get_data_type(&self) -> &ArrowType {
155 &self.data_type
156 }
157
158 fn read_records(&mut self, batch_size: usize) -> Result<usize> {
159 read_records(&mut self.record_reader, self.pages.as_mut(), batch_size)
160 }
161
162 fn consume_batch(&mut self) -> Result<ArrayRef> {
163 let target_type = &self.data_type;
164
165 let len = self.record_reader.values_written();
168
169 let record_data = self
170 .record_reader
171 .consume_record_data()
172 .into_buffer(target_type);
173
174 let nulls = self
175 .record_reader
176 .consume_compact_bitmap()
177 .and_then(|b| NullBuffer::from_unsliced_buffer(b, len));
178
179 let array: ArrayRef = match T::get_physical_type() {
180 PhysicalType::BOOLEAN => Arc::new(BooleanArray::new(
181 BooleanBuffer::new(record_data, 0, len),
182 nulls,
183 )),
184 PhysicalType::INT32 => Arc::new(Int32Array::new(
185 ScalarBuffer::new(record_data, 0, len),
186 nulls,
187 )),
188 PhysicalType::INT64 => Arc::new(Int64Array::new(
189 ScalarBuffer::new(record_data, 0, len),
190 nulls,
191 )),
192 PhysicalType::FLOAT => Arc::new(Float32Array::new(
193 ScalarBuffer::new(record_data, 0, len),
194 nulls,
195 )),
196 PhysicalType::DOUBLE => Arc::new(Float64Array::new(
197 ScalarBuffer::new(record_data, 0, len),
198 nulls,
199 )),
200 PhysicalType::INT96 => Arc::new(Int64Array::new(
201 ScalarBuffer::new(record_data, 0, len),
202 nulls,
203 )),
204 PhysicalType::BYTE_ARRAY | PhysicalType::FIXED_LEN_BYTE_ARRAY => {
205 unreachable!("PrimitiveArrayReaders don't support complex physical types");
206 }
207 };
208
209 let array = coerce_array(array, target_type)?;
211
212 self.def_levels_buffer = self.record_reader.consume_def_levels();
214 self.rep_levels_buffer = self.record_reader.consume_rep_levels();
215 self.record_reader.reset();
216 Ok(array)
217 }
218
219 fn skip_records(&mut self, num_records: usize) -> Result<usize> {
220 skip_records(&mut self.record_reader, self.pages.as_mut(), num_records)
221 }
222
223 fn get_def_levels(&self) -> Option<&[i16]> {
224 self.def_levels_buffer.as_deref()
225 }
226
227 fn get_rep_levels(&self) -> Option<&[i16]> {
228 self.rep_levels_buffer.as_deref()
229 }
230
231 fn max_def_level(&self) -> i16 {
232 self.record_reader.max_def_level()
233 }
234}
235
236fn coerce_array(array: ArrayRef, target_type: &ArrowType) -> Result<ArrayRef> {
240 if let ArrowType::Dictionary(key_type, value_type) = target_type {
241 let dictionary = pack_dictionary(key_type, array.as_ref())?;
242 let any_dictionary = dictionary.as_any_dictionary();
243
244 let coerced_values =
245 coerce_array(Arc::clone(any_dictionary.values()), value_type.as_ref())?;
246
247 return Ok(any_dictionary.with_values(coerced_values));
248 }
249
250 match array.data_type() {
251 ArrowType::Int32 => coerce_i32(array.as_primitive(), target_type),
252 ArrowType::Int64 => coerce_i64(array.as_primitive(), target_type),
253 ArrowType::Boolean | ArrowType::Float32 | ArrowType::Float64 => Ok(array),
254 _ => unreachable!("Cannot coerce array of type {}", array.data_type()),
255 }
256}
257
258fn coerce_i32(array: &Int32Array, target_type: &ArrowType) -> Result<ArrayRef> {
259 Ok(match target_type {
260 ArrowType::UInt8 => {
261 let array = array.unary(|i| i as u8) as UInt8Array;
262 Arc::new(array) as ArrayRef
263 }
264 ArrowType::Int8 => {
265 let array = array.unary(|i| i as i8) as Int8Array;
266 Arc::new(array) as ArrayRef
267 }
268 ArrowType::UInt16 => {
269 let array = array.unary(|i| i as u16) as UInt16Array;
270 Arc::new(array) as ArrayRef
271 }
272 ArrowType::Int16 => {
273 let array = array.unary(|i| i as i16) as Int16Array;
274 Arc::new(array) as ArrayRef
275 }
276 ArrowType::Int32 => Arc::new(array.clone()),
277 ArrowType::UInt32 => Arc::new(UInt32Array::new(
280 array.values().inner().clone().into(),
281 array.nulls().cloned(),
282 )) as ArrayRef,
283 ArrowType::Date32 => Arc::new(array.reinterpret_cast::<Date32Type>()) as _,
284 ArrowType::Date64 => {
285 let array: Date64Array = array.unary(|x| x as i64 * 86_400_000);
286 Arc::new(array) as ArrayRef
287 }
288 ArrowType::Time32(TimeUnit::Second) => {
289 Arc::new(array.reinterpret_cast::<Time32SecondType>()) as ArrayRef
290 }
291 ArrowType::Time32(TimeUnit::Millisecond) => {
292 Arc::new(array.reinterpret_cast::<Time32MillisecondType>()) as ArrayRef
293 }
294 ArrowType::Timestamp(time_unit, timezone) => match time_unit {
295 TimeUnit::Second => {
296 let array: TimestampSecondArray = array
297 .unary(|x| x as i64)
298 .with_timezone_opt(timezone.clone());
299 Arc::new(array) as _
300 }
301 TimeUnit::Millisecond => {
302 let array: TimestampMillisecondArray = array
303 .unary(|x| x as i64)
304 .with_timezone_opt(timezone.clone());
305 Arc::new(array) as _
306 }
307 TimeUnit::Microsecond => {
308 let array: TimestampMicrosecondArray = array
309 .unary(|x| x as i64)
310 .with_timezone_opt(timezone.clone());
311 Arc::new(array) as _
312 }
313 TimeUnit::Nanosecond => {
314 let array: TimestampNanosecondArray = array
315 .unary(|x| x as i64)
316 .with_timezone_opt(timezone.clone());
317 Arc::new(array) as _
318 }
319 },
320 ArrowType::Decimal32(p, s) => {
321 let array = array
322 .reinterpret_cast::<Decimal32Type>()
323 .with_precision_and_scale(*p, *s)?;
324 Arc::new(array) as ArrayRef
325 }
326 ArrowType::Decimal64(p, s) => {
327 let array: Decimal64Array =
328 array.unary(|i| i as i64).with_precision_and_scale(*p, *s)?;
329 Arc::new(array) as ArrayRef
330 }
331 ArrowType::Decimal128(p, s) => {
332 let array: Decimal128Array = array
333 .unary(|i| i as i128)
334 .with_precision_and_scale(*p, *s)?;
335 Arc::new(array) as ArrayRef
336 }
337 ArrowType::Decimal256(p, s) => {
338 let array: Decimal256Array = array
339 .unary(|i| i256::from_i128(i as i128))
340 .with_precision_and_scale(*p, *s)?;
341 Arc::new(array) as ArrayRef
342 }
343 _ => unreachable!("Cannot coerce i32 to {target_type}"),
344 })
345}
346
347fn coerce_i64(array: &Int64Array, target_type: &ArrowType) -> Result<ArrayRef> {
348 Ok(match target_type {
349 ArrowType::Int64 => Arc::new(array.clone()) as _,
350 ArrowType::UInt64 => Arc::new(UInt64Array::new(
353 array.values().inner().clone().into(),
354 array.nulls().cloned(),
355 )) as ArrayRef,
356 ArrowType::Date64 => Arc::new(array.reinterpret_cast::<Date64Type>()) as _,
357 ArrowType::Time64(TimeUnit::Microsecond) => {
358 Arc::new(array.reinterpret_cast::<Time64MicrosecondType>()) as _
359 }
360 ArrowType::Time64(TimeUnit::Nanosecond) => {
361 Arc::new(array.reinterpret_cast::<Time64NanosecondType>()) as _
362 }
363 ArrowType::Duration(unit) => match unit {
364 TimeUnit::Second => Arc::new(array.reinterpret_cast::<DurationSecondType>()) as _,
365 TimeUnit::Millisecond => {
366 Arc::new(array.reinterpret_cast::<DurationMillisecondType>()) as _
367 }
368 TimeUnit::Microsecond => {
369 Arc::new(array.reinterpret_cast::<DurationMicrosecondType>()) as _
370 }
371 TimeUnit::Nanosecond => {
372 Arc::new(array.reinterpret_cast::<DurationNanosecondType>()) as _
373 }
374 },
375 ArrowType::Timestamp(time_unit, timezone) => match time_unit {
376 TimeUnit::Second => {
377 let array = array
378 .reinterpret_cast::<TimestampSecondType>()
379 .with_timezone_opt(timezone.clone());
380 Arc::new(array) as _
381 }
382 TimeUnit::Millisecond => {
383 let array = array
384 .reinterpret_cast::<TimestampMillisecondType>()
385 .with_timezone_opt(timezone.clone());
386 Arc::new(array) as _
387 }
388 TimeUnit::Microsecond => {
389 let array = array
390 .reinterpret_cast::<TimestampMicrosecondType>()
391 .with_timezone_opt(timezone.clone());
392 Arc::new(array) as _
393 }
394 TimeUnit::Nanosecond => {
395 let array = array
396 .reinterpret_cast::<TimestampNanosecondType>()
397 .with_timezone_opt(timezone.clone());
398 Arc::new(array) as _
399 }
400 },
401 ArrowType::Decimal64(p, s) => {
402 let array = array
403 .reinterpret_cast::<Decimal64Type>()
404 .with_precision_and_scale(*p, *s)?;
405 Arc::new(array) as _
406 }
407 ArrowType::Decimal128(p, s) => {
408 let array: Decimal128Array = array
409 .unary(|i| i as i128)
410 .with_precision_and_scale(*p, *s)?;
411 Arc::new(array) as _
412 }
413 ArrowType::Decimal256(p, s) => {
414 let array: Decimal256Array = array
415 .unary(|i| i256::from_i128(i as i128))
416 .with_precision_and_scale(*p, *s)?;
417 Arc::new(array) as _
418 }
419 _ => unreachable!("Cannot coerce i64 to {target_type}"),
420 })
421}
422
423macro_rules! pack_dictionary_helper {
424 ($t:ty, $values:ident) => {
425 match $values.data_type() {
426 ArrowType::Int32 => pack_dictionary_impl::<$t, Int32Type>($values.as_primitive()),
427 ArrowType::Int64 => pack_dictionary_impl::<$t, Int64Type>($values.as_primitive()),
428 ArrowType::Float32 => pack_dictionary_impl::<$t, Float32Type>($values.as_primitive()),
429 ArrowType::Float64 => pack_dictionary_impl::<$t, Float64Type>($values.as_primitive()),
430 _ => unreachable!("Invalid physical type"),
431 }
432 };
433}
434
435fn pack_dictionary(key: &ArrowType, values: &dyn Array) -> Result<ArrayRef> {
436 downcast_integer! {
437 key => (pack_dictionary_helper, values),
438 _ => unreachable!("Invalid key type"),
439 }
440}
441
442fn pack_dictionary_impl<K: ArrowDictionaryKeyType, V: ArrowPrimitiveType>(
443 values: &PrimitiveArray<V>,
444) -> Result<ArrayRef> {
445 let mut builder = PrimitiveDictionaryBuilder::<K, V>::with_capacity(1024, values.len());
446 builder.extend(values);
447 Ok(Arc::new(builder.finish()))
448}
449
450#[cfg(test)]
451mod tests {
452 use super::*;
453 use crate::arrow::array_reader::test_util::EmptyPageIterator;
454 use crate::arrow::arrow_reader::DEFAULT_BATCH_SIZE;
455 use crate::basic::Encoding;
456 use crate::column::page::Page;
457 use crate::data_type::{Int32Type, Int64Type};
458 use crate::schema::parser::parse_message_type;
459 use crate::schema::types::SchemaDescriptor;
460 use crate::util::InMemoryPageIterator;
461 use crate::util::test_common::rand_gen::make_pages;
462 use arrow::datatypes::ArrowPrimitiveType;
463 use arrow_array::{Array, Date32Array, PrimitiveArray};
464
465 use arrow::datatypes::DataType::{Date32, Decimal128};
466 use rand::distr::uniform::SampleUniform;
467 use std::collections::VecDeque;
468
469 #[allow(clippy::too_many_arguments)]
470 fn make_column_chunks<T: DataType>(
471 column_desc: ColumnDescPtr,
472 encoding: Encoding,
473 num_levels: usize,
474 min_value: T::T,
475 max_value: T::T,
476 def_levels: &mut Vec<i16>,
477 rep_levels: &mut Vec<i16>,
478 values: &mut Vec<T::T>,
479 page_lists: &mut Vec<Vec<Page>>,
480 use_v2: bool,
481 num_chunks: usize,
482 ) where
483 T::T: PartialOrd + SampleUniform + Copy,
484 {
485 for _i in 0..num_chunks {
486 let mut pages = VecDeque::new();
487 let mut data = Vec::new();
488 let mut page_def_levels = Vec::new();
489 let mut page_rep_levels = Vec::new();
490
491 make_pages::<T>(
492 column_desc.clone(),
493 encoding,
494 1,
495 num_levels,
496 min_value,
497 max_value,
498 &mut page_def_levels,
499 &mut page_rep_levels,
500 &mut data,
501 &mut pages,
502 use_v2,
503 );
504
505 def_levels.append(&mut page_def_levels);
506 rep_levels.append(&mut page_rep_levels);
507 values.append(&mut data);
508 page_lists.push(Vec::from(pages));
509 }
510 }
511
512 #[test]
513 fn test_primitive_array_reader_empty_pages() {
514 let message_type = "
516 message test_schema {
517 REQUIRED INT32 leaf;
518 }
519 ";
520
521 let schema = parse_message_type(message_type)
522 .map(|t| Arc::new(SchemaDescriptor::new(Arc::new(t))))
523 .unwrap();
524
525 let mut array_reader = PrimitiveArrayReader::<Int32Type>::new(
526 Box::<EmptyPageIterator>::default(),
527 schema.column(0),
528 None,
529 DEFAULT_BATCH_SIZE,
530 None,
531 )
532 .unwrap();
533
534 let array = array_reader.next_batch(50).unwrap();
536 assert!(array.is_empty());
537 }
538
539 #[test]
540 fn test_primitive_array_reader_data() {
541 let message_type = "
543 message test_schema {
544 REQUIRED INT32 leaf;
545 }
546 ";
547
548 let schema = parse_message_type(message_type)
549 .map(|t| Arc::new(SchemaDescriptor::new(Arc::new(t))))
550 .unwrap();
551
552 let column_desc = schema.column(0);
553
554 {
556 let mut data = Vec::new();
557 let mut page_lists = Vec::new();
558 make_column_chunks::<Int32Type>(
559 column_desc.clone(),
560 Encoding::PLAIN,
561 100,
562 1,
563 200,
564 &mut Vec::new(),
565 &mut Vec::new(),
566 &mut data,
567 &mut page_lists,
568 true,
569 2,
570 );
571 let page_iterator = InMemoryPageIterator::new(page_lists);
572
573 let mut array_reader = PrimitiveArrayReader::<Int32Type>::new(
574 Box::new(page_iterator),
575 column_desc,
576 None,
577 DEFAULT_BATCH_SIZE,
578 None,
579 )
580 .unwrap();
581
582 let array = array_reader.next_batch(50).unwrap();
584 let array = array.as_any().downcast_ref::<Int32Array>().unwrap();
585
586 assert_eq!(&Int32Array::from(data[0..50].to_vec()), array);
587
588 let array = array_reader.next_batch(100).unwrap();
591 let array = array.as_any().downcast_ref::<Int32Array>().unwrap();
592
593 assert_eq!(&Int32Array::from(data[50..150].to_vec()), array);
594
595 let array = array_reader.next_batch(100).unwrap();
597 let array = array.as_any().downcast_ref::<Int32Array>().unwrap();
598
599 assert_eq!(&Int32Array::from(data[150..200].to_vec()), array);
600 }
601 }
602
603 macro_rules! test_primitive_array_reader_one_type {
604 (
605 $arrow_parquet_type:ty,
606 $physical_type:expr,
607 $converted_type_str:expr,
608 $result_arrow_type:ty,
609 $result_arrow_cast_type:ty,
610 $result_primitive_type:ty
611 $(, $timezone:expr)?
612 ) => {{
613 let message_type = format!(
614 "
615 message test_schema {{
616 REQUIRED {:?} leaf ({});
617 }}
618 ",
619 $physical_type, $converted_type_str
620 );
621 let schema = parse_message_type(&message_type)
622 .map(|t| Arc::new(SchemaDescriptor::new(Arc::new(t))))
623 .unwrap();
624
625 let column_desc = schema.column(0);
626
627 {
629 let mut data = Vec::new();
630 let mut page_lists = Vec::new();
631 make_column_chunks::<$arrow_parquet_type>(
632 column_desc.clone(),
633 Encoding::PLAIN,
634 100,
635 1,
636 200,
637 &mut Vec::new(),
638 &mut Vec::new(),
639 &mut data,
640 &mut page_lists,
641 true,
642 2,
643 );
644 let page_iterator = InMemoryPageIterator::new(page_lists);
645 let mut array_reader = PrimitiveArrayReader::<$arrow_parquet_type>::new(
646 Box::new(page_iterator),
647 column_desc.clone(),
648 None,
649 DEFAULT_BATCH_SIZE,
650 None,
651 )
652 .expect("Unable to get array reader");
653
654 let array = array_reader
655 .next_batch(50)
656 .expect("Unable to get batch from reader");
657
658 let result_data_type = <$result_arrow_type>::DATA_TYPE;
659 let array = array
660 .as_any()
661 .downcast_ref::<PrimitiveArray<$result_arrow_type>>()
662 .expect(
663 format!(
664 "Unable to downcast {:?} to {:?}",
665 array.data_type(),
666 result_data_type
667 )
668 .as_str(),
669 )
670 $(.clone().with_timezone($timezone))?
671 ;
672
673 #[expect(
675 trivial_numeric_casts,
676 reason = "the cast is a no-op when the source and result types are the same"
677 )]
678 let expected = PrimitiveArray::<$result_arrow_cast_type>::from(
679 data[0..50]
680 .iter()
681 .map(|x| *x as $result_primitive_type)
682 .collect::<Vec<$result_primitive_type>>(),
683 );
684 let expected = Arc::new(expected) as ArrayRef;
685 let expected = arrow::compute::cast(&expected, &result_data_type)
686 .expect("Unable to cast expected array");
687 assert_eq!(expected.data_type(), &result_data_type);
688 let expected = expected
689 .as_any()
690 .downcast_ref::<PrimitiveArray<$result_arrow_type>>()
691 .expect(
692 format!(
693 "Unable to downcast expected {:?} to {:?}",
694 expected.data_type(),
695 result_data_type
696 )
697 .as_str(),
698 )
699 $(.clone().with_timezone($timezone))?
700 ;
701 assert_eq!(expected, array);
702 }
703 }};
704 }
705
706 #[test]
707 fn test_primitive_array_reader_temporal_types() {
708 test_primitive_array_reader_one_type!(
709 crate::data_type::Int32Type,
710 PhysicalType::INT32,
711 "DATE",
712 arrow::datatypes::Date32Type,
713 arrow::datatypes::Int32Type,
714 i32
715 );
716 test_primitive_array_reader_one_type!(
717 crate::data_type::Int32Type,
718 PhysicalType::INT32,
719 "TIME_MILLIS",
720 arrow::datatypes::Time32MillisecondType,
721 arrow::datatypes::Int32Type,
722 i32
723 );
724 test_primitive_array_reader_one_type!(
725 crate::data_type::Int64Type,
726 PhysicalType::INT64,
727 "TIME_MICROS",
728 arrow::datatypes::Time64MicrosecondType,
729 arrow::datatypes::Int64Type,
730 i64
731 );
732 test_primitive_array_reader_one_type!(
733 crate::data_type::Int64Type,
734 PhysicalType::INT64,
735 "TIMESTAMP_MILLIS",
736 arrow::datatypes::TimestampMillisecondType,
737 arrow::datatypes::Int64Type,
738 i64,
739 "UTC"
740 );
741 test_primitive_array_reader_one_type!(
742 crate::data_type::Int64Type,
743 PhysicalType::INT64,
744 "TIMESTAMP_MICROS",
745 arrow::datatypes::TimestampMicrosecondType,
746 arrow::datatypes::Int64Type,
747 i64,
748 "UTC"
749 );
750 }
751
752 #[test]
753 fn test_primitive_array_reader_def_and_rep_levels() {
754 let message_type = "
756 message test_schema {
757 REPEATED Group test_mid {
758 OPTIONAL INT32 leaf;
759 }
760 }
761 ";
762
763 let schema = parse_message_type(message_type)
764 .map(|t| Arc::new(SchemaDescriptor::new(Arc::new(t))))
765 .unwrap();
766
767 let column_desc = schema.column(0);
768
769 {
771 let mut def_levels = Vec::new();
772 let mut rep_levels = Vec::new();
773 let mut page_lists = Vec::new();
774 make_column_chunks::<Int32Type>(
775 column_desc.clone(),
776 Encoding::PLAIN,
777 100,
778 1,
779 200,
780 &mut def_levels,
781 &mut rep_levels,
782 &mut Vec::new(),
783 &mut page_lists,
784 true,
785 2,
786 );
787
788 let page_iterator = InMemoryPageIterator::new(page_lists);
789
790 let mut array_reader = PrimitiveArrayReader::<Int32Type>::new(
791 Box::new(page_iterator),
792 column_desc,
793 None,
794 DEFAULT_BATCH_SIZE,
795 None,
796 )
797 .unwrap();
798
799 let mut accu_len: usize = 0;
800
801 let array = array_reader.next_batch(50).unwrap();
803 assert_eq!(
804 Some(&def_levels[accu_len..(accu_len + array.len())]),
805 array_reader.get_def_levels()
806 );
807 assert_eq!(
808 Some(&rep_levels[accu_len..(accu_len + array.len())]),
809 array_reader.get_rep_levels()
810 );
811 accu_len += array.len();
812
813 let array = array_reader.next_batch(100).unwrap();
816 assert_eq!(
817 Some(&def_levels[accu_len..(accu_len + array.len())]),
818 array_reader.get_def_levels()
819 );
820 assert_eq!(
821 Some(&rep_levels[accu_len..(accu_len + array.len())]),
822 array_reader.get_rep_levels()
823 );
824 accu_len += array.len();
825
826 let array = array_reader.next_batch(100).unwrap();
828 assert_eq!(
829 Some(&def_levels[accu_len..(accu_len + array.len())]),
830 array_reader.get_def_levels()
831 );
832 assert_eq!(
833 Some(&rep_levels[accu_len..(accu_len + array.len())]),
834 array_reader.get_rep_levels()
835 );
836 }
837 }
838
839 #[test]
840 fn test_primitive_array_reader_decimal_types() {
841 let message_type = "
843 message test_schema {
844 REQUIRED INT32 decimal1 (DECIMAL(8,2));
845 }
846 ";
847 let schema = parse_message_type(message_type)
848 .map(|t| Arc::new(SchemaDescriptor::new(Arc::new(t))))
849 .unwrap();
850 let column_desc = schema.column(0);
851
852 {
854 let mut data = Vec::new();
855 let mut page_lists = Vec::new();
856 make_column_chunks::<Int32Type>(
857 column_desc.clone(),
858 Encoding::PLAIN,
859 100,
860 -99999999,
861 99999999,
862 &mut Vec::new(),
863 &mut Vec::new(),
864 &mut data,
865 &mut page_lists,
866 true,
867 2,
868 );
869 let page_iterator = InMemoryPageIterator::new(page_lists);
870
871 let mut array_reader = PrimitiveArrayReader::<Int32Type>::new(
872 Box::new(page_iterator),
873 column_desc,
874 None,
875 DEFAULT_BATCH_SIZE,
876 None,
877 )
878 .unwrap();
879
880 let array = array_reader.next_batch(50).unwrap();
883 assert_eq!(array.data_type(), &Decimal128(8, 2));
884 let array = array.as_any().downcast_ref::<Decimal128Array>().unwrap();
885 let data_decimal_array = data[0..50]
886 .iter()
887 .copied()
888 .map(|v| Some(v as i128))
889 .collect::<Decimal128Array>()
890 .with_precision_and_scale(8, 2)
891 .unwrap();
892 assert_eq!(array, &data_decimal_array);
893
894 let data_decimal_array = data[0..50]
896 .iter()
897 .copied()
898 .map(|v| Some(v as i128))
899 .collect::<Decimal128Array>()
900 .with_precision_and_scale(9, 0)
901 .unwrap();
902 assert_ne!(array, &data_decimal_array)
903 }
904
905 let message_type = "
907 message test_schema {
908 REQUIRED INT64 decimal1 (DECIMAL(18,4));
909 }
910 ";
911 let schema = parse_message_type(message_type)
912 .map(|t| Arc::new(SchemaDescriptor::new(Arc::new(t))))
913 .unwrap();
914 let column_desc = schema.column(0);
915
916 {
918 let mut data = Vec::new();
919 let mut page_lists = Vec::new();
920 make_column_chunks::<Int64Type>(
921 column_desc.clone(),
922 Encoding::PLAIN,
923 100,
924 -999999999999999999,
925 999999999999999999,
926 &mut Vec::new(),
927 &mut Vec::new(),
928 &mut data,
929 &mut page_lists,
930 true,
931 2,
932 );
933 let page_iterator = InMemoryPageIterator::new(page_lists);
934
935 let mut array_reader = PrimitiveArrayReader::<Int64Type>::new(
936 Box::new(page_iterator),
937 column_desc,
938 None,
939 DEFAULT_BATCH_SIZE,
940 None,
941 )
942 .unwrap();
943
944 let array = array_reader.next_batch(50).unwrap();
947 assert_eq!(array.data_type(), &Decimal128(18, 4));
948 let array = array.as_any().downcast_ref::<Decimal128Array>().unwrap();
949 let data_decimal_array = data[0..50]
950 .iter()
951 .copied()
952 .map(|v| Some(v as i128))
953 .collect::<Decimal128Array>()
954 .with_precision_and_scale(18, 4)
955 .unwrap();
956 assert_eq!(array, &data_decimal_array);
957
958 let data_decimal_array = data[0..50]
960 .iter()
961 .copied()
962 .map(|v| Some(v as i128))
963 .collect::<Decimal128Array>()
964 .with_precision_and_scale(34, 0)
965 .unwrap();
966 assert_ne!(array, &data_decimal_array)
967 }
968 }
969
970 #[test]
971 fn test_primitive_array_reader_date32_type() {
972 let message_type = "
974 message test_schema {
975 REQUIRED INT32 date1 (DATE);
976 }
977 ";
978 let schema = parse_message_type(message_type)
979 .map(|t| Arc::new(SchemaDescriptor::new(Arc::new(t))))
980 .unwrap();
981 let column_desc = schema.column(0);
982
983 {
985 let mut data = Vec::new();
986 let mut page_lists = Vec::new();
987 make_column_chunks::<Int32Type>(
988 column_desc.clone(),
989 Encoding::PLAIN,
990 100,
991 -99999999,
992 99999999,
993 &mut Vec::new(),
994 &mut Vec::new(),
995 &mut data,
996 &mut page_lists,
997 true,
998 2,
999 );
1000 let page_iterator = InMemoryPageIterator::new(page_lists);
1001
1002 let mut array_reader = PrimitiveArrayReader::<Int32Type>::new(
1003 Box::new(page_iterator),
1004 column_desc,
1005 None,
1006 DEFAULT_BATCH_SIZE,
1007 None,
1008 )
1009 .unwrap();
1010
1011 let array = array_reader.next_batch(50).unwrap();
1014 assert_eq!(array.data_type(), &Date32);
1015 let array = array.as_any().downcast_ref::<Date32Array>().unwrap();
1016 let data_date_array = data[0..50]
1017 .iter()
1018 .copied()
1019 .map(Some)
1020 .collect::<Date32Array>();
1021 assert_eq!(array, &data_date_array);
1022 }
1023 }
1024}