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 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 _ 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 _ => {
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
325pub enum Reader {
327 PrimitiveReader(TypePtr, Box<TripletIter>),
329 OptionReader(i16, Box<Reader>),
331 GroupReader(Option<TypePtr>, i16, Vec<Reader>),
334 RepeatedReader(TypePtr, i16, i16, Box<Reader>),
337 KeyValueReader(TypePtr, i16, i16, Box<Reader>, Box<Reader>),
340}
341
342impl Reader {
343 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 fn is_element_type(repeated_type: &Type) -> bool {
358 if repeated_type.is_list() || repeated_type.has_single_repeated_child() {
368 return false;
369 }
370
371 repeated_type.is_primitive() ||
379 repeated_type.is_group() && repeated_type.get_fields().len() > 1 ||
391 repeated_type.name() == "array" ||
402 repeated_type.name().ends_with("_tuple")
412 }
413
414 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 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 break;
484 }
485
486 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 break;
511 }
512
513 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 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 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 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 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 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 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
630enum 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
649pub 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 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 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 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 Ok(Self::new(None, Some(row_iter), descr))
714 }
715
716 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 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 #[inline]
752 fn get_proj_descr(proj: Option<Type>, root_descr: SchemaDescPtr) -> Result<SchemaDescPtr> {
753 match proj {
754 Some(projection) => {
755 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 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 #[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 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
814pub 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 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 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)] 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)] 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 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 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 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 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 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 row_group_writer.close().unwrap();
1678 file_writer.close().unwrap();
1679 assert_eq!(&buffer[0..4], b"PAR1");
1680
1681 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 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 let rows = test_file_reader_rows("map_no_value.parquet", None).unwrap();
1881
1882 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 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 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 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}