@@ -23,7 +23,7 @@ use crate::arrow::array_reader::byte_view_array::make_byte_view_array_reader;
23
23
use crate :: arrow:: array_reader:: empty_array:: make_empty_array_reader;
24
24
use crate :: arrow:: array_reader:: fixed_len_byte_array:: make_fixed_len_byte_array_reader;
25
25
use crate :: arrow:: array_reader:: {
26
- make_byte_array_dictionary_reader, make_byte_array_reader, ArrayReader ,
26
+ make_byte_array_dictionary_reader, make_byte_array_reader, ArrayReader , CachedPredicateResult ,
27
27
FixedSizeListArrayReader , ListArrayReader , MapArrayReader , NullArrayReader ,
28
28
PrimitiveArrayReader , RowGroups , StructArrayReader ,
29
29
} ;
@@ -37,11 +37,18 @@ use crate::schema::types::{ColumnDescriptor, ColumnPath, Type};
37
37
/// Builds [`ArrayReader`]s from parquet schema, projection mask, and RowGroups reader
38
38
pub ( crate ) struct ArrayReaderBuilder < ' a > {
39
39
row_groups : & ' a dyn RowGroups ,
40
+ cached_predicate_result : Option < & ' a CachedPredicateResult > ,
40
41
}
41
42
42
43
impl < ' a > ArrayReaderBuilder < ' a > {
43
- pub ( crate ) fn new ( row_groups : & ' a dyn RowGroups ) -> Self {
44
- Self { row_groups }
44
+ pub ( crate ) fn new (
45
+ row_groups : & ' a dyn RowGroups ,
46
+ cached_predicate_result : Option < & ' a CachedPredicateResult > ,
47
+ ) -> Self {
48
+ Self {
49
+ row_groups,
50
+ cached_predicate_result,
51
+ }
45
52
}
46
53
47
54
/// Create [`ArrayReader`] from parquet schema, projection mask, and parquet file reader.
@@ -68,6 +75,10 @@ impl<'a> ArrayReaderBuilder<'a> {
68
75
field : & ParquetField ,
69
76
mask : & ProjectionMask ,
70
77
) -> Result < Option < Box < dyn ArrayReader > > > {
78
+ if let Some ( builder) = self . build_cached_reader ( field, mask) ? {
79
+ return Ok ( Some ( builder) ) ;
80
+ }
81
+
71
82
match field. field_type {
72
83
ParquetFieldType :: Primitive { .. } => self . build_primitive_reader ( field, mask) ,
73
84
ParquetFieldType :: Group { .. } => match & field. arrow_type {
@@ -81,6 +92,33 @@ impl<'a> ArrayReaderBuilder<'a> {
81
92
}
82
93
}
83
94
95
+ /// Build cached array reader if the field is in the projection mask and in the cache
96
+ fn build_cached_reader (
97
+ & self ,
98
+ field : & ParquetField ,
99
+ mask : & ProjectionMask ,
100
+ ) -> Result < Option < Box < dyn ArrayReader > > > {
101
+ let Some ( cached_predicate_result) = self . cached_predicate_result else {
102
+ return Ok ( None ) ;
103
+ } ;
104
+
105
+ // TODO how to find a cached struct / list
106
+ // (Probably have to cache the individual fields)
107
+ let ParquetFieldType :: Primitive {
108
+ col_idx,
109
+ primitive_type : _,
110
+ } = & field. field_type
111
+ else {
112
+ return Ok ( None ) ;
113
+ } ;
114
+
115
+ if !mask. leaf_included ( * col_idx) {
116
+ return Ok ( None ) ;
117
+ }
118
+
119
+ cached_predicate_result. build_reader ( * col_idx)
120
+ }
121
+
84
122
/// Build array reader for map type.
85
123
fn build_map_reader (
86
124
& self ,
@@ -375,7 +413,8 @@ mod tests {
375
413
)
376
414
. unwrap ( ) ;
377
415
378
- let array_reader = ArrayReaderBuilder :: new ( & file_reader)
416
+ let cached_predicate_result = None ;
417
+ let array_reader = ArrayReaderBuilder :: new ( & file_reader, cached_predicate_result)
379
418
. build_array_reader ( fields. as_ref ( ) , & mask)
380
419
. unwrap ( ) ;
381
420
0 commit comments