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            _ => {}
127        }
128
129        path.push(String::from(field.name()));
130        let reader = if field.is_primitive() {
131            let col_path = ColumnPath::new(path.to_vec());
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    fn test_file_reader_rows_nonnullable() {
936        let rows = test_file_reader_rows("nonnullable.impala.parquet", None).unwrap();
937        let expected_rows = vec![row![
938            ("ID".to_string(), Field::Long(8)),
939            ("Int_Array".to_string(), list![Field::Int(-1)]),
940            (
941                "int_array_array".to_string(),
942                list![list![Field::Int(-1), Field::Int(-2)], list![]]
943            ),
944            (
945                "Int_Map".to_string(),
946                map![(Field::Str("k1".to_string()), Field::Int(-1))]
947            ),
948            (
949                "int_map_array".to_string(),
950                list![
951                    map![],
952                    map![(Field::Str("k1".to_string()), Field::Int(1))],
953                    map![],
954                    map![]
955                ]
956            ),
957            (
958                "nested_Struct".to_string(),
959                group![
960                    ("a".to_string(), Field::Int(-1)),
961                    ("B".to_string(), list![Field::Int(-1)]),
962                    (
963                        "c".to_string(),
964                        group![(
965                            "D".to_string(),
966                            list![list![group![
967                                ("e".to_string(), Field::Int(-1)),
968                                ("f".to_string(), Field::Str("nonnullable".to_string()))
969                            ]]]
970                        )]
971                    ),
972                    ("G".to_string(), map![])
973                ]
974            )
975        ]];
976        assert_eq!(rows, expected_rows);
977    }
978
979    #[test]
980    fn test_file_reader_rows_nullable() {
981        let rows = test_file_reader_rows("nullable.impala.parquet", None).unwrap();
982        let expected_rows = vec![
983            row![
984                ("id".to_string(), Field::Long(1)),
985                (
986                    "int_array".to_string(),
987                    list![Field::Int(1), Field::Int(2), Field::Int(3)]
988                ),
989                (
990                    "int_array_Array".to_string(),
991                    list![
992                        list![Field::Int(1), Field::Int(2)],
993                        list![Field::Int(3), Field::Int(4)]
994                    ]
995                ),
996                (
997                    "int_map".to_string(),
998                    map![
999                        (Field::Str("k1".to_string()), Field::Int(1)),
1000                        (Field::Str("k2".to_string()), Field::Int(100))
1001                    ]
1002                ),
1003                (
1004                    "int_Map_Array".to_string(),
1005                    list![map![(Field::Str("k1".to_string()), Field::Int(1))]]
1006                ),
1007                (
1008                    "nested_struct".to_string(),
1009                    group![
1010                        ("A".to_string(), Field::Int(1)),
1011                        ("b".to_string(), list![Field::Int(1)]),
1012                        (
1013                            "C".to_string(),
1014                            group![(
1015                                "d".to_string(),
1016                                list![
1017                                    list![
1018                                        group![
1019                                            ("E".to_string(), Field::Int(10)),
1020                                            ("F".to_string(), Field::Str("aaa".to_string()))
1021                                        ],
1022                                        group![
1023                                            ("E".to_string(), Field::Int(-10)),
1024                                            ("F".to_string(), Field::Str("bbb".to_string()))
1025                                        ]
1026                                    ],
1027                                    list![group![
1028                                        ("E".to_string(), Field::Int(11)),
1029                                        ("F".to_string(), Field::Str("c".to_string()))
1030                                    ]]
1031                                ]
1032                            )]
1033                        ),
1034                        (
1035                            "g".to_string(),
1036                            map![(
1037                                Field::Str("foo".to_string()),
1038                                group![(
1039                                    "H".to_string(),
1040                                    group![("i".to_string(), list![Field::Double(1.1)])]
1041                                )]
1042                            )]
1043                        )
1044                    ]
1045                )
1046            ],
1047            row![
1048                ("id".to_string(), Field::Long(2)),
1049                (
1050                    "int_array".to_string(),
1051                    list![
1052                        Field::Null,
1053                        Field::Int(1),
1054                        Field::Int(2),
1055                        Field::Null,
1056                        Field::Int(3),
1057                        Field::Null
1058                    ]
1059                ),
1060                (
1061                    "int_array_Array".to_string(),
1062                    list![
1063                        list![Field::Null, Field::Int(1), Field::Int(2), Field::Null],
1064                        list![Field::Int(3), Field::Null, Field::Int(4)],
1065                        list![],
1066                        Field::Null
1067                    ]
1068                ),
1069                (
1070                    "int_map".to_string(),
1071                    map![
1072                        (Field::Str("k1".to_string()), Field::Int(2)),
1073                        (Field::Str("k2".to_string()), Field::Null)
1074                    ]
1075                ),
1076                (
1077                    "int_Map_Array".to_string(),
1078                    list![
1079                        map![
1080                            (Field::Str("k3".to_string()), Field::Null),
1081                            (Field::Str("k1".to_string()), Field::Int(1))
1082                        ],
1083                        Field::Null,
1084                        map![]
1085                    ]
1086                ),
1087                (
1088                    "nested_struct".to_string(),
1089                    group![
1090                        ("A".to_string(), Field::Null),
1091                        ("b".to_string(), list![Field::Null]),
1092                        (
1093                            "C".to_string(),
1094                            group![(
1095                                "d".to_string(),
1096                                list![
1097                                    list![
1098                                        group![
1099                                            ("E".to_string(), Field::Null),
1100                                            ("F".to_string(), Field::Null)
1101                                        ],
1102                                        group![
1103                                            ("E".to_string(), Field::Int(10)),
1104                                            ("F".to_string(), Field::Str("aaa".to_string()))
1105                                        ],
1106                                        group![
1107                                            ("E".to_string(), Field::Null),
1108                                            ("F".to_string(), Field::Null)
1109                                        ],
1110                                        group![
1111                                            ("E".to_string(), Field::Int(-10)),
1112                                            ("F".to_string(), Field::Str("bbb".to_string()))
1113                                        ],
1114                                        group![
1115                                            ("E".to_string(), Field::Null),
1116                                            ("F".to_string(), Field::Null)
1117                                        ]
1118                                    ],
1119                                    list![
1120                                        group![
1121                                            ("E".to_string(), Field::Int(11)),
1122                                            ("F".to_string(), Field::Str("c".to_string()))
1123                                        ],
1124                                        Field::Null
1125                                    ],
1126                                    list![],
1127                                    Field::Null
1128                                ]
1129                            )]
1130                        ),
1131                        (
1132                            "g".to_string(),
1133                            map![
1134                                (
1135                                    Field::Str("g1".to_string()),
1136                                    group![(
1137                                        "H".to_string(),
1138                                        group![(
1139                                            "i".to_string(),
1140                                            list![Field::Double(2.2), Field::Null]
1141                                        )]
1142                                    )]
1143                                ),
1144                                (
1145                                    Field::Str("g2".to_string()),
1146                                    group![("H".to_string(), group![("i".to_string(), list![])])]
1147                                ),
1148                                (Field::Str("g3".to_string()), Field::Null),
1149                                (
1150                                    Field::Str("g4".to_string()),
1151                                    group![(
1152                                        "H".to_string(),
1153                                        group![("i".to_string(), Field::Null)]
1154                                    )]
1155                                ),
1156                                (
1157                                    Field::Str("g5".to_string()),
1158                                    group![("H".to_string(), Field::Null)]
1159                                )
1160                            ]
1161                        )
1162                    ]
1163                )
1164            ],
1165            row![
1166                ("id".to_string(), Field::Long(3)),
1167                ("int_array".to_string(), list![]),
1168                ("int_array_Array".to_string(), list![Field::Null]),
1169                ("int_map".to_string(), map![]),
1170                ("int_Map_Array".to_string(), list![Field::Null, Field::Null]),
1171                (
1172                    "nested_struct".to_string(),
1173                    group![
1174                        ("A".to_string(), Field::Null),
1175                        ("b".to_string(), Field::Null),
1176                        ("C".to_string(), group![("d".to_string(), list![])]),
1177                        ("g".to_string(), map![])
1178                    ]
1179                )
1180            ],
1181            row![
1182                ("id".to_string(), Field::Long(4)),
1183                ("int_array".to_string(), Field::Null),
1184                ("int_array_Array".to_string(), list![]),
1185                ("int_map".to_string(), map![]),
1186                ("int_Map_Array".to_string(), list![]),
1187                (
1188                    "nested_struct".to_string(),
1189                    group![
1190                        ("A".to_string(), Field::Null),
1191                        ("b".to_string(), Field::Null),
1192                        ("C".to_string(), group![("d".to_string(), Field::Null)]),
1193                        ("g".to_string(), Field::Null)
1194                    ]
1195                )
1196            ],
1197            row![
1198                ("id".to_string(), Field::Long(5)),
1199                ("int_array".to_string(), Field::Null),
1200                ("int_array_Array".to_string(), Field::Null),
1201                ("int_map".to_string(), map![]),
1202                ("int_Map_Array".to_string(), Field::Null),
1203                (
1204                    "nested_struct".to_string(),
1205                    group![
1206                        ("A".to_string(), Field::Null),
1207                        ("b".to_string(), Field::Null),
1208                        ("C".to_string(), Field::Null),
1209                        (
1210                            "g".to_string(),
1211                            map![(
1212                                Field::Str("foo".to_string()),
1213                                group![(
1214                                    "H".to_string(),
1215                                    group![(
1216                                        "i".to_string(),
1217                                        list![Field::Double(2.2), Field::Double(3.3)]
1218                                    )]
1219                                )]
1220                            )]
1221                        )
1222                    ]
1223                )
1224            ],
1225            row![
1226                ("id".to_string(), Field::Long(6)),
1227                ("int_array".to_string(), Field::Null),
1228                ("int_array_Array".to_string(), Field::Null),
1229                ("int_map".to_string(), Field::Null),
1230                ("int_Map_Array".to_string(), Field::Null),
1231                ("nested_struct".to_string(), Field::Null)
1232            ],
1233            row![
1234                ("id".to_string(), Field::Long(7)),
1235                ("int_array".to_string(), Field::Null),
1236                (
1237                    "int_array_Array".to_string(),
1238                    list![Field::Null, list![Field::Int(5), Field::Int(6)]]
1239                ),
1240                (
1241                    "int_map".to_string(),
1242                    map![
1243                        (Field::Str("k1".to_string()), Field::Null),
1244                        (Field::Str("k3".to_string()), Field::Null)
1245                    ]
1246                ),
1247                ("int_Map_Array".to_string(), Field::Null),
1248                (
1249                    "nested_struct".to_string(),
1250                    group![
1251                        ("A".to_string(), Field::Int(7)),
1252                        (
1253                            "b".to_string(),
1254                            list![Field::Int(2), Field::Int(3), Field::Null]
1255                        ),
1256                        (
1257                            "C".to_string(),
1258                            group![(
1259                                "d".to_string(),
1260                                list![list![], list![Field::Null], Field::Null]
1261                            )]
1262                        ),
1263                        ("g".to_string(), Field::Null)
1264                    ]
1265                )
1266            ],
1267        ];
1268        assert_eq!(rows, expected_rows);
1269    }
1270
1271    #[test]
1272    fn test_file_reader_rows_projection() {
1273        let schema = "
1274      message spark_schema {
1275        REQUIRED DOUBLE c;
1276        REQUIRED INT32 b;
1277      }
1278    ";
1279        let schema = parse_message_type(schema).unwrap();
1280        let rows = test_file_reader_rows("nested_maps.snappy.parquet", Some(schema)).unwrap();
1281        let expected_rows = vec![
1282            row![
1283                ("c".to_string(), Field::Double(1.0)),
1284                ("b".to_string(), Field::Int(1))
1285            ],
1286            row![
1287                ("c".to_string(), Field::Double(1.0)),
1288                ("b".to_string(), Field::Int(1))
1289            ],
1290            row![
1291                ("c".to_string(), Field::Double(1.0)),
1292                ("b".to_string(), Field::Int(1))
1293            ],
1294            row![
1295                ("c".to_string(), Field::Double(1.0)),
1296                ("b".to_string(), Field::Int(1))
1297            ],
1298            row![
1299                ("c".to_string(), Field::Double(1.0)),
1300                ("b".to_string(), Field::Int(1))
1301            ],
1302            row![
1303                ("c".to_string(), Field::Double(1.0)),
1304                ("b".to_string(), Field::Int(1))
1305            ],
1306        ];
1307        assert_eq!(rows, expected_rows);
1308    }
1309
1310    #[test]
1311    fn test_iter_columns_in_row() {
1312        let r = row![
1313            ("c".to_string(), Field::Double(1.0)),
1314            ("b".to_string(), Field::Int(1))
1315        ];
1316        let mut result = Vec::new();
1317        for (name, record) in r.get_column_iter() {
1318            result.push((name, record));
1319        }
1320        assert_eq!(
1321            vec![
1322                (&"c".to_string(), &Field::Double(1.0)),
1323                (&"b".to_string(), &Field::Int(1))
1324            ],
1325            result
1326        );
1327    }
1328
1329    #[test]
1330    fn test_into_columns_in_row() {
1331        let r = row![
1332            ("a".to_string(), Field::Str("My string".to_owned())),
1333            ("b".to_string(), Field::Int(1))
1334        ];
1335        assert_eq!(
1336            r.into_columns(),
1337            vec![
1338                ("a".to_string(), Field::Str("My string".to_owned())),
1339                ("b".to_string(), Field::Int(1)),
1340            ]
1341        );
1342    }
1343
1344    #[test]
1345    fn test_file_reader_rows_projection_map() {
1346        let schema = "
1347      message spark_schema {
1348        OPTIONAL group a (MAP) {
1349          REPEATED group key_value {
1350            REQUIRED BYTE_ARRAY key (UTF8);
1351            OPTIONAL group value (MAP) {
1352              REPEATED group key_value {
1353                REQUIRED INT32 key;
1354                REQUIRED BOOLEAN value;
1355              }
1356            }
1357          }
1358        }
1359      }
1360    ";
1361        let schema = parse_message_type(schema).unwrap();
1362        let rows = test_file_reader_rows("nested_maps.snappy.parquet", Some(schema)).unwrap();
1363        let expected_rows = vec![
1364            row![(
1365                "a".to_string(),
1366                map![(
1367                    Field::Str("a".to_string()),
1368                    map![
1369                        (Field::Int(1), Field::Bool(true)),
1370                        (Field::Int(2), Field::Bool(false))
1371                    ]
1372                )]
1373            )],
1374            row![(
1375                "a".to_string(),
1376                map![(
1377                    Field::Str("b".to_string()),
1378                    map![(Field::Int(1), Field::Bool(true))]
1379                )]
1380            )],
1381            row![(
1382                "a".to_string(),
1383                map![(Field::Str("c".to_string()), Field::Null)]
1384            )],
1385            row![("a".to_string(), map![(Field::Str("d".to_string()), map![])])],
1386            row![(
1387                "a".to_string(),
1388                map![(
1389                    Field::Str("e".to_string()),
1390                    map![(Field::Int(1), Field::Bool(true))]
1391                )]
1392            )],
1393            row![(
1394                "a".to_string(),
1395                map![(
1396                    Field::Str("f".to_string()),
1397                    map![
1398                        (Field::Int(3), Field::Bool(true)),
1399                        (Field::Int(4), Field::Bool(false)),
1400                        (Field::Int(5), Field::Bool(true))
1401                    ]
1402                )]
1403            )],
1404        ];
1405        assert_eq!(rows, expected_rows);
1406    }
1407
1408    #[test]
1409    fn test_file_reader_rows_projection_list() {
1410        let schema = "
1411      message spark_schema {
1412        OPTIONAL group a (LIST) {
1413          REPEATED group list {
1414            OPTIONAL group element (LIST) {
1415              REPEATED group list {
1416                OPTIONAL group element (LIST) {
1417                  REPEATED group list {
1418                    OPTIONAL BYTE_ARRAY element (UTF8);
1419                  }
1420                }
1421              }
1422            }
1423          }
1424        }
1425      }
1426    ";
1427        let schema = parse_message_type(schema).unwrap();
1428        let rows = test_file_reader_rows("nested_lists.snappy.parquet", Some(schema)).unwrap();
1429        let expected_rows = vec![
1430            row![(
1431                "a".to_string(),
1432                list![
1433                    list![
1434                        list![Field::Str("a".to_string()), Field::Str("b".to_string())],
1435                        list![Field::Str("c".to_string())]
1436                    ],
1437                    list![Field::Null, list![Field::Str("d".to_string())]]
1438                ]
1439            )],
1440            row![(
1441                "a".to_string(),
1442                list![
1443                    list![
1444                        list![Field::Str("a".to_string()), Field::Str("b".to_string())],
1445                        list![Field::Str("c".to_string()), Field::Str("d".to_string())]
1446                    ],
1447                    list![Field::Null, list![Field::Str("e".to_string())]]
1448                ]
1449            )],
1450            row![(
1451                "a".to_string(),
1452                list![
1453                    list![
1454                        list![Field::Str("a".to_string()), Field::Str("b".to_string())],
1455                        list![Field::Str("c".to_string()), Field::Str("d".to_string())],
1456                        list![Field::Str("e".to_string())]
1457                    ],
1458                    list![Field::Null, list![Field::Str("f".to_string())]]
1459                ]
1460            )],
1461        ];
1462        assert_eq!(rows, expected_rows);
1463    }
1464
1465    #[test]
1466    fn test_file_reader_rows_invalid_projection() {
1467        let schema = "
1468      message spark_schema {
1469        REQUIRED INT32 key;
1470        REQUIRED BOOLEAN value;
1471      }
1472    ";
1473        let schema = parse_message_type(schema).unwrap();
1474        let res = test_file_reader_rows("nested_maps.snappy.parquet", Some(schema));
1475        assert_eq!(
1476            res.unwrap_err().to_string(),
1477            "Parquet error: Root schema does not contain projection"
1478        );
1479    }
1480
1481    #[test]
1482    fn test_row_group_rows_invalid_projection() {
1483        let schema = "
1484      message spark_schema {
1485        REQUIRED INT32 key;
1486        REQUIRED BOOLEAN value;
1487      }
1488    ";
1489        let schema = parse_message_type(schema).unwrap();
1490        let res = test_row_group_rows("nested_maps.snappy.parquet", Some(schema));
1491        assert_eq!(
1492            res.unwrap_err().to_string(),
1493            "Parquet error: Root schema does not contain projection"
1494        );
1495    }
1496
1497    #[test]
1498    fn test_file_reader_rows_nested_map_type() {
1499        let schema = "
1500      message spark_schema {
1501        OPTIONAL group a (MAP) {
1502          REPEATED group key_value {
1503            REQUIRED BYTE_ARRAY key (UTF8);
1504            OPTIONAL group value (MAP) {
1505              REPEATED group key_value {
1506                REQUIRED INT32 key;
1507              }
1508            }
1509          }
1510        }
1511      }
1512    ";
1513        let schema = parse_message_type(schema).unwrap();
1514        test_file_reader_rows("nested_maps.snappy.parquet", Some(schema)).unwrap();
1515    }
1516
1517    #[test]
1518    fn test_file_reader_iter() {
1519        let path = get_test_path("alltypes_plain.parquet");
1520        let reader = SerializedFileReader::try_from(path.as_path()).unwrap();
1521        let iter = RowIter::from_file_into(Box::new(reader));
1522
1523        let values: Vec<_> = iter.flat_map(|r| r.unwrap().get_int(0)).collect();
1524        assert_eq!(values, &[4, 5, 6, 7, 2, 3, 0, 1]);
1525    }
1526
1527    #[test]
1528    fn test_file_reader_iter_projection() {
1529        let path = get_test_path("alltypes_plain.parquet");
1530        let reader = SerializedFileReader::try_from(path.as_path()).unwrap();
1531        let schema = "message schema { OPTIONAL INT32 id; }";
1532        let proj = parse_message_type(schema).ok();
1533
1534        let iter = RowIter::from_file_into(Box::new(reader))
1535            .project(proj)
1536            .unwrap();
1537        let values: Vec<_> = iter.flat_map(|r| r.unwrap().get_int(0)).collect();
1538
1539        assert_eq!(values, &[4, 5, 6, 7, 2, 3, 0, 1]);
1540    }
1541
1542    #[test]
1543    fn test_file_reader_iter_projection_err() {
1544        let schema = "
1545      message spark_schema {
1546        REQUIRED INT32 key;
1547        REQUIRED BOOLEAN value;
1548      }
1549    ";
1550        let proj = parse_message_type(schema).ok();
1551        let path = get_test_path("nested_maps.snappy.parquet");
1552        let reader = SerializedFileReader::try_from(path.as_path()).unwrap();
1553        let res = RowIter::from_file_into(Box::new(reader)).project(proj);
1554
1555        assert_eq!(
1556            res.err().unwrap().to_string(),
1557            "Parquet error: Root schema does not contain projection"
1558        );
1559    }
1560
1561    #[test]
1562    fn test_tree_reader_handle_repeated_fields_with_no_annotation() {
1563        // Array field `phoneNumbers` does not contain LIST annotation.
1564        // We parse it as struct with `phone` repeated field as array.
1565        let rows = test_file_reader_rows("repeated_no_annotation.parquet", None).unwrap();
1566        let expected_rows = vec![
1567            row![
1568                ("id".to_string(), Field::Int(1)),
1569                ("phoneNumbers".to_string(), Field::Null)
1570            ],
1571            row![
1572                ("id".to_string(), Field::Int(2)),
1573                ("phoneNumbers".to_string(), Field::Null)
1574            ],
1575            row![
1576                ("id".to_string(), Field::Int(3)),
1577                (
1578                    "phoneNumbers".to_string(),
1579                    group![("phone".to_string(), list![])]
1580                )
1581            ],
1582            row![
1583                ("id".to_string(), Field::Int(4)),
1584                (
1585                    "phoneNumbers".to_string(),
1586                    group![(
1587                        "phone".to_string(),
1588                        list![group![
1589                            ("number".to_string(), Field::Long(5555555555)),
1590                            ("kind".to_string(), Field::Null)
1591                        ]]
1592                    )]
1593                )
1594            ],
1595            row![
1596                ("id".to_string(), Field::Int(5)),
1597                (
1598                    "phoneNumbers".to_string(),
1599                    group![(
1600                        "phone".to_string(),
1601                        list![group![
1602                            ("number".to_string(), Field::Long(1111111111)),
1603                            ("kind".to_string(), Field::Str("home".to_string()))
1604                        ]]
1605                    )]
1606                )
1607            ],
1608            row![
1609                ("id".to_string(), Field::Int(6)),
1610                (
1611                    "phoneNumbers".to_string(),
1612                    group![(
1613                        "phone".to_string(),
1614                        list![
1615                            group![
1616                                ("number".to_string(), Field::Long(1111111111)),
1617                                ("kind".to_string(), Field::Str("home".to_string()))
1618                            ],
1619                            group![
1620                                ("number".to_string(), Field::Long(2222222222)),
1621                                ("kind".to_string(), Field::Null)
1622                            ],
1623                            group![
1624                                ("number".to_string(), Field::Long(3333333333)),
1625                                ("kind".to_string(), Field::Str("mobile".to_string()))
1626                            ]
1627                        ]
1628                    )]
1629                )
1630            ],
1631        ];
1632
1633        assert_eq!(rows, expected_rows);
1634    }
1635
1636    #[test]
1637    fn test_tree_reader_handle_nested_repeated_fields_with_no_annotation() {
1638        // Create schema
1639        let schema = Arc::new(
1640            parse_message_type(
1641                "
1642            message schema {
1643                REPEATED group level1 {
1644                    REPEATED group level2 {
1645                        REQUIRED group level3 {
1646                            REQUIRED INT64 value3;
1647                        }
1648                    }
1649                    REQUIRED INT64 value1;
1650                }
1651            }",
1652            )
1653            .unwrap(),
1654        );
1655
1656        // Write Parquet file to buffer
1657        let mut buffer: Vec<u8> = Vec::new();
1658        let mut file_writer =
1659            SerializedFileWriter::new(&mut buffer, schema, Default::default()).unwrap();
1660        let mut row_group_writer = file_writer.next_row_group().unwrap();
1661
1662        // Write column level1.level2.level3.value3
1663        let mut column_writer = row_group_writer.next_column().unwrap().unwrap();
1664        column_writer
1665            .typed::<Int64Type>()
1666            .write_batch(&[30, 31, 32], Some(&[2, 2, 2]), Some(&[0, 0, 0]))
1667            .unwrap();
1668        column_writer.close().unwrap();
1669
1670        // Write column level1.value1
1671        let mut column_writer = row_group_writer.next_column().unwrap().unwrap();
1672        column_writer
1673            .typed::<Int64Type>()
1674            .write_batch(&[10, 11, 12], Some(&[1, 1, 1]), Some(&[0, 0, 0]))
1675            .unwrap();
1676        column_writer.close().unwrap();
1677
1678        // Finalize Parquet file
1679        row_group_writer.close().unwrap();
1680        file_writer.close().unwrap();
1681        assert_eq!(&buffer[0..4], b"PAR1");
1682
1683        // Read Parquet file from buffer
1684        let file_reader = SerializedFileReader::new(Bytes::from(buffer)).unwrap();
1685        let rows: Vec<_> = file_reader
1686            .get_row_iter(None)
1687            .unwrap()
1688            .map(|row| row.unwrap())
1689            .collect();
1690
1691        let expected_rows = vec![
1692            row![(
1693                "level1".to_string(),
1694                list![group![
1695                    (
1696                        "level2".to_string(),
1697                        list![group![(
1698                            "level3".to_string(),
1699                            group![("value3".to_string(), Field::Long(30))]
1700                        )]]
1701                    ),
1702                    ("value1".to_string(), Field::Long(10))
1703                ]]
1704            )],
1705            row![(
1706                "level1".to_string(),
1707                list![group![
1708                    (
1709                        "level2".to_string(),
1710                        list![group![(
1711                            "level3".to_string(),
1712                            group![("value3".to_string(), Field::Long(31))]
1713                        )]]
1714                    ),
1715                    ("value1".to_string(), Field::Long(11))
1716                ]]
1717            )],
1718            row![(
1719                "level1".to_string(),
1720                list![group![
1721                    (
1722                        "level2".to_string(),
1723                        list![group![(
1724                            "level3".to_string(),
1725                            group![("value3".to_string(), Field::Long(32))]
1726                        )]]
1727                    ),
1728                    ("value1".to_string(), Field::Long(12))
1729                ]]
1730            )],
1731        ];
1732
1733        assert_eq!(rows, expected_rows);
1734    }
1735
1736    #[test]
1737    fn test_tree_reader_handle_primitive_repeated_fields_with_no_annotation() {
1738        // In this test the REPEATED fields are primitives
1739        let rows = test_file_reader_rows("repeated_primitive_no_list.parquet", None).unwrap();
1740        let expected_rows = vec![
1741            row![
1742                (
1743                    "Int32_list".to_string(),
1744                    Field::ListInternal(make_list([0, 1, 2, 3].map(Field::Int).to_vec()))
1745                ),
1746                (
1747                    "String_list".to_string(),
1748                    Field::ListInternal(make_list(
1749                        ["foo", "zero", "one", "two"]
1750                            .map(|s| Field::Str(s.to_string()))
1751                            .to_vec()
1752                    ))
1753                ),
1754                (
1755                    "group_of_lists".to_string(),
1756                    group![
1757                        (
1758                            "Int32_list_in_group".to_string(),
1759                            Field::ListInternal(make_list([0, 1, 2, 3].map(Field::Int).to_vec()))
1760                        ),
1761                        (
1762                            "String_list_in_group".to_string(),
1763                            Field::ListInternal(make_list(
1764                                ["foo", "zero", "one", "two"]
1765                                    .map(|s| Field::Str(s.to_string()))
1766                                    .to_vec()
1767                            ))
1768                        )
1769                    ]
1770                )
1771            ],
1772            row![
1773                (
1774                    "Int32_list".to_string(),
1775                    Field::ListInternal(make_list(vec![]))
1776                ),
1777                (
1778                    "String_list".to_string(),
1779                    Field::ListInternal(make_list(
1780                        ["three"].map(|s| Field::Str(s.to_string())).to_vec()
1781                    ))
1782                ),
1783                (
1784                    "group_of_lists".to_string(),
1785                    group![
1786                        (
1787                            "Int32_list_in_group".to_string(),
1788                            Field::ListInternal(make_list(vec![]))
1789                        ),
1790                        (
1791                            "String_list_in_group".to_string(),
1792                            Field::ListInternal(make_list(
1793                                ["three"].map(|s| Field::Str(s.to_string())).to_vec()
1794                            ))
1795                        )
1796                    ]
1797                )
1798            ],
1799            row![
1800                (
1801                    "Int32_list".to_string(),
1802                    Field::ListInternal(make_list(vec![Field::Int(4)]))
1803                ),
1804                (
1805                    "String_list".to_string(),
1806                    Field::ListInternal(make_list(
1807                        ["four"].map(|s| Field::Str(s.to_string())).to_vec()
1808                    ))
1809                ),
1810                (
1811                    "group_of_lists".to_string(),
1812                    group![
1813                        (
1814                            "Int32_list_in_group".to_string(),
1815                            Field::ListInternal(make_list(vec![Field::Int(4)]))
1816                        ),
1817                        (
1818                            "String_list_in_group".to_string(),
1819                            Field::ListInternal(make_list(
1820                                ["four"].map(|s| Field::Str(s.to_string())).to_vec()
1821                            ))
1822                        )
1823                    ]
1824                )
1825            ],
1826            row![
1827                (
1828                    "Int32_list".to_string(),
1829                    Field::ListInternal(make_list([5, 6, 7, 8].map(Field::Int).to_vec()))
1830                ),
1831                (
1832                    "String_list".to_string(),
1833                    Field::ListInternal(make_list(
1834                        ["five", "six", "seven", "eight"]
1835                            .map(|s| Field::Str(s.to_string()))
1836                            .to_vec()
1837                    ))
1838                ),
1839                (
1840                    "group_of_lists".to_string(),
1841                    group![
1842                        (
1843                            "Int32_list_in_group".to_string(),
1844                            Field::ListInternal(make_list([5, 6, 7, 8].map(Field::Int).to_vec()))
1845                        ),
1846                        (
1847                            "String_list_in_group".to_string(),
1848                            Field::ListInternal(make_list(
1849                                ["five", "six", "seven", "eight"]
1850                                    .map(|s| Field::Str(s.to_string()))
1851                                    .to_vec()
1852                            ))
1853                        )
1854                    ]
1855                )
1856            ],
1857        ];
1858        assert_eq!(rows, expected_rows);
1859    }
1860
1861    #[test]
1862    fn test_map_no_value() {
1863        // File schema:
1864        // message schema {
1865        //   required group my_map (MAP) {
1866        //     repeated group key_value {
1867        //       required int32 key;
1868        //       optional int32 value;
1869        //     }
1870        //   }
1871        //   required group my_map_no_v (MAP) {
1872        //     repeated group key_value {
1873        //       required int32 key;
1874        //     }
1875        //   }
1876        //   required group my_list (LIST) {
1877        //     repeated group list {
1878        //       required int32 element;
1879        //     }
1880        //   }
1881        // }
1882        let rows = test_file_reader_rows("map_no_value.parquet", None).unwrap();
1883
1884        // the my_map_no_v and my_list columns should be equivalent lists by this point
1885        for row in rows {
1886            let cols = row.into_columns();
1887            assert_eq!(cols[1].1, cols[2].1);
1888        }
1889    }
1890
1891    fn test_file_reader_rows(file_name: &str, schema: Option<Type>) -> Result<Vec<Row>> {
1892        let file = get_test_file(file_name);
1893        let file_reader: Box<dyn FileReader> = Box::new(SerializedFileReader::new(file)?);
1894        let iter = file_reader.get_row_iter(schema)?;
1895        Ok(iter.map(|row| row.unwrap()).collect())
1896    }
1897
1898    fn test_row_group_rows(file_name: &str, schema: Option<Type>) -> Result<Vec<Row>> {
1899        let file = get_test_file(file_name);
1900        let file_reader: Box<dyn FileReader> = Box::new(SerializedFileReader::new(file)?);
1901        // Check the first row group only, because files will contain only single row
1902        // group
1903        let row_group_reader = file_reader.get_row_group(0).unwrap();
1904        let iter = row_group_reader.get_row_iter(schema)?;
1905        Ok(iter.map(|row| row.unwrap()).collect())
1906    }
1907
1908    #[test]
1909    fn test_read_old_nested_list() {
1910        let rows = test_file_reader_rows("old_list_structure.parquet", None).unwrap();
1911        let expected_rows = vec![row![(
1912            "a".to_string(),
1913            Field::ListInternal(make_list(
1914                [
1915                    make_list([1, 2].map(Field::Int).to_vec()),
1916                    make_list([3, 4].map(Field::Int).to_vec())
1917                ]
1918                .map(Field::ListInternal)
1919                .to_vec()
1920            ))
1921        ),]];
1922        assert_eq!(rows, expected_rows);
1923    }
1924
1925    fn assert_err_on_overcount(file_name: &str, proj_schema: Option<Type>) {
1926        let file = get_test_file(file_name);
1927        let file_reader = SerializedFileReader::new(file).unwrap();
1928        let metadata = file_reader.metadata();
1929        let row_group_reader = file_reader.get_row_group(0).unwrap();
1930        let actual_rows = row_group_reader.metadata().num_rows() as usize;
1931
1932        let descr = match proj_schema {
1933            Some(schema) => Arc::new(SchemaDescriptor::new(Arc::new(schema))),
1934            None => metadata.file_metadata().schema_descr_ptr(),
1935        };
1936        let reader = TreeBuilder::new().build(descr, &*row_group_reader).unwrap();
1937        let iter = ReaderIter::new(reader, actual_rows + 1).unwrap();
1938
1939        let rows: Vec<Result<Row>> = iter.collect();
1940        assert_eq!(rows.len(), actual_rows + 1);
1941        for row in &rows[..actual_rows] {
1942            assert!(row.is_ok(), "Expected Ok row, got: {:?}", row);
1943        }
1944        let err = rows[actual_rows].as_ref().unwrap_err();
1945        assert!(
1946            err.to_string().contains("Unexpected end of column data"),
1947            "Unexpected error message: {}",
1948            err
1949        );
1950    }
1951
1952    #[test]
1953    fn test_reader_iter_returns_error_when_num_records_exceeds_data() {
1954        assert_err_on_overcount("nulls.snappy.parquet", None);
1955    }
1956
1957    #[test]
1958    fn test_reader_iter_returns_error_for_repeated_field_when_num_records_exceeds_data() {
1959        assert_err_on_overcount("repeated_primitive_no_list.parquet", None);
1960    }
1961
1962    #[test]
1963    fn test_reader_iter_returns_error_for_map_field_when_num_records_exceeds_data() {
1964        let schema = parse_message_type(
1965            "message schema {
1966               REQUIRED group my_map (MAP) {
1967                 REPEATED group key_value {
1968                   REQUIRED INT32 key;
1969                   OPTIONAL INT32 value;
1970                 }
1971               }
1972             }",
1973        )
1974        .unwrap();
1975        assert_err_on_overcount("map_no_value.parquet", Some(schema));
1976    }
1977}