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