1use std::io::Write;
24use std::str::FromStr;
25use std::{fmt, str};
26
27pub use crate::compression::{BrotliLevel, GzipLevel, ZstdLevel};
28use crate::file::metadata::HeapSize;
29use crate::parquet_thrift::{
30 ElementType, FieldType, ReadThrift, ThriftCompactInputProtocol, ThriftCompactOutputProtocol,
31 WriteThrift, WriteThriftField, validate_list_type,
32};
33use crate::{
34 thrift_enum, thrift_struct, thrift_union_all_empty, thrift_union_with_unknown,
35 write_thrift_field,
36};
37
38use crate::errors::{ParquetError, Result};
39
40thrift_enum!(
47enum Type {
54 BOOLEAN = 0;
55 INT32 = 1;
56 INT64 = 2;
57 INT96 = 3; FLOAT = 4;
59 DOUBLE = 5;
60 BYTE_ARRAY = 6;
61 FIXED_LEN_BYTE_ARRAY = 7;
62}
63);
64
65thrift_enum!(
71enum ConvertedType {
79 NONE = -1;
81
82 UTF8 = 0;
84
85 MAP = 1;
87
88 MAP_KEY_VALUE = 2;
90
91 LIST = 3;
94
95 ENUM = 4;
97
98 DECIMAL = 5;
111
112 DATE = 6;
114
115 TIME_MILLIS = 7;
118
119 TIME_MICROS = 8;
122
123 TIMESTAMP_MILLIS = 9;
126
127 TIMESTAMP_MICROS = 10;
130
131 UINT_8 = 11;
133
134 UINT_16 = 12;
136
137 UINT_32 = 13;
139
140 UINT_64 = 14;
142
143 INT_8 = 15;
145
146 INT_16 = 16;
148
149 INT_32 = 17;
151
152 INT_64 = 18;
154
155 JSON = 19;
157
158 BSON = 20;
160
161 INTERVAL = 21;
171}
172);
173
174thrift_union_all_empty!(
178union TimeUnit {
180 1: MilliSeconds MILLIS
181 2: MicroSeconds MICROS
182 3: NanoSeconds NANOS
183}
184);
185
186thrift_struct!(
190pub struct DecimalType {
191 1: required i32 scale
193 2: required i32 precision
195}
196);
197
198thrift_struct!(
199pub struct TimestampType {
200 1: required bool is_adjusted_to_u_t_c
202 2: required TimeUnit unit
204}
205);
206
207pub use TimestampType as TimeType;
209
210thrift_struct!(
211pub struct IntType {
212 1: required i8 bit_width
214 2: required bool is_signed
216}
217);
218
219thrift_struct!(
220pub struct VariantType {
221 1: optional i8 specification_version
224}
225);
226
227thrift_struct!(
228pub struct GeometryType {
229 1: optional string crs;
232}
233);
234
235thrift_struct!(
236pub struct GeographyType {
237 1: optional string crs;
239 2: optional EdgeInterpolationAlgorithm algorithm;
242}
243);
244
245impl GeographyType {
246 pub fn algorithm(&self) -> Option<EdgeInterpolationAlgorithm> {
252 self.algorithm.or(Some(Default::default()))
253 }
254}
255
256thrift_union_with_unknown!(
257union LogicalType {
263 1: String
265 2: Map
267 3: List
269 4: Enum
271 5: (DecimalType) Decimal
273 6: Date
275 7: (TimeType) Time
277 8: (TimestampType) Timestamp
279 10: (IntType) Integer
282 11: Unknown
284 12: Json
286 13: Bson
288 14: Uuid
290 15: Float16
292 16: (VariantType) Variant
294 17: (GeometryType) Geometry
296 18: (GeographyType) Geography
298}
299);
300
301impl LogicalType {
302 pub fn integer(bit_width: i8, is_signed: bool) -> Self {
304 Self::Integer(IntType {
305 bit_width,
306 is_signed,
307 })
308 }
309
310 pub fn decimal(scale: i32, precision: i32) -> Self {
312 Self::Decimal(DecimalType { scale, precision })
313 }
314
315 pub fn time(is_adjusted_to_u_t_c: bool, unit: TimeUnit) -> Self {
317 Self::Time(TimeType {
318 is_adjusted_to_u_t_c,
319 unit,
320 })
321 }
322
323 pub fn timestamp(is_adjusted_to_u_t_c: bool, unit: TimeUnit) -> Self {
325 Self::Timestamp(TimestampType {
326 is_adjusted_to_u_t_c,
327 unit,
328 })
329 }
330
331 pub fn variant(specification_version: Option<i8>) -> Self {
333 Self::Variant(VariantType {
334 specification_version,
335 })
336 }
337
338 pub fn geometry(crs: Option<String>) -> Self {
340 Self::Geometry(GeometryType { crs })
341 }
342
343 pub fn geography(crs: Option<String>, algorithm: Option<EdgeInterpolationAlgorithm>) -> Self {
345 Self::Geography(GeographyType { crs, algorithm })
346 }
347}
348
349thrift_enum!(
354enum FieldRepetitionType {
356 REQUIRED = 0;
358 OPTIONAL = 1;
360 REPEATED = 2;
362}
363);
364
365pub type Repetition = FieldRepetitionType;
367
368thrift_enum!(
372enum Encoding {
389 PLAIN = 0;
398 PLAIN_DICTIONARY = 2;
405 RLE = 3;
409 #[deprecated(
422 since = "51.0.0",
423 note = "Please see documentation for compatibility issues and use the RLE/bit-packing hybrid encoding instead"
424 )]
425 BIT_PACKED = 4;
426 DELTA_BINARY_PACKED = 5;
430 DELTA_LENGTH_BYTE_ARRAY = 6;
434 DELTA_BYTE_ARRAY = 7;
439 RLE_DICTIONARY = 8;
443 BYTE_STREAM_SPLIT = 9;
452}
453);
454
455impl FromStr for Encoding {
456 type Err = ParquetError;
457
458 fn from_str(s: &str) -> Result<Self, Self::Err> {
459 match s {
460 "PLAIN" | "plain" => Ok(Encoding::PLAIN),
461 "PLAIN_DICTIONARY" | "plain_dictionary" => Ok(Encoding::PLAIN_DICTIONARY),
462 "RLE" | "rle" => Ok(Encoding::RLE),
463 #[allow(deprecated)]
464 "BIT_PACKED" | "bit_packed" => Ok(Encoding::BIT_PACKED),
465 "DELTA_BINARY_PACKED" | "delta_binary_packed" => Ok(Encoding::DELTA_BINARY_PACKED),
466 "DELTA_LENGTH_BYTE_ARRAY" | "delta_length_byte_array" => {
467 Ok(Encoding::DELTA_LENGTH_BYTE_ARRAY)
468 }
469 "DELTA_BYTE_ARRAY" | "delta_byte_array" => Ok(Encoding::DELTA_BYTE_ARRAY),
470 "RLE_DICTIONARY" | "rle_dictionary" => Ok(Encoding::RLE_DICTIONARY),
471 "BYTE_STREAM_SPLIT" | "byte_stream_split" => Ok(Encoding::BYTE_STREAM_SPLIT),
472 _ => Err(general_err!("unknown encoding: {}", s)),
473 }
474 }
475}
476
477#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
511pub struct EncodingMask(i32);
512
513impl EncodingMask {
514 const MAX_ENCODING: i32 = Encoding::MAX_DISCRIMINANT;
516 const ALLOWED_MASK: u32 =
519 !(1u32 << (EncodingMask::MAX_ENCODING as u32 + 1)).wrapping_sub(1) | (1 << 1);
520
521 pub fn try_new(val: i32) -> Result<Self> {
525 if val as u32 & Self::ALLOWED_MASK != 0 {
526 return Err(general_err!("Attempt to create invalid mask: 0x{:x}", val));
527 }
528 Ok(Self(val))
529 }
530
531 pub fn as_i32(&self) -> i32 {
533 self.0
534 }
535
536 pub fn new_from_encodings<'a>(encodings: impl Iterator<Item = &'a Encoding>) -> Self {
538 let mut mask = 0;
539 for &e in encodings {
540 mask |= 1 << (e as i32);
541 }
542 Self(mask)
543 }
544
545 pub fn insert(&mut self, val: Encoding) {
547 self.0 |= 1 << (val as i32);
548 }
549
550 pub fn is_set(&self, val: Encoding) -> bool {
552 self.0 & (1 << (val as i32)) != 0
553 }
554
555 pub fn is_only(&self, val: Encoding) -> bool {
557 self.0 == (1 << (val as i32))
558 }
559
560 pub fn all_set<'a>(&self, mut encodings: impl Iterator<Item = &'a Encoding>) -> bool {
562 encodings.all(|&e| self.is_set(e))
563 }
564
565 pub fn encodings(&self) -> impl Iterator<Item = Encoding> {
567 Self::mask_to_encodings_iter(self.0)
568 }
569
570 fn mask_to_encodings_iter(mask: i32) -> impl Iterator<Item = Encoding> {
571 (0..=Self::MAX_ENCODING)
572 .filter(move |i| mask & (1 << i) != 0)
573 .map(i32_to_encoding)
574 }
575}
576
577impl HeapSize for EncodingMask {
578 fn heap_size(&self) -> usize {
579 0 }
581}
582
583impl<'a, R: ThriftCompactInputProtocol<'a>> ReadThrift<'a, R> for EncodingMask {
584 fn read_thrift(prot: &mut R) -> Result<Self> {
585 let mut mask = 0;
586
587 let list_ident = prot.read_list_begin()?;
589 validate_list_type(ElementType::I32, &list_ident)?;
591 for _ in 0..list_ident.size {
592 let val = Encoding::read_thrift(prot)?;
593 mask |= 1 << val as i32;
594 }
595 Ok(Self(mask))
596 }
597}
598
599#[allow(deprecated)]
600fn i32_to_encoding(val: i32) -> Encoding {
601 match val {
602 0 => Encoding::PLAIN,
603 2 => Encoding::PLAIN_DICTIONARY,
604 3 => Encoding::RLE,
605 4 => Encoding::BIT_PACKED,
606 5 => Encoding::DELTA_BINARY_PACKED,
607 6 => Encoding::DELTA_LENGTH_BYTE_ARRAY,
608 7 => Encoding::DELTA_BYTE_ARRAY,
609 8 => Encoding::RLE_DICTIONARY,
610 9 => Encoding::BYTE_STREAM_SPLIT,
611 _ => panic!("Impossible encoding {val}"),
612 }
613}
614
615thrift_enum!(
619enum CompressionCodec {
629 UNCOMPRESSED = 0;
630 SNAPPY = 1;
631 GZIP = 2;
632 LZO = 3;
633 BROTLI = 4; LZ4 = 5; ZSTD = 6; LZ4_RAW = 7; }
638);
639
640#[derive(Debug, Clone, Copy, PartialEq, Eq)]
661#[allow(non_camel_case_types)]
662pub enum Compression {
663 UNCOMPRESSED,
665 SNAPPY,
667 GZIP(GzipLevel),
669 LZO,
671 BROTLI(BrotliLevel),
673 LZ4,
675 ZSTD(ZstdLevel),
677 LZ4_RAW,
679}
680
681impl From<CompressionCodec> for Compression {
682 fn from(value: CompressionCodec) -> Self {
683 match value {
684 CompressionCodec::UNCOMPRESSED => Compression::UNCOMPRESSED,
685 CompressionCodec::SNAPPY => Compression::SNAPPY,
686 CompressionCodec::GZIP => Compression::GZIP(Default::default()),
687 CompressionCodec::LZO => Compression::LZO,
688 CompressionCodec::BROTLI => Compression::BROTLI(Default::default()),
689 CompressionCodec::LZ4 => Compression::LZ4,
690 CompressionCodec::ZSTD => Compression::ZSTD(Default::default()),
691 CompressionCodec::LZ4_RAW => Compression::LZ4_RAW,
692 }
693 }
694}
695
696impl From<Compression> for CompressionCodec {
697 fn from(value: Compression) -> Self {
698 match value {
699 Compression::UNCOMPRESSED => CompressionCodec::UNCOMPRESSED,
700 Compression::SNAPPY => CompressionCodec::SNAPPY,
701 Compression::GZIP(_) => CompressionCodec::GZIP,
702 Compression::LZO => CompressionCodec::LZO,
703 Compression::BROTLI(_) => CompressionCodec::BROTLI,
704 Compression::LZ4 => CompressionCodec::LZ4,
705 Compression::ZSTD(_) => CompressionCodec::ZSTD,
706 Compression::LZ4_RAW => CompressionCodec::LZ4_RAW,
707 }
708 }
709}
710
711fn split_compression_string(str_setting: &str) -> Result<(&str, Option<i32>), ParquetError> {
712 let split_setting = str_setting.split_once('(');
713
714 match split_setting {
715 Some((codec, level_str)) => {
716 let level = &level_str[..level_str.len() - 1]
717 .parse::<i32>()
718 .map_err(|_| {
719 ParquetError::General(format!("invalid compression level: {level_str}"))
720 })?;
721 Ok((codec, Some(*level)))
722 }
723 None => Ok((str_setting, None)),
724 }
725}
726
727fn check_level_is_none(level: &Option<i32>) -> Result<(), ParquetError> {
728 if level.is_some() {
729 return Err(ParquetError::General(
730 "compression level is not supported".to_string(),
731 ));
732 }
733
734 Ok(())
735}
736
737fn require_level(codec: &str, level: Option<i32>) -> Result<i32, ParquetError> {
738 level.ok_or(ParquetError::General(format!(
739 "{codec} requires a compression level",
740 )))
741}
742
743impl FromStr for Compression {
744 type Err = ParquetError;
745
746 fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
747 let (codec, level) = split_compression_string(s)?;
748
749 let c = match codec {
750 "UNCOMPRESSED" | "uncompressed" => {
751 check_level_is_none(&level)?;
752 Compression::UNCOMPRESSED
753 }
754 "SNAPPY" | "snappy" => {
755 check_level_is_none(&level)?;
756 Compression::SNAPPY
757 }
758 "GZIP" | "gzip" => {
759 let level = require_level(codec, level)?;
760 Compression::GZIP(GzipLevel::try_new(level.try_into()?)?)
761 }
762 "LZO" | "lzo" => {
763 check_level_is_none(&level)?;
764 Compression::LZO
765 }
766 "BROTLI" | "brotli" => {
767 let level = require_level(codec, level)?;
768 Compression::BROTLI(BrotliLevel::try_new(level.try_into()?)?)
769 }
770 "LZ4" | "lz4" => {
771 check_level_is_none(&level)?;
772 Compression::LZ4
773 }
774 "ZSTD" | "zstd" => {
775 let level = require_level(codec, level)?;
776 Compression::ZSTD(ZstdLevel::try_new(level)?)
777 }
778 "LZ4_RAW" | "lz4_raw" => {
779 check_level_is_none(&level)?;
780 Compression::LZ4_RAW
781 }
782 _ => {
783 return Err(ParquetError::General(format!(
784 "unsupport compression {codec}"
785 )));
786 }
787 };
788
789 Ok(c)
790 }
791}
792
793thrift_enum!(
797enum PageType {
800 DATA_PAGE = 0;
801 INDEX_PAGE = 1;
802 DICTIONARY_PAGE = 2;
803 DATA_PAGE_V2 = 3;
804}
805);
806
807thrift_enum!(
811enum BoundaryOrder {
814 UNORDERED = 0;
815 ASCENDING = 1;
816 DESCENDING = 2;
817}
818);
819
820#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
827#[repr(i32)]
828#[derive(Default)]
829pub enum EdgeInterpolationAlgorithm {
830 #[default]
832 SPHERICAL = 0,
833 VINCENTY = 1,
835 THOMAS = 2,
837 ANDOYER = 3,
839 KARNEY = 4,
841 _Unknown(i32),
843}
844
845#[cfg(feature = "geospatial")]
846impl EdgeInterpolationAlgorithm {
847 pub fn try_as_edges(&self) -> Result<parquet_geospatial::WkbEdges> {
853 match &self {
854 Self::SPHERICAL => Ok(parquet_geospatial::WkbEdges::Spherical),
855 Self::VINCENTY => Ok(parquet_geospatial::WkbEdges::Vincenty),
856 Self::THOMAS => Ok(parquet_geospatial::WkbEdges::Thomas),
857 Self::ANDOYER => Ok(parquet_geospatial::WkbEdges::Andoyer),
858 Self::KARNEY => Ok(parquet_geospatial::WkbEdges::Karney),
859 unknown => Err(general_err!(
860 "Unknown edge interpolation algorithm: {}",
861 unknown
862 )),
863 }
864 }
865}
866
867impl fmt::Display for EdgeInterpolationAlgorithm {
868 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
869 f.write_fmt(format_args!("{0:?}", self))
870 }
871}
872
873#[cfg(feature = "geospatial")]
874impl From<parquet_geospatial::WkbEdges> for EdgeInterpolationAlgorithm {
875 fn from(value: parquet_geospatial::WkbEdges) -> Self {
876 match value {
877 parquet_geospatial::WkbEdges::Spherical => Self::SPHERICAL,
878 parquet_geospatial::WkbEdges::Vincenty => Self::VINCENTY,
879 parquet_geospatial::WkbEdges::Thomas => Self::THOMAS,
880 parquet_geospatial::WkbEdges::Andoyer => Self::ANDOYER,
881 parquet_geospatial::WkbEdges::Karney => Self::KARNEY,
882 }
883 }
884}
885
886impl FromStr for EdgeInterpolationAlgorithm {
887 type Err = ParquetError;
888
889 fn from_str(s: &str) -> Result<Self> {
890 match s.to_ascii_uppercase().as_str() {
891 "SPHERICAL" => Ok(EdgeInterpolationAlgorithm::SPHERICAL),
892 "VINCENTY" => Ok(EdgeInterpolationAlgorithm::VINCENTY),
893 "THOMAS" => Ok(EdgeInterpolationAlgorithm::THOMAS),
894 "ANDOYER" => Ok(EdgeInterpolationAlgorithm::ANDOYER),
895 "KARNEY" => Ok(EdgeInterpolationAlgorithm::KARNEY),
896 unknown => Err(general_err!(
897 "Unknown edge interpolation algorithm: {}",
898 unknown
899 )),
900 }
901 }
902}
903
904impl<'a, R: ThriftCompactInputProtocol<'a>> ReadThrift<'a, R> for EdgeInterpolationAlgorithm {
905 fn read_thrift(prot: &mut R) -> Result<Self> {
906 let val = prot.read_i32()?;
907 match val {
908 0 => Ok(Self::SPHERICAL),
909 1 => Ok(Self::VINCENTY),
910 2 => Ok(Self::THOMAS),
911 3 => Ok(Self::ANDOYER),
912 4 => Ok(Self::KARNEY),
913 _ => Ok(Self::_Unknown(val)),
914 }
915 }
916}
917
918impl WriteThrift for EdgeInterpolationAlgorithm {
919 const ELEMENT_TYPE: ElementType = ElementType::I32;
920 fn write_thrift<W: Write>(&self, writer: &mut ThriftCompactOutputProtocol<W>) -> Result<()> {
921 let val: i32 = match *self {
922 Self::SPHERICAL => 0,
923 Self::VINCENTY => 1,
924 Self::THOMAS => 2,
925 Self::ANDOYER => 3,
926 Self::KARNEY => 4,
927 Self::_Unknown(i) => i,
928 };
929 writer.write_i32(val)
930 }
931}
932
933write_thrift_field!(EdgeInterpolationAlgorithm, FieldType::I32);
934
935thrift_union_all_empty!(
939union BloomFilterAlgorithm {
941 1: SplitBlockAlgorithm BLOCK;
943}
944);
945
946thrift_union_all_empty!(
950union BloomFilterHash {
953 1: XxHash XXHASH;
955}
956);
957
958thrift_union_all_empty!(
962union BloomFilterCompression {
964 1: Uncompressed UNCOMPRESSED;
965}
966);
967
968#[derive(Debug, Clone, Copy, PartialEq, Eq)]
979#[allow(non_camel_case_types)]
980pub enum SortOrder {
981 SIGNED,
983 UNSIGNED,
985 UNDEFINED,
987 TOTAL_ORDER,
989 INT96_TIMESTAMP,
994}
995
996impl SortOrder {
997 pub fn is_signed(&self) -> bool {
999 matches!(self, Self::SIGNED)
1000 }
1001}
1002
1003#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1024#[allow(non_camel_case_types)]
1025pub enum ColumnOrder {
1026 TYPE_DEFINED_ORDER(SortOrder),
1029 IEEE_754_TOTAL_ORDER,
1031 INT96_TIMESTAMP_ORDER,
1033 UNDEFINED,
1037 UNKNOWN,
1040}
1041
1042impl ColumnOrder {
1043 pub fn column_order_for_type(
1045 logical_type: Option<&LogicalType>,
1046 converted_type: ConvertedType,
1047 physical_type: Type,
1048 ) -> ColumnOrder {
1049 if Some(&LogicalType::Float16) == logical_type
1050 || matches!(physical_type, Type::FLOAT | Type::DOUBLE)
1051 {
1052 ColumnOrder::IEEE_754_TOTAL_ORDER
1053 } else if matches!(physical_type, Type::INT96) {
1054 ColumnOrder::INT96_TIMESTAMP_ORDER
1055 } else {
1056 let sort_order =
1057 Self::get_sort_order_for_type(logical_type, converted_type, physical_type, true);
1058 ColumnOrder::TYPE_DEFINED_ORDER(sort_order)
1059 }
1060 }
1061
1062 #[deprecated(since = "60.0.0", note = "use `ColumnOrder::sort_order` instead")]
1069 pub fn sort_order_for_type(
1070 logical_type: Option<&LogicalType>,
1071 converted_type: ConvertedType,
1072 physical_type: Type,
1073 is_type_defined: bool,
1074 ) -> SortOrder {
1075 ColumnOrder::get_sort_order_for_type(
1076 logical_type,
1077 converted_type,
1078 physical_type,
1079 is_type_defined,
1080 )
1081 }
1082
1083 pub(crate) fn get_sort_order_for_type(
1086 logical_type: Option<&LogicalType>,
1087 converted_type: ConvertedType,
1088 physical_type: Type,
1089 is_type_defined: bool,
1090 ) -> SortOrder {
1091 match logical_type {
1092 Some(logical) => match logical {
1093 LogicalType::String | LogicalType::Enum | LogicalType::Json | LogicalType::Bson => {
1094 SortOrder::UNSIGNED
1095 }
1096 LogicalType::Integer(int) => match int.is_signed {
1097 true => SortOrder::SIGNED,
1098 false => SortOrder::UNSIGNED,
1099 },
1100 LogicalType::Map | LogicalType::List => SortOrder::UNDEFINED,
1101 LogicalType::Decimal(_) => SortOrder::SIGNED,
1102 LogicalType::Date => SortOrder::SIGNED,
1103 LogicalType::Time(_) => SortOrder::SIGNED,
1104 LogicalType::Timestamp(_) => SortOrder::SIGNED,
1105 LogicalType::Unknown => SortOrder::UNDEFINED,
1106 LogicalType::Uuid => SortOrder::UNSIGNED,
1107 LogicalType::Float16 => {
1108 if is_type_defined {
1109 SortOrder::SIGNED
1110 } else {
1111 SortOrder::TOTAL_ORDER
1112 }
1113 }
1114 LogicalType::Variant(_)
1115 | LogicalType::Geometry(_)
1116 | LogicalType::Geography(_)
1117 | LogicalType::_Unknown { .. } => SortOrder::UNDEFINED,
1118 },
1119 None => Self::get_converted_sort_order(converted_type, physical_type, is_type_defined),
1121 }
1122 }
1123
1124 fn get_converted_sort_order(
1125 converted_type: ConvertedType,
1126 physical_type: Type,
1127 is_type_defined: bool,
1128 ) -> SortOrder {
1129 match converted_type {
1130 ConvertedType::UTF8
1132 | ConvertedType::JSON
1133 | ConvertedType::BSON
1134 | ConvertedType::ENUM => SortOrder::UNSIGNED,
1135
1136 ConvertedType::INT_8
1137 | ConvertedType::INT_16
1138 | ConvertedType::INT_32
1139 | ConvertedType::INT_64 => SortOrder::SIGNED,
1140
1141 ConvertedType::UINT_8
1142 | ConvertedType::UINT_16
1143 | ConvertedType::UINT_32
1144 | ConvertedType::UINT_64 => SortOrder::UNSIGNED,
1145
1146 ConvertedType::DECIMAL => SortOrder::SIGNED,
1148
1149 ConvertedType::DATE => SortOrder::SIGNED,
1150
1151 ConvertedType::TIME_MILLIS
1152 | ConvertedType::TIME_MICROS
1153 | ConvertedType::TIMESTAMP_MILLIS
1154 | ConvertedType::TIMESTAMP_MICROS => SortOrder::SIGNED,
1155
1156 ConvertedType::INTERVAL => SortOrder::UNDEFINED,
1157
1158 ConvertedType::LIST | ConvertedType::MAP | ConvertedType::MAP_KEY_VALUE => {
1159 SortOrder::UNDEFINED
1160 }
1161
1162 ConvertedType::NONE => Self::get_default_sort_order(physical_type, is_type_defined),
1164 }
1165 }
1166
1167 fn get_default_sort_order(physical_type: Type, is_type_defined: bool) -> SortOrder {
1169 match physical_type {
1170 Type::BOOLEAN => SortOrder::UNSIGNED,
1172 Type::INT32 | Type::INT64 => SortOrder::SIGNED,
1173 Type::INT96 => {
1174 if is_type_defined {
1175 SortOrder::UNDEFINED
1176 } else {
1177 SortOrder::INT96_TIMESTAMP
1178 }
1179 }
1180 Type::FLOAT | Type::DOUBLE => {
1192 if is_type_defined {
1193 SortOrder::SIGNED
1194 } else {
1195 SortOrder::TOTAL_ORDER
1196 }
1197 }
1198 Type::BYTE_ARRAY | Type::FIXED_LEN_BYTE_ARRAY => SortOrder::UNSIGNED,
1200 }
1201 }
1202
1203 pub fn sort_order(&self) -> SortOrder {
1205 match *self {
1206 ColumnOrder::TYPE_DEFINED_ORDER(order) => order,
1207 ColumnOrder::IEEE_754_TOTAL_ORDER => SortOrder::TOTAL_ORDER,
1208 ColumnOrder::INT96_TIMESTAMP_ORDER => SortOrder::INT96_TIMESTAMP,
1209 ColumnOrder::UNDEFINED => SortOrder::SIGNED,
1210 ColumnOrder::UNKNOWN => SortOrder::UNDEFINED,
1211 }
1212 }
1213}
1214
1215impl<'a, R: ThriftCompactInputProtocol<'a>> ReadThrift<'a, R> for ColumnOrder {
1216 fn read_thrift(prot: &mut R) -> Result<Self> {
1217 let field_ident = prot.read_field_begin(0)?;
1218 if field_ident.field_type == FieldType::Stop {
1219 return Err(general_err!("Received empty union from remote ColumnOrder"));
1220 }
1221 let ret = match field_ident.id {
1222 1 => {
1223 prot.skip_empty_struct()?;
1225 Self::TYPE_DEFINED_ORDER(SortOrder::SIGNED)
1226 }
1227 2 => {
1228 prot.skip_empty_struct()?;
1229 Self::IEEE_754_TOTAL_ORDER
1230 }
1231 3 => {
1232 prot.skip_empty_struct()?;
1233 Self::INT96_TIMESTAMP_ORDER
1234 }
1235 _ => {
1236 prot.skip(field_ident.field_type)?;
1237 Self::UNKNOWN
1238 }
1239 };
1240 let field_ident = prot.read_field_begin(field_ident.id)?;
1241 if field_ident.field_type != FieldType::Stop {
1242 return Err(general_err!(
1243 "Received multiple fields for union from remote ColumnOrder"
1244 ));
1245 }
1246 Ok(ret)
1247 }
1248}
1249
1250impl WriteThrift for ColumnOrder {
1251 const ELEMENT_TYPE: ElementType = ElementType::Struct;
1252
1253 fn write_thrift<W: Write>(&self, writer: &mut ThriftCompactOutputProtocol<W>) -> Result<()> {
1254 match *self {
1255 Self::TYPE_DEFINED_ORDER(_) => {
1256 writer.write_field_begin(FieldType::Struct, 1, 0)?;
1257 writer.write_struct_end()?;
1258 }
1259 Self::IEEE_754_TOTAL_ORDER => {
1260 writer.write_field_begin(FieldType::Struct, 2, 0)?;
1261 writer.write_struct_end()?;
1262 }
1263 Self::INT96_TIMESTAMP_ORDER => {
1264 writer.write_field_begin(FieldType::Struct, 3, 0)?;
1265 writer.write_struct_end()?;
1266 }
1267 _ => return Err(general_err!("Attempt to write undefined ColumnOrder")),
1268 }
1269 writer.write_struct_end()
1271 }
1272}
1273
1274impl fmt::Display for Compression {
1278 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1279 write!(f, "{self:?}")
1280 }
1281}
1282
1283impl fmt::Display for SortOrder {
1284 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1285 write!(f, "{self:?}")
1286 }
1287}
1288
1289impl fmt::Display for ColumnOrder {
1290 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1291 write!(f, "{self:?}")
1292 }
1293}
1294
1295impl From<Option<LogicalType>> for ConvertedType {
1305 fn from(value: Option<LogicalType>) -> Self {
1306 match value {
1307 Some(value) => match value {
1308 LogicalType::String => ConvertedType::UTF8,
1309 LogicalType::Map => ConvertedType::MAP,
1310 LogicalType::List => ConvertedType::LIST,
1311 LogicalType::Enum => ConvertedType::ENUM,
1312 LogicalType::Decimal { .. } => ConvertedType::DECIMAL,
1313 LogicalType::Date => ConvertedType::DATE,
1314 LogicalType::Time(time) => match time.unit {
1315 TimeUnit::MILLIS => ConvertedType::TIME_MILLIS,
1316 TimeUnit::MICROS => ConvertedType::TIME_MICROS,
1317 TimeUnit::NANOS => ConvertedType::NONE,
1318 },
1319 LogicalType::Timestamp(time) => match time.unit {
1320 TimeUnit::MILLIS => ConvertedType::TIMESTAMP_MILLIS,
1321 TimeUnit::MICROS => ConvertedType::TIMESTAMP_MICROS,
1322 TimeUnit::NANOS => ConvertedType::NONE,
1323 },
1324 LogicalType::Integer(int_type) => match (int_type.bit_width, int_type.is_signed) {
1325 (8, true) => ConvertedType::INT_8,
1326 (16, true) => ConvertedType::INT_16,
1327 (32, true) => ConvertedType::INT_32,
1328 (64, true) => ConvertedType::INT_64,
1329 (8, false) => ConvertedType::UINT_8,
1330 (16, false) => ConvertedType::UINT_16,
1331 (32, false) => ConvertedType::UINT_32,
1332 (64, false) => ConvertedType::UINT_64,
1333 (bit_width, is_signed) => panic!(
1334 "Integer type bit_width={bit_width}, signed={is_signed} is not supported"
1335 ),
1336 },
1337 LogicalType::Json => ConvertedType::JSON,
1338 LogicalType::Bson => ConvertedType::BSON,
1339 LogicalType::Uuid
1340 | LogicalType::Float16
1341 | LogicalType::Variant(_)
1342 | LogicalType::Geometry(_)
1343 | LogicalType::Geography(_)
1344 | LogicalType::_Unknown { .. }
1345 | LogicalType::Unknown => ConvertedType::NONE,
1346 },
1347 None => ConvertedType::NONE,
1348 }
1349 }
1350}
1351
1352impl str::FromStr for Repetition {
1356 type Err = ParquetError;
1357
1358 fn from_str(s: &str) -> Result<Self> {
1359 match s {
1360 "REQUIRED" => Ok(Repetition::REQUIRED),
1361 "OPTIONAL" => Ok(Repetition::OPTIONAL),
1362 "REPEATED" => Ok(Repetition::REPEATED),
1363 other => Err(general_err!("Invalid parquet repetition {}", other)),
1364 }
1365 }
1366}
1367
1368impl str::FromStr for Type {
1369 type Err = ParquetError;
1370
1371 fn from_str(s: &str) -> Result<Self> {
1372 match s {
1373 "BOOLEAN" => Ok(Type::BOOLEAN),
1374 "INT32" => Ok(Type::INT32),
1375 "INT64" => Ok(Type::INT64),
1376 "INT96" => Ok(Type::INT96),
1377 "FLOAT" => Ok(Type::FLOAT),
1378 "DOUBLE" => Ok(Type::DOUBLE),
1379 "BYTE_ARRAY" | "BINARY" => Ok(Type::BYTE_ARRAY),
1380 "FIXED_LEN_BYTE_ARRAY" => Ok(Type::FIXED_LEN_BYTE_ARRAY),
1381 other => Err(general_err!("Invalid parquet type {}", other)),
1382 }
1383 }
1384}
1385
1386impl str::FromStr for ConvertedType {
1387 type Err = ParquetError;
1388
1389 fn from_str(s: &str) -> Result<Self> {
1390 match s {
1391 "NONE" => Ok(ConvertedType::NONE),
1392 "UTF8" => Ok(ConvertedType::UTF8),
1393 "MAP" => Ok(ConvertedType::MAP),
1394 "MAP_KEY_VALUE" => Ok(ConvertedType::MAP_KEY_VALUE),
1395 "LIST" => Ok(ConvertedType::LIST),
1396 "ENUM" => Ok(ConvertedType::ENUM),
1397 "DECIMAL" => Ok(ConvertedType::DECIMAL),
1398 "DATE" => Ok(ConvertedType::DATE),
1399 "TIME_MILLIS" => Ok(ConvertedType::TIME_MILLIS),
1400 "TIME_MICROS" => Ok(ConvertedType::TIME_MICROS),
1401 "TIMESTAMP_MILLIS" => Ok(ConvertedType::TIMESTAMP_MILLIS),
1402 "TIMESTAMP_MICROS" => Ok(ConvertedType::TIMESTAMP_MICROS),
1403 "UINT_8" => Ok(ConvertedType::UINT_8),
1404 "UINT_16" => Ok(ConvertedType::UINT_16),
1405 "UINT_32" => Ok(ConvertedType::UINT_32),
1406 "UINT_64" => Ok(ConvertedType::UINT_64),
1407 "INT_8" => Ok(ConvertedType::INT_8),
1408 "INT_16" => Ok(ConvertedType::INT_16),
1409 "INT_32" => Ok(ConvertedType::INT_32),
1410 "INT_64" => Ok(ConvertedType::INT_64),
1411 "JSON" => Ok(ConvertedType::JSON),
1412 "BSON" => Ok(ConvertedType::BSON),
1413 "INTERVAL" => Ok(ConvertedType::INTERVAL),
1414 other => Err(general_err!("Invalid parquet converted type {}", other)),
1415 }
1416 }
1417}
1418
1419impl str::FromStr for LogicalType {
1420 type Err = ParquetError;
1421
1422 fn from_str(s: &str) -> Result<Self> {
1423 match s {
1424 "INTEGER" => Ok(LogicalType::integer(8, false)),
1426 "MAP" => Ok(LogicalType::Map),
1427 "LIST" => Ok(LogicalType::List),
1428 "ENUM" => Ok(LogicalType::Enum),
1429 "DECIMAL" => Ok(LogicalType::decimal(-1, -1)),
1430 "DATE" => Ok(LogicalType::Date),
1431 "TIME" => Ok(LogicalType::time(false, TimeUnit::MILLIS)),
1432 "TIMESTAMP" => Ok(LogicalType::timestamp(false, TimeUnit::MILLIS)),
1433 "STRING" => Ok(LogicalType::String),
1434 "JSON" => Ok(LogicalType::Json),
1435 "BSON" => Ok(LogicalType::Bson),
1436 "UUID" => Ok(LogicalType::Uuid),
1437 "UNKNOWN" => Ok(LogicalType::Unknown),
1438 "INTERVAL" => Err(general_err!(
1439 "Interval parquet logical type not yet supported"
1440 )),
1441 "FLOAT16" => Ok(LogicalType::Float16),
1442 "VARIANT" => Ok(LogicalType::variant(None)),
1443 "GEOMETRY" => Ok(LogicalType::geometry(None)),
1444 "GEOGRAPHY" => Ok(LogicalType::geography(
1445 None,
1446 Some(EdgeInterpolationAlgorithm::SPHERICAL),
1447 )),
1448 other => Err(general_err!("Invalid parquet logical type {}", other)),
1449 }
1450 }
1451}
1452
1453#[cfg(test)]
1454#[allow(deprecated)] mod tests {
1456 use super::*;
1457 use crate::parquet_thrift::{ThriftSliceInputProtocol, tests::test_roundtrip};
1458
1459 #[test]
1460 fn test_display_type() {
1461 assert_eq!(Type::BOOLEAN.to_string(), "BOOLEAN");
1462 assert_eq!(Type::INT32.to_string(), "INT32");
1463 assert_eq!(Type::INT64.to_string(), "INT64");
1464 assert_eq!(Type::INT96.to_string(), "INT96");
1465 assert_eq!(Type::FLOAT.to_string(), "FLOAT");
1466 assert_eq!(Type::DOUBLE.to_string(), "DOUBLE");
1467 assert_eq!(Type::BYTE_ARRAY.to_string(), "BYTE_ARRAY");
1468 assert_eq!(
1469 Type::FIXED_LEN_BYTE_ARRAY.to_string(),
1470 "FIXED_LEN_BYTE_ARRAY"
1471 );
1472 }
1473
1474 #[test]
1475 fn test_from_string_into_type() {
1476 assert_eq!(
1477 Type::BOOLEAN.to_string().parse::<Type>().unwrap(),
1478 Type::BOOLEAN
1479 );
1480 assert_eq!(
1481 Type::INT32.to_string().parse::<Type>().unwrap(),
1482 Type::INT32
1483 );
1484 assert_eq!(
1485 Type::INT64.to_string().parse::<Type>().unwrap(),
1486 Type::INT64
1487 );
1488 assert_eq!(
1489 Type::INT96.to_string().parse::<Type>().unwrap(),
1490 Type::INT96
1491 );
1492 assert_eq!(
1493 Type::FLOAT.to_string().parse::<Type>().unwrap(),
1494 Type::FLOAT
1495 );
1496 assert_eq!(
1497 Type::DOUBLE.to_string().parse::<Type>().unwrap(),
1498 Type::DOUBLE
1499 );
1500 assert_eq!(
1501 Type::BYTE_ARRAY.to_string().parse::<Type>().unwrap(),
1502 Type::BYTE_ARRAY
1503 );
1504 assert_eq!("BINARY".parse::<Type>().unwrap(), Type::BYTE_ARRAY);
1505 assert_eq!(
1506 Type::FIXED_LEN_BYTE_ARRAY
1507 .to_string()
1508 .parse::<Type>()
1509 .unwrap(),
1510 Type::FIXED_LEN_BYTE_ARRAY
1511 );
1512 }
1513
1514 #[test]
1515 fn test_converted_type_roundtrip() {
1516 test_roundtrip(ConvertedType::UTF8);
1517 test_roundtrip(ConvertedType::MAP);
1518 test_roundtrip(ConvertedType::MAP_KEY_VALUE);
1519 test_roundtrip(ConvertedType::LIST);
1520 test_roundtrip(ConvertedType::ENUM);
1521 test_roundtrip(ConvertedType::DECIMAL);
1522 test_roundtrip(ConvertedType::DATE);
1523 test_roundtrip(ConvertedType::TIME_MILLIS);
1524 test_roundtrip(ConvertedType::TIME_MICROS);
1525 test_roundtrip(ConvertedType::TIMESTAMP_MILLIS);
1526 test_roundtrip(ConvertedType::TIMESTAMP_MICROS);
1527 test_roundtrip(ConvertedType::UINT_8);
1528 test_roundtrip(ConvertedType::UINT_16);
1529 test_roundtrip(ConvertedType::UINT_32);
1530 test_roundtrip(ConvertedType::UINT_64);
1531 test_roundtrip(ConvertedType::INT_8);
1532 test_roundtrip(ConvertedType::INT_16);
1533 test_roundtrip(ConvertedType::INT_32);
1534 test_roundtrip(ConvertedType::INT_64);
1535 test_roundtrip(ConvertedType::JSON);
1536 test_roundtrip(ConvertedType::BSON);
1537 test_roundtrip(ConvertedType::INTERVAL);
1538 }
1539
1540 #[test]
1541 fn test_read_invalid_converted_type() {
1542 let mut prot = ThriftSliceInputProtocol::new(&[0x7eu8]);
1543 let res = ConvertedType::read_thrift(&mut prot);
1544 assert!(res.is_err());
1545 assert_eq!(
1546 res.unwrap_err().to_string(),
1547 "Parquet error: Unexpected ConvertedType 63"
1548 );
1549 }
1550
1551 #[test]
1552 fn test_display_converted_type() {
1553 assert_eq!(ConvertedType::NONE.to_string(), "NONE");
1554 assert_eq!(ConvertedType::UTF8.to_string(), "UTF8");
1555 assert_eq!(ConvertedType::MAP.to_string(), "MAP");
1556 assert_eq!(ConvertedType::MAP_KEY_VALUE.to_string(), "MAP_KEY_VALUE");
1557 assert_eq!(ConvertedType::LIST.to_string(), "LIST");
1558 assert_eq!(ConvertedType::ENUM.to_string(), "ENUM");
1559 assert_eq!(ConvertedType::DECIMAL.to_string(), "DECIMAL");
1560 assert_eq!(ConvertedType::DATE.to_string(), "DATE");
1561 assert_eq!(ConvertedType::TIME_MILLIS.to_string(), "TIME_MILLIS");
1562 assert_eq!(ConvertedType::DATE.to_string(), "DATE");
1563 assert_eq!(ConvertedType::TIME_MICROS.to_string(), "TIME_MICROS");
1564 assert_eq!(
1565 ConvertedType::TIMESTAMP_MILLIS.to_string(),
1566 "TIMESTAMP_MILLIS"
1567 );
1568 assert_eq!(
1569 ConvertedType::TIMESTAMP_MICROS.to_string(),
1570 "TIMESTAMP_MICROS"
1571 );
1572 assert_eq!(ConvertedType::UINT_8.to_string(), "UINT_8");
1573 assert_eq!(ConvertedType::UINT_16.to_string(), "UINT_16");
1574 assert_eq!(ConvertedType::UINT_32.to_string(), "UINT_32");
1575 assert_eq!(ConvertedType::UINT_64.to_string(), "UINT_64");
1576 assert_eq!(ConvertedType::INT_8.to_string(), "INT_8");
1577 assert_eq!(ConvertedType::INT_16.to_string(), "INT_16");
1578 assert_eq!(ConvertedType::INT_32.to_string(), "INT_32");
1579 assert_eq!(ConvertedType::INT_64.to_string(), "INT_64");
1580 assert_eq!(ConvertedType::JSON.to_string(), "JSON");
1581 assert_eq!(ConvertedType::BSON.to_string(), "BSON");
1582 assert_eq!(ConvertedType::INTERVAL.to_string(), "INTERVAL");
1583 assert_eq!(ConvertedType::DECIMAL.to_string(), "DECIMAL")
1584 }
1585
1586 #[test]
1587 fn test_from_string_into_converted_type() {
1588 assert_eq!(
1589 ConvertedType::NONE
1590 .to_string()
1591 .parse::<ConvertedType>()
1592 .unwrap(),
1593 ConvertedType::NONE
1594 );
1595 assert_eq!(
1596 ConvertedType::UTF8
1597 .to_string()
1598 .parse::<ConvertedType>()
1599 .unwrap(),
1600 ConvertedType::UTF8
1601 );
1602 assert_eq!(
1603 ConvertedType::MAP
1604 .to_string()
1605 .parse::<ConvertedType>()
1606 .unwrap(),
1607 ConvertedType::MAP
1608 );
1609 assert_eq!(
1610 ConvertedType::MAP_KEY_VALUE
1611 .to_string()
1612 .parse::<ConvertedType>()
1613 .unwrap(),
1614 ConvertedType::MAP_KEY_VALUE
1615 );
1616 assert_eq!(
1617 ConvertedType::LIST
1618 .to_string()
1619 .parse::<ConvertedType>()
1620 .unwrap(),
1621 ConvertedType::LIST
1622 );
1623 assert_eq!(
1624 ConvertedType::ENUM
1625 .to_string()
1626 .parse::<ConvertedType>()
1627 .unwrap(),
1628 ConvertedType::ENUM
1629 );
1630 assert_eq!(
1631 ConvertedType::DECIMAL
1632 .to_string()
1633 .parse::<ConvertedType>()
1634 .unwrap(),
1635 ConvertedType::DECIMAL
1636 );
1637 assert_eq!(
1638 ConvertedType::DATE
1639 .to_string()
1640 .parse::<ConvertedType>()
1641 .unwrap(),
1642 ConvertedType::DATE
1643 );
1644 assert_eq!(
1645 ConvertedType::TIME_MILLIS
1646 .to_string()
1647 .parse::<ConvertedType>()
1648 .unwrap(),
1649 ConvertedType::TIME_MILLIS
1650 );
1651 assert_eq!(
1652 ConvertedType::TIME_MICROS
1653 .to_string()
1654 .parse::<ConvertedType>()
1655 .unwrap(),
1656 ConvertedType::TIME_MICROS
1657 );
1658 assert_eq!(
1659 ConvertedType::TIMESTAMP_MILLIS
1660 .to_string()
1661 .parse::<ConvertedType>()
1662 .unwrap(),
1663 ConvertedType::TIMESTAMP_MILLIS
1664 );
1665 assert_eq!(
1666 ConvertedType::TIMESTAMP_MICROS
1667 .to_string()
1668 .parse::<ConvertedType>()
1669 .unwrap(),
1670 ConvertedType::TIMESTAMP_MICROS
1671 );
1672 assert_eq!(
1673 ConvertedType::UINT_8
1674 .to_string()
1675 .parse::<ConvertedType>()
1676 .unwrap(),
1677 ConvertedType::UINT_8
1678 );
1679 assert_eq!(
1680 ConvertedType::UINT_16
1681 .to_string()
1682 .parse::<ConvertedType>()
1683 .unwrap(),
1684 ConvertedType::UINT_16
1685 );
1686 assert_eq!(
1687 ConvertedType::UINT_32
1688 .to_string()
1689 .parse::<ConvertedType>()
1690 .unwrap(),
1691 ConvertedType::UINT_32
1692 );
1693 assert_eq!(
1694 ConvertedType::UINT_64
1695 .to_string()
1696 .parse::<ConvertedType>()
1697 .unwrap(),
1698 ConvertedType::UINT_64
1699 );
1700 assert_eq!(
1701 ConvertedType::INT_8
1702 .to_string()
1703 .parse::<ConvertedType>()
1704 .unwrap(),
1705 ConvertedType::INT_8
1706 );
1707 assert_eq!(
1708 ConvertedType::INT_16
1709 .to_string()
1710 .parse::<ConvertedType>()
1711 .unwrap(),
1712 ConvertedType::INT_16
1713 );
1714 assert_eq!(
1715 ConvertedType::INT_32
1716 .to_string()
1717 .parse::<ConvertedType>()
1718 .unwrap(),
1719 ConvertedType::INT_32
1720 );
1721 assert_eq!(
1722 ConvertedType::INT_64
1723 .to_string()
1724 .parse::<ConvertedType>()
1725 .unwrap(),
1726 ConvertedType::INT_64
1727 );
1728 assert_eq!(
1729 ConvertedType::JSON
1730 .to_string()
1731 .parse::<ConvertedType>()
1732 .unwrap(),
1733 ConvertedType::JSON
1734 );
1735 assert_eq!(
1736 ConvertedType::BSON
1737 .to_string()
1738 .parse::<ConvertedType>()
1739 .unwrap(),
1740 ConvertedType::BSON
1741 );
1742 assert_eq!(
1743 ConvertedType::INTERVAL
1744 .to_string()
1745 .parse::<ConvertedType>()
1746 .unwrap(),
1747 ConvertedType::INTERVAL
1748 );
1749 assert_eq!(
1750 ConvertedType::DECIMAL
1751 .to_string()
1752 .parse::<ConvertedType>()
1753 .unwrap(),
1754 ConvertedType::DECIMAL
1755 )
1756 }
1757
1758 #[test]
1759 fn test_logical_to_converted_type() {
1760 let logical_none: Option<LogicalType> = None;
1761 assert_eq!(ConvertedType::from(logical_none), ConvertedType::NONE);
1762 assert_eq!(
1763 ConvertedType::from(Some(LogicalType::decimal(5, 20))),
1764 ConvertedType::DECIMAL
1765 );
1766 assert_eq!(
1767 ConvertedType::from(Some(LogicalType::Bson)),
1768 ConvertedType::BSON
1769 );
1770 assert_eq!(
1771 ConvertedType::from(Some(LogicalType::Json)),
1772 ConvertedType::JSON
1773 );
1774 assert_eq!(
1775 ConvertedType::from(Some(LogicalType::String)),
1776 ConvertedType::UTF8
1777 );
1778 assert_eq!(
1779 ConvertedType::from(Some(LogicalType::Date)),
1780 ConvertedType::DATE
1781 );
1782 assert_eq!(
1783 ConvertedType::from(Some(LogicalType::time(true, TimeUnit::MILLIS))),
1784 ConvertedType::TIME_MILLIS
1785 );
1786 assert_eq!(
1787 ConvertedType::from(Some(LogicalType::time(true, TimeUnit::MICROS))),
1788 ConvertedType::TIME_MICROS
1789 );
1790 assert_eq!(
1791 ConvertedType::from(Some(LogicalType::time(false, TimeUnit::NANOS))),
1792 ConvertedType::NONE
1793 );
1794 assert_eq!(
1795 ConvertedType::from(Some(LogicalType::timestamp(true, TimeUnit::MILLIS))),
1796 ConvertedType::TIMESTAMP_MILLIS
1797 );
1798 assert_eq!(
1799 ConvertedType::from(Some(LogicalType::timestamp(false, TimeUnit::MICROS))),
1800 ConvertedType::TIMESTAMP_MICROS
1801 );
1802 assert_eq!(
1803 ConvertedType::from(Some(LogicalType::timestamp(false, TimeUnit::NANOS))),
1804 ConvertedType::NONE
1805 );
1806 assert_eq!(
1807 ConvertedType::from(Some(LogicalType::integer(8, false))),
1808 ConvertedType::UINT_8
1809 );
1810 assert_eq!(
1811 ConvertedType::from(Some(LogicalType::integer(8, true))),
1812 ConvertedType::INT_8
1813 );
1814 assert_eq!(
1815 ConvertedType::from(Some(LogicalType::integer(16, false))),
1816 ConvertedType::UINT_16
1817 );
1818 assert_eq!(
1819 ConvertedType::from(Some(LogicalType::integer(16, true))),
1820 ConvertedType::INT_16
1821 );
1822 assert_eq!(
1823 ConvertedType::from(Some(LogicalType::integer(32, false))),
1824 ConvertedType::UINT_32
1825 );
1826 assert_eq!(
1827 ConvertedType::from(Some(LogicalType::integer(32, true))),
1828 ConvertedType::INT_32
1829 );
1830 assert_eq!(
1831 ConvertedType::from(Some(LogicalType::integer(64, false))),
1832 ConvertedType::UINT_64
1833 );
1834 assert_eq!(
1835 ConvertedType::from(Some(LogicalType::integer(64, true))),
1836 ConvertedType::INT_64
1837 );
1838 assert_eq!(
1839 ConvertedType::from(Some(LogicalType::List)),
1840 ConvertedType::LIST
1841 );
1842 assert_eq!(
1843 ConvertedType::from(Some(LogicalType::Map)),
1844 ConvertedType::MAP
1845 );
1846 assert_eq!(
1847 ConvertedType::from(Some(LogicalType::Uuid)),
1848 ConvertedType::NONE
1849 );
1850 assert_eq!(
1851 ConvertedType::from(Some(LogicalType::Enum)),
1852 ConvertedType::ENUM
1853 );
1854 assert_eq!(
1855 ConvertedType::from(Some(LogicalType::Float16)),
1856 ConvertedType::NONE
1857 );
1858 assert_eq!(
1859 ConvertedType::from(Some(LogicalType::variant(None))),
1860 ConvertedType::NONE
1861 );
1862 assert_eq!(
1863 ConvertedType::from(Some(LogicalType::geometry(None))),
1864 ConvertedType::NONE
1865 );
1866 assert_eq!(
1867 ConvertedType::from(Some(LogicalType::geography(None, Some(Default::default())))),
1868 ConvertedType::NONE
1869 );
1870 assert_eq!(
1871 ConvertedType::from(Some(LogicalType::Unknown)),
1872 ConvertedType::NONE
1873 );
1874 }
1875
1876 #[test]
1877 fn test_logical_type_roundtrip() {
1878 test_roundtrip(LogicalType::String);
1879 test_roundtrip(LogicalType::Map);
1880 test_roundtrip(LogicalType::List);
1881 test_roundtrip(LogicalType::Enum);
1882 test_roundtrip(LogicalType::decimal(0, 20));
1883 test_roundtrip(LogicalType::Date);
1884 test_roundtrip(LogicalType::time(true, TimeUnit::MICROS));
1885 test_roundtrip(LogicalType::time(false, TimeUnit::MILLIS));
1886 test_roundtrip(LogicalType::time(false, TimeUnit::NANOS));
1887 test_roundtrip(LogicalType::timestamp(false, TimeUnit::MICROS));
1888 test_roundtrip(LogicalType::timestamp(true, TimeUnit::MILLIS));
1889 test_roundtrip(LogicalType::timestamp(true, TimeUnit::NANOS));
1890 test_roundtrip(LogicalType::integer(8, true));
1891 test_roundtrip(LogicalType::integer(16, false));
1892 test_roundtrip(LogicalType::integer(32, true));
1893 test_roundtrip(LogicalType::integer(64, false));
1894 test_roundtrip(LogicalType::Json);
1895 test_roundtrip(LogicalType::Bson);
1896 test_roundtrip(LogicalType::Uuid);
1897 test_roundtrip(LogicalType::Float16);
1898 test_roundtrip(LogicalType::variant(Some(1)));
1899 test_roundtrip(LogicalType::variant(None));
1900 test_roundtrip(LogicalType::geometry(Some("foo".to_owned())));
1901 test_roundtrip(LogicalType::geometry(None));
1902 test_roundtrip(LogicalType::geography(
1903 Some("foo".to_owned()),
1904 Some(EdgeInterpolationAlgorithm::ANDOYER),
1905 ));
1906 test_roundtrip(LogicalType::geography(
1907 None,
1908 Some(EdgeInterpolationAlgorithm::KARNEY),
1909 ));
1910 test_roundtrip(LogicalType::geography(
1911 Some("foo".to_owned()),
1912 Some(EdgeInterpolationAlgorithm::SPHERICAL),
1913 ));
1914 test_roundtrip(LogicalType::geography(
1915 None,
1916 Some(EdgeInterpolationAlgorithm::SPHERICAL),
1917 ));
1918 }
1919
1920 #[test]
1921 fn test_display_repetition() {
1922 assert_eq!(Repetition::REQUIRED.to_string(), "REQUIRED");
1923 assert_eq!(Repetition::OPTIONAL.to_string(), "OPTIONAL");
1924 assert_eq!(Repetition::REPEATED.to_string(), "REPEATED");
1925 }
1926
1927 #[test]
1928 fn test_from_string_into_repetition() {
1929 assert_eq!(
1930 Repetition::REQUIRED
1931 .to_string()
1932 .parse::<Repetition>()
1933 .unwrap(),
1934 Repetition::REQUIRED
1935 );
1936 assert_eq!(
1937 Repetition::OPTIONAL
1938 .to_string()
1939 .parse::<Repetition>()
1940 .unwrap(),
1941 Repetition::OPTIONAL
1942 );
1943 assert_eq!(
1944 Repetition::REPEATED
1945 .to_string()
1946 .parse::<Repetition>()
1947 .unwrap(),
1948 Repetition::REPEATED
1949 );
1950 }
1951
1952 #[test]
1953 fn test_display_encoding() {
1954 assert_eq!(Encoding::PLAIN.to_string(), "PLAIN");
1955 assert_eq!(Encoding::PLAIN_DICTIONARY.to_string(), "PLAIN_DICTIONARY");
1956 assert_eq!(Encoding::RLE.to_string(), "RLE");
1957 assert_eq!(Encoding::BIT_PACKED.to_string(), "BIT_PACKED");
1958 assert_eq!(
1959 Encoding::DELTA_BINARY_PACKED.to_string(),
1960 "DELTA_BINARY_PACKED"
1961 );
1962 assert_eq!(
1963 Encoding::DELTA_LENGTH_BYTE_ARRAY.to_string(),
1964 "DELTA_LENGTH_BYTE_ARRAY"
1965 );
1966 assert_eq!(Encoding::DELTA_BYTE_ARRAY.to_string(), "DELTA_BYTE_ARRAY");
1967 assert_eq!(Encoding::RLE_DICTIONARY.to_string(), "RLE_DICTIONARY");
1968 }
1969
1970 #[test]
1971 fn test_compression_conversion() {
1972 assert_eq!(
1973 CompressionCodec::from(Compression::UNCOMPRESSED),
1974 CompressionCodec::UNCOMPRESSED
1975 );
1976 assert_eq!(
1977 CompressionCodec::from(Compression::SNAPPY),
1978 CompressionCodec::SNAPPY
1979 );
1980 assert_eq!(
1981 CompressionCodec::from(Compression::GZIP(Default::default())),
1982 CompressionCodec::GZIP
1983 );
1984 assert_eq!(
1985 CompressionCodec::from(Compression::LZO),
1986 CompressionCodec::LZO
1987 );
1988 assert_eq!(
1989 CompressionCodec::from(Compression::BROTLI(Default::default())),
1990 CompressionCodec::BROTLI
1991 );
1992 assert_eq!(
1993 CompressionCodec::from(Compression::LZ4),
1994 CompressionCodec::LZ4
1995 );
1996 assert_eq!(
1997 CompressionCodec::from(Compression::ZSTD(Default::default())),
1998 CompressionCodec::ZSTD
1999 );
2000 assert_eq!(
2001 CompressionCodec::from(Compression::LZ4_RAW),
2002 CompressionCodec::LZ4_RAW
2003 );
2004
2005 assert_eq!(
2006 Compression::from(CompressionCodec::UNCOMPRESSED),
2007 Compression::UNCOMPRESSED
2008 );
2009 assert_eq!(
2010 Compression::from(CompressionCodec::SNAPPY),
2011 Compression::SNAPPY
2012 );
2013 assert_eq!(
2014 Compression::from(CompressionCodec::GZIP),
2015 Compression::GZIP(Default::default())
2016 );
2017 assert_eq!(Compression::from(CompressionCodec::LZO), Compression::LZO);
2018 assert_eq!(
2019 Compression::from(CompressionCodec::BROTLI),
2020 Compression::BROTLI(Default::default())
2021 );
2022 assert_eq!(Compression::from(CompressionCodec::LZ4), Compression::LZ4);
2023 assert_eq!(
2024 Compression::from(CompressionCodec::ZSTD),
2025 Compression::ZSTD(Default::default())
2026 );
2027 assert_eq!(
2028 Compression::from(CompressionCodec::LZ4_RAW),
2029 Compression::LZ4_RAW
2030 );
2031 }
2032
2033 #[test]
2034 fn test_display_compression() {
2035 assert_eq!(Compression::UNCOMPRESSED.to_string(), "UNCOMPRESSED");
2036 assert_eq!(Compression::SNAPPY.to_string(), "SNAPPY");
2037 assert_eq!(
2038 Compression::GZIP(Default::default()).to_string(),
2039 "GZIP(GzipLevel(6))"
2040 );
2041 assert_eq!(Compression::LZO.to_string(), "LZO");
2042 assert_eq!(
2043 Compression::BROTLI(Default::default()).to_string(),
2044 "BROTLI(BrotliLevel(1))"
2045 );
2046 assert_eq!(Compression::LZ4.to_string(), "LZ4");
2047 assert_eq!(
2048 Compression::ZSTD(Default::default()).to_string(),
2049 "ZSTD(ZstdLevel(1))"
2050 );
2051 }
2052
2053 #[test]
2054 fn test_display_page_type() {
2055 assert_eq!(PageType::DATA_PAGE.to_string(), "DATA_PAGE");
2056 assert_eq!(PageType::INDEX_PAGE.to_string(), "INDEX_PAGE");
2057 assert_eq!(PageType::DICTIONARY_PAGE.to_string(), "DICTIONARY_PAGE");
2058 assert_eq!(PageType::DATA_PAGE_V2.to_string(), "DATA_PAGE_V2");
2059 }
2060
2061 #[test]
2062 fn test_display_sort_order() {
2063 assert_eq!(SortOrder::SIGNED.to_string(), "SIGNED");
2064 assert_eq!(SortOrder::UNSIGNED.to_string(), "UNSIGNED");
2065 assert_eq!(SortOrder::UNDEFINED.to_string(), "UNDEFINED");
2066 assert_eq!(SortOrder::TOTAL_ORDER.to_string(), "TOTAL_ORDER");
2067 assert_eq!(SortOrder::INT96_TIMESTAMP.to_string(), "INT96_TIMESTAMP");
2068 }
2069
2070 #[test]
2071 fn test_display_column_order() {
2072 assert_eq!(
2073 ColumnOrder::TYPE_DEFINED_ORDER(SortOrder::SIGNED).to_string(),
2074 "TYPE_DEFINED_ORDER(SIGNED)"
2075 );
2076 assert_eq!(
2077 ColumnOrder::TYPE_DEFINED_ORDER(SortOrder::UNSIGNED).to_string(),
2078 "TYPE_DEFINED_ORDER(UNSIGNED)"
2079 );
2080 assert_eq!(
2081 ColumnOrder::TYPE_DEFINED_ORDER(SortOrder::UNDEFINED).to_string(),
2082 "TYPE_DEFINED_ORDER(UNDEFINED)"
2083 );
2084 assert_eq!(
2085 ColumnOrder::IEEE_754_TOTAL_ORDER.to_string(),
2086 "IEEE_754_TOTAL_ORDER"
2087 );
2088 assert_eq!(
2089 ColumnOrder::INT96_TIMESTAMP_ORDER.to_string(),
2090 "INT96_TIMESTAMP_ORDER"
2091 );
2092 assert_eq!(ColumnOrder::UNDEFINED.to_string(), "UNDEFINED");
2093 }
2094
2095 #[test]
2096 fn test_column_order_roundtrip() {
2097 test_roundtrip(ColumnOrder::TYPE_DEFINED_ORDER(SortOrder::SIGNED))
2099 }
2100
2101 #[test]
2102 fn test_column_order_get_logical_type_sort_order() {
2103 fn check_sort_order(types: Vec<LogicalType>, expected_order: SortOrder) {
2106 for tpe in types {
2107 assert_eq!(
2108 ColumnOrder::column_order_for_type(
2109 Some(&tpe),
2110 ConvertedType::NONE,
2111 Type::BYTE_ARRAY
2112 )
2113 .sort_order(),
2114 expected_order
2115 );
2116 }
2117 }
2118
2119 let unsigned = vec![
2121 LogicalType::String,
2122 LogicalType::Json,
2123 LogicalType::Bson,
2124 LogicalType::Enum,
2125 LogicalType::Uuid,
2126 LogicalType::integer(8, false),
2127 LogicalType::integer(16, false),
2128 LogicalType::integer(32, false),
2129 LogicalType::integer(64, false),
2130 ];
2131 check_sort_order(unsigned, SortOrder::UNSIGNED);
2132
2133 let signed = vec![
2135 LogicalType::integer(8, true),
2136 LogicalType::integer(16, true),
2137 LogicalType::integer(32, true),
2138 LogicalType::integer(64, true),
2139 LogicalType::decimal(20, 4),
2140 LogicalType::Date,
2141 LogicalType::time(false, TimeUnit::MILLIS),
2142 LogicalType::time(false, TimeUnit::MICROS),
2143 LogicalType::time(true, TimeUnit::NANOS),
2144 LogicalType::timestamp(false, TimeUnit::MILLIS),
2145 LogicalType::timestamp(false, TimeUnit::MICROS),
2146 LogicalType::timestamp(true, TimeUnit::NANOS),
2147 ];
2148 check_sort_order(signed, SortOrder::SIGNED);
2149
2150 let float = vec![LogicalType::Float16];
2151 check_sort_order(float, SortOrder::TOTAL_ORDER);
2152
2153 let undefined = vec![
2155 LogicalType::List,
2156 LogicalType::Map,
2157 LogicalType::variant(None),
2158 LogicalType::geometry(None),
2159 LogicalType::geography(None, Some(Default::default())),
2160 ];
2161 check_sort_order(undefined, SortOrder::UNDEFINED);
2162 }
2163
2164 #[test]
2165 fn test_column_order_get_converted_type_sort_order() {
2166 fn check_sort_order(types: Vec<ConvertedType>, expected_order: SortOrder) {
2169 for tpe in types {
2170 assert_eq!(
2171 ColumnOrder::column_order_for_type(None, tpe, Type::BYTE_ARRAY).sort_order(),
2172 expected_order
2173 );
2174 }
2175 }
2176
2177 let unsigned = vec![
2179 ConvertedType::UTF8,
2180 ConvertedType::JSON,
2181 ConvertedType::BSON,
2182 ConvertedType::ENUM,
2183 ConvertedType::UINT_8,
2184 ConvertedType::UINT_16,
2185 ConvertedType::UINT_32,
2186 ConvertedType::UINT_64,
2187 ];
2188 check_sort_order(unsigned, SortOrder::UNSIGNED);
2189
2190 let signed = vec![
2192 ConvertedType::INT_8,
2193 ConvertedType::INT_16,
2194 ConvertedType::INT_32,
2195 ConvertedType::INT_64,
2196 ConvertedType::DECIMAL,
2197 ConvertedType::DATE,
2198 ConvertedType::TIME_MILLIS,
2199 ConvertedType::TIME_MICROS,
2200 ConvertedType::TIMESTAMP_MILLIS,
2201 ConvertedType::TIMESTAMP_MICROS,
2202 ];
2203 check_sort_order(signed, SortOrder::SIGNED);
2204
2205 let undefined = vec![
2207 ConvertedType::LIST,
2208 ConvertedType::MAP,
2209 ConvertedType::MAP_KEY_VALUE,
2210 ConvertedType::INTERVAL,
2211 ];
2212 check_sort_order(undefined, SortOrder::UNDEFINED);
2213
2214 check_sort_order(vec![ConvertedType::NONE], SortOrder::UNSIGNED);
2217 }
2218
2219 #[test]
2220 fn test_column_order_get_default_sort_order() {
2221 assert_eq!(
2223 ColumnOrder::get_default_sort_order(Type::BOOLEAN, true),
2224 SortOrder::UNSIGNED
2225 );
2226 assert_eq!(
2227 ColumnOrder::get_default_sort_order(Type::INT32, true),
2228 SortOrder::SIGNED
2229 );
2230 assert_eq!(
2231 ColumnOrder::get_default_sort_order(Type::INT64, true),
2232 SortOrder::SIGNED
2233 );
2234 assert_eq!(
2235 ColumnOrder::get_default_sort_order(Type::INT96, true),
2236 SortOrder::UNDEFINED
2237 );
2238 assert_eq!(
2239 ColumnOrder::get_default_sort_order(Type::INT96, false),
2240 SortOrder::INT96_TIMESTAMP
2241 );
2242 assert_eq!(
2243 ColumnOrder::get_default_sort_order(Type::FLOAT, false),
2244 SortOrder::TOTAL_ORDER
2245 );
2246 assert_eq!(
2247 ColumnOrder::get_default_sort_order(Type::DOUBLE, false),
2248 SortOrder::TOTAL_ORDER
2249 );
2250 assert_eq!(
2251 ColumnOrder::get_default_sort_order(Type::FLOAT, true),
2252 SortOrder::SIGNED
2253 );
2254 assert_eq!(
2255 ColumnOrder::get_default_sort_order(Type::DOUBLE, true),
2256 SortOrder::SIGNED
2257 );
2258 assert_eq!(
2259 ColumnOrder::get_default_sort_order(Type::BYTE_ARRAY, true),
2260 SortOrder::UNSIGNED
2261 );
2262 assert_eq!(
2263 ColumnOrder::get_default_sort_order(Type::FIXED_LEN_BYTE_ARRAY, true),
2264 SortOrder::UNSIGNED
2265 );
2266 }
2267
2268 #[test]
2269 fn test_column_order_sort_order() {
2270 assert_eq!(
2271 ColumnOrder::TYPE_DEFINED_ORDER(SortOrder::SIGNED).sort_order(),
2272 SortOrder::SIGNED
2273 );
2274 assert_eq!(
2275 ColumnOrder::TYPE_DEFINED_ORDER(SortOrder::UNSIGNED).sort_order(),
2276 SortOrder::UNSIGNED
2277 );
2278 assert_eq!(
2279 ColumnOrder::TYPE_DEFINED_ORDER(SortOrder::UNDEFINED).sort_order(),
2280 SortOrder::UNDEFINED
2281 );
2282 assert_eq!(
2283 ColumnOrder::IEEE_754_TOTAL_ORDER.sort_order(),
2284 SortOrder::TOTAL_ORDER
2285 );
2286 assert_eq!(
2287 ColumnOrder::INT96_TIMESTAMP_ORDER.sort_order(),
2288 SortOrder::INT96_TIMESTAMP
2289 );
2290 assert_eq!(ColumnOrder::UNDEFINED.sort_order(), SortOrder::SIGNED);
2291 }
2292
2293 #[test]
2294 fn test_parse_encoding() {
2295 let mut encoding: Encoding = "PLAIN".parse().unwrap();
2296 assert_eq!(encoding, Encoding::PLAIN);
2297 encoding = "PLAIN_DICTIONARY".parse().unwrap();
2298 assert_eq!(encoding, Encoding::PLAIN_DICTIONARY);
2299 encoding = "RLE".parse().unwrap();
2300 assert_eq!(encoding, Encoding::RLE);
2301 encoding = "BIT_PACKED".parse().unwrap();
2302 assert_eq!(encoding, Encoding::BIT_PACKED);
2303 encoding = "DELTA_BINARY_PACKED".parse().unwrap();
2304 assert_eq!(encoding, Encoding::DELTA_BINARY_PACKED);
2305 encoding = "DELTA_LENGTH_BYTE_ARRAY".parse().unwrap();
2306 assert_eq!(encoding, Encoding::DELTA_LENGTH_BYTE_ARRAY);
2307 encoding = "DELTA_BYTE_ARRAY".parse().unwrap();
2308 assert_eq!(encoding, Encoding::DELTA_BYTE_ARRAY);
2309 encoding = "RLE_DICTIONARY".parse().unwrap();
2310 assert_eq!(encoding, Encoding::RLE_DICTIONARY);
2311 encoding = "BYTE_STREAM_SPLIT".parse().unwrap();
2312 assert_eq!(encoding, Encoding::BYTE_STREAM_SPLIT);
2313
2314 encoding = "byte_stream_split".parse().unwrap();
2316 assert_eq!(encoding, Encoding::BYTE_STREAM_SPLIT);
2317
2318 match "plain_xxx".parse::<Encoding>() {
2320 Ok(e) => {
2321 panic!("Should not be able to parse {e:?}");
2322 }
2323 Err(e) => {
2324 assert_eq!(e.to_string(), "Parquet error: unknown encoding: plain_xxx");
2325 }
2326 }
2327 }
2328
2329 #[test]
2330 fn test_parse_compression() {
2331 let mut compress: Compression = "snappy".parse().unwrap();
2332 assert_eq!(compress, Compression::SNAPPY);
2333 compress = "lzo".parse().unwrap();
2334 assert_eq!(compress, Compression::LZO);
2335 compress = "zstd(3)".parse().unwrap();
2336 assert_eq!(compress, Compression::ZSTD(ZstdLevel::try_new(3).unwrap()));
2337 compress = "zstd(-3)".parse().unwrap();
2338 assert_eq!(compress, Compression::ZSTD(ZstdLevel::try_new(-3).unwrap()));
2339 compress = "LZ4_RAW".parse().unwrap();
2340 assert_eq!(compress, Compression::LZ4_RAW);
2341 compress = "uncompressed".parse().unwrap();
2342 assert_eq!(compress, Compression::UNCOMPRESSED);
2343 compress = "snappy".parse().unwrap();
2344 assert_eq!(compress, Compression::SNAPPY);
2345 compress = "gzip(9)".parse().unwrap();
2346 assert_eq!(compress, Compression::GZIP(GzipLevel::try_new(9).unwrap()));
2347 compress = "lzo".parse().unwrap();
2348 assert_eq!(compress, Compression::LZO);
2349 compress = "brotli(3)".parse().unwrap();
2350 assert_eq!(
2351 compress,
2352 Compression::BROTLI(BrotliLevel::try_new(3).unwrap())
2353 );
2354 compress = "lz4".parse().unwrap();
2355 assert_eq!(compress, Compression::LZ4);
2356
2357 let mut err = "plain_xxx".parse::<Encoding>().unwrap_err();
2359 assert_eq!(
2360 err.to_string(),
2361 "Parquet error: unknown encoding: plain_xxx"
2362 );
2363
2364 err = "gzip(-10)".parse::<Encoding>().unwrap_err();
2366 assert_eq!(
2367 err.to_string(),
2368 "Parquet error: unknown encoding: gzip(-10)"
2369 );
2370 }
2371
2372 #[test]
2373 fn test_display_boundary_order() {
2374 assert_eq!(BoundaryOrder::ASCENDING.to_string(), "ASCENDING");
2375 assert_eq!(BoundaryOrder::DESCENDING.to_string(), "DESCENDING");
2376 assert_eq!(BoundaryOrder::UNORDERED.to_string(), "UNORDERED");
2377 }
2378
2379 #[test]
2380 fn test_display_edge_algo() {
2381 assert_eq!(
2382 EdgeInterpolationAlgorithm::SPHERICAL.to_string(),
2383 "SPHERICAL"
2384 );
2385 assert_eq!(EdgeInterpolationAlgorithm::VINCENTY.to_string(), "VINCENTY");
2386 assert_eq!(EdgeInterpolationAlgorithm::THOMAS.to_string(), "THOMAS");
2387 assert_eq!(EdgeInterpolationAlgorithm::ANDOYER.to_string(), "ANDOYER");
2388 assert_eq!(EdgeInterpolationAlgorithm::KARNEY.to_string(), "KARNEY");
2389 }
2390
2391 #[test]
2392 fn test_from_str_edge_algo() {
2393 assert_eq!(
2394 "spHErical".parse::<EdgeInterpolationAlgorithm>().unwrap(),
2395 EdgeInterpolationAlgorithm::SPHERICAL
2396 );
2397 assert_eq!(
2398 "vinceNTY".parse::<EdgeInterpolationAlgorithm>().unwrap(),
2399 EdgeInterpolationAlgorithm::VINCENTY
2400 );
2401 assert_eq!(
2402 "tHOmas".parse::<EdgeInterpolationAlgorithm>().unwrap(),
2403 EdgeInterpolationAlgorithm::THOMAS
2404 );
2405 assert_eq!(
2406 "anDOYEr".parse::<EdgeInterpolationAlgorithm>().unwrap(),
2407 EdgeInterpolationAlgorithm::ANDOYER
2408 );
2409 assert_eq!(
2410 "kaRNey".parse::<EdgeInterpolationAlgorithm>().unwrap(),
2411 EdgeInterpolationAlgorithm::KARNEY
2412 );
2413 assert!(
2414 "does not exist"
2415 .parse::<EdgeInterpolationAlgorithm>()
2416 .is_err()
2417 );
2418 }
2419
2420 fn encodings_roundtrip(mut encodings: Vec<Encoding>) {
2421 encodings.sort();
2422 let mask = EncodingMask::new_from_encodings(encodings.iter());
2423 assert!(mask.all_set(encodings.iter()));
2424 let v = mask.encodings().collect::<Vec<_>>();
2425 assert_eq!(v, encodings);
2426 }
2427
2428 #[test]
2429 fn test_encoding_roundtrip() {
2430 encodings_roundtrip(
2431 [
2432 Encoding::RLE,
2433 Encoding::PLAIN,
2434 Encoding::DELTA_BINARY_PACKED,
2435 ]
2436 .into(),
2437 );
2438 encodings_roundtrip([Encoding::RLE_DICTIONARY, Encoding::PLAIN_DICTIONARY].into());
2439 encodings_roundtrip([].into());
2440 let encodings = [
2441 Encoding::PLAIN,
2442 Encoding::BIT_PACKED,
2443 Encoding::RLE,
2444 Encoding::DELTA_BINARY_PACKED,
2445 Encoding::DELTA_BYTE_ARRAY,
2446 Encoding::DELTA_LENGTH_BYTE_ARRAY,
2447 Encoding::PLAIN_DICTIONARY,
2448 Encoding::RLE_DICTIONARY,
2449 Encoding::BYTE_STREAM_SPLIT,
2450 ];
2451 encodings_roundtrip(encodings.into());
2452 }
2453
2454 #[test]
2455 fn test_invalid_encoding_mask() {
2456 let res = EncodingMask::try_new(-1);
2458 assert!(res.is_err());
2459 let err = res.unwrap_err();
2460 assert_eq!(
2461 err.to_string(),
2462 "Parquet error: Attempt to create invalid mask: 0xffffffff"
2463 );
2464
2465 let res = EncodingMask::try_new(2);
2467 assert!(res.is_err());
2468 let err = res.unwrap_err();
2469 assert_eq!(
2470 err.to_string(),
2471 "Parquet error: Attempt to create invalid mask: 0x2"
2472 );
2473 }
2474
2475 #[test]
2476 fn test_encoding_mask_is_only() {
2477 let mask = EncodingMask::new_from_encodings([Encoding::PLAIN].iter());
2478 assert!(mask.is_only(Encoding::PLAIN));
2479
2480 let mask =
2481 EncodingMask::new_from_encodings([Encoding::PLAIN, Encoding::PLAIN_DICTIONARY].iter());
2482 assert!(!mask.is_only(Encoding::PLAIN));
2483 }
2484}