1pub use thrift::protocol::TCompactOutputProtocol;
21use thrift::protocol::{TInputProtocol, TOutputProtocol};
22
23pub trait TSerializable: Sized {
27 fn read_from_in_protocol<T: TInputProtocol>(i_prot: &mut T) -> thrift::Result<Self>;
29 fn write_to_out_protocol<T: TOutputProtocol>(&self, o_prot: &mut T) -> thrift::Result<()>;
31}
32
33#[cfg(test)]
34mod tests {
35 use crate::{
36 basic::Type,
37 file::page_index::{column_index::ColumnIndexMetaData, index_reader::decode_column_index},
38 };
39
40 #[test]
41 #[allow(deprecated)]
42 fn legacy_statistics_reject_oversized_binary_before_allocation() {
43 use crate::{format::Statistics, thrift::TSerializable};
44 use thrift::{Error, ProtocolErrorKind, protocol::TCompactInputProtocol};
45
46 let bytes = [0x18, 0x81, 0x80, 0x80, 0x32];
49 let mut input = TCompactInputProtocol::new(bytes.as_slice());
50 let error = Statistics::read_from_in_protocol(&mut input).unwrap_err();
51 assert!(
52 matches!(error, Error::Protocol(error) if error.kind == ProtocolErrorKind::SizeLimit)
53 );
54 }
55
56 #[test]
57 #[allow(deprecated)]
58 fn legacy_statistics_compact_protocol_roundtrip() {
59 use crate::{format::Statistics, thrift::TSerializable};
60 use thrift::protocol::{TCompactInputProtocol, TCompactOutputProtocol};
61
62 let expected = Statistics {
63 min_value: Some(vec![0, 1, 255]),
64 max_value: Some(vec![255, 0, 1]),
65 null_count: Some(7),
66 ..Default::default()
67 };
68 let mut bytes = Vec::new();
69 expected
70 .write_to_out_protocol(&mut TCompactOutputProtocol::new(&mut bytes))
71 .unwrap();
72 let actual =
73 Statistics::read_from_in_protocol(&mut TCompactInputProtocol::new(bytes.as_slice()))
74 .unwrap();
75 assert_eq!(actual, expected);
76 }
77
78 #[test]
79 pub fn read_boolean_list_field_type() {
80 let bytes = vec![
84 0x19, 0x21, 2, 1, 0x19, 0x28, 1, 0, 0, 0x19, 0x28, 1, 1, 0, 0x15, 0, 0,
85 ];
86 let index = decode_column_index(&bytes, Type::BOOLEAN).unwrap();
87
88 let index = match index {
89 ColumnIndexMetaData::BOOLEAN(index) => index,
90 _ => panic!("expected boolean column index"),
91 };
92
93 assert!(!index.is_null_page(0));
95 assert!(index.is_null_page(1));
96 assert!(!index.min_value(0).unwrap()); assert!(index.max_value(0).unwrap()); assert!(index.min_value(1).is_none());
99 assert!(index.max_value(1).is_none());
100 }
101
102 #[test]
103 pub fn read_boolean_list_alternative_encoding() {
104 let bytes = vec![
107 0x19, 0x22, 0, 1, 0x19, 0x28, 1, 0, 0, 0x19, 0x28, 1, 1, 0, 0x15, 0, 0,
108 ];
109 let index = decode_column_index(&bytes, Type::BOOLEAN).unwrap();
110
111 let index = match index {
112 ColumnIndexMetaData::BOOLEAN(index) => index,
113 _ => panic!("expected boolean column index"),
114 };
115
116 assert!(!index.is_null_page(0));
118 assert!(index.is_null_page(1));
119 assert!(!index.min_value(0).unwrap()); assert!(index.max_value(0).unwrap()); assert!(index.min_value(1).is_none());
122 assert!(index.max_value(1).is_none());
123 }
124}