Skip to main content

parquet/record/
reader.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18//! Contains implementation of record assembly and converting Parquet types into
19//! [`Row`]s.
20
21use std::{collections::HashMap, fmt, sync::Arc};
22
23use crate::basic::{ConvertedType, Repetition};
24use crate::errors::{ParquetError, Result};
25use crate::file::reader::{FileReader, RowGroupReader};
26use crate::record::{
27    api::{Field, Row, make_list, make_map},
28    triplet::TripletIter,
29};
30use crate::schema::types::{ColumnPath, SchemaDescPtr, SchemaDescriptor, Type, TypePtr};
31
32/// Default batch size for a reader
33const DEFAULT_BATCH_SIZE: usize = 1024;
34
35/// Tree builder for `Reader` enum.
36/// Serves as a container of options for building a reader tree and a builder, and
37/// accessing a records iterator [`RowIter`].
38pub struct TreeBuilder {
39    // Batch size (>= 1) for triplet iterators
40    batch_size: usize,
41}
42
43impl Default for TreeBuilder {
44    fn default() -> Self {
45        Self::new()
46    }
47}
48
49impl TreeBuilder {
50    /// Creates new tree builder with default parameters.
51    pub fn new() -> Self {
52        Self {
53            batch_size: DEFAULT_BATCH_SIZE,
54        }
55    }
56
57    /// Sets batch size for this tree builder.
58    pub fn with_batch_size(mut self, batch_size: usize) -> Self {
59        self.batch_size = batch_size;
60        self
61    }
62
63    /// Creates new root reader for provided schema and row group.
64    pub fn build(
65        &self,
66        descr: SchemaDescPtr,
67        row_group_reader: &dyn RowGroupReader,
68    ) -> Result<Reader> {
69        // Prepare lookup table of column path -> original column index
70        // This allows to prune columns and map schema leaf nodes to the column readers
71        let mut paths: HashMap<ColumnPath, usize> = HashMap::new();
72        let row_group_metadata = row_group_reader.metadata();
73
74        for col_index in 0..row_group_reader.num_columns() {
75            let col_meta = row_group_metadata.column(col_index);
76            let col_path = col_meta.column_path().clone();
77            paths.insert(col_path, col_index);
78        }
79
80        // Build child readers for the message type
81        let mut readers = Vec::new();
82        let mut path = Vec::new();
83
84        for field in descr.root_schema().get_fields() {
85            let reader =
86                self.reader_tree(field.clone(), &mut path, 0, 0, &paths, row_group_reader)?;
87            readers.push(reader);
88        }
89
90        // Return group reader for message type,
91        // it is always required with definition level 0
92        Ok(Reader::GroupReader(None, 0, readers))
93    }
94
95    /// Creates iterator of `Row`s directly from schema descriptor and row group.
96    pub fn as_iter(
97        &self,
98        descr: SchemaDescPtr,
99        row_group_reader: &dyn RowGroupReader,
100    ) -> Result<ReaderIter> {
101        let num_records = row_group_reader.metadata().num_rows() as usize;
102        ReaderIter::new(self.build(descr, row_group_reader)?, num_records)
103    }
104
105    /// Builds tree of readers for the current schema recursively.
106    fn reader_tree(
107        &self,
108        field: TypePtr,
109        path: &mut Vec<String>,
110        mut curr_def_level: i16,
111        mut curr_rep_level: i16,
112        paths: &HashMap<ColumnPath, usize>,
113        row_group_reader: &dyn RowGroupReader,
114    ) -> Result<Reader> {
115        assert!(field.get_basic_info().has_repetition());
116        // Update current definition and repetition levels for this type
117        let repetition = field.get_basic_info().repetition();
118        match repetition {
119            Repetition::OPTIONAL => {
120                curr_def_level += 1;
121            }
122            Repetition::REPEATED => {
123                curr_def_level += 1;
124                curr_rep_level += 1;
125            }
126            Repetition::REQUIRED => {}
127        }
128
129        path.push(String::from(field.name()));
130        let reader = if field.is_primitive() {
131            let col_path = ColumnPath::new(path.clone());
132            let orig_index = *paths
133                .get(&col_path)
134                .ok_or(general_err!("Path {:?} not found", col_path))?;
135            let col_descr = row_group_reader
136                .metadata()
137                .column(orig_index)
138                .column_descr_ptr();
139            let col_reader = row_group_reader.get_column_reader(orig_index)?;
140            let column = TripletIter::new(col_descr, col_reader, self.batch_size);
141            let reader = Reader::PrimitiveReader(field.clone(), Box::new(column));
142            if repetition == Repetition::REPEATED {
143                Reader::RepeatedReader(
144                    field,
145                    curr_def_level - 1,
146                    curr_rep_level - 1,
147                    Box::new(reader),
148                )
149            } else {
150                reader
151            }
152        } else {
153            match field.get_basic_info().converted_type() {
154                // List types
155                ConvertedType::LIST => {
156                    assert_eq!(field.get_fields().len(), 1, "Invalid list type {field:?}");
157
158                    let repeated_field = field.get_fields()[0].clone();
159                    assert_eq!(
160                        repeated_field.get_basic_info().repetition(),
161                        Repetition::REPEATED,
162                        "Invalid list type {field:?}"
163                    );
164
165                    if Reader::is_element_type(&repeated_field) {
166                        // Support for backward compatible lists
167                        let reader = self.reader_tree(
168                            repeated_field,
169                            path,
170                            curr_def_level,
171                            curr_rep_level,
172                            paths,
173                            row_group_reader,
174                        )?;
175
176                        Reader::RepeatedReader(
177                            field,
178                            curr_def_level,
179                            curr_rep_level,
180                            Box::new(reader),
181                        )
182                    } else {
183                        let child_field = repeated_field.get_fields()[0].clone();
184
185                        path.push(String::from(repeated_field.name()));
186
187                        let reader = self.reader_tree(
188                            child_field,
189                            path,
190                            curr_def_level + 1,
191                            curr_rep_level + 1,
192                            paths,
193                            row_group_reader,
194                        )?;
195
196                        path.pop();
197
198                        Reader::RepeatedReader(
199                            field,
200                            curr_def_level,
201                            curr_rep_level,
202                            Box::new(reader),
203                        )
204                    }
205                }
206                // Map types (key-value pairs)
207                ConvertedType::MAP | ConvertedType::MAP_KEY_VALUE => {
208                    assert_eq!(field.get_fields().len(), 1, "Invalid map type: {field:?}");
209                    assert!(
210                        !field.get_fields()[0].is_primitive(),
211                        "Invalid map type: {field:?}"
212                    );
213
214                    let key_value_type = field.get_fields()[0].clone();
215                    assert_eq!(
216                        key_value_type.get_basic_info().repetition(),
217                        Repetition::REPEATED,
218                        "Invalid map type: {field:?}"
219                    );
220                    // Parquet spec allows no value. In that case treat as a list. #1642
221                    if key_value_type.get_fields().len() != 1 {
222                        // If not a list, then there can only be 2 fields in the struct
223                        assert_eq!(
224                            key_value_type.get_fields().len(),
225                            2,
226                            "Invalid map type: {field:?}"
227                        );
228                    }
229
230                    path.push(String::from(key_value_type.name()));
231
232                    let key_type = &key_value_type.get_fields()[0];
233                    assert!(
234                        key_type.is_primitive(),
235                        "Map key type is expected to be a primitive type, but found {key_type:?}"
236                    );
237                    let key_reader = self.reader_tree(
238                        key_type.clone(),
239                        path,
240                        curr_def_level + 1,
241                        curr_rep_level + 1,
242                        paths,
243                        row_group_reader,
244                    )?;
245
246                    if key_value_type.get_fields().len() == 1 {
247                        path.pop();
248                        Reader::RepeatedReader(
249                            field,
250                            curr_def_level,
251                            curr_rep_level,
252                            Box::new(key_reader),
253                        )
254                    } else {
255                        let value_type = &key_value_type.get_fields()[1];
256                        let value_reader = self.reader_tree(
257                            value_type.clone(),
258                            path,
259                            curr_def_level + 1,
260                            curr_rep_level + 1,
261                            paths,
262                            row_group_reader,
263                        )?;
264
265                        path.pop();
266
267                        Reader::KeyValueReader(
268                            field,
269                            curr_def_level,
270                            curr_rep_level,
271                            Box::new(key_reader),
272                            Box::new(value_reader),
273                        )
274                    }
275                }
276                // A repeated field that is neither contained by a `LIST`- or
277                // `MAP`-annotated group nor annotated by `LIST` or `MAP`
278                // should be interpreted as a required list of required
279                // elements where the element type is the type of the field.
280                _ if repetition == Repetition::REPEATED => {
281                    let required_field = Type::group_type_builder(field.name())
282                        .with_repetition(Repetition::REQUIRED)
283                        .with_converted_type(field.get_basic_info().converted_type())
284                        .with_fields(field.get_fields().to_vec())
285                        .build()?;
286
287                    path.pop();
288
289                    let reader = self.reader_tree(
290                        Arc::new(required_field),
291                        path,
292                        curr_def_level,
293                        curr_rep_level,
294                        paths,
295                        row_group_reader,
296                    )?;
297
298                    return Ok(Reader::RepeatedReader(
299                        field,
300                        curr_def_level - 1,
301                        curr_rep_level - 1,
302                        Box::new(reader),
303                    ));
304                }
305                // Group types (structs)
306                _ => {
307                    let mut readers = Vec::new();
308                    for child in field.get_fields() {
309                        let reader = self.reader_tree(
310                            child.clone(),
311                            path,
312                            curr_def_level,
313                            curr_rep_level,
314                            paths,
315                            row_group_reader,
316                        )?;
317                        readers.push(reader);
318                    }
319                    Reader::GroupReader(Some(field), curr_def_level, readers)
320                }
321            }
322        };
323        path.pop();
324
325        Ok(Reader::option(repetition, curr_def_level, reader))
326    }
327}
328
329/// Reader tree for record assembly
330pub enum Reader {
331    /// Primitive reader with type information and triplet iterator
332    PrimitiveReader(TypePtr, Box<TripletIter>),
333    /// Optional reader with definition level of a parent and a reader
334    OptionReader(i16, Box<Reader>),
335    /// Group (struct) reader with type information, definition level and list of child
336    /// readers. When it represents message type, type information is None
337    GroupReader(Option<TypePtr>, i16, Vec<Reader>),
338    /// Reader for repeated values, e.g. lists, contains type information, definition
339    /// level, repetition level and a child reader
340    RepeatedReader(TypePtr, i16, i16, Box<Reader>),
341    /// Reader of key-value pairs, e.g. maps, contains type information, definition
342    /// level, repetition level, child reader for keys and child reader for values
343    KeyValueReader(TypePtr, i16, i16, Box<Reader>, Box<Reader>),
344}
345
346impl Reader {
347    /// Wraps reader in option reader based on repetition.
348    fn option(repetition: Repetition, def_level: i16, reader: Reader) -> Self {
349        if repetition == Repetition::OPTIONAL {
350            Reader::OptionReader(def_level - 1, Box::new(reader))
351        } else {
352            reader
353        }
354    }
355
356    /// Returns true if repeated type is an element type for the list.
357    /// Used to determine legacy list types.
358    /// This method is copied from Spark Parquet reader and is based on the reference:
359    /// <https://github.com/apache/parquet-format/blob/master/LogicalTypes.md>
360    ///   #backward-compatibility-rules
361    fn is_element_type(repeated_type: &Type) -> bool {
362        // For legacy 2-level list types whose element type is a 2-level list
363        //
364        //    // ARRAY<ARRAY<INT>> (nullable list, non-null elements)
365        //    optional group my_list (LIST) {
366        //      repeated group array (LIST) {
367        //        repeated int32 array;
368        //      };
369        //    }
370        //
371        if repeated_type.is_list() || repeated_type.has_single_repeated_child() {
372            return false;
373        }
374
375        // For legacy 2-level list types with primitive element type, e.g.:
376        //
377        //    // ARRAY<INT> (nullable list, non-null elements)
378        //    optional group my_list (LIST) {
379        //      repeated int32 element;
380        //    }
381        //
382        repeated_type.is_primitive() ||
383    // For legacy 2-level list types whose element type is a group type with 2 or more
384    // fields, e.g.:
385    //
386    //    // ARRAY<STRUCT<str: STRING, num: INT>> (nullable list, non-null elements)
387    //    optional group my_list (LIST) {
388    //      repeated group element {
389    //        required binary str (UTF8);
390    //        required int32 num;
391    //      };
392    //    }
393    //
394    repeated_type.is_group() && repeated_type.get_fields().len() > 1 ||
395    // For legacy 2-level list types generated by parquet-avro (Parquet version < 1.6.0),
396    // e.g.:
397    //
398    //    // ARRAY<STRUCT<str: STRING>> (nullable list, non-null elements)
399    //    optional group my_list (LIST) {
400    //      repeated group array {
401    //        required binary str (UTF8);
402    //      };
403    //    }
404    //
405    repeated_type.name() == "array" ||
406    // For Parquet data generated by parquet-thrift, e.g.:
407    //
408    //    // ARRAY<STRUCT<str: STRING>> (nullable list, non-null elements)
409    //    optional group my_list (LIST) {
410    //      repeated group my_list_tuple {
411    //        required binary str (UTF8);
412    //      };
413    //    }
414    //
415    repeated_type.name().ends_with("_tuple")
416    }
417
418    /// Reads current record as `Row` from the reader tree.
419    /// Automatically advances all necessary readers.
420    /// This must be called on the root level reader (i.e., for Message type).
421    /// Otherwise, it will panic.
422    fn read(&mut self) -> Result<Row> {
423        match *self {
424            Reader::GroupReader(_, _, ref mut readers) => {
425                let mut fields = Vec::new();
426                for reader in readers {
427                    fields.push((String::from(reader.field_name()), reader.read_field()?));
428                }
429                Ok(Row::new(fields))
430            }
431            _ => panic!("Cannot call read() on {self}"),
432        }
433    }
434
435    /// Reads current record as `Field` from the reader tree.
436    /// Automatically advances all necessary readers.
437    fn read_field(&mut self) -> Result<Field> {
438        let field = match *self {
439            Reader::PrimitiveReader(_, ref mut column) => {
440                if !column.has_next() {
441                    return Err(general_err!("Unexpected end of column data"));
442                }
443                let value = column.current_value()?;
444                column.read_next()?;
445                value
446            }
447            Reader::OptionReader(def_level, ref mut reader) => {
448                if !reader.has_next() {
449                    return Err(general_err!("Unexpected end of column data"));
450                }
451                if reader.current_def_level() > def_level {
452                    reader.read_field()?
453                } else {
454                    reader.advance_columns()?;
455                    Field::Null
456                }
457            }
458            Reader::GroupReader(_, def_level, ref mut readers) => {
459                let mut fields = Vec::new();
460                for reader in readers {
461                    if reader.repetition() != Repetition::OPTIONAL
462                        || reader.current_def_level() > def_level
463                    {
464                        fields.push((String::from(reader.field_name()), reader.read_field()?));
465                    } else {
466                        reader.advance_columns()?;
467                        fields.push((String::from(reader.field_name()), Field::Null));
468                    }
469                }
470                let row = Row::new(fields);
471                Field::Group(row)
472            }
473            Reader::RepeatedReader(_, def_level, rep_level, ref mut reader) => {
474                if !reader.has_next() {
475                    return Err(general_err!("Unexpected end of column data"));
476                }
477                let mut elements = Vec::new();
478                loop {
479                    if reader.current_def_level() > def_level {
480                        elements.push(reader.read_field()?);
481                    } else {
482                        reader.advance_columns()?;
483                        // If the current definition level is equal to the definition
484                        // level of this repeated type, then the
485                        // result is an empty list and the repetition level
486                        // will always be <= rl.
487                        break;
488                    }
489
490                    // This covers case when we are out of repetition levels and should
491                    // close the group, or there are no values left to
492                    // buffer.
493                    if !reader.has_next() || reader.current_rep_level() <= rep_level {
494                        break;
495                    }
496                }
497                Field::ListInternal(make_list(elements))
498            }
499            Reader::KeyValueReader(_, def_level, rep_level, ref mut keys, ref mut values) => {
500                if !keys.has_next() {
501                    return Err(general_err!("Unexpected end of column data"));
502                }
503                let mut pairs = Vec::new();
504                loop {
505                    if keys.current_def_level() > def_level {
506                        pairs.push((keys.read_field()?, values.read_field()?));
507                    } else {
508                        keys.advance_columns()?;
509                        values.advance_columns()?;
510                        // If the current definition level is equal to the definition
511                        // level of this repeated type, then the
512                        // result is an empty list and the repetition level
513                        // will always be <= rl.
514                        break;
515                    }
516
517                    // This covers case when we are out of repetition levels and should
518                    // close the group, or there are no values left to
519                    // buffer.
520                    if !keys.has_next() || keys.current_rep_level() <= rep_level {
521                        break;
522                    }
523                }
524
525                Field::MapInternal(make_map(pairs))
526            }
527        };
528        Ok(field)
529    }
530
531    /// Returns field name for the current reader.
532    fn field_name(&self) -> &str {
533        match *self {
534            Reader::PrimitiveReader(ref field, _) => field.name(),
535            Reader::OptionReader(_, ref reader) => reader.field_name(),
536            Reader::GroupReader(ref opt, ..) => match opt {
537                Some(field) => field.name(),
538                None => panic!("Field is None for group reader"),
539            },
540            Reader::RepeatedReader(ref field, ..) => field.name(),
541            Reader::KeyValueReader(ref field, ..) => field.name(),
542        }
543    }
544
545    /// Returns repetition for the current reader.
546    fn repetition(&self) -> Repetition {
547        match *self {
548            Reader::PrimitiveReader(ref field, _) => field.get_basic_info().repetition(),
549            Reader::OptionReader(_, ref reader) => reader.repetition(),
550            Reader::GroupReader(ref opt, ..) => match opt {
551                Some(field) => field.get_basic_info().repetition(),
552                None => panic!("Field is None for group reader"),
553            },
554            Reader::RepeatedReader(ref field, ..) => field.get_basic_info().repetition(),
555            Reader::KeyValueReader(ref field, ..) => field.get_basic_info().repetition(),
556        }
557    }
558
559    /// Returns true, if current reader has more values, false otherwise.
560    /// Method does not advance internal iterator.
561    fn has_next(&self) -> bool {
562        match *self {
563            Reader::PrimitiveReader(_, ref column) => column.has_next(),
564            Reader::OptionReader(_, ref reader) => reader.has_next(),
565            Reader::GroupReader(_, _, ref readers) => readers.first().unwrap().has_next(),
566            Reader::RepeatedReader(_, _, _, ref reader) => reader.has_next(),
567            Reader::KeyValueReader(_, _, _, ref keys, _) => keys.has_next(),
568        }
569    }
570
571    /// Returns current definition level,
572    /// Method does not advance internal iterator.
573    fn current_def_level(&self) -> i16 {
574        match *self {
575            Reader::PrimitiveReader(_, ref column) => column.current_def_level(),
576            Reader::OptionReader(_, ref reader) => reader.current_def_level(),
577            Reader::GroupReader(_, _, ref readers) => match readers.first() {
578                Some(reader) => reader.current_def_level(),
579                None => panic!("Current definition level: empty group reader"),
580            },
581            Reader::RepeatedReader(_, _, _, ref reader) => reader.current_def_level(),
582            Reader::KeyValueReader(_, _, _, ref keys, _) => keys.current_def_level(),
583        }
584    }
585
586    /// Returns current repetition level.
587    /// Method does not advance internal iterator.
588    fn current_rep_level(&self) -> i16 {
589        match *self {
590            Reader::PrimitiveReader(_, ref column) => column.current_rep_level(),
591            Reader::OptionReader(_, ref reader) => reader.current_rep_level(),
592            Reader::GroupReader(_, _, ref readers) => match readers.first() {
593                Some(reader) => reader.current_rep_level(),
594                None => panic!("Current repetition level: empty group reader"),
595            },
596            Reader::RepeatedReader(_, _, _, ref reader) => reader.current_rep_level(),
597            Reader::KeyValueReader(_, _, _, ref keys, _) => keys.current_rep_level(),
598        }
599    }
600
601    /// Advances leaf columns for the current reader.
602    fn advance_columns(&mut self) -> Result<()> {
603        match *self {
604            Reader::PrimitiveReader(_, ref mut column) => column.read_next().map(|_| ()),
605            Reader::OptionReader(_, ref mut reader) => reader.advance_columns(),
606            Reader::GroupReader(_, _, ref mut readers) => {
607                for reader in readers {
608                    reader.advance_columns()?;
609                }
610                Ok(())
611            }
612            Reader::RepeatedReader(_, _, _, ref mut reader) => reader.advance_columns(),
613            Reader::KeyValueReader(_, _, _, ref mut keys, ref mut values) => {
614                keys.advance_columns()?;
615                values.advance_columns()
616            }
617        }
618    }
619}
620
621impl fmt::Display for Reader {
622    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
623        let s = match self {
624            Reader::PrimitiveReader(..) => "PrimitiveReader",
625            Reader::OptionReader(..) => "OptionReader",
626            Reader::GroupReader(..) => "GroupReader",
627            Reader::RepeatedReader(..) => "RepeatedReader",
628            Reader::KeyValueReader(..) => "KeyValueReader",
629        };
630        write!(f, "{s}")
631    }
632}
633
634// ----------------------------------------------------------------------
635// Row iterators
636
637/// The enum Either with variants That represents a reference and a box of
638/// [`FileReader`].
639enum Either<'a> {
640    Left(&'a dyn FileReader),
641    Right(Box<dyn FileReader>),
642}
643
644impl Either<'_> {
645    fn reader(&self) -> &dyn FileReader {
646        match *self {
647            Either::Left(r) => r,
648            Either::Right(ref r) => &**r,
649        }
650    }
651}
652
653/// Access parquet data as an iterator of [`Row`]
654///
655/// # Caveats
656///
657/// Parquet stores data in a columnar fashion using [Dremel] encoding, and is therefore highly
658/// optimised for reading data by column, not row. As a consequence applications concerned with
659/// performance should prefer the columnar arrow or [ColumnReader] APIs.
660///
661/// Additionally the current implementation does not correctly handle repeated fields ([#2394]),
662/// and workloads looking to handle such schema should use the other APIs.
663///
664/// [#2394]: https://github.com/apache/arrow-rs/issues/2394
665/// [ColumnReader]: crate::file::reader::RowGroupReader::get_column_reader
666/// [Dremel]: https://research.google/pubs/pub36632/
667pub struct RowIter<'a> {
668    descr: SchemaDescPtr,
669    tree_builder: TreeBuilder,
670    file_reader: Option<Either<'a>>,
671    current_row_group: usize,
672    num_row_groups: usize,
673    row_iter: Option<ReaderIter>,
674}
675
676impl<'a> RowIter<'a> {
677    /// Creates a new iterator of [`Row`]s.
678    fn new(
679        file_reader: Option<Either<'a>>,
680        row_iter: Option<ReaderIter>,
681        descr: SchemaDescPtr,
682    ) -> Self {
683        let tree_builder = Self::tree_builder();
684        let num_row_groups = match file_reader {
685            Some(ref r) => r.reader().num_row_groups(),
686            None => 0,
687        };
688
689        Self {
690            descr,
691            file_reader,
692            tree_builder,
693            num_row_groups,
694            row_iter,
695            current_row_group: 0,
696        }
697    }
698
699    /// Creates iterator of [`Row`]s for all row groups in a
700    /// file.
701    pub fn from_file(proj: Option<Type>, reader: &'a dyn FileReader) -> Result<Self> {
702        let either = Either::Left(reader);
703        let descr =
704            Self::get_proj_descr(proj, reader.metadata().file_metadata().schema_descr_ptr())?;
705
706        Ok(Self::new(Some(either), None, descr))
707    }
708
709    /// Creates iterator of [`Row`]s for a specific row group.
710    pub fn from_row_group(proj: Option<Type>, reader: &'a dyn RowGroupReader) -> Result<Self> {
711        let descr = Self::get_proj_descr(proj, reader.metadata().schema_descr_ptr())?;
712        let tree_builder = Self::tree_builder();
713        let row_iter = tree_builder.as_iter(descr.clone(), reader)?;
714
715        // For row group we need to set `current_row_group` >= `num_row_groups`, because
716        // we only have one row group and can't buffer more.
717        Ok(Self::new(None, Some(row_iter), descr))
718    }
719
720    /// Creates a iterator of [`Row`]s from a [`FileReader`] using the full file schema.
721    pub fn from_file_into(reader: Box<dyn FileReader>) -> Self {
722        let either = Either::Right(reader);
723        let descr = either
724            .reader()
725            .metadata()
726            .file_metadata()
727            .schema_descr_ptr();
728
729        Self::new(Some(either), None, descr)
730    }
731
732    /// Tries to create a iterator of [`Row`]s using projections.
733    /// Returns a error if a file reader is not the source of this iterator.
734    ///
735    /// The Projected schema can be a subset of or equal to the file schema,
736    /// when it is None, full file schema is assumed.
737    pub fn project(self, proj: Option<Type>) -> Result<Self> {
738        match self.file_reader {
739            Some(ref either) => {
740                let schema = either
741                    .reader()
742                    .metadata()
743                    .file_metadata()
744                    .schema_descr_ptr();
745                let descr = Self::get_proj_descr(proj, schema)?;
746
747                Ok(Self::new(self.file_reader, None, descr))
748            }
749            None => Err(general_err!("File reader is required to use projections")),
750        }
751    }
752
753    /// Helper method to get schema descriptor for projected schema.
754    /// If projection is None, then full schema is returned.
755    #[inline]
756    fn get_proj_descr(proj: Option<Type>, root_descr: SchemaDescPtr) -> Result<SchemaDescPtr> {
757        match proj {
758            Some(projection) => {
759                // check if projection is part of file schema
760                let root_schema = root_descr.root_schema();
761                if !root_schema.check_contains(&projection) {
762                    return Err(general_err!("Root schema does not contain projection"));
763                }
764                Ok(Arc::new(SchemaDescriptor::new(Arc::new(projection))))
765            }
766            None => Ok(root_descr),
767        }
768    }
769
770    /// Sets batch size for this row iter.
771    pub fn with_batch_size(mut self, batch_size: usize) -> Self {
772        self.tree_builder = self.tree_builder.with_batch_size(batch_size);
773        self
774    }
775
776    /// Returns common tree builder, so the same settings are applied to both iterators
777    /// from file reader and row group.
778    #[inline]
779    fn tree_builder() -> TreeBuilder {
780        TreeBuilder::new()
781    }
782}
783
784impl Iterator for RowIter<'_> {
785    type Item = Result<Row>;
786
787    fn next(&mut self) -> Option<Result<Row>> {
788        let mut row = self.row_iter.as_mut().and_then(|iter| iter.next());
789
790        while row.is_none() && self.current_row_group < self.num_row_groups {
791            // We do not expect any failures when accessing a row group, and file reader
792            // must be set for selecting next row group.
793            if let Some(ref either) = self.file_reader {
794                let file_reader = either.reader();
795                let row_group_reader = &*file_reader
796                    .get_row_group(self.current_row_group)
797                    .expect("Row group is required to advance");
798
799                match self
800                    .tree_builder
801                    .as_iter(self.descr.clone(), row_group_reader)
802                {
803                    Ok(mut iter) => {
804                        row = iter.next();
805
806                        self.current_row_group += 1;
807                        self.row_iter = Some(iter);
808                    }
809                    Err(e) => return Some(Err(e)),
810                }
811            }
812        }
813
814        row
815    }
816}
817
818/// Internal iterator of [`Row`]s for a reader.
819pub struct ReaderIter {
820    root_reader: Reader,
821    records_left: usize,
822}
823
824impl ReaderIter {
825    fn new(mut root_reader: Reader, num_records: usize) -> Result<Self> {
826        // Prepare root reader by advancing all column vectors
827        root_reader.advance_columns()?;
828        Ok(Self {
829            root_reader,
830            records_left: num_records,
831        })
832    }
833}
834
835impl Iterator for ReaderIter {
836    type Item = Result<Row>;
837
838    fn next(&mut self) -> Option<Result<Row>> {
839        if self.records_left > 0 {
840            self.records_left -= 1;
841            Some(self.root_reader.read())
842        } else {
843            None
844        }
845    }
846}
847
848#[cfg(test)]
849mod tests {
850    use super::*;
851
852    use crate::data_type::Int64Type;
853    use crate::file::reader::SerializedFileReader;
854    use crate::file::writer::SerializedFileWriter;
855    use crate::record::api::RowAccessor;
856    use crate::schema::parser::parse_message_type;
857    use crate::util::test_common::file_util::{get_test_file, get_test_path};
858    use bytes::Bytes;
859
860    // Convenient macros to assemble row, list, map, and group.
861
862    macro_rules! row {
863        ($($e:tt)*) => {
864            {
865                Row::new(vec![$($e)*])
866            }
867        }
868    }
869
870    macro_rules! list {
871        ($($e:tt)*) => {
872            {
873                Field::ListInternal(make_list(vec![$($e)*]))
874            }
875        }
876    }
877
878    macro_rules! map {
879        ($($e:tt)*) => {
880            {
881                Field::MapInternal(make_map(vec![$($e)*]))
882            }
883        }
884    }
885
886    macro_rules! group {
887        ( $( $e:expr ), * ) => {
888            {
889                Field::Group(row!($( $e ), *))
890            }
891        }
892    }
893
894    #[test]
895    fn test_file_reader_rows_nulls() {
896        let rows = test_file_reader_rows("nulls.snappy.parquet", None).unwrap();
897        let expected_rows = vec![
898            row![(
899                "b_struct".to_string(),
900                group![("b_c_int".to_string(), Field::Null)]
901            )],
902            row![(
903                "b_struct".to_string(),
904                group![("b_c_int".to_string(), Field::Null)]
905            )],
906            row![(
907                "b_struct".to_string(),
908                group![("b_c_int".to_string(), Field::Null)]
909            )],
910            row![(
911                "b_struct".to_string(),
912                group![("b_c_int".to_string(), Field::Null)]
913            )],
914            row![(
915                "b_struct".to_string(),
916                group![("b_c_int".to_string(), Field::Null)]
917            )],
918            row![(
919                "b_struct".to_string(),
920                group![("b_c_int".to_string(), Field::Null)]
921            )],
922            row![(
923                "b_struct".to_string(),
924                group![("b_c_int".to_string(), Field::Null)]
925            )],
926            row![(
927                "b_struct".to_string(),
928                group![("b_c_int".to_string(), Field::Null)]
929            )],
930        ];
931        assert_eq!(rows, expected_rows);
932    }
933
934    #[test]
935    #[cfg_attr(miri, ignore)] // Takes too long
936    fn test_file_reader_rows_nonnullable() {
937        let rows = test_file_reader_rows("nonnullable.impala.parquet", None).unwrap();
938        let expected_rows = vec![row![
939            ("ID".to_string(), Field::Long(8)),
940            ("Int_Array".to_string(), list![Field::Int(-1)]),
941            (
942                "int_array_array".to_string(),
943                list![list![Field::Int(-1), Field::Int(-2)], list![]]
944            ),
945            (
946                "Int_Map".to_string(),
947                map![(Field::Str("k1".to_string()), Field::Int(-1))]
948            ),
949            (
950                "int_map_array".to_string(),
951                list![
952                    map![],
953                    map![(Field::Str("k1".to_string()), Field::Int(1))],
954                    map![],
955                    map![]
956                ]
957            ),
958            (
959                "nested_Struct".to_string(),
960                group![
961                    ("a".to_string(), Field::Int(-1)),
962                    ("B".to_string(), list![Field::Int(-1)]),
963                    (
964                        "c".to_string(),
965                        group![(
966                            "D".to_string(),
967                            list![list![group![
968                                ("e".to_string(), Field::Int(-1)),
969                                ("f".to_string(), Field::Str("nonnullable".to_string()))
970                            ]]]
971                        )]
972                    ),
973                    ("G".to_string(), map![])
974                ]
975            )
976        ]];
977        assert_eq!(rows, expected_rows);
978    }
979
980    #[test]
981    #[cfg_attr(miri, ignore)] // Takes too long
982    fn test_file_reader_rows_nullable() {
983        let rows = test_file_reader_rows("nullable.impala.parquet", None).unwrap();
984        let expected_rows = vec![
985            row![
986                ("id".to_string(), Field::Long(1)),
987                (
988                    "int_array".to_string(),
989                    list![Field::Int(1), Field::Int(2), Field::Int(3)]
990                ),
991                (
992                    "int_array_Array".to_string(),
993                    list![
994                        list![Field::Int(1), Field::Int(2)],
995                        list![Field::Int(3), Field::Int(4)]
996                    ]
997                ),
998                (
999                    "int_map".to_string(),
1000                    map![
1001                        (Field::Str("k1".to_string()), Field::Int(1)),
1002                        (Field::Str("k2".to_string()), Field::Int(100))
1003                    ]
1004                ),
1005                (
1006                    "int_Map_Array".to_string(),
1007                    list![map![(Field::Str("k1".to_string()), Field::Int(1))]]
1008                ),
1009                (
1010                    "nested_struct".to_string(),
1011                    group![
1012                        ("A".to_string(), Field::Int(1)),
1013                        ("b".to_string(), list![Field::Int(1)]),
1014                        (
1015                            "C".to_string(),
1016                            group![(
1017                                "d".to_string(),
1018                                list![
1019                                    list![
1020                                        group![
1021                                            ("E".to_string(), Field::Int(10)),
1022                                            ("F".to_string(), Field::Str("aaa".to_string()))
1023                                        ],
1024                                        group![
1025                                            ("E".to_string(), Field::Int(-10)),
1026                                            ("F".to_string(), Field::Str("bbb".to_string()))
1027                                        ]
1028                                    ],
1029                                    list![group![
1030                                        ("E".to_string(), Field::Int(11)),
1031                                        ("F".to_string(), Field::Str("c".to_string()))
1032                                    ]]
1033                                ]
1034                            )]
1035                        ),
1036                        (
1037                            "g".to_string(),
1038                            map![(
1039                                Field::Str("foo".to_string()),
1040                                group![(
1041                                    "H".to_string(),
1042                                    group![("i".to_string(), list![Field::Double(1.1)])]
1043                                )]
1044                            )]
1045                        )
1046                    ]
1047                )
1048            ],
1049            row![
1050                ("id".to_string(), Field::Long(2)),
1051                (
1052                    "int_array".to_string(),
1053                    list![
1054                        Field::Null,
1055                        Field::Int(1),
1056                        Field::Int(2),
1057                        Field::Null,
1058                        Field::Int(3),
1059                        Field::Null
1060                    ]
1061                ),
1062                (
1063                    "int_array_Array".to_string(),
1064                    list![
1065                        list![Field::Null, Field::Int(1), Field::Int(2), Field::Null],
1066                        list![Field::Int(3), Field::Null, Field::Int(4)],
1067                        list![],
1068                        Field::Null
1069                    ]
1070                ),
1071                (
1072                    "int_map".to_string(),
1073                    map![
1074                        (Field::Str("k1".to_string()), Field::Int(2)),
1075                        (Field::Str("k2".to_string()), Field::Null)
1076                    ]
1077                ),
1078                (
1079                    "int_Map_Array".to_string(),
1080                    list![
1081                        map![
1082                            (Field::Str("k3".to_string()), Field::Null),
1083                            (Field::Str("k1".to_string()), Field::Int(1))
1084                        ],
1085                        Field::Null,
1086                        map![]
1087                    ]
1088                ),
1089                (
1090                    "nested_struct".to_string(),
1091                    group![
1092                        ("A".to_string(), Field::Null),
1093                        ("b".to_string(), list![Field::Null]),
1094                        (
1095                            "C".to_string(),
1096                            group![(
1097                                "d".to_string(),
1098                                list![
1099                                    list![
1100                                        group![
1101                                            ("E".to_string(), Field::Null),
1102                                            ("F".to_string(), Field::Null)
1103                                        ],
1104                                        group![
1105                                            ("E".to_string(), Field::Int(10)),
1106                                            ("F".to_string(), Field::Str("aaa".to_string()))
1107                                        ],
1108                                        group![
1109                                            ("E".to_string(), Field::Null),
1110                                            ("F".to_string(), Field::Null)
1111                                        ],
1112                                        group![
1113                                            ("E".to_string(), Field::Int(-10)),
1114                                            ("F".to_string(), Field::Str("bbb".to_string()))
1115                                        ],
1116                                        group![
1117                                            ("E".to_string(), Field::Null),
1118                                            ("F".to_string(), Field::Null)
1119                                        ]
1120                                    ],
1121                                    list![
1122                                        group![
1123                                            ("E".to_string(), Field::Int(11)),
1124                                            ("F".to_string(), Field::Str("c".to_string()))
1125                                        ],
1126                                        Field::Null
1127                                    ],
1128                                    list![],
1129                                    Field::Null
1130                                ]
1131                            )]
1132                        ),
1133                        (
1134                            "g".to_string(),
1135                            map![
1136                                (
1137                                    Field::Str("g1".to_string()),
1138                                    group![(
1139                                        "H".to_string(),
1140                                        group![(
1141                                            "i".to_string(),
1142                                            list![Field::Double(2.2), Field::Null]
1143                                        )]
1144                                    )]
1145                                ),
1146                                (
1147                                    Field::Str("g2".to_string()),
1148                                    group![("H".to_string(), group![("i".to_string(), list![])])]
1149                                ),
1150                                (Field::Str("g3".to_string()), Field::Null),
1151                                (
1152                                    Field::Str("g4".to_string()),
1153                                    group![(
1154                                        "H".to_string(),
1155                                        group![("i".to_string(), Field::Null)]
1156                                    )]
1157                                ),
1158                                (
1159                                    Field::Str("g5".to_string()),
1160                                    group![("H".to_string(), Field::Null)]
1161                                )
1162                            ]
1163                        )
1164                    ]
1165                )
1166            ],
1167            row![
1168                ("id".to_string(), Field::Long(3)),
1169                ("int_array".to_string(), list![]),
1170                ("int_array_Array".to_string(), list![Field::Null]),
1171                ("int_map".to_string(), map![]),
1172                ("int_Map_Array".to_string(), list![Field::Null, Field::Null]),
1173                (
1174                    "nested_struct".to_string(),
1175                    group![
1176                        ("A".to_string(), Field::Null),
1177                        ("b".to_string(), Field::Null),
1178                        ("C".to_string(), group![("d".to_string(), list![])]),
1179                        ("g".to_string(), map![])
1180                    ]
1181                )
1182            ],
1183            row![
1184                ("id".to_string(), Field::Long(4)),
1185                ("int_array".to_string(), Field::Null),
1186                ("int_array_Array".to_string(), list![]),
1187                ("int_map".to_string(), map![]),
1188                ("int_Map_Array".to_string(), list![]),
1189                (
1190                    "nested_struct".to_string(),
1191                    group![
1192                        ("A".to_string(), Field::Null),
1193                        ("b".to_string(), Field::Null),
1194                        ("C".to_string(), group![("d".to_string(), Field::Null)]),
1195                        ("g".to_string(), Field::Null)
1196                    ]
1197                )
1198            ],
1199            row![
1200                ("id".to_string(), Field::Long(5)),
1201                ("int_array".to_string(), Field::Null),
1202                ("int_array_Array".to_string(), Field::Null),
1203                ("int_map".to_string(), map![]),
1204                ("int_Map_Array".to_string(), Field::Null),
1205                (
1206                    "nested_struct".to_string(),
1207                    group![
1208                        ("A".to_string(), Field::Null),
1209                        ("b".to_string(), Field::Null),
1210                        ("C".to_string(), Field::Null),
1211                        (
1212                            "g".to_string(),
1213                            map![(
1214                                Field::Str("foo".to_string()),
1215                                group![(
1216                                    "H".to_string(),
1217                                    group![(
1218                                        "i".to_string(),
1219                                        list![Field::Double(2.2), Field::Double(3.3)]
1220                                    )]
1221                                )]
1222                            )]
1223                        )
1224                    ]
1225                )
1226            ],
1227            row![
1228                ("id".to_string(), Field::Long(6)),
1229                ("int_array".to_string(), Field::Null),
1230                ("int_array_Array".to_string(), Field::Null),
1231                ("int_map".to_string(), Field::Null),
1232                ("int_Map_Array".to_string(), Field::Null),
1233                ("nested_struct".to_string(), Field::Null)
1234            ],
1235            row![
1236                ("id".to_string(), Field::Long(7)),
1237                ("int_array".to_string(), Field::Null),
1238                (
1239                    "int_array_Array".to_string(),
1240                    list![Field::Null, list![Field::Int(5), Field::Int(6)]]
1241                ),
1242                (
1243                    "int_map".to_string(),
1244                    map![
1245                        (Field::Str("k1".to_string()), Field::Null),
1246                        (Field::Str("k3".to_string()), Field::Null)
1247                    ]
1248                ),
1249                ("int_Map_Array".to_string(), Field::Null),
1250                (
1251                    "nested_struct".to_string(),
1252                    group![
1253                        ("A".to_string(), Field::Int(7)),
1254                        (
1255                            "b".to_string(),
1256                            list![Field::Int(2), Field::Int(3), Field::Null]
1257                        ),
1258                        (
1259                            "C".to_string(),
1260                            group![(
1261                                "d".to_string(),
1262                                list![list![], list![Field::Null], Field::Null]
1263                            )]
1264                        ),
1265                        ("g".to_string(), Field::Null)
1266                    ]
1267                )
1268            ],
1269        ];
1270        assert_eq!(rows, expected_rows);
1271    }
1272
1273    #[test]
1274    fn test_file_reader_rows_projection() {
1275        let schema = "
1276      message spark_schema {
1277        REQUIRED DOUBLE c;
1278        REQUIRED INT32 b;
1279      }
1280    ";
1281        let schema = parse_message_type(schema).unwrap();
1282        let rows = test_file_reader_rows("nested_maps.snappy.parquet", Some(schema)).unwrap();
1283        let expected_rows = vec![
1284            row![
1285                ("c".to_string(), Field::Double(1.0)),
1286                ("b".to_string(), Field::Int(1))
1287            ],
1288            row![
1289                ("c".to_string(), Field::Double(1.0)),
1290                ("b".to_string(), Field::Int(1))
1291            ],
1292            row![
1293                ("c".to_string(), Field::Double(1.0)),
1294                ("b".to_string(), Field::Int(1))
1295            ],
1296            row![
1297                ("c".to_string(), Field::Double(1.0)),
1298                ("b".to_string(), Field::Int(1))
1299            ],
1300            row![
1301                ("c".to_string(), Field::Double(1.0)),
1302                ("b".to_string(), Field::Int(1))
1303            ],
1304            row![
1305                ("c".to_string(), Field::Double(1.0)),
1306                ("b".to_string(), Field::Int(1))
1307            ],
1308        ];
1309        assert_eq!(rows, expected_rows);
1310    }
1311
1312    #[test]
1313    fn test_iter_columns_in_row() {
1314        let r = row![
1315            ("c".to_string(), Field::Double(1.0)),
1316            ("b".to_string(), Field::Int(1))
1317        ];
1318        let mut result = Vec::new();
1319        for (name, record) in r.get_column_iter() {
1320            result.push((name, record));
1321        }
1322        assert_eq!(
1323            vec![
1324                (&"c".to_string(), &Field::Double(1.0)),
1325                (&"b".to_string(), &Field::Int(1))
1326            ],
1327            result
1328        );
1329    }
1330
1331    #[test]
1332    fn test_into_columns_in_row() {
1333        let r = row![
1334            ("a".to_string(), Field::Str("My string".to_owned())),
1335            ("b".to_string(), Field::Int(1))
1336        ];
1337        assert_eq!(
1338            r.into_columns(),
1339            vec![
1340                ("a".to_string(), Field::Str("My string".to_owned())),
1341                ("b".to_string(), Field::Int(1)),
1342            ]
1343        );
1344    }
1345
1346    #[test]
1347    fn test_file_reader_rows_projection_map() {
1348        let schema = "
1349      message spark_schema {
1350        OPTIONAL group a (MAP) {
1351          REPEATED group key_value {
1352            REQUIRED BYTE_ARRAY key (UTF8);
1353            OPTIONAL group value (MAP) {
1354              REPEATED group key_value {
1355                REQUIRED INT32 key;
1356                REQUIRED BOOLEAN value;
1357              }
1358            }
1359          }
1360        }
1361      }
1362    ";
1363        let schema = parse_message_type(schema).unwrap();
1364        let rows = test_file_reader_rows("nested_maps.snappy.parquet", Some(schema)).unwrap();
1365        let expected_rows = vec![
1366            row![(
1367                "a".to_string(),
1368                map![(
1369                    Field::Str("a".to_string()),
1370                    map![
1371                        (Field::Int(1), Field::Bool(true)),
1372                        (Field::Int(2), Field::Bool(false))
1373                    ]
1374                )]
1375            )],
1376            row![(
1377                "a".to_string(),
1378                map![(
1379                    Field::Str("b".to_string()),
1380                    map![(Field::Int(1), Field::Bool(true))]
1381                )]
1382            )],
1383            row![(
1384                "a".to_string(),
1385                map![(Field::Str("c".to_string()), Field::Null)]
1386            )],
1387            row![("a".to_string(), map![(Field::Str("d".to_string()), map![])])],
1388            row![(
1389                "a".to_string(),
1390                map![(
1391                    Field::Str("e".to_string()),
1392                    map![(Field::Int(1), Field::Bool(true))]
1393                )]
1394            )],
1395            row![(
1396                "a".to_string(),
1397                map![(
1398                    Field::Str("f".to_string()),
1399                    map![
1400                        (Field::Int(3), Field::Bool(true)),
1401                        (Field::Int(4), Field::Bool(false)),
1402                        (Field::Int(5), Field::Bool(true))
1403                    ]
1404                )]
1405            )],
1406        ];
1407        assert_eq!(rows, expected_rows);
1408    }
1409
1410    #[test]
1411    fn test_file_reader_rows_projection_list() {
1412        let schema = "
1413      message spark_schema {
1414        OPTIONAL group a (LIST) {
1415          REPEATED group list {
1416            OPTIONAL group element (LIST) {
1417              REPEATED group list {
1418                OPTIONAL group element (LIST) {
1419                  REPEATED group list {
1420                    OPTIONAL BYTE_ARRAY element (UTF8);
1421                  }
1422                }
1423              }
1424            }
1425          }
1426        }
1427      }
1428    ";
1429        let schema = parse_message_type(schema).unwrap();
1430        let rows = test_file_reader_rows("nested_lists.snappy.parquet", Some(schema)).unwrap();
1431        let expected_rows = vec![
1432            row![(
1433                "a".to_string(),
1434                list![
1435                    list![
1436                        list![Field::Str("a".to_string()), Field::Str("b".to_string())],
1437                        list![Field::Str("c".to_string())]
1438                    ],
1439                    list![Field::Null, list![Field::Str("d".to_string())]]
1440                ]
1441            )],
1442            row![(
1443                "a".to_string(),
1444                list![
1445                    list![
1446                        list![Field::Str("a".to_string()), Field::Str("b".to_string())],
1447                        list![Field::Str("c".to_string()), Field::Str("d".to_string())]
1448                    ],
1449                    list![Field::Null, list![Field::Str("e".to_string())]]
1450                ]
1451            )],
1452            row![(
1453                "a".to_string(),
1454                list![
1455                    list![
1456                        list![Field::Str("a".to_string()), Field::Str("b".to_string())],
1457                        list![Field::Str("c".to_string()), Field::Str("d".to_string())],
1458                        list![Field::Str("e".to_string())]
1459                    ],
1460                    list![Field::Null, list![Field::Str("f".to_string())]]
1461                ]
1462            )],
1463        ];
1464        assert_eq!(rows, expected_rows);
1465    }
1466
1467    #[test]
1468    fn test_file_reader_rows_invalid_projection() {
1469        let schema = "
1470      message spark_schema {
1471        REQUIRED INT32 key;
1472        REQUIRED BOOLEAN value;
1473      }
1474    ";
1475        let schema = parse_message_type(schema).unwrap();
1476        let res = test_file_reader_rows("nested_maps.snappy.parquet", Some(schema));
1477        assert_eq!(
1478            res.unwrap_err().to_string(),
1479            "Parquet error: Root schema does not contain projection"
1480        );
1481    }
1482
1483    #[test]
1484    fn test_row_group_rows_invalid_projection() {
1485        let schema = "
1486      message spark_schema {
1487        REQUIRED INT32 key;
1488        REQUIRED BOOLEAN value;
1489      }
1490    ";
1491        let schema = parse_message_type(schema).unwrap();
1492        let res = test_row_group_rows("nested_maps.snappy.parquet", Some(schema));
1493        assert_eq!(
1494            res.unwrap_err().to_string(),
1495            "Parquet error: Root schema does not contain projection"
1496        );
1497    }
1498
1499    #[test]
1500    fn test_file_reader_rows_nested_map_type() {
1501        let schema = "
1502      message spark_schema {
1503        OPTIONAL group a (MAP) {
1504          REPEATED group key_value {
1505            REQUIRED BYTE_ARRAY key (UTF8);
1506            OPTIONAL group value (MAP) {
1507              REPEATED group key_value {
1508                REQUIRED INT32 key;
1509              }
1510            }
1511          }
1512        }
1513      }
1514    ";
1515        let schema = parse_message_type(schema).unwrap();
1516        test_file_reader_rows("nested_maps.snappy.parquet", Some(schema)).unwrap();
1517    }
1518
1519    #[test]
1520    fn test_file_reader_iter() {
1521        let path = get_test_path("alltypes_plain.parquet");
1522        let reader = SerializedFileReader::try_from(path.as_path()).unwrap();
1523        let iter = RowIter::from_file_into(Box::new(reader));
1524
1525        let values: Vec<_> = iter.flat_map(|r| r.unwrap().get_int(0)).collect();
1526        assert_eq!(values, &[4, 5, 6, 7, 2, 3, 0, 1]);
1527    }
1528
1529    #[test]
1530    fn test_file_reader_iter_projection() {
1531        let path = get_test_path("alltypes_plain.parquet");
1532        let reader = SerializedFileReader::try_from(path.as_path()).unwrap();
1533        let schema = "message schema { OPTIONAL INT32 id; }";
1534        let proj = parse_message_type(schema).ok();
1535
1536        let iter = RowIter::from_file_into(Box::new(reader))
1537            .project(proj)
1538            .unwrap();
1539        let values: Vec<_> = iter.flat_map(|r| r.unwrap().get_int(0)).collect();
1540
1541        assert_eq!(values, &[4, 5, 6, 7, 2, 3, 0, 1]);
1542    }
1543
1544    #[test]
1545    fn test_file_reader_iter_projection_err() {
1546        let schema = "
1547      message spark_schema {
1548        REQUIRED INT32 key;
1549        REQUIRED BOOLEAN value;
1550      }
1551    ";
1552        let proj = parse_message_type(schema).ok();
1553        let path = get_test_path("nested_maps.snappy.parquet");
1554        let reader = SerializedFileReader::try_from(path.as_path()).unwrap();
1555        let res = RowIter::from_file_into(Box::new(reader)).project(proj);
1556
1557        assert_eq!(
1558            res.err().unwrap().to_string(),
1559            "Parquet error: Root schema does not contain projection"
1560        );
1561    }
1562
1563    #[test]
1564    fn test_tree_reader_handle_repeated_fields_with_no_annotation() {
1565        // Array field `phoneNumbers` does not contain LIST annotation.
1566        // We parse it as struct with `phone` repeated field as array.
1567        let rows = test_file_reader_rows("repeated_no_annotation.parquet", None).unwrap();
1568        let expected_rows = vec![
1569            row![
1570                ("id".to_string(), Field::Int(1)),
1571                ("phoneNumbers".to_string(), Field::Null)
1572            ],
1573            row![
1574                ("id".to_string(), Field::Int(2)),
1575                ("phoneNumbers".to_string(), Field::Null)
1576            ],
1577            row![
1578                ("id".to_string(), Field::Int(3)),
1579                (
1580                    "phoneNumbers".to_string(),
1581                    group![("phone".to_string(), list![])]
1582                )
1583            ],
1584            row![
1585                ("id".to_string(), Field::Int(4)),
1586                (
1587                    "phoneNumbers".to_string(),
1588                    group![(
1589                        "phone".to_string(),
1590                        list![group![
1591                            ("number".to_string(), Field::Long(5555555555)),
1592                            ("kind".to_string(), Field::Null)
1593                        ]]
1594                    )]
1595                )
1596            ],
1597            row![
1598                ("id".to_string(), Field::Int(5)),
1599                (
1600                    "phoneNumbers".to_string(),
1601                    group![(
1602                        "phone".to_string(),
1603                        list![group![
1604                            ("number".to_string(), Field::Long(1111111111)),
1605                            ("kind".to_string(), Field::Str("home".to_string()))
1606                        ]]
1607                    )]
1608                )
1609            ],
1610            row![
1611                ("id".to_string(), Field::Int(6)),
1612                (
1613                    "phoneNumbers".to_string(),
1614                    group![(
1615                        "phone".to_string(),
1616                        list![
1617                            group![
1618                                ("number".to_string(), Field::Long(1111111111)),
1619                                ("kind".to_string(), Field::Str("home".to_string()))
1620                            ],
1621                            group![
1622                                ("number".to_string(), Field::Long(2222222222)),
1623                                ("kind".to_string(), Field::Null)
1624                            ],
1625                            group![
1626                                ("number".to_string(), Field::Long(3333333333)),
1627                                ("kind".to_string(), Field::Str("mobile".to_string()))
1628                            ]
1629                        ]
1630                    )]
1631                )
1632            ],
1633        ];
1634
1635        assert_eq!(rows, expected_rows);
1636    }
1637
1638    #[test]
1639    fn test_tree_reader_handle_nested_repeated_fields_with_no_annotation() {
1640        // Create schema
1641        let schema = Arc::new(
1642            parse_message_type(
1643                "
1644            message schema {
1645                REPEATED group level1 {
1646                    REPEATED group level2 {
1647                        REQUIRED group level3 {
1648                            REQUIRED INT64 value3;
1649                        }
1650                    }
1651                    REQUIRED INT64 value1;
1652                }
1653            }",
1654            )
1655            .unwrap(),
1656        );
1657
1658        // Write Parquet file to buffer
1659        let mut buffer: Vec<u8> = Vec::new();
1660        let mut file_writer =
1661            SerializedFileWriter::new(&mut buffer, schema, Default::default()).unwrap();
1662        let mut row_group_writer = file_writer.next_row_group().unwrap();
1663
1664        // Write column level1.level2.level3.value3
1665        let mut column_writer = row_group_writer.next_column().unwrap().unwrap();
1666        column_writer
1667            .typed::<Int64Type>()
1668            .write_batch(&[30, 31, 32], Some(&[2, 2, 2]), Some(&[0, 0, 0]))
1669            .unwrap();
1670        column_writer.close().unwrap();
1671
1672        // Write column level1.value1
1673        let mut column_writer = row_group_writer.next_column().unwrap().unwrap();
1674        column_writer
1675            .typed::<Int64Type>()
1676            .write_batch(&[10, 11, 12], Some(&[1, 1, 1]), Some(&[0, 0, 0]))
1677            .unwrap();
1678        column_writer.close().unwrap();
1679
1680        // Finalize Parquet file
1681        row_group_writer.close().unwrap();
1682        file_writer.close().unwrap();
1683        assert_eq!(&buffer[0..4], b"PAR1");
1684
1685        // Read Parquet file from buffer
1686        let file_reader = SerializedFileReader::new(Bytes::from(buffer)).unwrap();
1687        let rows: Vec<_> = file_reader
1688            .get_row_iter(None)
1689            .unwrap()
1690            .map(|row| row.unwrap())
1691            .collect();
1692
1693        let expected_rows = vec![
1694            row![(
1695                "level1".to_string(),
1696                list![group![
1697                    (
1698                        "level2".to_string(),
1699                        list![group![(
1700                            "level3".to_string(),
1701                            group![("value3".to_string(), Field::Long(30))]
1702                        )]]
1703                    ),
1704                    ("value1".to_string(), Field::Long(10))
1705                ]]
1706            )],
1707            row![(
1708                "level1".to_string(),
1709                list![group![
1710                    (
1711                        "level2".to_string(),
1712                        list![group![(
1713                            "level3".to_string(),
1714                            group![("value3".to_string(), Field::Long(31))]
1715                        )]]
1716                    ),
1717                    ("value1".to_string(), Field::Long(11))
1718                ]]
1719            )],
1720            row![(
1721                "level1".to_string(),
1722                list![group![
1723                    (
1724                        "level2".to_string(),
1725                        list![group![(
1726                            "level3".to_string(),
1727                            group![("value3".to_string(), Field::Long(32))]
1728                        )]]
1729                    ),
1730                    ("value1".to_string(), Field::Long(12))
1731                ]]
1732            )],
1733        ];
1734
1735        assert_eq!(rows, expected_rows);
1736    }
1737
1738    #[test]
1739    fn test_tree_reader_handle_primitive_repeated_fields_with_no_annotation() {
1740        // In this test the REPEATED fields are primitives
1741        let rows = test_file_reader_rows("repeated_primitive_no_list.parquet", None).unwrap();
1742        let expected_rows = vec![
1743            row![
1744                (
1745                    "Int32_list".to_string(),
1746                    Field::ListInternal(make_list([0, 1, 2, 3].map(Field::Int).to_vec()))
1747                ),
1748                (
1749                    "String_list".to_string(),
1750                    Field::ListInternal(make_list(
1751                        ["foo", "zero", "one", "two"]
1752                            .map(|s| Field::Str(s.to_string()))
1753                            .to_vec()
1754                    ))
1755                ),
1756                (
1757                    "group_of_lists".to_string(),
1758                    group![
1759                        (
1760                            "Int32_list_in_group".to_string(),
1761                            Field::ListInternal(make_list([0, 1, 2, 3].map(Field::Int).to_vec()))
1762                        ),
1763                        (
1764                            "String_list_in_group".to_string(),
1765                            Field::ListInternal(make_list(
1766                                ["foo", "zero", "one", "two"]
1767                                    .map(|s| Field::Str(s.to_string()))
1768                                    .to_vec()
1769                            ))
1770                        )
1771                    ]
1772                )
1773            ],
1774            row![
1775                (
1776                    "Int32_list".to_string(),
1777                    Field::ListInternal(make_list(vec![]))
1778                ),
1779                (
1780                    "String_list".to_string(),
1781                    Field::ListInternal(make_list(
1782                        ["three"].map(|s| Field::Str(s.to_string())).to_vec()
1783                    ))
1784                ),
1785                (
1786                    "group_of_lists".to_string(),
1787                    group![
1788                        (
1789                            "Int32_list_in_group".to_string(),
1790                            Field::ListInternal(make_list(vec![]))
1791                        ),
1792                        (
1793                            "String_list_in_group".to_string(),
1794                            Field::ListInternal(make_list(
1795                                ["three"].map(|s| Field::Str(s.to_string())).to_vec()
1796                            ))
1797                        )
1798                    ]
1799                )
1800            ],
1801            row![
1802                (
1803                    "Int32_list".to_string(),
1804                    Field::ListInternal(make_list(vec![Field::Int(4)]))
1805                ),
1806                (
1807                    "String_list".to_string(),
1808                    Field::ListInternal(make_list(
1809                        ["four"].map(|s| Field::Str(s.to_string())).to_vec()
1810                    ))
1811                ),
1812                (
1813                    "group_of_lists".to_string(),
1814                    group![
1815                        (
1816                            "Int32_list_in_group".to_string(),
1817                            Field::ListInternal(make_list(vec![Field::Int(4)]))
1818                        ),
1819                        (
1820                            "String_list_in_group".to_string(),
1821                            Field::ListInternal(make_list(
1822                                ["four"].map(|s| Field::Str(s.to_string())).to_vec()
1823                            ))
1824                        )
1825                    ]
1826                )
1827            ],
1828            row![
1829                (
1830                    "Int32_list".to_string(),
1831                    Field::ListInternal(make_list([5, 6, 7, 8].map(Field::Int).to_vec()))
1832                ),
1833                (
1834                    "String_list".to_string(),
1835                    Field::ListInternal(make_list(
1836                        ["five", "six", "seven", "eight"]
1837                            .map(|s| Field::Str(s.to_string()))
1838                            .to_vec()
1839                    ))
1840                ),
1841                (
1842                    "group_of_lists".to_string(),
1843                    group![
1844                        (
1845                            "Int32_list_in_group".to_string(),
1846                            Field::ListInternal(make_list([5, 6, 7, 8].map(Field::Int).to_vec()))
1847                        ),
1848                        (
1849                            "String_list_in_group".to_string(),
1850                            Field::ListInternal(make_list(
1851                                ["five", "six", "seven", "eight"]
1852                                    .map(|s| Field::Str(s.to_string()))
1853                                    .to_vec()
1854                            ))
1855                        )
1856                    ]
1857                )
1858            ],
1859        ];
1860        assert_eq!(rows, expected_rows);
1861    }
1862
1863    #[test]
1864    fn test_map_no_value() {
1865        // File schema:
1866        // message schema {
1867        //   required group my_map (MAP) {
1868        //     repeated group key_value {
1869        //       required int32 key;
1870        //       optional int32 value;
1871        //     }
1872        //   }
1873        //   required group my_map_no_v (MAP) {
1874        //     repeated group key_value {
1875        //       required int32 key;
1876        //     }
1877        //   }
1878        //   required group my_list (LIST) {
1879        //     repeated group list {
1880        //       required int32 element;
1881        //     }
1882        //   }
1883        // }
1884        let rows = test_file_reader_rows("map_no_value.parquet", None).unwrap();
1885
1886        // the my_map_no_v and my_list columns should be equivalent lists by this point
1887        for row in rows {
1888            let cols = row.into_columns();
1889            assert_eq!(cols[1].1, cols[2].1);
1890        }
1891    }
1892
1893    fn test_file_reader_rows(file_name: &str, schema: Option<Type>) -> Result<Vec<Row>> {
1894        let file = get_test_file(file_name);
1895        let file_reader: Box<dyn FileReader> = Box::new(SerializedFileReader::new(file)?);
1896        let iter = file_reader.get_row_iter(schema)?;
1897        Ok(iter.map(|row| row.unwrap()).collect())
1898    }
1899
1900    fn test_row_group_rows(file_name: &str, schema: Option<Type>) -> Result<Vec<Row>> {
1901        let file = get_test_file(file_name);
1902        let file_reader: Box<dyn FileReader> = Box::new(SerializedFileReader::new(file)?);
1903        // Check the first row group only, because files will contain only single row
1904        // group
1905        let row_group_reader = file_reader.get_row_group(0).unwrap();
1906        let iter = row_group_reader.get_row_iter(schema)?;
1907        Ok(iter.map(|row| row.unwrap()).collect())
1908    }
1909
1910    #[test]
1911    fn test_read_old_nested_list() {
1912        let rows = test_file_reader_rows("old_list_structure.parquet", None).unwrap();
1913        let expected_rows = vec![row![(
1914            "a".to_string(),
1915            Field::ListInternal(make_list(
1916                [
1917                    make_list([1, 2].map(Field::Int).to_vec()),
1918                    make_list([3, 4].map(Field::Int).to_vec())
1919                ]
1920                .map(Field::ListInternal)
1921                .to_vec()
1922            ))
1923        ),]];
1924        assert_eq!(rows, expected_rows);
1925    }
1926
1927    fn assert_err_on_overcount(file_name: &str, proj_schema: Option<Type>) {
1928        let file = get_test_file(file_name);
1929        let file_reader = SerializedFileReader::new(file).unwrap();
1930        let metadata = file_reader.metadata();
1931        let row_group_reader = file_reader.get_row_group(0).unwrap();
1932        let actual_rows = row_group_reader.metadata().num_rows() as usize;
1933
1934        let descr = match proj_schema {
1935            Some(schema) => Arc::new(SchemaDescriptor::new(Arc::new(schema))),
1936            None => metadata.file_metadata().schema_descr_ptr(),
1937        };
1938        let reader = TreeBuilder::new().build(descr, &*row_group_reader).unwrap();
1939        let iter = ReaderIter::new(reader, actual_rows + 1).unwrap();
1940
1941        let rows: Vec<Result<Row>> = iter.collect();
1942        assert_eq!(rows.len(), actual_rows + 1);
1943        for row in &rows[..actual_rows] {
1944            assert!(row.is_ok(), "Expected Ok row, got: {row:?}");
1945        }
1946        let err = rows[actual_rows].as_ref().unwrap_err();
1947        assert!(
1948            err.to_string().contains("Unexpected end of column data"),
1949            "Unexpected error message: {err}"
1950        );
1951    }
1952
1953    #[test]
1954    fn test_reader_iter_returns_error_when_num_records_exceeds_data() {
1955        assert_err_on_overcount("nulls.snappy.parquet", None);
1956    }
1957
1958    #[test]
1959    fn test_reader_iter_returns_error_for_repeated_field_when_num_records_exceeds_data() {
1960        assert_err_on_overcount("repeated_primitive_no_list.parquet", None);
1961    }
1962
1963    #[test]
1964    fn test_reader_iter_returns_error_for_map_field_when_num_records_exceeds_data() {
1965        let schema = parse_message_type(
1966            "message schema {
1967               REQUIRED group my_map (MAP) {
1968                 REPEATED group key_value {
1969                   REQUIRED INT32 key;
1970                   OPTIONAL INT32 value;
1971                 }
1972               }
1973             }",
1974        )
1975        .unwrap();
1976        assert_err_on_overcount("map_no_value.parquet", Some(schema));
1977    }
1978}