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