1use crate::arrow::buffer::bit_util::sign_extend_be;
10use crate::arrow::parquet_column;
11use crate::basic::{ColumnOrder, Type as PhysicalType};
12use crate::data_type::Int96;
13use crate::errors::{ParquetError, Result};
14use crate::file::metadata::RowGroupMetaData;
15use crate::file::metadata::page_index::PageIndexProvider;
16use crate::file::page_index::column_index::ColumnIndexMetaData;
17use crate::file::statistics::Statistics as ParquetStatistics;
18use crate::schema::types::SchemaDescriptor;
19use arrow_array::builder::{
20 BinaryBuilder, BinaryViewBuilder, BooleanBuilder, Date32Builder, Date64Builder,
21 Decimal32Builder, Decimal64Builder, FixedSizeBinaryBuilder, Float16Builder, Float32Builder,
22 Float64Builder, Int8Builder, Int16Builder, Int32Builder, Int64Builder, LargeBinaryBuilder,
23 LargeStringBuilder, StringBuilder, StringViewBuilder, Time32MillisecondBuilder,
24 Time32SecondBuilder, Time64MicrosecondBuilder, Time64NanosecondBuilder,
25 TimestampMicrosecondBuilder, TimestampMillisecondBuilder, TimestampNanosecondBuilder,
26 TimestampSecondBuilder, UInt8Builder, UInt16Builder, UInt32Builder, UInt64Builder,
27};
28use arrow_array::{
29 ArrayRef, BinaryArray, BooleanArray, Date32Array, Date64Array, Decimal32Array, Decimal64Array,
30 Decimal128Array, Decimal256Array, Float16Array, Float32Array, Float64Array, Int8Array,
31 Int16Array, Int32Array, Int64Array, LargeBinaryArray, Time32MillisecondArray,
32 Time32SecondArray, Time64MicrosecondArray, Time64NanosecondArray, TimestampMicrosecondArray,
33 TimestampMillisecondArray, TimestampNanosecondArray, TimestampSecondArray, UInt8Array,
34 UInt16Array, UInt32Array, UInt64Array, new_null_array,
35};
36use arrow_buffer::{NullBufferBuilder, i256};
37use arrow_schema::{DataType, Field, Schema, TimeUnit};
38use half::f16;
39use std::sync::Arc;
40
41pub(crate) fn from_bytes_to_i32(b: &[u8]) -> i32 {
44 i32::from_be_bytes(sign_extend_be::<4>(b))
48}
49
50pub(crate) fn from_bytes_to_i64(b: &[u8]) -> i64 {
53 i64::from_be_bytes(sign_extend_be::<8>(b))
54}
55
56pub(crate) fn from_bytes_to_i128(b: &[u8]) -> i128 {
59 i128::from_be_bytes(sign_extend_be::<16>(b))
60}
61
62pub(crate) fn from_bytes_to_i256(b: &[u8]) -> i256 {
65 i256::from_be_bytes(sign_extend_be::<32>(b))
66}
67
68pub(crate) fn from_bytes_to_f16(b: &[u8]) -> Option<f16> {
70 match b {
71 [low, high] => Some(f16::from_be_bytes([*high, *low])),
72 _ => None,
73 }
74}
75
76fn int96_statistics(min: &Int96, max: &Int96, unit: &TimeUnit) -> Option<(i64, i64)> {
79 let convert = |value: &Int96| {
80 const NANOS_PER_DAY: u64 = 86_400_000_000_000;
81 let words = value.data();
82 let nanos = (u64::from(words[1]) << 32) | u64::from(words[0]);
83 if nanos >= NANOS_PER_DAY {
84 return None;
85 }
86 let divisor = match unit {
87 TimeUnit::Second => 1_000_000_000,
88 TimeUnit::Millisecond => 1_000_000,
89 TimeUnit::Microsecond => 1_000,
90 TimeUnit::Nanosecond => 1,
91 };
92 let timestamp = i128::from(value.to_seconds()) * i128::from(1_000_000_000 / divisor)
96 + i128::from((nanos % 1_000_000_000) / divisor);
97 i64::try_from(timestamp).ok()
98 };
99 Some((convert(min)?, convert(max)?))
100}
101
102macro_rules! make_stats_iterator {
114 ($iterator_type:ident, $func:ident, $parquet_statistics_type:path, $stat_value_type:ty) => {
115 struct $iterator_type<'a, I>
122 where
123 I: Iterator<Item = Option<&'a ParquetStatistics>>,
124 {
125 iter: I,
126 }
127
128 impl<'a, I> $iterator_type<'a, I>
129 where
130 I: Iterator<Item = Option<&'a ParquetStatistics>>,
131 {
132 fn new(iter: I) -> Self {
134 Self { iter }
135 }
136 }
137
138 impl<'a, I> Iterator for $iterator_type<'a, I>
140 where
141 I: Iterator<Item = Option<&'a ParquetStatistics>>,
142 {
143 type Item = Option<&'a $stat_value_type>;
144
145 fn next(&mut self) -> Option<Self::Item> {
147 let next = self.iter.next();
148 next.map(|x| {
149 x.and_then(|stats| match stats {
150 $parquet_statistics_type(s) => s.$func(),
151 _ => None,
152 })
153 })
154 }
155
156 fn size_hint(&self) -> (usize, Option<usize>) {
157 self.iter.size_hint()
158 }
159 }
160 };
161}
162
163make_stats_iterator!(
164 MinBooleanStatsIterator,
165 min_opt,
166 ParquetStatistics::Boolean,
167 bool
168);
169make_stats_iterator!(
170 MaxBooleanStatsIterator,
171 max_opt,
172 ParquetStatistics::Boolean,
173 bool
174);
175make_stats_iterator!(
176 MinInt32StatsIterator,
177 min_opt,
178 ParquetStatistics::Int32,
179 i32
180);
181make_stats_iterator!(
182 MaxInt32StatsIterator,
183 max_opt,
184 ParquetStatistics::Int32,
185 i32
186);
187make_stats_iterator!(
188 MinInt64StatsIterator,
189 min_opt,
190 ParquetStatistics::Int64,
191 i64
192);
193make_stats_iterator!(
194 MaxInt64StatsIterator,
195 max_opt,
196 ParquetStatistics::Int64,
197 i64
198);
199make_stats_iterator!(
200 MinFloatStatsIterator,
201 min_opt,
202 ParquetStatistics::Float,
203 f32
204);
205make_stats_iterator!(
206 MaxFloatStatsIterator,
207 max_opt,
208 ParquetStatistics::Float,
209 f32
210);
211make_stats_iterator!(
212 MinDoubleStatsIterator,
213 min_opt,
214 ParquetStatistics::Double,
215 f64
216);
217make_stats_iterator!(
218 MaxDoubleStatsIterator,
219 max_opt,
220 ParquetStatistics::Double,
221 f64
222);
223make_stats_iterator!(
224 MinByteArrayStatsIterator,
225 min_bytes_opt,
226 ParquetStatistics::ByteArray,
227 [u8]
228);
229make_stats_iterator!(
230 MaxByteArrayStatsIterator,
231 max_bytes_opt,
232 ParquetStatistics::ByteArray,
233 [u8]
234);
235make_stats_iterator!(
236 MinFixedLenByteArrayStatsIterator,
237 min_bytes_opt,
238 ParquetStatistics::FixedLenByteArray,
239 [u8]
240);
241make_stats_iterator!(
242 MaxFixedLenByteArrayStatsIterator,
243 max_bytes_opt,
244 ParquetStatistics::FixedLenByteArray,
245 [u8]
246);
247
248macro_rules! make_decimal_stats_iterator {
266 ($iterator_type:ident, $func:ident, $bytes_func:ident, $stat_value_type:ident, $convert_func: ident) => {
267 struct $iterator_type<'a, I>
268 where
269 I: Iterator<Item = Option<&'a ParquetStatistics>>,
270 {
271 iter: I,
272 }
273
274 impl<'a, I> $iterator_type<'a, I>
275 where
276 I: Iterator<Item = Option<&'a ParquetStatistics>>,
277 {
278 fn new(iter: I) -> Self {
279 Self { iter }
280 }
281 }
282
283 impl<'a, I> Iterator for $iterator_type<'a, I>
284 where
285 I: Iterator<Item = Option<&'a ParquetStatistics>>,
286 {
287 type Item = Option<$stat_value_type>;
288
289 fn next(&mut self) -> Option<Self::Item> {
290 let next = self.iter.next();
291 next.map(|x| {
292 x.and_then(|stats| match stats {
293 ParquetStatistics::Int32(s) => {
294 s.$func().map(|x| $stat_value_type::from(*x))
295 }
296 ParquetStatistics::Int64(s) => s
297 .$func()
298 .map(|x| $stat_value_type::try_from(*x).ok())
299 .flatten(),
300 ParquetStatistics::ByteArray(s) => s.$bytes_func().map($convert_func),
301 ParquetStatistics::FixedLenByteArray(s) => {
302 s.$bytes_func().map($convert_func)
303 }
304 _ => None,
305 })
306 })
307 }
308
309 fn size_hint(&self) -> (usize, Option<usize>) {
310 self.iter.size_hint()
311 }
312 }
313 };
314}
315
316make_decimal_stats_iterator!(
317 MinDecimal32StatsIterator,
318 min_opt,
319 min_bytes_opt,
320 i32,
321 from_bytes_to_i32
322);
323make_decimal_stats_iterator!(
324 MaxDecimal32StatsIterator,
325 max_opt,
326 max_bytes_opt,
327 i32,
328 from_bytes_to_i32
329);
330make_decimal_stats_iterator!(
331 MinDecimal64StatsIterator,
332 min_opt,
333 min_bytes_opt,
334 i64,
335 from_bytes_to_i64
336);
337make_decimal_stats_iterator!(
338 MaxDecimal64StatsIterator,
339 max_opt,
340 max_bytes_opt,
341 i64,
342 from_bytes_to_i64
343);
344make_decimal_stats_iterator!(
345 MinDecimal128StatsIterator,
346 min_opt,
347 min_bytes_opt,
348 i128,
349 from_bytes_to_i128
350);
351make_decimal_stats_iterator!(
352 MaxDecimal128StatsIterator,
353 max_opt,
354 max_bytes_opt,
355 i128,
356 from_bytes_to_i128
357);
358make_decimal_stats_iterator!(
359 MinDecimal256StatsIterator,
360 min_opt,
361 min_bytes_opt,
362 i256,
363 from_bytes_to_i256
364);
365make_decimal_stats_iterator!(
366 MaxDecimal256StatsIterator,
367 max_opt,
368 max_bytes_opt,
369 i256,
370 from_bytes_to_i256
371);
372
373macro_rules! make_timestamp_stats_iterator {
375 ($iterator_type:ident, $func:ident, $bound:tt) => {
376 struct $iterator_type<'a, I>
377 where
378 I: Iterator<Item = Option<&'a ParquetStatistics>>,
379 {
380 iter: I,
381 unit: TimeUnit,
382 }
383
384 impl<'a, I> $iterator_type<'a, I>
385 where
386 I: Iterator<Item = Option<&'a ParquetStatistics>>,
387 {
388 fn new(iter: I, unit: TimeUnit) -> Self {
389 Self { iter, unit }
390 }
391 }
392
393 impl<'a, I> Iterator for $iterator_type<'a, I>
394 where
395 I: Iterator<Item = Option<&'a ParquetStatistics>>,
396 {
397 type Item = Option<i64>;
398
399 fn next(&mut self) -> Option<Self::Item> {
400 self.iter.next().map(|statistics| {
401 let statistics = statistics?;
402 match statistics {
403 ParquetStatistics::Int64(values) => values.$func().copied(),
404 ParquetStatistics::Int96(values) if !statistics.is_min_max_deprecated() => {
407 int96_statistics(values.min_opt()?, values.max_opt()?, &self.unit)
408 .map(|bounds| bounds.$bound)
409 }
410 _ => None,
411 }
412 })
413 }
414
415 fn size_hint(&self) -> (usize, Option<usize>) {
416 self.iter.size_hint()
417 }
418 }
419 };
420}
421
422make_timestamp_stats_iterator!(MinTimestampStatsIterator, min_opt, 0);
423make_timestamp_stats_iterator!(MaxTimestampStatsIterator, max_opt, 1);
424
425macro_rules! get_statistics {
432 (Min, $data_type: ident, $iterator: ident, $physical_type: ident) => {
433 get_statistics!(
434 $data_type,
435 $iterator,
436 $physical_type,
437 MinBooleanStatsIterator,
438 MinInt32StatsIterator,
439 MinInt64StatsIterator,
440 MinTimestampStatsIterator,
441 MinFloatStatsIterator,
442 MinDoubleStatsIterator,
443 MinByteArrayStatsIterator,
444 MinFixedLenByteArrayStatsIterator,
445 MinDecimal32StatsIterator,
446 MinDecimal64StatsIterator,
447 MinDecimal128StatsIterator,
448 MinDecimal256StatsIterator,
449 min_statistics
450 )
451 };
452 (Max, $data_type: ident, $iterator: ident, $physical_type: ident) => {
453 get_statistics!(
454 $data_type,
455 $iterator,
456 $physical_type,
457 MaxBooleanStatsIterator,
458 MaxInt32StatsIterator,
459 MaxInt64StatsIterator,
460 MaxTimestampStatsIterator,
461 MaxFloatStatsIterator,
462 MaxDoubleStatsIterator,
463 MaxByteArrayStatsIterator,
464 MaxFixedLenByteArrayStatsIterator,
465 MaxDecimal32StatsIterator,
466 MaxDecimal64StatsIterator,
467 MaxDecimal128StatsIterator,
468 MaxDecimal256StatsIterator,
469 max_statistics
470 )
471 };
472 (
473 $data_type: ident,
474 $iterator: ident,
475 $physical_type: ident,
476 $boolean_iter: ident,
477 $int32_iter: ident,
478 $int64_iter: ident,
479 $timestamp_iter: ident,
480 $float_iter: ident,
481 $double_iter: ident,
482 $byte_array_iter: ident,
483 $fixed_len_byte_array_iter: ident,
484 $decimal32_iter: ident,
485 $decimal64_iter: ident,
486 $decimal128_iter: ident,
487 $decimal256_iter: ident,
488 $dictionary_statistics: ident
489 ) => {
490 match $data_type {
491 DataType::Boolean => Ok(Arc::new(BooleanArray::from_iter(
492 $boolean_iter::new($iterator).map(|x| x.copied()),
493 ))),
494 DataType::Int8 => Ok(Arc::new(Int8Array::from_iter(
495 $int32_iter::new($iterator).map(|x| {
496 x.and_then(|x| i8::try_from(*x).ok())
497 }),
498 ))),
499 DataType::Int16 => Ok(Arc::new(Int16Array::from_iter(
500 $int32_iter::new($iterator).map(|x| {
501 x.and_then(|x| i16::try_from(*x).ok())
502 }),
503 ))),
504 DataType::Int32 => Ok(Arc::new(Int32Array::from_iter(
505 $int32_iter::new($iterator).map(|x| x.copied()),
506 ))),
507 DataType::Int64 => Ok(Arc::new(Int64Array::from_iter(
508 $int64_iter::new($iterator).map(|x| x.copied()),
509 ))),
510 DataType::UInt8 => Ok(Arc::new(UInt8Array::from_iter(
511 $int32_iter::new($iterator).map(|x| {
512 x.and_then(|x| u8::try_from(*x).ok())
513 }),
514 ))),
515 DataType::UInt16 => Ok(Arc::new(UInt16Array::from_iter(
516 $int32_iter::new($iterator).map(|x| {
517 x.and_then(|x| u16::try_from(*x).ok())
518 }),
519 ))),
520 DataType::UInt32 => Ok(Arc::new(UInt32Array::from_iter(
521 $int32_iter::new($iterator).map(|x| x.map(|x| *x as u32)),
522 ))),
523 DataType::UInt64 => Ok(Arc::new(UInt64Array::from_iter(
524 $int64_iter::new($iterator).map(|x| x.map(|x| *x as u64)),
525 ))),
526 DataType::Float16 => Ok(Arc::new(Float16Array::from_iter(
527 $fixed_len_byte_array_iter::new($iterator).map(|x| x.and_then(|x| {
528 from_bytes_to_f16(x)
529 })),
530 ))),
531 DataType::Float32 => Ok(Arc::new(Float32Array::from_iter(
532 $float_iter::new($iterator).map(|x| x.copied()),
533 ))),
534 DataType::Float64 => Ok(Arc::new(Float64Array::from_iter(
535 $double_iter::new($iterator).map(|x| x.copied()),
536 ))),
537 DataType::Date32 => Ok(Arc::new(Date32Array::from_iter(
538 $int32_iter::new($iterator).map(|x| x.copied()),
539 ))),
540 DataType::Date64 if $physical_type == Some(PhysicalType::INT32) => Ok(Arc::new(Date64Array::from_iter(
541 $int32_iter::new($iterator)
542 .map(|x| x.map(|x| i64::from(*x) * 24 * 60 * 60 * 1000))))),
543 DataType::Date64 if $physical_type == Some(PhysicalType::INT64) => Ok(Arc::new(Date64Array::from_iter(
544 $int64_iter::new($iterator).map(|x| x.copied()),))),
545 DataType::Timestamp(unit, timezone) =>{
546 let iter = $timestamp_iter::new($iterator, *unit);
547 Ok(match unit {
548 TimeUnit::Second => Arc::new(TimestampSecondArray::from_iter(iter).with_timezone_opt(timezone.clone())),
549 TimeUnit::Millisecond => Arc::new(TimestampMillisecondArray::from_iter(iter).with_timezone_opt(timezone.clone())),
550 TimeUnit::Microsecond => Arc::new(TimestampMicrosecondArray::from_iter(iter).with_timezone_opt(timezone.clone())),
551 TimeUnit::Nanosecond => Arc::new(TimestampNanosecondArray::from_iter(iter).with_timezone_opt(timezone.clone())),
552 })
553 },
554 DataType::Time32(unit) => {
555 Ok(match unit {
556 TimeUnit::Second => Arc::new(Time32SecondArray::from_iter(
557 $int32_iter::new($iterator).map(|x| x.copied()),
558 )),
559 TimeUnit::Millisecond => Arc::new(Time32MillisecondArray::from_iter(
560 $int32_iter::new($iterator).map(|x| x.copied()),
561 )),
562 _ => {
563 let len = $iterator.count();
564 new_null_array($data_type, len)
566 }
567 })
568 },
569 DataType::Time64(unit) => {
570 Ok(match unit {
571 TimeUnit::Microsecond => Arc::new(Time64MicrosecondArray::from_iter(
572 $int64_iter::new($iterator).map(|x| x.copied()),
573 )),
574 TimeUnit::Nanosecond => Arc::new(Time64NanosecondArray::from_iter(
575 $int64_iter::new($iterator).map(|x| x.copied()),
576 )),
577 _ => {
578 let len = $iterator.count();
579 new_null_array($data_type, len)
581 }
582 })
583 },
584 DataType::Binary => Ok(Arc::new(BinaryArray::from_iter(
585 $byte_array_iter::new($iterator)
586 ))),
587 DataType::LargeBinary => Ok(Arc::new(LargeBinaryArray::from_iter(
588 $byte_array_iter::new($iterator)
589 ))),
590 DataType::Utf8 => {
591 let iterator = $byte_array_iter::new($iterator);
592 let mut builder = StringBuilder::new();
593 for x in iterator {
594 let Some(x) = x else {
595 builder.append_null(); continue;
597 };
598
599 let Ok(x) = std::str::from_utf8(x) else {
600 builder.append_null();
601 continue;
602 };
603
604 builder.append_value(x);
605 }
606 Ok(Arc::new(builder.finish()))
607 },
608 DataType::LargeUtf8 => {
609 let iterator = $byte_array_iter::new($iterator);
610 let mut builder = LargeStringBuilder::new();
611 for x in iterator {
612 let Some(x) = x else {
613 builder.append_null(); continue;
615 };
616
617 let Ok(x) = std::str::from_utf8(x) else {
618 builder.append_null();
619 continue;
620 };
621
622 builder.append_value(x);
623 }
624 Ok(Arc::new(builder.finish()))
625 },
626 DataType::FixedSizeBinary(size) => {
627 let iterator = $fixed_len_byte_array_iter::new($iterator);
628 let mut builder = FixedSizeBinaryBuilder::new(*size);
629 for x in iterator {
630 let Some(x) = x else {
631 builder.append_null(); continue;
633 };
634
635 if x.len().try_into() != Ok(*size){
637 builder.append_null();
638 continue;
639 }
640
641 builder.append_value(x).expect("ensure to append successfully here, because size have been checked before");
642 }
643 Ok(Arc::new(builder.finish()))
644 },
645 DataType::Decimal32(precision, scale) => {
646 let arr = Decimal32Array::from_iter(
647 $decimal32_iter::new($iterator)
648 ).with_precision_and_scale(*precision, *scale)?;
649 Ok(Arc::new(arr))
650 },
651 DataType::Decimal64(precision, scale) => {
652 let arr = Decimal64Array::from_iter(
653 $decimal64_iter::new($iterator)
654 ).with_precision_and_scale(*precision, *scale)?;
655 Ok(Arc::new(arr))
656 },
657 DataType::Decimal128(precision, scale) => {
658 let arr = Decimal128Array::from_iter(
659 $decimal128_iter::new($iterator)
660 ).with_precision_and_scale(*precision, *scale)?;
661 Ok(Arc::new(arr))
662 },
663 DataType::Decimal256(precision, scale) => {
664 let arr = Decimal256Array::from_iter(
665 $decimal256_iter::new($iterator)
666 ).with_precision_and_scale(*precision, *scale)?;
667 Ok(Arc::new(arr))
668 },
669 DataType::Dictionary(_, value_type) => {
670 $dictionary_statistics(value_type, $iterator, $physical_type)
671 },
672 DataType::Utf8View => {
673 let iterator = $byte_array_iter::new($iterator);
674 let mut builder = StringViewBuilder::new();
675 for x in iterator {
676 let Some(x) = x else {
677 builder.append_null(); continue;
679 };
680
681 let Ok(x) = std::str::from_utf8(x) else {
682 builder.append_null();
683 continue;
684 };
685
686 builder.append_value(x);
687 }
688 Ok(Arc::new(builder.finish()))
689 },
690 DataType::BinaryView => {
691 let iterator = $byte_array_iter::new($iterator);
692 let mut builder = BinaryViewBuilder::new();
693 for x in iterator {
694 let Some(x) = x else {
695 builder.append_null(); continue;
697 };
698
699 builder.append_value(x);
700 }
701 Ok(Arc::new(builder.finish()))
702 }
703
704 DataType::Map(_,_) |
705 DataType::Duration(_) |
706 DataType::Interval(_) |
707 DataType::Date64 | DataType::Null |
709 DataType::List(_) |
710 DataType::ListView(_) |
711 DataType::FixedSizeList(_, _) |
712 DataType::LargeList(_) |
713 DataType::LargeListView(_) |
714 DataType::Struct(_) |
715 DataType::Union(_, _) |
716 DataType::RunEndEncoded(_, _) => {
717 let len = $iterator.count();
718 Ok(new_null_array($data_type, len))
720 }
721 }
722 };
723}
724
725macro_rules! get_data_page_statistics {
726 (Min, $data_type: ident, $iterator: ident, $physical_type: ident) => {
727 get_data_page_statistics!(
728 $data_type,
729 $iterator,
730 $physical_type,
731 min_values_iter,
732 true,
733 min_page_statistics
734 )
735 };
736 (Max, $data_type: ident, $iterator: ident, $physical_type: ident) => {
737 get_data_page_statistics!(
738 $data_type,
739 $iterator,
740 $physical_type,
741 max_values_iter,
742 false,
743 max_page_statistics
744 )
745 };
746 (
747 $data_type: ident,
748 $iterator: ident,
749 $physical_type: ident,
750 $values_iter: ident,
751 $is_min: expr,
752 $page_statistics: ident
753 ) => {{
754 let chunks: Vec<(usize, Option<&ColumnIndexMetaData>)> = $iterator.collect();
755 let capacity: usize = chunks.iter().map(|c| c.0).sum();
756 match $data_type {
757 DataType::Boolean => {
758 let mut b = BooleanBuilder::with_capacity(capacity);
759 for (len, index) in chunks {
760 match index {
761 Some(ColumnIndexMetaData::BOOLEAN(index)) => {
762 for val in index.$values_iter() {
763 b.append_option(val.copied());
764 }
765 }
766 _ => b.append_nulls(len),
767 }
768 }
769 Ok(Arc::new(b.finish()))
770 },
771 DataType::UInt8 => {
772 let mut b = UInt8Builder::with_capacity(capacity);
773 for (len, index) in chunks {
774 match index {
775 Some(ColumnIndexMetaData::INT32(index)) => {
776 b.extend_from_iter_option(
777 index.$values_iter()
778 .map(|val| val.and_then(|&x| u8::try_from(x).ok())),
779 );
780 }
781 _ => b.append_nulls(len),
782 }
783 }
784 Ok(Arc::new(b.finish()))
785 },
786 DataType::UInt16 => {
787 let mut b = UInt16Builder::with_capacity(capacity);
788 for (len, index) in chunks {
789 match index {
790 Some(ColumnIndexMetaData::INT32(index)) => {
791 b.extend_from_iter_option(
792 index.$values_iter()
793 .map(|val| val.and_then(|&x| u16::try_from(x).ok())),
794 );
795 }
796 _ => b.append_nulls(len),
797 }
798 }
799 Ok(Arc::new(b.finish()))
800 },
801 DataType::UInt32 => {
802 let mut b = UInt32Builder::with_capacity(capacity);
803 for (len, index) in chunks {
804 match index {
805 Some(ColumnIndexMetaData::INT32(index)) => {
806 b.extend_from_iter_option(
807 index.$values_iter()
808 .map(|val| val.map(|&x| x as u32)),
809 );
810 }
811 _ => b.append_nulls(len),
812 }
813 }
814 Ok(Arc::new(b.finish()))
815 },
816 DataType::UInt64 => {
817 let mut b = UInt64Builder::with_capacity(capacity);
818 for (len, index) in chunks {
819 match index {
820 Some(ColumnIndexMetaData::INT64(index)) => {
821 b.extend_from_iter_option(
822 index.$values_iter()
823 .map(|val| val.map(|&x| x as u64)),
824 );
825 }
826 _ => b.append_nulls(len),
827 }
828 }
829 Ok(Arc::new(b.finish()))
830 },
831 DataType::Int8 => {
832 let mut b = Int8Builder::with_capacity(capacity);
833 for (len, index) in chunks {
834 match index {
835 Some(ColumnIndexMetaData::INT32(index)) => {
836 b.extend_from_iter_option(
837 index.$values_iter()
838 .map(|val| val.and_then(|&x| i8::try_from(x).ok())),
839 );
840 }
841 _ => b.append_nulls(len),
842 }
843 }
844 Ok(Arc::new(b.finish()))
845 },
846 DataType::Int16 => {
847 let mut b = Int16Builder::with_capacity(capacity);
848 for (len, index) in chunks {
849 match index {
850 Some(ColumnIndexMetaData::INT32(index)) => {
851 b.extend_from_iter_option(
852 index.$values_iter()
853 .map(|val| val.and_then(|&x| i16::try_from(x).ok())),
854 );
855 }
856 _ => b.append_nulls(len),
857 }
858 }
859 Ok(Arc::new(b.finish()))
860 },
861 DataType::Int32 => {
862 let mut b = Int32Builder::with_capacity(capacity);
863 for (len, index) in chunks {
864 match index {
865 Some(ColumnIndexMetaData::INT32(index)) => {
866 b.extend_from_iter_option(
867 index.$values_iter()
868 .map(|val| val.copied()),
869 );
870 }
871 _ => b.append_nulls(len),
872 }
873 }
874 Ok(Arc::new(b.finish()))
875 },
876 DataType::Int64 => {
877 let mut b = Int64Builder::with_capacity(capacity);
878 for (len, index) in chunks {
879 match index {
880 Some(ColumnIndexMetaData::INT64(index)) => {
881 b.extend_from_iter_option(
882 index.$values_iter()
883 .map(|val| val.copied()),
884 );
885 }
886 _ => b.append_nulls(len),
887 }
888 }
889 Ok(Arc::new(b.finish()))
890 },
891 DataType::Float16 => {
892 let mut b = Float16Builder::with_capacity(capacity);
893 for (len, index) in chunks {
894 match index {
895 Some(ColumnIndexMetaData::FIXED_LEN_BYTE_ARRAY(index)) => {
896 b.extend_from_iter_option(
897 index.$values_iter()
898 .map(|val| val.and_then(|x| from_bytes_to_f16(x))),
899 );
900 }
901 _ => b.append_nulls(len),
902 }
903 }
904 Ok(Arc::new(b.finish()))
905 },
906 DataType::Float32 => {
907 let mut b = Float32Builder::with_capacity(capacity);
908 for (len, index) in chunks {
909 match index {
910 Some(ColumnIndexMetaData::FLOAT(index)) => {
911 b.extend_from_iter_option(
912 index.$values_iter()
913 .map(|val| val.copied()),
914 );
915 }
916 _ => b.append_nulls(len),
917 }
918 }
919 Ok(Arc::new(b.finish()))
920 },
921 DataType::Float64 => {
922 let mut b = Float64Builder::with_capacity(capacity);
923 for (len, index) in chunks {
924 match index {
925 Some(ColumnIndexMetaData::DOUBLE(index)) => {
926 b.extend_from_iter_option(
927 index.$values_iter()
928 .map(|val| val.copied()),
929 );
930 }
931 _ => b.append_nulls(len),
932 }
933 }
934 Ok(Arc::new(b.finish()))
935 },
936 DataType::Binary => {
937 let mut b = BinaryBuilder::with_capacity(capacity, capacity * 10);
938 for (len, index) in chunks {
939 match index {
940 Some(ColumnIndexMetaData::BYTE_ARRAY(index)) => {
941 for val in index.$values_iter() {
942 b.append_option(val.map(|x| x.as_ref()));
943 }
944 }
945 _ => b.append_nulls(len),
946 }
947 }
948 Ok(Arc::new(b.finish()))
949 },
950 DataType::LargeBinary => {
951 let mut b = LargeBinaryBuilder::with_capacity(capacity, capacity * 10);
952 for (len, index) in chunks {
953 match index {
954 Some(ColumnIndexMetaData::BYTE_ARRAY(index)) => {
955 for val in index.$values_iter() {
956 b.append_option(val.map(|x| x.as_ref()));
957 }
958 }
959 _ => b.append_nulls(len),
960 }
961 }
962 Ok(Arc::new(b.finish()))
963 },
964 DataType::Utf8 => {
965 let mut b = StringBuilder::with_capacity(capacity, capacity * 10);
966 for (len, index) in chunks {
967 match index {
968 Some(ColumnIndexMetaData::BYTE_ARRAY(index)) => {
969 for val in index.$values_iter() {
970 match val {
971 Some(x) => match std::str::from_utf8(x.as_ref()) {
972 Ok(s) => b.append_value(s),
973 _ => b.append_null(),
974 }
975 None => b.append_null(),
976 }
977 }
978 }
979 _ => b.append_nulls(len),
980 }
981 }
982 Ok(Arc::new(b.finish()))
983 },
984 DataType::LargeUtf8 => {
985 let mut b = LargeStringBuilder::with_capacity(capacity, capacity * 10);
986 for (len, index) in chunks {
987 match index {
988 Some(ColumnIndexMetaData::BYTE_ARRAY(index)) => {
989 for val in index.$values_iter() {
990 match val {
991 Some(x) => match std::str::from_utf8(x.as_ref()) {
992 Ok(s) => b.append_value(s),
993 _ => b.append_null(),
994 }
995 None => b.append_null(),
996 }
997 }
998 }
999 _ => b.append_nulls(len),
1000 }
1001 }
1002 Ok(Arc::new(b.finish()))
1003 },
1004 DataType::Dictionary(_, value_type) => {
1005 $page_statistics(value_type, chunks.into_iter(), $physical_type)
1006 },
1007 DataType::Timestamp(unit, timezone) => {
1008 match unit {
1009 TimeUnit::Second => {
1010 let mut b = TimestampSecondBuilder::with_capacity(capacity);
1011 for (len, index) in chunks {
1012 match index {
1013 Some(ColumnIndexMetaData::INT64(index)) => {
1014 b.extend_from_iter_option(
1015 index.$values_iter()
1016 .map(|val| val.copied()),
1017 );
1018 }
1019 Some(ColumnIndexMetaData::INT96(index)) => {
1020 b.extend_from_iter_option(
1021 index.min_values_iter().zip(index.max_values_iter())
1022 .map(|(min, max)| {
1023 let (min, max) = int96_statistics(min?, max?, unit)?;
1024 Some(if $is_min { min } else { max })
1025 }),
1026 );
1027 }
1028 _ => b.append_nulls(len),
1029 }
1030 }
1031 Ok(Arc::new(b.finish().with_timezone_opt(timezone.clone())))
1032 }
1033 TimeUnit::Millisecond => {
1034 let mut b = TimestampMillisecondBuilder::with_capacity(capacity);
1035 for (len, index) in chunks {
1036 match index {
1037 Some(ColumnIndexMetaData::INT64(index)) => {
1038 b.extend_from_iter_option(
1039 index.$values_iter()
1040 .map(|val| val.copied()),
1041 );
1042 }
1043 Some(ColumnIndexMetaData::INT96(index)) => {
1044 b.extend_from_iter_option(
1045 index.min_values_iter().zip(index.max_values_iter())
1046 .map(|(min, max)| {
1047 let (min, max) = int96_statistics(min?, max?, unit)?;
1048 Some(if $is_min { min } else { max })
1049 }),
1050 );
1051 }
1052 _ => b.append_nulls(len),
1053 }
1054 }
1055 Ok(Arc::new(b.finish().with_timezone_opt(timezone.clone())))
1056 }
1057 TimeUnit::Microsecond => {
1058 let mut b = TimestampMicrosecondBuilder::with_capacity(capacity);
1059 for (len, index) in chunks {
1060 match index {
1061 Some(ColumnIndexMetaData::INT64(index)) => {
1062 b.extend_from_iter_option(
1063 index.$values_iter()
1064 .map(|val| val.copied()),
1065 );
1066 }
1067 Some(ColumnIndexMetaData::INT96(index)) => {
1068 b.extend_from_iter_option(
1069 index.min_values_iter().zip(index.max_values_iter())
1070 .map(|(min, max)| {
1071 let (min, max) = int96_statistics(min?, max?, unit)?;
1072 Some(if $is_min { min } else { max })
1073 }),
1074 );
1075 }
1076 _ => b.append_nulls(len),
1077 }
1078 }
1079 Ok(Arc::new(b.finish().with_timezone_opt(timezone.clone())))
1080 }
1081 TimeUnit::Nanosecond => {
1082 let mut b = TimestampNanosecondBuilder::with_capacity(capacity);
1083 for (len, index) in chunks {
1084 match index {
1085 Some(ColumnIndexMetaData::INT64(index)) => {
1086 b.extend_from_iter_option(
1087 index.$values_iter()
1088 .map(|val| val.copied()),
1089 );
1090 }
1091 Some(ColumnIndexMetaData::INT96(index)) => {
1092 b.extend_from_iter_option(
1093 index.min_values_iter().zip(index.max_values_iter())
1094 .map(|(min, max)| {
1095 let (min, max) = int96_statistics(min?, max?, unit)?;
1096 Some(if $is_min { min } else { max })
1097 }),
1098 );
1099 }
1100 _ => b.append_nulls(len),
1101 }
1102 }
1103 Ok(Arc::new(b.finish().with_timezone_opt(timezone.clone())))
1104 }
1105 }
1106 },
1107 DataType::Date32 => {
1108 let mut b = Date32Builder::with_capacity(capacity);
1109 for (len, index) in chunks {
1110 match index {
1111 Some(ColumnIndexMetaData::INT32(index)) => {
1112 b.extend_from_iter_option(
1113 index.$values_iter()
1114 .map(|val| val.copied()),
1115 );
1116 }
1117 _ => b.append_nulls(len),
1118 }
1119 }
1120 Ok(Arc::new(b.finish()))
1121 },
1122 DataType::Date64 if $physical_type == Some(PhysicalType::INT32)=> {
1123 let mut b = Date64Builder::with_capacity(capacity);
1124 for (len, index) in chunks {
1125 match index {
1126 Some(ColumnIndexMetaData::INT32(index)) => {
1127 b.extend_from_iter_option(
1128 index.$values_iter()
1129 .map(|val| val.map(|&x| (x as i64) * 24 * 60 * 60 * 1000)),
1130 );
1131 }
1132 _ => b.append_nulls(len),
1133 }
1134 }
1135 Ok(Arc::new(b.finish()))
1136 },
1137 DataType::Date64 if $physical_type == Some(PhysicalType::INT64) => {
1138 let mut b = Date64Builder::with_capacity(capacity);
1139 for (len, index) in chunks {
1140 match index {
1141 Some(ColumnIndexMetaData::INT64(index)) => {
1142 b.extend_from_iter_option(
1143 index.$values_iter()
1144 .map(|val| val.copied()),
1145 );
1146 }
1147 _ => b.append_nulls(len),
1148 }
1149 }
1150 Ok(Arc::new(b.finish()))
1151 },
1152 DataType::Decimal32(precision, scale) => {
1153 let mut b = Decimal32Builder::with_capacity(capacity);
1154 for (len, index) in chunks {
1155 match index {
1156 Some(ColumnIndexMetaData::INT32(index)) => {
1157 b.extend_from_iter_option(
1158 index.$values_iter()
1159 .map(|val| val.copied()),
1160 );
1161 }
1162 Some(ColumnIndexMetaData::INT64(index)) => {
1163 b.extend_from_iter_option(
1164 index.$values_iter()
1165 .map(|val| val.and_then(|&x| i32::try_from(x).ok())),
1166 );
1167 }
1168 Some(ColumnIndexMetaData::BYTE_ARRAY(index)) => {
1169 b.extend_from_iter_option(
1170 index.$values_iter()
1171 .map(|val| val.map(|x| from_bytes_to_i32(x.as_ref()))),
1172 );
1173 }
1174 Some(ColumnIndexMetaData::FIXED_LEN_BYTE_ARRAY(index)) => {
1175 b.extend_from_iter_option(
1176 index.$values_iter()
1177 .map(|val| val.map(|x| from_bytes_to_i32(x.as_ref()))),
1178 );
1179 }
1180 _ => b.append_nulls(len),
1181 }
1182 }
1183 Ok(Arc::new(b.with_precision_and_scale(*precision, *scale)?.finish()))
1184 },
1185 DataType::Decimal64(precision, scale) => {
1186 let mut b = Decimal64Builder::with_capacity(capacity);
1187 for (len, index) in chunks {
1188 match index {
1189 Some(ColumnIndexMetaData::INT32(index)) => {
1190 b.extend_from_iter_option(
1191 index.$values_iter()
1192 .map(|val| val.map(|x| *x as i64)),
1193 );
1194 }
1195 Some(ColumnIndexMetaData::INT64(index)) => {
1196 b.extend_from_iter_option(
1197 index.$values_iter()
1198 .map(|val| val.copied()),
1199 );
1200 }
1201 Some(ColumnIndexMetaData::BYTE_ARRAY(index)) => {
1202 b.extend_from_iter_option(
1203 index.$values_iter()
1204 .map(|val| val.map(|x| from_bytes_to_i64(x.as_ref()))),
1205 );
1206 }
1207 Some(ColumnIndexMetaData::FIXED_LEN_BYTE_ARRAY(index)) => {
1208 b.extend_from_iter_option(
1209 index.$values_iter()
1210 .map(|val| val.map(|x| from_bytes_to_i64(x.as_ref()))),
1211 );
1212 }
1213 _ => b.append_nulls(len),
1214 }
1215 }
1216 Ok(Arc::new(b.with_precision_and_scale(*precision, *scale)?.finish()))
1217 },
1218 DataType::Decimal128(precision, scale) => {
1219 let mut b = Decimal128Array::builder(capacity);
1220 for (len, index) in chunks {
1221 match index {
1222 Some(ColumnIndexMetaData::INT32(index)) => {
1223 b.extend_from_iter_option(
1224 index.$values_iter()
1225 .map(|val| val.map(|x| *x as i128)),
1226 );
1227 }
1228 Some(ColumnIndexMetaData::INT64(index)) => {
1229 b.extend_from_iter_option(
1230 index.$values_iter()
1231 .map(|val| val.map(|x| *x as i128)),
1232 );
1233 }
1234 Some(ColumnIndexMetaData::BYTE_ARRAY(index)) => {
1235 b.extend_from_iter_option(
1236 index.$values_iter()
1237 .map(|val| val.map(|x| from_bytes_to_i128(x.as_ref()))),
1238 );
1239 }
1240 Some(ColumnIndexMetaData::FIXED_LEN_BYTE_ARRAY(index)) => {
1241 b.extend_from_iter_option(
1242 index.$values_iter()
1243 .map(|val| val.map(|x| from_bytes_to_i128(x.as_ref()))),
1244 );
1245 }
1246 _ => b.append_nulls(len),
1247 }
1248 }
1249 Ok(Arc::new(b.with_precision_and_scale(*precision, *scale)?.finish()))
1250 },
1251 DataType::Decimal256(precision, scale) => {
1252 let mut b = Decimal256Array::builder(capacity);
1253 for (len, index) in chunks {
1254 match index {
1255 Some(ColumnIndexMetaData::INT32(index)) => {
1256 b.extend_from_iter_option(
1257 index.$values_iter()
1258 .map(|val| val.map(|x| i256::from_i128(*x as i128))),
1259 );
1260 }
1261 Some(ColumnIndexMetaData::INT64(index)) => {
1262 b.extend_from_iter_option(
1263 index.$values_iter()
1264 .map(|val| val.map(|x| i256::from_i128(*x as i128))),
1265 );
1266 }
1267 Some(ColumnIndexMetaData::BYTE_ARRAY(index)) => {
1268 b.extend_from_iter_option(
1269 index.$values_iter()
1270 .map(|val| val.map(|x| from_bytes_to_i256(x.as_ref()))),
1271 );
1272 }
1273 Some(ColumnIndexMetaData::FIXED_LEN_BYTE_ARRAY(index)) => {
1274 b.extend_from_iter_option(
1275 index.$values_iter()
1276 .map(|val| val.map(|x| from_bytes_to_i256(x.as_ref()))),
1277 );
1278 }
1279 _ => b.append_nulls(len),
1280 }
1281 }
1282 Ok(Arc::new(b.with_precision_and_scale(*precision, *scale)?.finish()))
1283 },
1284 DataType::Time32(unit) => {
1285 match unit {
1286 TimeUnit::Second => {
1287 let mut b = Time32SecondBuilder::with_capacity(capacity);
1288 for (len, index) in chunks {
1289 match index {
1290 Some(ColumnIndexMetaData::INT32(index)) => {
1291 b.extend_from_iter_option(
1292 index.$values_iter()
1293 .map(|val| val.copied()),
1294 );
1295 }
1296 _ => b.append_nulls(len),
1297 }
1298 }
1299 Ok(Arc::new(b.finish()))
1300 }
1301 TimeUnit::Millisecond => {
1302 let mut b = Time32MillisecondBuilder::with_capacity(capacity);
1303 for (len, index) in chunks {
1304 match index {
1305 Some(ColumnIndexMetaData::INT32(index)) => {
1306 b.extend_from_iter_option(
1307 index.$values_iter()
1308 .map(|val| val.copied()),
1309 );
1310 }
1311 _ => b.append_nulls(len),
1312 }
1313 }
1314 Ok(Arc::new(b.finish()))
1315 }
1316 _ => {
1317 Ok(new_null_array($data_type, capacity))
1318 }
1319 }
1320 }
1321 DataType::Time64(unit) => {
1322 match unit {
1323 TimeUnit::Microsecond => {
1324 let mut b = Time64MicrosecondBuilder::with_capacity(capacity);
1325 for (len, index) in chunks {
1326 match index {
1327 Some(ColumnIndexMetaData::INT64(index)) => {
1328 b.extend_from_iter_option(
1329 index.$values_iter()
1330 .map(|val| val.copied()),
1331 );
1332 }
1333 _ => b.append_nulls(len),
1334 }
1335 }
1336 Ok(Arc::new(b.finish()))
1337 }
1338 TimeUnit::Nanosecond => {
1339 let mut b = Time64NanosecondBuilder::with_capacity(capacity);
1340 for (len, index) in chunks {
1341 match index {
1342 Some(ColumnIndexMetaData::INT64(index)) => {
1343 b.extend_from_iter_option(
1344 index.$values_iter()
1345 .map(|val| val.copied()),
1346 );
1347 }
1348 _ => b.append_nulls(len),
1349 }
1350 }
1351 Ok(Arc::new(b.finish()))
1352 }
1353 _ => {
1354 Ok(new_null_array($data_type, capacity))
1355 }
1356 }
1357 },
1358 DataType::FixedSizeBinary(size) => {
1359 let mut b = FixedSizeBinaryBuilder::with_capacity(capacity, *size);
1360 for (len, index) in chunks {
1361 match index {
1362 Some(ColumnIndexMetaData::FIXED_LEN_BYTE_ARRAY(index)) => {
1363 for val in index.$values_iter() {
1364 match val {
1365 Some(v) => {
1366 if v.len() == *size as usize {
1367 let _ = b.append_value(v.as_ref())?;
1368 } else {
1369 b.append_null();
1370 }
1371 }
1372 None => b.append_null(),
1373 }
1374 }
1375 }
1376 _ => b.append_nulls(len),
1377 }
1378 }
1379 Ok(Arc::new(b.finish()))
1380 },
1381 DataType::Utf8View => {
1382 let mut b = StringViewBuilder::with_capacity(capacity);
1383 for (len, index) in chunks {
1384 match index {
1385 Some(ColumnIndexMetaData::BYTE_ARRAY(index)) => {
1386 for val in index.$values_iter() {
1387 match val {
1388 Some(x) => match std::str::from_utf8(x.as_ref()) {
1389 Ok(s) => b.append_value(s),
1390 _ => b.append_null(),
1391 }
1392 None => b.append_null(),
1393 }
1394 }
1395 }
1396 _ => {
1397 for _ in 0..len { b.append_null(); }
1398 }
1399 }
1400 }
1401 Ok(Arc::new(b.finish()))
1402 },
1403 DataType::BinaryView => {
1404 let mut b = BinaryViewBuilder::with_capacity(capacity);
1405 for (len, index) in chunks {
1406 match index {
1407 Some(ColumnIndexMetaData::BYTE_ARRAY(index)) => {
1408 for val in index.$values_iter() {
1409 match val {
1410 Some(v) => b.append_value(v.as_ref()),
1411 None => b.append_null(),
1412 }
1413 }
1414 }
1415 _ => {
1416 for _ in 0..len { b.append_null(); }
1417 }
1418 }
1419 }
1420 Ok(Arc::new(b.finish()))
1421 },
1422 DataType::Date64 | DataType::Null |
1424 DataType::Duration(_) |
1425 DataType::Interval(_) |
1426 DataType::List(_) |
1427 DataType::ListView(_) |
1428 DataType::FixedSizeList(_, _) |
1429 DataType::LargeList(_) |
1430 DataType::LargeListView(_) |
1431 DataType::Struct(_) |
1432 DataType::Union(_, _) |
1433 DataType::Map(_, _) |
1434 DataType::RunEndEncoded(_, _) => {
1435 Ok(new_null_array($data_type, capacity))
1437 },
1438 }
1439 }
1440 };
1441}
1442fn min_statistics<'a, I: Iterator<Item = Option<&'a ParquetStatistics>>>(
1447 data_type: &DataType,
1448 iterator: I,
1449 physical_type: Option<PhysicalType>,
1450) -> Result<ArrayRef> {
1451 get_statistics!(Min, data_type, iterator, physical_type)
1452}
1453
1454fn max_statistics<'a, I: Iterator<Item = Option<&'a ParquetStatistics>>>(
1458 data_type: &DataType,
1459 iterator: I,
1460 physical_type: Option<PhysicalType>,
1461) -> Result<ArrayRef> {
1462 get_statistics!(Max, data_type, iterator, physical_type)
1463}
1464
1465pub(crate) fn min_page_statistics<'a, I>(
1468 data_type: &DataType,
1469 iterator: I,
1470 physical_type: Option<PhysicalType>,
1471) -> Result<ArrayRef>
1472where
1473 I: Iterator<Item = (usize, Option<&'a ColumnIndexMetaData>)>,
1474{
1475 get_data_page_statistics!(Min, data_type, iterator, physical_type)
1476}
1477
1478pub(crate) fn max_page_statistics<'a, I>(
1481 data_type: &DataType,
1482 iterator: I,
1483 physical_type: Option<PhysicalType>,
1484) -> Result<ArrayRef>
1485where
1486 I: Iterator<Item = (usize, Option<&'a ColumnIndexMetaData>)>,
1487{
1488 get_data_page_statistics!(Max, data_type, iterator, physical_type)
1489}
1490
1491pub(crate) fn null_counts_page_statistics<'a, I>(iterator: I) -> Result<UInt64Array>
1496where
1497 I: Iterator<Item = (usize, Option<&'a ColumnIndexMetaData>)>,
1498{
1499 let chunks: Vec<_> = iterator.collect();
1500 let total_capacity: usize = chunks.iter().map(|(len, _)| *len).sum();
1501 let mut values = Vec::with_capacity(total_capacity);
1502 let mut nulls = NullBufferBuilder::new(total_capacity);
1503 for (len, index) in chunks {
1504 match index {
1505 Some(index) if index.null_counts().is_some() => {
1506 values.extend(index.null_counts().unwrap().iter().map(|&x| x as u64));
1507 nulls.append_n_non_nulls(len);
1508 }
1509 _ => {
1510 values.resize(values.len() + len, 0);
1511 nulls.append_n_nulls(len);
1512 }
1513 }
1514 }
1515 let null_buffer = nulls.build();
1516 let array = UInt64Array::new(values.into(), null_buffer);
1517 Ok(array)
1518}
1519
1520pub(crate) fn nan_counts_page_statistics<'a, I>(iterator: I) -> Result<UInt64Array>
1525where
1526 I: Iterator<Item = (usize, Option<&'a ColumnIndexMetaData>)>,
1527{
1528 let chunks: Vec<_> = iterator.collect();
1529 let total_capacity: usize = chunks.iter().map(|(len, _)| *len).sum();
1530 let mut values = Vec::with_capacity(total_capacity);
1531 let mut nulls = NullBufferBuilder::new(total_capacity);
1532 for (len, index) in chunks {
1533 match index {
1534 Some(index) if index.nan_counts().is_some() => {
1535 values.extend(index.nan_counts().unwrap().iter().map(|&x| x as u64));
1536 nulls.append_n_non_nulls(len);
1537 }
1538 _ => {
1539 values.resize(values.len() + len, 0);
1540 nulls.append_n_nulls(len);
1541 }
1542 }
1543 }
1544 let null_buffer = nulls.build();
1545 let array = UInt64Array::new(values.into(), null_buffer);
1546 Ok(array)
1547}
1548
1549#[derive(Debug)]
1580pub struct StatisticsConverter<'a> {
1581 parquet_column_index: Option<usize>,
1583 arrow_field: &'a Field,
1585 missing_null_counts_as_zero: bool,
1587 physical_type: Option<PhysicalType>,
1589 column_order: Option<ColumnOrder>,
1591}
1592
1593impl<'a> StatisticsConverter<'a> {
1594 pub fn parquet_column_index(&self) -> Option<usize> {
1599 self.parquet_column_index
1600 }
1601
1602 pub fn arrow_field(&self) -> &'a Field {
1604 self.arrow_field
1605 }
1606
1607 pub fn with_missing_null_counts_as_zero(mut self, missing_null_counts_as_zero: bool) -> Self {
1620 self.missing_null_counts_as_zero = missing_null_counts_as_zero;
1621 self
1622 }
1623
1624 pub fn with_column_orders(mut self, column_orders: Option<&[ColumnOrder]>) -> Self {
1636 self.column_order = self
1637 .parquet_column_index
1638 .and_then(|index| column_orders?.get(index).copied());
1639 self
1640 }
1641
1642 pub fn row_group_row_counts<I>(&self, metadatas: I) -> Result<Option<UInt64Array>>
1673 where
1674 I: IntoIterator<Item = &'a RowGroupMetaData>,
1675 {
1676 let Some(_) = self.parquet_column_index else {
1677 return Ok(None);
1678 };
1679
1680 let mut builder = UInt64Array::builder(10);
1681 for metadata in metadatas {
1682 let row_count = metadata.num_rows();
1683 let row_count: u64 = row_count.try_into().map_err(|e| {
1684 arrow_err!(format!(
1685 "Parquet row count {row_count} too large to convert to u64: {e}"
1686 ))
1687 })?;
1688 builder.append_value(row_count);
1689 }
1690 Ok(Some(builder.finish()))
1691 }
1692
1693 pub fn try_new<'b>(
1708 column_name: &'b str,
1709 arrow_schema: &'a Schema,
1710 parquet_schema: &'a SchemaDescriptor,
1711 ) -> Result<Self> {
1712 let Some((_idx, arrow_field)) = arrow_schema.column_with_name(column_name) else {
1714 return Err(arrow_err!(format!(
1715 "Column '{}' not found in schema for statistics conversion",
1716 column_name
1717 )));
1718 };
1719
1720 let parquet_index = match parquet_column(parquet_schema, arrow_schema, column_name) {
1722 Some((parquet_idx, matched_field)) => {
1723 if matched_field.as_ref() != arrow_field {
1725 return Err(arrow_err!(format!(
1726 "Matched column '{:?}' does not match original matched column '{:?}'",
1727 matched_field, arrow_field
1728 )));
1729 }
1730 Some(parquet_idx)
1731 }
1732 None => None,
1733 };
1734
1735 Ok(Self {
1736 parquet_column_index: parquet_index,
1737 arrow_field,
1738 missing_null_counts_as_zero: true,
1739 physical_type: parquet_index.map(|idx| parquet_schema.column(idx).physical_type()),
1740 column_order: None,
1741 })
1742 }
1743
1744 pub fn from_column_index(
1766 parquet_column_index: usize,
1767 arrow_field: &'a Field,
1768 parquet_schema: &'a SchemaDescriptor,
1769 ) -> Result<Self> {
1770 if parquet_column_index >= parquet_schema.columns().len() {
1771 return Err(arrow_err!(format!(
1772 "Parquet column index {} out of bounds, column count {}",
1773 parquet_column_index,
1774 parquet_schema.columns().len()
1775 )));
1776 }
1777
1778 let physical_type = parquet_schema.column(parquet_column_index).physical_type();
1779
1780 Ok(Self {
1781 parquet_column_index: Some(parquet_column_index),
1782 arrow_field,
1783 missing_null_counts_as_zero: true,
1784 physical_type: Some(physical_type),
1785 column_order: None,
1786 })
1787 }
1788
1789 pub fn row_group_mins<I>(&self, metadatas: I) -> Result<ArrayRef>
1833 where
1834 I: IntoIterator<Item = &'a RowGroupMetaData>,
1835 {
1836 let data_type = self.arrow_field.data_type();
1837
1838 let Some(parquet_index) = self.parquet_column_index else {
1839 return Ok(self.make_null_array(data_type, metadatas));
1840 };
1841
1842 let iter = metadatas.into_iter().map(|x| {
1843 x.column(parquet_index)
1844 .statistics()
1845 .filter(|_| self.is_min_max_order_supported())
1846 });
1847 min_statistics(data_type, iter, self.physical_type)
1848 }
1849
1850 pub fn row_group_maxes<I>(&self, metadatas: I) -> Result<ArrayRef>
1854 where
1855 I: IntoIterator<Item = &'a RowGroupMetaData>,
1856 {
1857 let data_type = self.arrow_field.data_type();
1858
1859 let Some(parquet_index) = self.parquet_column_index else {
1860 return Ok(self.make_null_array(data_type, metadatas));
1861 };
1862
1863 let iter = metadatas.into_iter().map(|x| {
1864 x.column(parquet_index)
1865 .statistics()
1866 .filter(|_| self.is_min_max_order_supported())
1867 });
1868 max_statistics(data_type, iter, self.physical_type)
1869 }
1870
1871 pub fn row_group_is_max_value_exact<I>(&self, metadatas: I) -> Result<BooleanArray>
1875 where
1876 I: IntoIterator<Item = &'a RowGroupMetaData>,
1877 {
1878 let Some(parquet_index) = self.parquet_column_index else {
1879 let num_row_groups = metadatas.into_iter().count();
1880 return Ok(BooleanArray::from_iter(std::iter::repeat_n(
1881 None,
1882 num_row_groups,
1883 )));
1884 };
1885
1886 let is_max_value_exact = metadatas
1887 .into_iter()
1888 .map(|x| x.column(parquet_index).statistics())
1889 .map(|s| s.map(|s| s.max_is_exact()));
1890 Ok(BooleanArray::from_iter(is_max_value_exact))
1891 }
1892
1893 pub fn row_group_is_min_value_exact<I>(&self, metadatas: I) -> Result<BooleanArray>
1897 where
1898 I: IntoIterator<Item = &'a RowGroupMetaData>,
1899 {
1900 let Some(parquet_index) = self.parquet_column_index else {
1901 let num_row_groups = metadatas.into_iter().count();
1902 return Ok(BooleanArray::from_iter(std::iter::repeat_n(
1903 None,
1904 num_row_groups,
1905 )));
1906 };
1907
1908 let is_min_value_exact = metadatas
1909 .into_iter()
1910 .map(|x| x.column(parquet_index).statistics())
1911 .map(|s| s.map(|s| s.min_is_exact()));
1912 Ok(BooleanArray::from_iter(is_min_value_exact))
1913 }
1914
1915 pub fn row_group_null_counts<I>(&self, metadatas: I) -> Result<UInt64Array>
1919 where
1920 I: IntoIterator<Item = &'a RowGroupMetaData>,
1921 {
1922 let Some(parquet_index) = self.parquet_column_index else {
1923 let num_row_groups = metadatas.into_iter().count();
1924 return Ok(UInt64Array::from_iter(std::iter::repeat_n(
1925 None,
1926 num_row_groups,
1927 )));
1928 };
1929
1930 let null_counts = metadatas
1931 .into_iter()
1932 .map(|x| x.column(parquet_index).statistics())
1933 .map(|s| {
1934 let s = s?;
1935 if self.missing_null_counts_as_zero {
1936 Some(s.null_count_opt().unwrap_or(0))
1937 } else {
1938 s.null_count_opt()
1939 }
1940 });
1941 Ok(UInt64Array::from_iter(null_counts))
1942 }
1943
1944 pub fn row_group_nan_counts<I>(&self, metadatas: I) -> Result<UInt64Array>
1948 where
1949 I: IntoIterator<Item = &'a RowGroupMetaData>,
1950 {
1951 let Some(parquet_index) = self.parquet_column_index else {
1952 let num_row_groups = metadatas.into_iter().count();
1953 return Ok(UInt64Array::from_iter(std::iter::repeat_n(
1954 None,
1955 num_row_groups,
1956 )));
1957 };
1958
1959 let nan_counts = metadatas
1960 .into_iter()
1961 .map(|x| x.column(parquet_index).statistics())
1962 .map(|s| s?.nan_count_opt());
1963 Ok(UInt64Array::from_iter(nan_counts))
1964 }
1965
1966 pub fn row_group_distinct_counts<I>(&self, metadatas: I) -> Result<UInt64Array>
1970 where
1971 I: IntoIterator<Item = &'a RowGroupMetaData>,
1972 {
1973 let Some(parquet_index) = self.parquet_column_index else {
1974 let num_row_groups = metadatas.into_iter().count();
1975 return Ok(UInt64Array::from_iter(std::iter::repeat_n(
1976 None,
1977 num_row_groups,
1978 )));
1979 };
1980
1981 let distinct_counts = metadatas
1982 .into_iter()
1983 .map(|x| x.column(parquet_index).statistics())
1984 .map(|s| s?.distinct_count_opt());
1985 Ok(UInt64Array::from_iter(distinct_counts))
1986 }
1987
1988 pub fn data_page_mins<I>(
2038 &self,
2039 page_index: &dyn PageIndexProvider,
2040 row_group_indices: I,
2041 ) -> Result<ArrayRef>
2042 where
2043 I: IntoIterator<Item = &'a usize>,
2044 {
2045 let data_type = self.arrow_field.data_type();
2046
2047 let Some(parquet_index) = self.parquet_column_index else {
2048 return Ok(self.make_null_array(data_type, row_group_indices));
2049 };
2050
2051 let iter = row_group_indices.into_iter().map(|rg_index| {
2052 let column_page_index_per_row_group_per_column = page_index
2053 .column_index(*rg_index, parquet_index)
2054 .filter(|_| self.is_min_max_order_supported());
2055 let num_data_pages = page_index
2056 .num_data_pages(*rg_index, parquet_index)
2057 .unwrap_or(0);
2058
2059 (num_data_pages, column_page_index_per_row_group_per_column)
2060 });
2061
2062 min_page_statistics(data_type, iter, self.physical_type)
2063 }
2064
2065 pub fn data_page_maxes<I>(
2069 &self,
2070 page_index: &dyn PageIndexProvider,
2071 row_group_indices: I,
2072 ) -> Result<ArrayRef>
2073 where
2074 I: IntoIterator<Item = &'a usize>,
2075 {
2076 let data_type = self.arrow_field.data_type();
2077
2078 let Some(parquet_index) = self.parquet_column_index else {
2079 return Ok(self.make_null_array(data_type, row_group_indices));
2080 };
2081
2082 let iter = row_group_indices.into_iter().map(|rg_index| {
2083 let column_page_index_per_row_group_per_column = page_index
2084 .column_index(*rg_index, parquet_index)
2085 .filter(|_| self.is_min_max_order_supported());
2086 let num_data_pages = page_index
2087 .num_data_pages(*rg_index, parquet_index)
2088 .unwrap_or(0);
2089
2090 (num_data_pages, column_page_index_per_row_group_per_column)
2091 });
2092
2093 max_page_statistics(data_type, iter, self.physical_type)
2094 }
2095
2096 pub fn data_page_null_counts<I>(
2100 &self,
2101 page_index: &dyn PageIndexProvider,
2102 row_group_indices: I,
2103 ) -> Result<UInt64Array>
2104 where
2105 I: IntoIterator<Item = &'a usize>,
2106 {
2107 let Some(parquet_index) = self.parquet_column_index else {
2108 let num_row_groups = row_group_indices.into_iter().count();
2109 return Ok(UInt64Array::new_null(num_row_groups));
2110 };
2111
2112 let iter = row_group_indices.into_iter().map(|rg_index| {
2113 let column_page_index_per_row_group_per_column =
2114 page_index.column_index(*rg_index, parquet_index);
2115 let num_data_pages = page_index
2116 .num_data_pages(*rg_index, parquet_index)
2117 .unwrap_or(0);
2118
2119 (num_data_pages, column_page_index_per_row_group_per_column)
2120 });
2121 null_counts_page_statistics(iter)
2122 }
2123
2124 pub fn data_page_nan_counts<I>(
2128 &self,
2129 page_index: &dyn PageIndexProvider,
2130 row_group_indices: I,
2131 ) -> Result<UInt64Array>
2132 where
2133 I: IntoIterator<Item = &'a usize>,
2134 {
2135 let Some(parquet_index) = self.parquet_column_index else {
2136 let num_row_groups = row_group_indices.into_iter().count();
2137 return Ok(UInt64Array::new_null(num_row_groups));
2138 };
2139
2140 let iter = row_group_indices.into_iter().map(|rg_index| {
2141 let column_page_index_per_row_group_per_column =
2142 page_index.column_index(*rg_index, parquet_index);
2143 let num_data_pages = page_index
2144 .num_data_pages(*rg_index, parquet_index)
2145 .unwrap_or(0);
2146
2147 (num_data_pages, column_page_index_per_row_group_per_column)
2148 });
2149 nan_counts_page_statistics(iter)
2150 }
2151
2152 pub fn data_page_row_counts<I>(
2170 &self,
2171 page_index: &dyn PageIndexProvider,
2172 row_group_metadatas: &'a [RowGroupMetaData],
2173 row_group_indices: I,
2174 ) -> Result<Option<UInt64Array>>
2175 where
2176 I: IntoIterator<Item = &'a usize>,
2177 {
2178 let Some(parquet_index) = self.parquet_column_index else {
2179 return Ok(None);
2183 };
2184
2185 let mut row_counts = Vec::new();
2186 let mut nulls = NullBufferBuilder::new(0);
2187 for rg_idx in row_group_indices {
2188 let Some(offset_index) = page_index.offset_index(*rg_idx, parquet_index) else {
2189 let num_pages = page_index
2193 .column_index(*rg_idx, parquet_index)
2194 .map(|index| index.num_pages() as usize)
2195 .unwrap_or(0);
2196 row_counts.resize(row_counts.len() + num_pages, 0);
2197 nulls.append_n_nulls(num_pages);
2198 continue;
2199 };
2200 let page_locations = offset_index.page_locations();
2201
2202 let row_count_per_page = page_locations
2203 .windows(2)
2204 .map(|loc| Some(loc[1].first_row_index as u64 - loc[0].first_row_index as u64));
2205
2206 let num_rows_in_row_group = &row_group_metadatas[*rg_idx].num_rows();
2208 let row_count_per_page = row_count_per_page.chain(std::iter::once(Some(
2209 *num_rows_in_row_group as u64
2210 - page_locations.last().unwrap().first_row_index as u64,
2211 )));
2212
2213 row_counts.extend(row_count_per_page.clone().map(|x| x.unwrap_or(0)));
2214 for val in row_count_per_page {
2215 if val.is_some() {
2216 nulls.append_non_null();
2217 } else {
2218 nulls.append_null();
2219 }
2220 }
2221 }
2222
2223 Ok(Some(UInt64Array::new(row_counts.into(), nulls.build())))
2224 }
2225
2226 fn is_min_max_order_supported(&self) -> bool {
2227 self.physical_type != Some(PhysicalType::INT96)
2228 || self.column_order == Some(ColumnOrder::INT96_TIMESTAMP_ORDER)
2229 }
2230
2231 fn make_null_array<I, A>(&self, data_type: &DataType, metadatas: I) -> ArrayRef
2233 where
2234 I: IntoIterator<Item = A>,
2235 {
2236 let num_row_groups = metadatas.into_iter().count();
2238 new_null_array(data_type, num_row_groups)
2239 }
2240}
2241
2242