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