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