1use std::sync::Arc;
33
34use crate::basic::{ConvertedType, LogicalType, Repetition, TimeUnit, Type as PhysicalType};
35use crate::errors::{ParquetError, Result};
36use crate::schema::types::{Type, TypePtr};
37
38pub fn parse_message_type(message_type: &str) -> Result<Type> {
42 let mut parser = Parser {
43 tokenizer: &mut Tokenizer::from_str(message_type),
44 };
45 parser.parse_message_type()
46}
47
48struct Tokenizer<'a> {
53 tokens: Vec<&'a str>,
55 index: usize,
57}
58
59impl<'a> Tokenizer<'a> {
60 pub fn from_str(string: &'a str) -> Self {
62 let vec = string
63 .split_whitespace()
64 .flat_map(Self::split_token)
65 .collect();
66 Tokenizer {
67 tokens: vec,
68 index: 0,
69 }
70 }
71
72 fn is_schema_delim(c: char) -> bool {
74 c == ';' || c == '{' || c == '}' || c == '(' || c == ')' || c == '=' || c == ','
75 }
76
77 fn split_token(string: &str) -> Vec<&str> {
81 let mut buffer: Vec<&str> = Vec::new();
82 let mut tail = string;
83 while let Some(index) = tail.find(Self::is_schema_delim) {
84 let (h, t) = tail.split_at(index);
85 if !h.is_empty() {
86 buffer.push(h);
87 }
88 buffer.push(&t[0..1]);
89 tail = &t[1..];
90 }
91 if !tail.is_empty() {
92 buffer.push(tail);
93 }
94 buffer
95 }
96
97 fn backtrack(&mut self) {
99 self.index -= 1;
100 }
101}
102
103impl<'a> Iterator for Tokenizer<'a> {
104 type Item = &'a str;
105
106 fn next(&mut self) -> Option<&'a str> {
107 if self.index < self.tokens.len() {
108 self.index += 1;
109 Some(self.tokens[self.index - 1])
110 } else {
111 None
112 }
113 }
114}
115
116struct Parser<'a> {
120 tokenizer: &'a mut Tokenizer<'a>,
121}
122
123fn assert_token(token: Option<&str>, expected: &str) -> Result<()> {
125 match token {
126 Some(value) if value == expected => Ok(()),
127 Some(other) => Err(general_err!(
128 "Expected '{}', found token '{}'",
129 expected,
130 other
131 )),
132 None => Err(general_err!(
133 "Expected '{}', but no token found (None)",
134 expected
135 )),
136 }
137}
138
139#[inline]
141fn parse_i32(value: Option<&str>, not_found_msg: &str, parse_fail_msg: &str) -> Result<i32> {
142 value
143 .ok_or_else(|| general_err!(not_found_msg))?
144 .parse::<i32>()
145 .map_err(|_| general_err!(parse_fail_msg))
146}
147
148#[inline]
150fn parse_bool(value: Option<&str>, not_found_msg: &str, parse_fail_msg: &str) -> Result<bool> {
151 value
152 .ok_or_else(|| general_err!(not_found_msg))?
153 .to_lowercase()
154 .parse::<bool>()
155 .map_err(|_| general_err!(parse_fail_msg))
156}
157
158fn parse_timeunit(
160 value: Option<&str>,
161 not_found_msg: &str,
162 parse_fail_msg: &str,
163) -> Result<TimeUnit> {
164 let v = value.ok_or_else(|| general_err!(not_found_msg))?;
165 match v.to_uppercase().as_str() {
166 "MILLIS" => Ok(TimeUnit::MILLIS),
167 "MICROS" => Ok(TimeUnit::MICROS),
168 "NANOS" => Ok(TimeUnit::NANOS),
169 _ => Err(general_err!(parse_fail_msg)),
170 }
171}
172
173impl Parser<'_> {
174 fn parse_message_type(&mut self) -> Result<Type> {
176 match self.tokenizer.next() {
178 Some("message") => {
179 let name = self
180 .tokenizer
181 .next()
182 .ok_or_else(|| general_err!("Expected name, found None"))?;
183 Type::group_type_builder(name)
184 .with_fields(self.parse_child_types()?)
185 .build()
186 }
187 _ => Err(general_err!("Message type does not start with 'message'")),
188 }
189 }
190
191 fn parse_child_types(&mut self) -> Result<Vec<TypePtr>> {
194 assert_token(self.tokenizer.next(), "{")?;
195 let mut vec = Vec::new();
196 while let Some(value) = self.tokenizer.next() {
197 if value == "}" {
198 break;
199 }
200 self.tokenizer.backtrack();
201 vec.push(Arc::new(self.add_type()?));
202 }
203 Ok(vec)
204 }
205
206 fn add_type(&mut self) -> Result<Type> {
207 let repetition = self
209 .tokenizer
210 .next()
211 .ok_or_else(|| general_err!("Expected repetition, found None"))
212 .and_then(|v| v.to_uppercase().parse::<Repetition>())?;
213
214 match self.tokenizer.next() {
215 Some(group) if group.to_uppercase() == "GROUP" => self.add_group_type(Some(repetition)),
216 Some(type_string) => {
217 let physical_type = type_string.to_uppercase().parse::<PhysicalType>()?;
218 self.add_primitive_type(repetition, physical_type)
219 }
220 None => Err(general_err!("Invalid type, could not extract next token")),
221 }
222 }
223
224 fn add_group_type(&mut self, repetition: Option<Repetition>) -> Result<Type> {
225 let name = self
227 .tokenizer
228 .next()
229 .ok_or_else(|| general_err!("Expected name, found None"))?;
230
231 let (logical_type, converted_type) = if self.tokenizer.next() == Some("(") {
233 let type_ = self
234 .tokenizer
235 .next()
236 .ok_or_else(|| general_err!("Expected converted type, found None"))
237 .and_then(|v| {
238 let upper = v.to_uppercase();
240 let logical = upper.parse::<LogicalType>();
241 match logical {
242 Ok(logical) => {
243 Ok((Some(logical.clone()), ConvertedType::from(Some(logical))))
244 }
245 Err(_) => Ok((None, upper.parse::<ConvertedType>()?)),
246 }
247 })?;
248 assert_token(self.tokenizer.next(), ")")?;
249 type_
250 } else {
251 self.tokenizer.backtrack();
252 (None, ConvertedType::NONE)
253 };
254
255 let id = if self.tokenizer.next() == Some("=") {
257 self.tokenizer.next().and_then(|v| v.parse::<i32>().ok())
258 } else {
259 self.tokenizer.backtrack();
260 None
261 };
262
263 let mut builder = Type::group_type_builder(name)
264 .with_logical_type(logical_type)
265 .with_converted_type(converted_type)
266 .with_fields(self.parse_child_types()?)
267 .with_id(id);
268 if let Some(rep) = repetition {
269 builder = builder.with_repetition(rep);
270 }
271 builder.build()
272 }
273
274 fn add_primitive_type(
275 &mut self,
276 repetition: Repetition,
277 physical_type: PhysicalType,
278 ) -> Result<Type> {
279 let mut length: i32 = -1;
281 if physical_type == PhysicalType::FIXED_LEN_BYTE_ARRAY {
282 assert_token(self.tokenizer.next(), "(")?;
283 length = parse_i32(
284 self.tokenizer.next(),
285 "Expected length for FIXED_LEN_BYTE_ARRAY, found None",
286 "Failed to parse length for FIXED_LEN_BYTE_ARRAY",
287 )?;
288 assert_token(self.tokenizer.next(), ")")?;
289 }
290
291 let name = self
293 .tokenizer
294 .next()
295 .ok_or_else(|| general_err!("Expected name, found None"))?;
296
297 let (logical_type, converted_type, precision, scale) = if self.tokenizer.next() == Some("(")
299 {
300 let (mut logical, mut converted) = self
301 .tokenizer
302 .next()
303 .ok_or_else(|| general_err!("Expected logical or converted type, found None"))
304 .and_then(|v| {
305 let upper = v.to_uppercase();
306 let logical = upper.parse::<LogicalType>();
307 match logical {
308 Ok(logical) => {
309 Ok((Some(logical.clone()), ConvertedType::from(Some(logical))))
310 }
311 Err(_) => Ok((None, upper.parse::<ConvertedType>()?)),
312 }
313 })?;
314
315 let mut precision: i32 = -1;
317 let mut scale: i32 = -1;
318
319 if let Some(type_) = &logical {
321 match type_ {
322 LogicalType::Decimal { .. } => {
323 if self.tokenizer.next() == Some("(") {
324 precision = parse_i32(
325 self.tokenizer.next(),
326 "Expected precision, found None",
327 "Failed to parse precision for DECIMAL type",
328 )?;
329 if self.tokenizer.next() == Some(",") {
330 scale = parse_i32(
331 self.tokenizer.next(),
332 "Expected scale, found None",
333 "Failed to parse scale for DECIMAL type",
334 )?;
335 assert_token(self.tokenizer.next(), ")")?;
336 } else {
337 scale = 0
338 }
339 logical = Some(LogicalType::decimal(scale, precision));
340 converted = ConvertedType::from(logical.clone());
341 }
342 }
343 LogicalType::Time { .. } => {
344 if self.tokenizer.next() == Some("(") {
345 let unit = parse_timeunit(
346 self.tokenizer.next(),
347 "Invalid timeunit found",
348 "Failed to parse timeunit for TIME type",
349 )?;
350 if self.tokenizer.next() == Some(",") {
351 let is_adjusted_to_u_t_c = parse_bool(
352 self.tokenizer.next(),
353 "Invalid boolean found",
354 "Failed to parse timezone info for TIME type",
355 )?;
356 assert_token(self.tokenizer.next(), ")")?;
357 logical = Some(LogicalType::time(is_adjusted_to_u_t_c, unit));
358 converted = ConvertedType::from(logical.clone());
359 } else {
360 self.tokenizer.backtrack();
362 }
363 }
364 }
365 LogicalType::Timestamp { .. } => {
366 if self.tokenizer.next() == Some("(") {
367 let unit = parse_timeunit(
368 self.tokenizer.next(),
369 "Invalid timeunit found",
370 "Failed to parse timeunit for TIMESTAMP type",
371 )?;
372 if self.tokenizer.next() == Some(",") {
373 let is_adjusted_to_u_t_c = parse_bool(
374 self.tokenizer.next(),
375 "Invalid boolean found",
376 "Failed to parse timezone info for TIMESTAMP type",
377 )?;
378 assert_token(self.tokenizer.next(), ")")?;
379 logical = Some(LogicalType::timestamp(is_adjusted_to_u_t_c, unit));
380 converted = ConvertedType::from(logical.clone());
381 } else {
382 self.tokenizer.backtrack();
384 }
385 }
386 }
387 LogicalType::Integer { .. } if self.tokenizer.next() == Some("(") => {
388 let bit_width = parse_i32(
389 self.tokenizer.next(),
390 "Invalid bit_width found",
391 "Failed to parse bit_width for INTEGER type",
392 )? as i8;
393 match physical_type {
394 PhysicalType::INT32 => match bit_width {
395 8 | 16 | 32 => {}
396 _ => {
397 return Err(general_err!(
398 "Incorrect bit width {} for INT32",
399 bit_width
400 ));
401 }
402 },
403 PhysicalType::INT64 => {
404 if bit_width != 64 {
405 return Err(general_err!(
406 "Incorrect bit width {} for INT64",
407 bit_width
408 ));
409 }
410 }
411 _ => {
412 return Err(general_err!(
413 "Logical type Integer cannot be used with physical type {}",
414 physical_type
415 ));
416 }
417 }
418 if self.tokenizer.next() == Some(",") {
419 let is_signed = parse_bool(
420 self.tokenizer.next(),
421 "Invalid boolean found",
422 "Failed to parse is_signed for INTEGER type",
423 )?;
424 assert_token(self.tokenizer.next(), ")")?;
425 logical = Some(LogicalType::integer(bit_width, is_signed));
426 converted = ConvertedType::from(logical.clone());
427 } else {
428 self.tokenizer.backtrack();
430 }
431 }
432 _ => {}
433 }
434 } else if converted == ConvertedType::DECIMAL {
435 if self.tokenizer.next() == Some("(") {
436 precision = parse_i32(
438 self.tokenizer.next(),
439 "Expected precision, found None",
440 "Failed to parse precision for DECIMAL type",
441 )?;
442
443 scale = if self.tokenizer.next() == Some(",") {
445 parse_i32(
446 self.tokenizer.next(),
447 "Expected scale, found None",
448 "Failed to parse scale for DECIMAL type",
449 )?
450 } else {
451 self.tokenizer.backtrack();
453 0
454 };
455
456 assert_token(self.tokenizer.next(), ")")?;
457 } else {
458 self.tokenizer.backtrack();
459 }
460 }
461
462 assert_token(self.tokenizer.next(), ")")?;
463 (logical, converted, precision, scale)
464 } else {
465 self.tokenizer.backtrack();
466 (None, ConvertedType::NONE, -1, -1)
467 };
468
469 let id = if self.tokenizer.next() == Some("=") {
471 self.tokenizer.next().and_then(|v| v.parse::<i32>().ok())
472 } else {
473 self.tokenizer.backtrack();
474 None
475 };
476 assert_token(self.tokenizer.next(), ";")?;
477
478 Type::primitive_type_builder(name, physical_type)
479 .with_repetition(repetition)
480 .with_logical_type(logical_type)
481 .with_converted_type(converted_type)
482 .with_length(length)
483 .with_precision(precision)
484 .with_scale(scale)
485 .with_id(id)
486 .build()
487 }
488}
489
490#[cfg(test)]
491mod tests {
492 use super::*;
493
494 #[test]
495 fn test_tokenize_empty_string() {
496 assert_eq!(Tokenizer::from_str("").next(), None);
497 }
498
499 #[test]
500 fn test_tokenize_delimiters() {
501 let mut iter = Tokenizer::from_str(",;{}()=");
502 assert_eq!(iter.next(), Some(","));
503 assert_eq!(iter.next(), Some(";"));
504 assert_eq!(iter.next(), Some("{"));
505 assert_eq!(iter.next(), Some("}"));
506 assert_eq!(iter.next(), Some("("));
507 assert_eq!(iter.next(), Some(")"));
508 assert_eq!(iter.next(), Some("="));
509 assert_eq!(iter.next(), None);
510 }
511
512 #[test]
513 fn test_tokenize_delimiters_with_whitespaces() {
514 let mut iter = Tokenizer::from_str(" , ; { } ( ) = ");
515 assert_eq!(iter.next(), Some(","));
516 assert_eq!(iter.next(), Some(";"));
517 assert_eq!(iter.next(), Some("{"));
518 assert_eq!(iter.next(), Some("}"));
519 assert_eq!(iter.next(), Some("("));
520 assert_eq!(iter.next(), Some(")"));
521 assert_eq!(iter.next(), Some("="));
522 assert_eq!(iter.next(), None);
523 }
524
525 #[test]
526 fn test_tokenize_words() {
527 let mut iter = Tokenizer::from_str("abc def ghi jkl mno");
528 assert_eq!(iter.next(), Some("abc"));
529 assert_eq!(iter.next(), Some("def"));
530 assert_eq!(iter.next(), Some("ghi"));
531 assert_eq!(iter.next(), Some("jkl"));
532 assert_eq!(iter.next(), Some("mno"));
533 assert_eq!(iter.next(), None);
534 }
535
536 #[test]
537 fn test_tokenize_backtrack() {
538 let mut iter = Tokenizer::from_str("abc;");
539 assert_eq!(iter.next(), Some("abc"));
540 assert_eq!(iter.next(), Some(";"));
541 iter.backtrack();
542 assert_eq!(iter.next(), Some(";"));
543 assert_eq!(iter.next(), None);
544 }
545
546 #[test]
547 fn test_tokenize_message_type() {
548 let schema = "
549 message schema {
550 required int32 a;
551 optional binary c (UTF8);
552 required group d {
553 required int32 a;
554 optional binary c (UTF8);
555 }
556 required group e (LIST) {
557 repeated group list {
558 required int32 element;
559 }
560 }
561 }
562 ";
563 let iter = Tokenizer::from_str(schema);
564 let mut res = Vec::new();
565 for token in iter {
566 res.push(token);
567 }
568 assert_eq!(
569 res,
570 vec![
571 "message", "schema", "{", "required", "int32", "a", ";", "optional", "binary", "c",
572 "(", "UTF8", ")", ";", "required", "group", "d", "{", "required", "int32", "a",
573 ";", "optional", "binary", "c", "(", "UTF8", ")", ";", "}", "required", "group",
574 "e", "(", "LIST", ")", "{", "repeated", "group", "list", "{", "required", "int32",
575 "element", ";", "}", "}", "}"
576 ]
577 );
578 }
579
580 #[test]
581 fn test_assert_token() {
582 assert!(assert_token(Some("a"), "a").is_ok());
583 assert!(assert_token(Some("a"), "b").is_err());
584 assert!(assert_token(None, "b").is_err());
585 }
586
587 fn parse(schema: &str) -> Result<Type, ParquetError> {
588 let mut iter = Tokenizer::from_str(schema);
589 Parser {
590 tokenizer: &mut iter,
591 }
592 .parse_message_type()
593 }
594
595 #[test]
596 fn test_parse_message_type_invalid() {
597 assert_eq!(
598 parse("test").unwrap_err().to_string(),
599 "Parquet error: Message type does not start with 'message'"
600 );
601 }
602
603 #[test]
604 fn test_parse_message_type_no_name() {
605 assert_eq!(
606 parse("message").unwrap_err().to_string(),
607 "Parquet error: Expected name, found None"
608 );
609 }
610
611 #[test]
612 fn test_parse_message_type_fixed_byte_array() {
613 let schema = "
614 message schema {
615 REQUIRED FIXED_LEN_BYTE_ARRAY col;
616 }
617 ";
618 assert_eq!(
619 parse(schema).unwrap_err().to_string(),
620 "Parquet error: Expected '(', found token 'col'"
621 );
622
623 let schema = "
624 message schema {
625 REQUIRED FIXED_LEN_BYTE_ARRAY(16) col;
626 }
627 ";
628 parse(schema).unwrap();
629 }
630
631 #[test]
632 fn test_parse_message_type_integer() {
633 let schema = "
635 message root {
636 optional int64 f1 (INTEGER());
637 }
638 ";
639 assert_eq!(
640 parse(schema).unwrap_err().to_string(),
641 "Parquet error: Failed to parse bit_width for INTEGER type"
642 );
643
644 let schema = "
646 message root {
647 optional int64 f1 (INTEGER(32,));
648 }
649 ";
650 assert_eq!(
651 parse(schema).unwrap_err().to_string(),
652 "Parquet error: Incorrect bit width 32 for INT64"
653 );
654
655 let schema = "
657 message root {
658 optional int32 f1 (INTEGER(eight,true));
659 }
660 ";
661 assert_eq!(
662 parse(schema).unwrap_err().to_string(),
663 "Parquet error: Failed to parse bit_width for INTEGER type"
664 );
665
666 let schema = "
668 message root {
669 optional int32 f1 (INTEGER(8,false));
670 optional int32 f2 (INTEGER(8,true));
671 optional int32 f3 (INTEGER(16,false));
672 optional int32 f4 (INTEGER(16,true));
673 optional int32 f5 (INTEGER(32,false));
674 optional int32 f6 (INTEGER(32,true));
675 optional int64 f7 (INTEGER(64,false));
676 optional int64 f7 (INTEGER(64,true));
677 }
678 ";
679 parse(schema).unwrap();
680 }
681
682 #[test]
683 fn test_parse_message_type_temporal() {
684 let schema = "
686 message root {
687 optional int64 f1 (TIMESTAMP();
688 }
689 ";
690 assert_eq!(
691 parse(schema).unwrap_err().to_string(),
692 "Parquet error: Failed to parse timeunit for TIMESTAMP type"
693 );
694
695 let schema = "
697 message root {
698 optional int64 f1 (TIMESTAMP(MILLIS,));
699 }
700 ";
701 assert_eq!(
702 parse(schema).unwrap_err().to_string(),
703 "Parquet error: Failed to parse timezone info for TIMESTAMP type"
704 );
705
706 let schema = "
708 message root {
709 optional int64 f1 (TIMESTAMP(YOCTOS,));
710 }
711 ";
712
713 assert_eq!(
714 parse(schema).unwrap_err().to_string(),
715 "Parquet error: Failed to parse timeunit for TIMESTAMP type"
716 );
717
718 let schema = "
720 message root {
721 optional int32 f1 (DATE);
722 optional int32 f2 (TIME(MILLIS,true));
723 optional int64 f3 (TIME(MICROS,false));
724 optional int64 f4 (TIME(NANOS,true));
725 optional int64 f5 (TIMESTAMP(MILLIS,true));
726 optional int64 f6 (TIMESTAMP(MICROS,true));
727 optional int64 f7 (TIMESTAMP(NANOS,false));
728 }
729 ";
730 parse(schema).unwrap();
731 }
732
733 #[test]
734 fn test_parse_message_type_decimal() {
735 let schema = "
740 message root {
741 optional int32 f1 (DECIMAL();
742 }
743 ";
744 assert_eq!(
745 parse(schema).unwrap_err().to_string(),
746 "Parquet error: Failed to parse precision for DECIMAL type"
747 );
748
749 let schema = "
751 message root {
752 optional int32 f1 (DECIMAL());
753 }
754 ";
755 assert_eq!(
756 parse(schema).unwrap_err().to_string(),
757 "Parquet error: Failed to parse precision for DECIMAL type"
758 );
759
760 let schema = "
762 message root {
763 optional int32 f1 (DECIMAL(8,));
764 }
765 ";
766 assert_eq!(
767 parse(schema).unwrap_err().to_string(),
768 "Parquet error: Failed to parse scale for DECIMAL type"
769 );
770
771 let schema = "
774 message root {
775 optional int32 f3 (DECIMAL);
776 }
777 ";
778 assert_eq!(
779 parse(schema).unwrap_err().to_string(),
780 "Parquet error: Expected ')', found token ';'"
781 );
782
783 let schema = "
785 message root {
786 optional int32 f1 (DECIMAL(8, 3));
787 optional int32 f2 (DECIMAL(8));
788 }
789 ";
790 parse(schema).unwrap();
791 }
792
793 #[test]
794 fn test_parse_message_type_compare_1() {
795 let schema = "
796 message root {
797 optional fixed_len_byte_array(5) f1 (DECIMAL(9, 3));
798 optional fixed_len_byte_array (16) f2 (DECIMAL (38, 18));
799 optional fixed_len_byte_array (2) f3 (FLOAT16);
800 }
801 ";
802 let message = parse(schema).unwrap();
803
804 let expected = Type::group_type_builder("root")
805 .with_fields(vec![
806 Arc::new(
807 Type::primitive_type_builder("f1", PhysicalType::FIXED_LEN_BYTE_ARRAY)
808 .with_logical_type(Some(LogicalType::decimal(3, 9)))
809 .with_converted_type(ConvertedType::DECIMAL)
810 .with_length(5)
811 .with_precision(9)
812 .with_scale(3)
813 .build()
814 .unwrap(),
815 ),
816 Arc::new(
817 Type::primitive_type_builder("f2", PhysicalType::FIXED_LEN_BYTE_ARRAY)
818 .with_logical_type(Some(LogicalType::decimal(18, 38)))
819 .with_converted_type(ConvertedType::DECIMAL)
820 .with_length(16)
821 .with_precision(38)
822 .with_scale(18)
823 .build()
824 .unwrap(),
825 ),
826 Arc::new(
827 Type::primitive_type_builder("f3", PhysicalType::FIXED_LEN_BYTE_ARRAY)
828 .with_logical_type(Some(LogicalType::Float16))
829 .with_length(2)
830 .build()
831 .unwrap(),
832 ),
833 ])
834 .build()
835 .unwrap();
836
837 assert_eq!(message, expected);
838 }
839
840 #[test]
841 fn test_parse_message_type_compare_2() {
842 let schema = "
843 message root {
844 required group a0 {
845 optional group a1 (LIST) {
846 repeated binary a2 (UTF8);
847 }
848
849 optional group b1 (LIST) {
850 repeated group b2 {
851 optional int32 b3;
852 optional double b4;
853 }
854 }
855 }
856 }
857 ";
858 let message = parse(schema).unwrap();
859
860 let expected = Type::group_type_builder("root")
861 .with_fields(vec![Arc::new(
862 Type::group_type_builder("a0")
863 .with_repetition(Repetition::REQUIRED)
864 .with_fields(vec![
865 Arc::new(
866 Type::group_type_builder("a1")
867 .with_repetition(Repetition::OPTIONAL)
868 .with_logical_type(Some(LogicalType::List))
869 .with_converted_type(ConvertedType::LIST)
870 .with_fields(vec![Arc::new(
871 Type::primitive_type_builder("a2", PhysicalType::BYTE_ARRAY)
872 .with_repetition(Repetition::REPEATED)
873 .with_converted_type(ConvertedType::UTF8)
874 .build()
875 .unwrap(),
876 )])
877 .build()
878 .unwrap(),
879 ),
880 Arc::new(
881 Type::group_type_builder("b1")
882 .with_repetition(Repetition::OPTIONAL)
883 .with_logical_type(Some(LogicalType::List))
884 .with_converted_type(ConvertedType::LIST)
885 .with_fields(vec![Arc::new(
886 Type::group_type_builder("b2")
887 .with_repetition(Repetition::REPEATED)
888 .with_fields(vec![
889 Arc::new(
890 Type::primitive_type_builder(
891 "b3",
892 PhysicalType::INT32,
893 )
894 .build()
895 .unwrap(),
896 ),
897 Arc::new(
898 Type::primitive_type_builder(
899 "b4",
900 PhysicalType::DOUBLE,
901 )
902 .build()
903 .unwrap(),
904 ),
905 ])
906 .build()
907 .unwrap(),
908 )])
909 .build()
910 .unwrap(),
911 ),
912 ])
913 .build()
914 .unwrap(),
915 )])
916 .build()
917 .unwrap();
918
919 assert_eq!(message, expected);
920 }
921
922 #[test]
923 fn test_parse_message_type_compare_3() {
924 let schema = "
925 message root {
926 required int32 _1 (INT_8);
927 required int32 _2 (INT_16);
928 required float _3;
929 required double _4;
930 optional int32 _5 (DATE);
931 optional binary _6 (UTF8);
932 }
933 ";
934 let message = parse(schema).unwrap();
935
936 let fields = vec![
937 Arc::new(
938 Type::primitive_type_builder("_1", PhysicalType::INT32)
939 .with_repetition(Repetition::REQUIRED)
940 .with_converted_type(ConvertedType::INT_8)
941 .build()
942 .unwrap(),
943 ),
944 Arc::new(
945 Type::primitive_type_builder("_2", PhysicalType::INT32)
946 .with_repetition(Repetition::REQUIRED)
947 .with_converted_type(ConvertedType::INT_16)
948 .build()
949 .unwrap(),
950 ),
951 Arc::new(
952 Type::primitive_type_builder("_3", PhysicalType::FLOAT)
953 .with_repetition(Repetition::REQUIRED)
954 .build()
955 .unwrap(),
956 ),
957 Arc::new(
958 Type::primitive_type_builder("_4", PhysicalType::DOUBLE)
959 .with_repetition(Repetition::REQUIRED)
960 .build()
961 .unwrap(),
962 ),
963 Arc::new(
964 Type::primitive_type_builder("_5", PhysicalType::INT32)
965 .with_logical_type(Some(LogicalType::Date))
966 .with_converted_type(ConvertedType::DATE)
967 .build()
968 .unwrap(),
969 ),
970 Arc::new(
971 Type::primitive_type_builder("_6", PhysicalType::BYTE_ARRAY)
972 .with_converted_type(ConvertedType::UTF8)
973 .build()
974 .unwrap(),
975 ),
976 ];
977
978 let expected = Type::group_type_builder("root")
979 .with_fields(fields)
980 .build()
981 .unwrap();
982 assert_eq!(message, expected);
983 }
984
985 #[test]
986 fn test_parse_message_type_compare_4() {
987 let schema = "
988 message root {
989 required int32 _1 (INTEGER(8,true));
990 required int32 _2 (INTEGER(16,false));
991 required float _3;
992 required double _4;
993 optional int32 _5 (DATE);
994 optional int32 _6 (TIME(MILLIS,false));
995 optional int64 _7 (TIME(MICROS,true));
996 optional int64 _8 (TIMESTAMP(MILLIS,true));
997 optional int64 _9 (TIMESTAMP(NANOS,false));
998 optional binary _10 (STRING);
999 }
1000 ";
1001 let message = parse(schema).unwrap();
1002
1003 let fields = vec![
1004 Arc::new(
1005 Type::primitive_type_builder("_1", PhysicalType::INT32)
1006 .with_repetition(Repetition::REQUIRED)
1007 .with_logical_type(Some(LogicalType::integer(8, true)))
1008 .build()
1009 .unwrap(),
1010 ),
1011 Arc::new(
1012 Type::primitive_type_builder("_2", PhysicalType::INT32)
1013 .with_repetition(Repetition::REQUIRED)
1014 .with_logical_type(Some(LogicalType::integer(16, false)))
1015 .build()
1016 .unwrap(),
1017 ),
1018 Arc::new(
1019 Type::primitive_type_builder("_3", PhysicalType::FLOAT)
1020 .with_repetition(Repetition::REQUIRED)
1021 .build()
1022 .unwrap(),
1023 ),
1024 Arc::new(
1025 Type::primitive_type_builder("_4", PhysicalType::DOUBLE)
1026 .with_repetition(Repetition::REQUIRED)
1027 .build()
1028 .unwrap(),
1029 ),
1030 Arc::new(
1031 Type::primitive_type_builder("_5", PhysicalType::INT32)
1032 .with_logical_type(Some(LogicalType::Date))
1033 .build()
1034 .unwrap(),
1035 ),
1036 Arc::new(
1037 Type::primitive_type_builder("_6", PhysicalType::INT32)
1038 .with_logical_type(Some(LogicalType::time(false, TimeUnit::MILLIS)))
1039 .build()
1040 .unwrap(),
1041 ),
1042 Arc::new(
1043 Type::primitive_type_builder("_7", PhysicalType::INT64)
1044 .with_logical_type(Some(LogicalType::time(true, TimeUnit::MICROS)))
1045 .build()
1046 .unwrap(),
1047 ),
1048 Arc::new(
1049 Type::primitive_type_builder("_8", PhysicalType::INT64)
1050 .with_logical_type(Some(LogicalType::timestamp(true, TimeUnit::MILLIS)))
1051 .build()
1052 .unwrap(),
1053 ),
1054 Arc::new(
1055 Type::primitive_type_builder("_9", PhysicalType::INT64)
1056 .with_logical_type(Some(LogicalType::timestamp(false, TimeUnit::NANOS)))
1057 .build()
1058 .unwrap(),
1059 ),
1060 Arc::new(
1061 Type::primitive_type_builder("_10", PhysicalType::BYTE_ARRAY)
1062 .with_logical_type(Some(LogicalType::String))
1063 .build()
1064 .unwrap(),
1065 ),
1066 ];
1067
1068 let expected = Type::group_type_builder("root")
1069 .with_fields(fields)
1070 .build()
1071 .unwrap();
1072 assert_eq!(message, expected);
1073 }
1074}