Skip to main content

parquet/
data_type.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18//! Data types that connect Parquet physical types with their Rust-specific
19//! representations.
20use bytes::Bytes;
21use half::f16;
22use std::cmp::Ordering;
23use std::fmt;
24use std::mem;
25use std::ops::{Deref, DerefMut};
26use std::str::from_utf8;
27
28use crate::basic::Type;
29use crate::column::reader::{ColumnReader, ColumnReaderImpl};
30use crate::column::writer::{ColumnWriter, ColumnWriterImpl};
31use crate::errors::{ParquetError, Result};
32use crate::util::bit_util::FromBytes;
33
34/// Rust representation for logical type INT96, value is backed by an array of `u32`.
35/// The type only takes 12 bytes, without extra padding.
36#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
37pub struct Int96 {
38    value: [u32; 3],
39}
40
41const JULIAN_DAY_OF_EPOCH: i64 = 2_440_588;
42
43/// Number of seconds in a day
44const SECONDS_IN_DAY: i64 = 86_400;
45/// Number of milliseconds in a second
46const MILLISECONDS: i64 = 1_000;
47/// Number of microseconds in a second
48const MICROSECONDS: i64 = 1_000_000;
49/// Number of nanoseconds in a second
50const NANOSECONDS: i64 = 1_000_000_000;
51
52/// Number of milliseconds in a day
53const MILLISECONDS_IN_DAY: i64 = SECONDS_IN_DAY * MILLISECONDS;
54/// Number of microseconds in a day
55const MICROSECONDS_IN_DAY: i64 = SECONDS_IN_DAY * MICROSECONDS;
56/// Number of nanoseconds in a day
57const NANOSECONDS_IN_DAY: i64 = SECONDS_IN_DAY * NANOSECONDS;
58
59impl Int96 {
60    /// Creates new INT96 type struct with no data set.
61    pub fn new() -> Self {
62        Self { value: [0; 3] }
63    }
64
65    /// Returns underlying data as slice of [`u32`].
66    #[inline]
67    pub fn data(&self) -> &[u32] {
68        &self.value
69    }
70
71    /// Sets data for this INT96 type.
72    #[inline]
73    pub fn set_data(&mut self, elem0: u32, elem1: u32, elem2: u32) {
74        self.value = [elem0, elem1, elem2];
75    }
76
77    /// Converts this INT96 into an i64 representing the number of SECONDS since EPOCH
78    ///
79    /// Will wrap around on overflow
80    #[inline]
81    pub fn to_seconds(&self) -> i64 {
82        let (day, nanos) = self.data_as_days_and_nanos();
83        (day as i64 - JULIAN_DAY_OF_EPOCH)
84            .wrapping_mul(SECONDS_IN_DAY)
85            .wrapping_add(nanos / 1_000_000_000)
86    }
87
88    /// Converts this INT96 into an i64 representing the number of MILLISECONDS since EPOCH
89    ///
90    /// Will wrap around on overflow
91    #[inline]
92    pub fn to_millis(&self) -> i64 {
93        let (day, nanos) = self.data_as_days_and_nanos();
94        (day as i64 - JULIAN_DAY_OF_EPOCH)
95            .wrapping_mul(MILLISECONDS_IN_DAY)
96            .wrapping_add(nanos / 1_000_000)
97    }
98
99    /// Converts this INT96 into an i64 representing the number of MICROSECONDS since EPOCH
100    ///
101    /// Will wrap around on overflow
102    #[inline]
103    pub fn to_micros(&self) -> i64 {
104        let (day, nanos) = self.data_as_days_and_nanos();
105        (day as i64 - JULIAN_DAY_OF_EPOCH)
106            .wrapping_mul(MICROSECONDS_IN_DAY)
107            .wrapping_add(nanos / 1_000)
108    }
109
110    /// Converts this INT96 into an i64 representing the number of NANOSECONDS since EPOCH
111    ///
112    /// Will wrap around on overflow
113    #[inline]
114    pub fn to_nanos(&self) -> i64 {
115        let (day, nanos) = self.data_as_days_and_nanos();
116        (day as i64 - JULIAN_DAY_OF_EPOCH)
117            .wrapping_mul(NANOSECONDS_IN_DAY)
118            .wrapping_add(nanos)
119    }
120
121    #[inline]
122    fn get_days(&self) -> i32 {
123        self.data()[2] as i32
124    }
125
126    #[inline]
127    fn get_nanos(&self) -> i64 {
128        ((self.data()[1] as i64) << 32) + self.data()[0] as i64
129    }
130
131    #[inline]
132    fn data_as_days_and_nanos(&self) -> (i32, i64) {
133        (self.get_days(), self.get_nanos())
134    }
135}
136
137impl PartialOrd for Int96 {
138    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
139        Some(self.cmp(other))
140    }
141}
142
143impl Ord for Int96 {
144    /// Order `Int96` correctly for (deprecated) timestamp types.
145    ///
146    /// Note: this is done even though the Int96 type is deprecated.
147    /// Because some engines, notably Spark and Databricks Photon, still write
148    /// Int96 timestamps, a new `ColumnOrder` variant has been added to
149    /// the Parquet specification. See [parquet-format/#584].
150    ///
151    /// [parquet-format/#584]: https://github.com/apache/parquet-format/pull/584
152    fn cmp(&self, other: &Self) -> Ordering {
153        match self.get_days().cmp(&other.get_days()) {
154            Ordering::Equal => self.get_nanos().cmp(&other.get_nanos()),
155            ord => ord,
156        }
157    }
158}
159impl From<Vec<u32>> for Int96 {
160    fn from(buf: Vec<u32>) -> Self {
161        assert_eq!(buf.len(), 3);
162        let mut result = Self::new();
163        result.set_data(buf[0], buf[1], buf[2]);
164        result
165    }
166}
167
168impl fmt::Display for Int96 {
169    #[cold]
170    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
171        write!(f, "{:?}", self.data())
172    }
173}
174
175/// Rust representation for BYTE_ARRAY and FIXED_LEN_BYTE_ARRAY Parquet physical types.
176/// Value is backed by a byte buffer.
177#[derive(Clone, Default)]
178pub struct ByteArray {
179    data: Option<Bytes>,
180}
181
182// Special case Debug that prints out byte arrays that are valid utf8 as &str's
183impl std::fmt::Debug for ByteArray {
184    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
185        let mut debug_struct = f.debug_struct("ByteArray");
186        match self.as_utf8() {
187            Ok(s) => debug_struct.field("data", &s),
188            Err(_) => debug_struct.field("data", &self.data),
189        };
190        debug_struct.finish()
191    }
192}
193
194impl PartialOrd for ByteArray {
195    fn partial_cmp(&self, other: &ByteArray) -> Option<Ordering> {
196        // sort nulls first (consistent with PartialCmp on Option)
197        //
198        // Since ByteBuffer doesn't implement PartialOrd, so can't
199        // derive an implementation
200        match (&self.data, &other.data) {
201            (None, None) => Some(Ordering::Equal),
202            (None, Some(_)) => Some(Ordering::Less),
203            (Some(_), None) => Some(Ordering::Greater),
204            (Some(self_data), Some(other_data)) => {
205                // compare slices directly
206                self_data.partial_cmp(&other_data)
207            }
208        }
209    }
210}
211
212impl ByteArray {
213    /// Creates new byte array with no data set.
214    #[inline]
215    pub fn new() -> Self {
216        ByteArray { data: None }
217    }
218
219    /// Gets length of the underlying byte buffer.
220    ///
221    /// # Panics
222    ///
223    /// Panics if no data has been set, e.g. on a [`ByteArray::new`] instance
224    #[inline]
225    pub fn len(&self) -> usize {
226        assert!(self.data.is_some());
227        self.data.as_ref().unwrap().len()
228    }
229
230    /// Checks if the underlying buffer is empty.
231    ///
232    /// # Panics
233    ///
234    /// Panics if no data has been set, see [`Self::len`]
235    #[inline]
236    pub fn is_empty(&self) -> bool {
237        self.len() == 0
238    }
239
240    /// Returns slice of data.
241    ///
242    /// # Panics
243    ///
244    /// Panics if no data has been set
245    #[inline]
246    pub fn data(&self) -> &[u8] {
247        self.data
248            .as_ref()
249            .expect("set_data should have been called")
250            .as_ref()
251    }
252
253    /// Set data from another byte buffer.
254    #[inline]
255    pub fn set_data(&mut self, data: Bytes) {
256        self.data = Some(data);
257    }
258
259    /// Returns `ByteArray` instance with slice of values for a data.
260    ///
261    /// # Panics
262    ///
263    /// Panics if no data has been set, or if `start + len` is out of bounds
264    #[inline]
265    pub fn slice(&self, start: usize, len: usize) -> Self {
266        Self::from(
267            self.data
268                .as_ref()
269                .expect("set_data should have been called")
270                .slice(start..start + len),
271        )
272    }
273
274    /// Try to convert the byte array to a utf8 slice
275    pub fn as_utf8(&self) -> Result<&str> {
276        let bytes = self
277            .data
278            .as_ref()
279            .map(|ptr| ptr.as_ref())
280            .ok_or_else(|| general_err!("Can't convert empty byte array to utf8"))?;
281        from_utf8(bytes).map_err(|e| e.into())
282    }
283}
284
285impl From<Vec<u8>> for ByteArray {
286    fn from(buf: Vec<u8>) -> ByteArray {
287        Self {
288            data: Some(buf.into()),
289        }
290    }
291}
292
293impl<'a> From<&'a [u8]> for ByteArray {
294    fn from(b: &'a [u8]) -> ByteArray {
295        let mut v = Vec::new();
296        v.extend_from_slice(b);
297        Self {
298            data: Some(v.into()),
299        }
300    }
301}
302
303impl<'a> From<&'a str> for ByteArray {
304    fn from(s: &'a str) -> ByteArray {
305        let mut v = Vec::new();
306        v.extend_from_slice(s.as_bytes());
307        Self {
308            data: Some(v.into()),
309        }
310    }
311}
312
313impl From<Bytes> for ByteArray {
314    fn from(value: Bytes) -> Self {
315        Self { data: Some(value) }
316    }
317}
318
319impl From<f16> for ByteArray {
320    fn from(value: f16) -> Self {
321        Self::from(value.to_le_bytes().as_slice())
322    }
323}
324
325impl PartialEq for ByteArray {
326    fn eq(&self, other: &ByteArray) -> bool {
327        match (&self.data, &other.data) {
328            (Some(d1), Some(d2)) => d1.as_ref() == d2.as_ref(),
329            (None, None) => true,
330            _ => false,
331        }
332    }
333}
334
335impl fmt::Display for ByteArray {
336    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
337        write!(f, "{:?}", self.data())
338    }
339}
340
341/// Wrapper type for performance reasons, this represents `FIXED_LEN_BYTE_ARRAY` but in all other
342/// considerations behaves the same as `ByteArray`
343///
344/// # Performance notes:
345/// This type is a little unfortunate, without it the compiler generates code that takes quite a
346/// big hit on the CPU pipeline. Essentially the previous version stalls awaiting the result of
347/// `T::get_physical_type() == Type::FIXED_LEN_BYTE_ARRAY`.
348///
349/// Its debatable if this is wanted, it is out of spec for what parquet documents as its base
350/// types, although there are code paths in the Rust (and potentially the C++) versions that
351/// warrant this.
352///
353/// With this wrapper type the compiler generates more targeted code paths matching the higher
354/// level logical types, removing the data-hazard from all decoding and encoding paths.
355#[repr(transparent)]
356#[derive(Clone, Debug, Default)]
357pub struct FixedLenByteArray(ByteArray);
358
359impl PartialEq for FixedLenByteArray {
360    fn eq(&self, other: &FixedLenByteArray) -> bool {
361        self.0.eq(&other.0)
362    }
363}
364
365impl PartialEq<ByteArray> for FixedLenByteArray {
366    fn eq(&self, other: &ByteArray) -> bool {
367        self.0.eq(other)
368    }
369}
370
371impl PartialEq<FixedLenByteArray> for ByteArray {
372    fn eq(&self, other: &FixedLenByteArray) -> bool {
373        self.eq(&other.0)
374    }
375}
376
377impl fmt::Display for FixedLenByteArray {
378    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
379        self.0.fmt(f)
380    }
381}
382
383impl PartialOrd for FixedLenByteArray {
384    fn partial_cmp(&self, other: &FixedLenByteArray) -> Option<Ordering> {
385        self.0.partial_cmp(&other.0)
386    }
387}
388
389impl PartialOrd<FixedLenByteArray> for ByteArray {
390    fn partial_cmp(&self, other: &FixedLenByteArray) -> Option<Ordering> {
391        self.partial_cmp(&other.0)
392    }
393}
394
395impl PartialOrd<ByteArray> for FixedLenByteArray {
396    fn partial_cmp(&self, other: &ByteArray) -> Option<Ordering> {
397        self.0.partial_cmp(other)
398    }
399}
400
401impl Deref for FixedLenByteArray {
402    type Target = ByteArray;
403
404    fn deref(&self) -> &Self::Target {
405        &self.0
406    }
407}
408
409impl DerefMut for FixedLenByteArray {
410    fn deref_mut(&mut self) -> &mut Self::Target {
411        &mut self.0
412    }
413}
414
415impl From<ByteArray> for FixedLenByteArray {
416    fn from(other: ByteArray) -> Self {
417        Self(other)
418    }
419}
420
421impl From<Vec<u8>> for FixedLenByteArray {
422    fn from(buf: Vec<u8>) -> FixedLenByteArray {
423        FixedLenByteArray(ByteArray::from(buf))
424    }
425}
426
427impl From<FixedLenByteArray> for ByteArray {
428    fn from(other: FixedLenByteArray) -> Self {
429        other.0
430    }
431}
432
433/// Rust representation for Decimal values.
434///
435/// This is not a representation of Parquet physical type, but rather a wrapper for
436/// DECIMAL logical type, and serves as container for raw parts of decimal values:
437/// unscaled value in bytes, precision and scale.
438#[derive(Clone, Debug)]
439pub enum Decimal {
440    /// Decimal backed by `i32`.
441    Int32 {
442        /// The underlying value
443        value: [u8; 4],
444        /// The total number of digits in the number
445        precision: i32,
446        /// The number of digits to the right of the decimal point
447        scale: i32,
448    },
449    /// Decimal backed by `i64`.
450    Int64 {
451        /// The underlying value
452        value: [u8; 8],
453        /// The total number of digits in the number
454        precision: i32,
455        /// The number of digits to the right of the decimal point
456        scale: i32,
457    },
458    /// Decimal backed by byte array.
459    Bytes {
460        /// The underlying value
461        value: ByteArray,
462        /// The total number of digits in the number
463        precision: i32,
464        /// The number of digits to the right of the decimal point
465        scale: i32,
466    },
467}
468
469impl Decimal {
470    /// Creates new decimal value from `i32`.
471    pub fn from_i32(value: i32, precision: i32, scale: i32) -> Self {
472        let bytes = value.to_be_bytes();
473        Decimal::Int32 {
474            value: bytes,
475            precision,
476            scale,
477        }
478    }
479
480    /// Creates new decimal value from `i64`.
481    pub fn from_i64(value: i64, precision: i32, scale: i32) -> Self {
482        let bytes = value.to_be_bytes();
483        Decimal::Int64 {
484            value: bytes,
485            precision,
486            scale,
487        }
488    }
489
490    /// Creates new decimal value from `ByteArray`.
491    pub fn from_bytes(value: ByteArray, precision: i32, scale: i32) -> Self {
492        Decimal::Bytes {
493            value,
494            precision,
495            scale,
496        }
497    }
498
499    /// Returns bytes of unscaled value.
500    pub fn data(&self) -> &[u8] {
501        match *self {
502            Decimal::Int32 { ref value, .. } => value,
503            Decimal::Int64 { ref value, .. } => value,
504            Decimal::Bytes { ref value, .. } => value.data(),
505        }
506    }
507
508    /// Returns decimal precision.
509    pub fn precision(&self) -> i32 {
510        match *self {
511            Decimal::Int32 { precision, .. } => precision,
512            Decimal::Int64 { precision, .. } => precision,
513            Decimal::Bytes { precision, .. } => precision,
514        }
515    }
516
517    /// Returns decimal scale.
518    pub fn scale(&self) -> i32 {
519        match *self {
520            Decimal::Int32 { scale, .. } => scale,
521            Decimal::Int64 { scale, .. } => scale,
522            Decimal::Bytes { scale, .. } => scale,
523        }
524    }
525}
526
527impl Default for Decimal {
528    fn default() -> Self {
529        Self::from_i32(0, 0, 0)
530    }
531}
532
533impl PartialEq for Decimal {
534    fn eq(&self, other: &Decimal) -> bool {
535        self.precision() == other.precision()
536            && self.scale() == other.scale()
537            && self.data() == other.data()
538    }
539}
540
541/// Converts an instance of data type to a slice of bytes as `u8`.
542pub trait AsBytes {
543    /// Returns slice of bytes for this data type.
544    fn as_bytes(&self) -> &[u8];
545}
546
547/// Converts an slice of a data type to a slice of bytes.
548pub trait SliceAsBytes: Sized {
549    /// Returns slice of bytes for a slice of this data type.
550    fn slice_as_bytes(self_: &[Self]) -> &[u8];
551    /// Return the internal representation as a mutable slice
552    ///
553    /// # Safety
554    /// If modified you are _required_ to ensure the internal representation
555    /// is valid and correct for the actual raw data
556    unsafe fn slice_as_bytes_mut(self_: &mut [Self]) -> &mut [u8];
557}
558
559impl AsBytes for [u8] {
560    fn as_bytes(&self) -> &[u8] {
561        self
562    }
563}
564
565macro_rules! gen_as_bytes {
566    ($source_ty:ident) => {
567        impl AsBytes for $source_ty {
568            fn as_bytes(&self) -> &[u8] {
569                // SAFETY: macro is only used with primitive types that have no padding, so the
570                // resulting slice always refers to initialized memory.
571                unsafe {
572                    std::slice::from_raw_parts(
573                        std::ptr::from_ref::<$source_ty>(self).cast::<u8>(),
574                        std::mem::size_of::<$source_ty>(),
575                    )
576                }
577            }
578        }
579
580        impl SliceAsBytes for $source_ty {
581            #[inline]
582            fn slice_as_bytes(self_: &[Self]) -> &[u8] {
583                // SAFETY: macro is only used with primitive types that have no padding, so the
584                // resulting slice always refers to initialized memory.
585                unsafe {
586                    std::slice::from_raw_parts(
587                        self_.as_ptr().cast::<u8>(),
588                        std::mem::size_of_val(self_),
589                    )
590                }
591            }
592
593            #[inline]
594            unsafe fn slice_as_bytes_mut(self_: &mut [Self]) -> &mut [u8] {
595                // SAFETY: macro is only used with primitive types that have no padding, so the
596                // resulting slice always refers to initialized memory. Moreover, self has no
597                // invalid bit patterns, so all writes to the resulting slice will be valid.
598                unsafe {
599                    std::slice::from_raw_parts_mut(
600                        self_.as_mut_ptr().cast::<u8>(),
601                        std::mem::size_of_val(self_),
602                    )
603                }
604            }
605        }
606    };
607}
608
609gen_as_bytes!(i8);
610gen_as_bytes!(i16);
611gen_as_bytes!(i32);
612gen_as_bytes!(i64);
613gen_as_bytes!(u8);
614gen_as_bytes!(u16);
615gen_as_bytes!(u32);
616gen_as_bytes!(u64);
617gen_as_bytes!(f32);
618gen_as_bytes!(f64);
619
620macro_rules! unimplemented_slice_as_bytes {
621    ($ty: ty) => {
622        impl SliceAsBytes for $ty {
623            fn slice_as_bytes(_self: &[Self]) -> &[u8] {
624                unimplemented!()
625            }
626
627            unsafe fn slice_as_bytes_mut(_self: &mut [Self]) -> &mut [u8] {
628                unimplemented!()
629            }
630        }
631    };
632}
633
634// TODO - Can Int96 and bool be implemented in these terms?
635unimplemented_slice_as_bytes!(Int96);
636unimplemented_slice_as_bytes!(bool);
637unimplemented_slice_as_bytes!(ByteArray);
638unimplemented_slice_as_bytes!(FixedLenByteArray);
639
640impl AsBytes for bool {
641    fn as_bytes(&self) -> &[u8] {
642        // SAFETY: a bool is guaranteed to be either 0x00 or 0x01 in memory, so the memory is
643        // valid.
644        unsafe { std::slice::from_raw_parts(std::ptr::from_ref::<bool>(self).cast::<u8>(), 1) }
645    }
646}
647
648impl AsBytes for Int96 {
649    fn as_bytes(&self) -> &[u8] {
650        // SAFETY: Int96::data is a &[u32; 3].
651        unsafe {
652            std::slice::from_raw_parts(std::ptr::from_ref::<[u32]>(self.data()).cast::<u8>(), 12)
653        }
654    }
655}
656
657impl AsBytes for ByteArray {
658    fn as_bytes(&self) -> &[u8] {
659        self.data()
660    }
661}
662
663impl AsBytes for FixedLenByteArray {
664    fn as_bytes(&self) -> &[u8] {
665        self.data()
666    }
667}
668
669impl AsBytes for Decimal {
670    fn as_bytes(&self) -> &[u8] {
671        self.data()
672    }
673}
674
675impl AsBytes for Vec<u8> {
676    fn as_bytes(&self) -> &[u8] {
677        self.as_slice()
678    }
679}
680
681impl AsBytes for &str {
682    fn as_bytes(&self) -> &[u8] {
683        (self as &str).as_bytes()
684    }
685}
686
687impl AsBytes for str {
688    fn as_bytes(&self) -> &[u8] {
689        (self as &str).as_bytes()
690    }
691}
692
693pub(crate) mod private {
694    use bytes::Bytes;
695
696    use crate::encodings::decoding::PlainDecoderDetails;
697    use crate::util::bit_util::{BitReader, BitWriter, read_num_bytes};
698
699    use super::{ParquetError, Result, SliceAsBytes};
700    use crate::basic::Type;
701    use crate::file::metadata::HeapSize;
702
703    /// Sealed trait to start to remove specialisation from implementations
704    ///
705    /// This is done to force the associated value type to be unimplementable outside of this
706    /// crate, and thus hint to the type system (and end user) traits are public for the contract
707    /// and not for extension.
708    pub trait ParquetValueType:
709        PartialEq
710        + std::fmt::Debug
711        + std::fmt::Display
712        + Default
713        + Clone
714        + super::AsBytes
715        + super::FromBytes
716        + SliceAsBytes
717        + PartialOrd
718        + Send
719        + HeapSize
720        + crate::encodings::decoding::private::GetDecoder
721        + crate::encodings::encoding::private::GetEncoder
722        + crate::file::statistics::private::MakeStatistics
723    {
724        const PHYSICAL_TYPE: Type;
725
726        /// Encode the value directly from a higher level encoder
727        fn encode<W: std::io::Write>(
728            values: &[Self],
729            writer: &mut W,
730            bit_writer: &mut BitWriter,
731        ) -> Result<()>;
732
733        /// Establish the data that will be decoded in a buffer
734        fn set_data(decoder: &mut PlainDecoderDetails, data: Bytes, num_values: usize);
735
736        /// Decode the value from a given buffer for a higher level decoder
737        fn decode(buffer: &mut [Self], decoder: &mut PlainDecoderDetails) -> Result<usize>;
738
739        fn skip(decoder: &mut PlainDecoderDetails, num_values: usize) -> Result<usize>;
740
741        /// Return the encoded size for a type
742        fn dict_encoding_size(&self) -> (usize, usize) {
743            (std::mem::size_of::<Self>(), 1)
744        }
745
746        /// Return the number of variable length bytes in a given slice of data
747        ///
748        /// Returns the sum of lengths for BYTE_ARRAY data, and None for all other data types
749        fn variable_length_bytes(_: &[Self]) -> Option<i64> {
750            None
751        }
752
753        /// Return the value as i64 if possible
754        ///
755        /// This is essentially the same as `std::convert::TryInto<i64>` but can't be
756        /// implemented for `f32` and `f64`, types that would fail orphan rules
757        fn as_i64(&self) -> Result<i64> {
758            Err(general_err!("Type cannot be converted to i64"))
759        }
760
761        /// Return the value as u64 if possible
762        ///
763        /// This is essentially the same as `std::convert::TryInto<u64>` but can't be
764        /// implemented for `f32` and `f64`, types that would fail orphan rules
765        fn as_u64(&self) -> Result<u64> {
766            self.as_i64()
767                .map_err(|_| general_err!("Type cannot be converted to u64"))
768                .map(|x| x as u64)
769        }
770
771        /// Return the value as an Any to allow for downcasts without transmutation
772        fn as_any(&self) -> &dyn std::any::Any;
773
774        /// Return the value as an mutable Any to allow for downcasts without transmutation
775        fn as_mut_any(&mut self) -> &mut dyn std::any::Any;
776
777        /// Sets the value of this object from the provided [`Bytes`]
778        ///
779        /// Only implemented for `ByteArray` and `FixedLenByteArray`. Will panic for other types.
780        fn set_from_bytes(&mut self, _data: Bytes) {
781            unimplemented!();
782        }
783    }
784
785    impl ParquetValueType for bool {
786        const PHYSICAL_TYPE: Type = Type::BOOLEAN;
787
788        #[inline]
789        fn encode<W: std::io::Write>(
790            values: &[Self],
791            _: &mut W,
792            bit_writer: &mut BitWriter,
793        ) -> Result<()> {
794            for value in values {
795                bit_writer.put_value(*value as u64, 1)
796            }
797            Ok(())
798        }
799
800        #[inline]
801        fn set_data(decoder: &mut PlainDecoderDetails, data: Bytes, num_values: usize) {
802            decoder.bit_reader.replace(BitReader::new(data));
803            decoder.num_values = num_values;
804        }
805
806        #[inline]
807        fn decode(buffer: &mut [Self], decoder: &mut PlainDecoderDetails) -> Result<usize> {
808            let bit_reader = decoder.bit_reader.as_mut().unwrap();
809            let num_values = std::cmp::min(buffer.len(), decoder.num_values);
810            let values_read = bit_reader.get_batch(&mut buffer[..num_values], 1);
811            decoder.num_values -= values_read;
812            Ok(values_read)
813        }
814
815        fn skip(decoder: &mut PlainDecoderDetails, num_values: usize) -> Result<usize> {
816            let bit_reader = decoder.bit_reader.as_mut().unwrap();
817            let num_values = std::cmp::min(num_values, decoder.num_values);
818            let values_read = bit_reader.skip(num_values, 1);
819            decoder.num_values -= values_read;
820            Ok(values_read)
821        }
822
823        #[inline]
824        fn as_i64(&self) -> Result<i64> {
825            Ok(*self as i64)
826        }
827
828        #[inline]
829        fn as_any(&self) -> &dyn std::any::Any {
830            self
831        }
832
833        #[inline]
834        fn as_mut_any(&mut self) -> &mut dyn std::any::Any {
835            self
836        }
837    }
838
839    macro_rules! impl_from_raw {
840        ($ty: ty, $physical_ty: expr, $self: ident => $as_i64: block) => {
841            impl ParquetValueType for $ty {
842                const PHYSICAL_TYPE: Type = $physical_ty;
843
844                #[inline]
845                fn encode<W: std::io::Write>(values: &[Self], writer: &mut W, _: &mut BitWriter) -> Result<()> {
846                    // SAFETY: Self is one of i32, i64, f32, f64, which have no padding.
847                    let raw = unsafe {
848                        std::slice::from_raw_parts(
849                            values.as_ptr().cast::<u8>(),
850                            std::mem::size_of_val(values),
851                        )
852                    };
853                    writer.write_all(raw)?;
854
855                    Ok(())
856                }
857
858                #[inline]
859                fn set_data(decoder: &mut PlainDecoderDetails, data: Bytes, num_values: usize) {
860                    decoder.data.replace(data);
861                    decoder.start = 0;
862                    decoder.num_values = num_values;
863                }
864
865                #[inline]
866                fn decode(buffer: &mut [Self], decoder: &mut PlainDecoderDetails) -> Result<usize> {
867                    let data = decoder.data.as_ref().expect("set_data should have been called");
868                    let num_values = std::cmp::min(buffer.len(), decoder.num_values);
869                    let bytes_left = data.len() - decoder.start;
870                    let bytes_to_decode = std::mem::size_of::<Self>() * num_values;
871
872                    if bytes_left < bytes_to_decode {
873                        return Err(eof_err!("Not enough bytes to decode"));
874                    }
875
876                    {
877                        // SAFETY: Self has no invalid bit patterns, so writing to the slice
878                        // obtained with slice_as_bytes_mut is always safe.
879                        let raw_buffer = &mut unsafe { Self::slice_as_bytes_mut(buffer) }[..bytes_to_decode];
880                        raw_buffer.copy_from_slice(data.slice(
881                            decoder.start..decoder.start + bytes_to_decode
882                        ).as_ref());
883                    };
884                    decoder.start += bytes_to_decode;
885                    decoder.num_values -= num_values;
886
887                    Ok(num_values)
888                }
889
890                #[inline]
891                fn skip(decoder: &mut PlainDecoderDetails, num_values: usize) -> Result<usize> {
892                    let data = decoder.data.as_ref().expect("set_data should have been called");
893                    let num_values = num_values.min(decoder.num_values);
894                    let bytes_left = data.len() - decoder.start;
895                    let bytes_to_skip = std::mem::size_of::<Self>() * num_values;
896
897                    if bytes_left < bytes_to_skip {
898                        return Err(eof_err!("Not enough bytes to skip"));
899                    }
900
901                    decoder.start += bytes_to_skip;
902                    decoder.num_values -= num_values;
903
904                    Ok(num_values)
905                }
906
907                #[inline]
908                fn as_i64(&$self) -> Result<i64> {
909                    $as_i64
910                }
911
912                #[inline]
913                fn as_any(&self) -> &dyn std::any::Any {
914                    self
915                }
916
917                #[inline]
918                fn as_mut_any(&mut self) -> &mut dyn std::any::Any {
919                    self
920                }
921            }
922        }
923    }
924
925    impl_from_raw!(i32, Type::INT32, self => { Ok(*self as i64) });
926    impl_from_raw!(i64, Type::INT64, self => { Ok(*self) });
927    impl_from_raw!(f32, Type::FLOAT, self => { Err(general_err!("Type cannot be converted to i64")) });
928    impl_from_raw!(f64, Type::DOUBLE, self => { Err(general_err!("Type cannot be converted to i64")) });
929
930    impl ParquetValueType for super::Int96 {
931        const PHYSICAL_TYPE: Type = Type::INT96;
932
933        #[inline]
934        fn encode<W: std::io::Write>(
935            values: &[Self],
936            writer: &mut W,
937            _: &mut BitWriter,
938        ) -> Result<()> {
939            for value in values {
940                let raw = SliceAsBytes::slice_as_bytes(value.data());
941                writer.write_all(raw)?;
942            }
943            Ok(())
944        }
945
946        #[inline]
947        fn set_data(decoder: &mut PlainDecoderDetails, data: Bytes, num_values: usize) {
948            decoder.data.replace(data);
949            decoder.start = 0;
950            decoder.num_values = num_values;
951        }
952
953        #[inline]
954        fn decode(buffer: &mut [Self], decoder: &mut PlainDecoderDetails) -> Result<usize> {
955            // TODO - Remove the duplication between this and the general slice method
956            let data = decoder
957                .data
958                .as_ref()
959                .expect("set_data should have been called");
960            let num_values = std::cmp::min(buffer.len(), decoder.num_values);
961            let bytes_left = data.len() - decoder.start;
962            let bytes_to_decode = 12 * num_values;
963
964            if bytes_left < bytes_to_decode {
965                return Err(eof_err!("Not enough bytes to decode"));
966            }
967
968            let data_range = data.slice(decoder.start..decoder.start + bytes_to_decode);
969            let bytes: &[u8] = &data_range;
970            decoder.start += bytes_to_decode;
971
972            let mut pos = 0; // position in byte array
973            for item in buffer.iter_mut().take(num_values) {
974                let elem0 = u32::from_le_bytes(bytes[pos..pos + 4].try_into().unwrap());
975                let elem1 = u32::from_le_bytes(bytes[pos + 4..pos + 8].try_into().unwrap());
976                let elem2 = u32::from_le_bytes(bytes[pos + 8..pos + 12].try_into().unwrap());
977
978                item.set_data(elem0, elem1, elem2);
979                pos += 12;
980            }
981            decoder.num_values -= num_values;
982
983            Ok(num_values)
984        }
985
986        fn skip(decoder: &mut PlainDecoderDetails, num_values: usize) -> Result<usize> {
987            let data = decoder
988                .data
989                .as_ref()
990                .expect("set_data should have been called");
991            let num_values = std::cmp::min(num_values, decoder.num_values);
992            let bytes_left = data.len() - decoder.start;
993            let bytes_to_skip = 12 * num_values;
994
995            if bytes_left < bytes_to_skip {
996                return Err(eof_err!("Not enough bytes to skip"));
997            }
998            decoder.start += bytes_to_skip;
999            decoder.num_values -= num_values;
1000
1001            Ok(num_values)
1002        }
1003
1004        #[inline]
1005        fn as_any(&self) -> &dyn std::any::Any {
1006            self
1007        }
1008
1009        #[inline]
1010        fn as_mut_any(&mut self) -> &mut dyn std::any::Any {
1011            self
1012        }
1013    }
1014
1015    impl HeapSize for super::Int96 {
1016        fn heap_size(&self) -> usize {
1017            0 // no heap allocations
1018        }
1019    }
1020
1021    impl ParquetValueType for super::ByteArray {
1022        const PHYSICAL_TYPE: Type = Type::BYTE_ARRAY;
1023
1024        #[inline]
1025        fn encode<W: std::io::Write>(
1026            values: &[Self],
1027            writer: &mut W,
1028            _: &mut BitWriter,
1029        ) -> Result<()> {
1030            for value in values {
1031                let len: u32 = value.len().try_into().unwrap();
1032                writer.write_all(&len.to_ne_bytes())?;
1033                let raw = value.data();
1034                writer.write_all(raw)?;
1035            }
1036            Ok(())
1037        }
1038
1039        #[inline]
1040        fn set_data(decoder: &mut PlainDecoderDetails, data: Bytes, num_values: usize) {
1041            decoder.data.replace(data);
1042            decoder.start = 0;
1043            decoder.num_values = num_values;
1044        }
1045
1046        #[inline]
1047        fn decode(buffer: &mut [Self], decoder: &mut PlainDecoderDetails) -> Result<usize> {
1048            let data = decoder
1049                .data
1050                .as_mut()
1051                .expect("set_data should have been called");
1052            let num_values = std::cmp::min(buffer.len(), decoder.num_values);
1053            for val_array in buffer.iter_mut().take(num_values) {
1054                let len: usize =
1055                    read_num_bytes::<u32>(4, data.slice(decoder.start..).as_ref()) as usize;
1056                decoder.start += std::mem::size_of::<u32>();
1057
1058                if data.len() < decoder.start + len {
1059                    return Err(eof_err!("Not enough bytes to decode"));
1060                }
1061
1062                val_array.set_data(data.slice(decoder.start..decoder.start + len));
1063                decoder.start += len;
1064            }
1065            decoder.num_values -= num_values;
1066
1067            Ok(num_values)
1068        }
1069
1070        fn variable_length_bytes(values: &[Self]) -> Option<i64> {
1071            Some(values.iter().map(|x| x.len() as i64).sum())
1072        }
1073
1074        fn skip(decoder: &mut PlainDecoderDetails, num_values: usize) -> Result<usize> {
1075            let data = decoder
1076                .data
1077                .as_mut()
1078                .expect("set_data should have been called");
1079            let num_values = num_values.min(decoder.num_values);
1080
1081            for _ in 0..num_values {
1082                let len: usize =
1083                    read_num_bytes::<u32>(4, data.slice(decoder.start..).as_ref()) as usize;
1084                decoder.start += std::mem::size_of::<u32>() + len;
1085            }
1086            decoder.num_values -= num_values;
1087
1088            Ok(num_values)
1089        }
1090
1091        #[inline]
1092        fn dict_encoding_size(&self) -> (usize, usize) {
1093            (std::mem::size_of::<u32>(), self.len())
1094        }
1095
1096        #[inline]
1097        fn as_any(&self) -> &dyn std::any::Any {
1098            self
1099        }
1100
1101        #[inline]
1102        fn as_mut_any(&mut self) -> &mut dyn std::any::Any {
1103            self
1104        }
1105
1106        #[inline]
1107        fn set_from_bytes(&mut self, data: Bytes) {
1108            self.set_data(data);
1109        }
1110    }
1111
1112    impl HeapSize for super::ByteArray {
1113        fn heap_size(&self) -> usize {
1114            // note: this is an estimate, not exact, so just return the size
1115            // of the actual data used, don't try to handle the fact that it may
1116            // be shared.
1117            self.data.as_ref().map(|data| data.len()).unwrap_or(0)
1118        }
1119    }
1120
1121    impl ParquetValueType for super::FixedLenByteArray {
1122        const PHYSICAL_TYPE: Type = Type::FIXED_LEN_BYTE_ARRAY;
1123
1124        #[inline]
1125        fn encode<W: std::io::Write>(
1126            values: &[Self],
1127            writer: &mut W,
1128            _: &mut BitWriter,
1129        ) -> Result<()> {
1130            for value in values {
1131                let raw = value.data();
1132                writer.write_all(raw)?;
1133            }
1134            Ok(())
1135        }
1136
1137        #[inline]
1138        fn set_data(decoder: &mut PlainDecoderDetails, data: Bytes, num_values: usize) {
1139            decoder.data.replace(data);
1140            decoder.start = 0;
1141            decoder.num_values = num_values;
1142        }
1143
1144        #[inline]
1145        fn decode(buffer: &mut [Self], decoder: &mut PlainDecoderDetails) -> Result<usize> {
1146            assert!(decoder.type_length > 0);
1147
1148            let data = decoder
1149                .data
1150                .as_mut()
1151                .expect("set_data should have been called");
1152            let num_values = std::cmp::min(buffer.len(), decoder.num_values);
1153
1154            for item in buffer.iter_mut().take(num_values) {
1155                let len = decoder.type_length as usize;
1156
1157                if data.len() < decoder.start + len {
1158                    return Err(eof_err!("Not enough bytes to decode"));
1159                }
1160
1161                item.set_data(data.slice(decoder.start..decoder.start + len));
1162                decoder.start += len;
1163            }
1164            decoder.num_values -= num_values;
1165
1166            Ok(num_values)
1167        }
1168
1169        fn skip(decoder: &mut PlainDecoderDetails, num_values: usize) -> Result<usize> {
1170            assert!(decoder.type_length > 0);
1171
1172            let data = decoder
1173                .data
1174                .as_mut()
1175                .expect("set_data should have been called");
1176            let num_values = std::cmp::min(num_values, decoder.num_values);
1177            for _ in 0..num_values {
1178                let len = decoder.type_length as usize;
1179
1180                if data.len() < decoder.start + len {
1181                    return Err(eof_err!("Not enough bytes to skip"));
1182                }
1183
1184                decoder.start += len;
1185            }
1186            decoder.num_values -= num_values;
1187
1188            Ok(num_values)
1189        }
1190
1191        #[inline]
1192        fn dict_encoding_size(&self) -> (usize, usize) {
1193            (std::mem::size_of::<u32>(), self.len())
1194        }
1195
1196        #[inline]
1197        fn as_any(&self) -> &dyn std::any::Any {
1198            self
1199        }
1200
1201        #[inline]
1202        fn as_mut_any(&mut self) -> &mut dyn std::any::Any {
1203            self
1204        }
1205
1206        #[inline]
1207        fn set_from_bytes(&mut self, data: Bytes) {
1208            self.set_data(data);
1209        }
1210    }
1211
1212    impl HeapSize for super::FixedLenByteArray {
1213        fn heap_size(&self) -> usize {
1214            self.0.heap_size()
1215        }
1216    }
1217}
1218
1219/// Contains the Parquet physical type information as well as the Rust primitive type
1220/// presentation.
1221pub trait DataType: 'static + Send {
1222    /// The physical type of the Parquet data type.
1223    type T: private::ParquetValueType;
1224
1225    /// Returns Parquet physical type.
1226    fn get_physical_type() -> Type {
1227        <Self::T as private::ParquetValueType>::PHYSICAL_TYPE
1228    }
1229
1230    /// Returns size in bytes for Rust representation of the physical type.
1231    fn get_type_size() -> usize;
1232
1233    /// Returns the underlying [`ColumnReaderImpl`] for the given [`ColumnReader`].
1234    fn get_column_reader(column_writer: ColumnReader) -> Option<ColumnReaderImpl<Self>>
1235    where
1236        Self: Sized;
1237
1238    /// Returns the underlying [`ColumnWriterImpl`] for the given [`ColumnWriter`].
1239    fn get_column_writer(column_writer: ColumnWriter<'_>) -> Option<ColumnWriterImpl<'_, Self>>
1240    where
1241        Self: Sized;
1242
1243    /// Returns a reference to the underlying [`ColumnWriterImpl`] for the given [`ColumnWriter`].
1244    fn get_column_writer_ref<'a, 'b: 'a>(
1245        column_writer: &'b ColumnWriter<'a>,
1246    ) -> Option<&'b ColumnWriterImpl<'a, Self>>
1247    where
1248        Self: Sized;
1249
1250    /// Returns a mutable reference to the underlying [`ColumnWriterImpl`] for the given
1251    fn get_column_writer_mut<'a, 'b: 'a>(
1252        column_writer: &'a mut ColumnWriter<'b>,
1253    ) -> Option<&'a mut ColumnWriterImpl<'b, Self>>
1254    where
1255        Self: Sized;
1256}
1257
1258macro_rules! make_type {
1259    ($name:ident, $reader_ident: ident, $writer_ident: ident, $native_ty:ty, $size:expr) => {
1260        #[doc = concat!("Parquet physical type: ", stringify!($name))]
1261        #[derive(Clone)]
1262        pub struct $name {}
1263
1264        impl DataType for $name {
1265            type T = $native_ty;
1266
1267            fn get_type_size() -> usize {
1268                $size
1269            }
1270
1271            fn get_column_reader(column_reader: ColumnReader) -> Option<ColumnReaderImpl<Self>> {
1272                match column_reader {
1273                    ColumnReader::$reader_ident(w) => Some(w),
1274                    _ => None,
1275                }
1276            }
1277
1278            fn get_column_writer(
1279                column_writer: ColumnWriter<'_>,
1280            ) -> Option<ColumnWriterImpl<'_, Self>> {
1281                match column_writer {
1282                    ColumnWriter::$writer_ident(w) => Some(w),
1283                    _ => None,
1284                }
1285            }
1286
1287            fn get_column_writer_ref<'a, 'b: 'a>(
1288                column_writer: &'a ColumnWriter<'b>,
1289            ) -> Option<&'a ColumnWriterImpl<'b, Self>> {
1290                match column_writer {
1291                    ColumnWriter::$writer_ident(w) => Some(w),
1292                    _ => None,
1293                }
1294            }
1295
1296            fn get_column_writer_mut<'a, 'b: 'a>(
1297                column_writer: &'a mut ColumnWriter<'b>,
1298            ) -> Option<&'a mut ColumnWriterImpl<'b, Self>> {
1299                match column_writer {
1300                    ColumnWriter::$writer_ident(w) => Some(w),
1301                    _ => None,
1302                }
1303            }
1304        }
1305    };
1306}
1307
1308// Generate struct definitions for all physical types
1309
1310make_type!(BoolType, BoolColumnReader, BoolColumnWriter, bool, 1);
1311make_type!(Int32Type, Int32ColumnReader, Int32ColumnWriter, i32, 4);
1312make_type!(Int64Type, Int64ColumnReader, Int64ColumnWriter, i64, 8);
1313make_type!(
1314    Int96Type,
1315    Int96ColumnReader,
1316    Int96ColumnWriter,
1317    Int96,
1318    mem::size_of::<Int96>()
1319);
1320make_type!(FloatType, FloatColumnReader, FloatColumnWriter, f32, 4);
1321make_type!(DoubleType, DoubleColumnReader, DoubleColumnWriter, f64, 8);
1322make_type!(
1323    ByteArrayType,
1324    ByteArrayColumnReader,
1325    ByteArrayColumnWriter,
1326    ByteArray,
1327    mem::size_of::<ByteArray>()
1328);
1329make_type!(
1330    FixedLenByteArrayType,
1331    FixedLenByteArrayColumnReader,
1332    FixedLenByteArrayColumnWriter,
1333    FixedLenByteArray,
1334    mem::size_of::<FixedLenByteArray>()
1335);
1336
1337impl AsRef<[u8]> for ByteArray {
1338    fn as_ref(&self) -> &[u8] {
1339        self.as_bytes()
1340    }
1341}
1342
1343impl AsRef<[u8]> for FixedLenByteArray {
1344    fn as_ref(&self) -> &[u8] {
1345        self.as_bytes()
1346    }
1347}
1348
1349/// Macro to reduce repetition in making type assertions on the physical type against `T`
1350macro_rules! ensure_phys_ty {
1351    ($($ty:pat_param)|+ , $($arg:tt)*) => {
1352        match T::get_physical_type() {
1353            $($ty => (),)*
1354            _ => panic!($($arg)*),
1355        };
1356    }
1357}
1358
1359#[cfg(test)]
1360mod tests {
1361    use super::*;
1362
1363    #[test]
1364    fn test_as_bytes() {
1365        // Test Int96
1366        let i96 = Int96::from(vec![1, 2, 3]);
1367        assert_eq!(i96.as_bytes(), &[1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0]);
1368
1369        // Test ByteArray
1370        let byte_arr = ByteArray::from(vec![1, 2, 3]);
1371        assert_eq!(byte_arr.as_bytes(), &[1, 2, 3]);
1372
1373        // Test Decimal
1374        let decimal = Decimal::from_i32(123, 5, 2);
1375        assert_eq!(decimal.as_bytes(), &[0, 0, 0, 123]);
1376        let decimal = Decimal::from_i64(123, 5, 2);
1377        assert_eq!(decimal.as_bytes(), &[0, 0, 0, 0, 0, 0, 0, 123]);
1378        let decimal = Decimal::from_bytes(ByteArray::from(vec![1, 2, 3]), 5, 2);
1379        assert_eq!(decimal.as_bytes(), &[1, 2, 3]);
1380    }
1381
1382    #[test]
1383    fn test_int96_from() {
1384        assert_eq!(
1385            Int96::from(vec![1, 12345, 1234567890]).data(),
1386            &[1, 12345, 1234567890]
1387        );
1388    }
1389
1390    #[test]
1391    fn test_byte_array_from() {
1392        assert_eq!(ByteArray::from(b"ABC".to_vec()).data(), b"ABC");
1393        assert_eq!(ByteArray::from("ABC").data(), b"ABC");
1394        assert_eq!(
1395            ByteArray::from(Bytes::from(vec![1u8, 2u8, 3u8, 4u8, 5u8])).data(),
1396            &[1u8, 2u8, 3u8, 4u8, 5u8]
1397        );
1398        let buf = vec![6u8, 7u8, 8u8, 9u8, 10u8];
1399        assert_eq!(ByteArray::from(buf).data(), &[6u8, 7u8, 8u8, 9u8, 10u8]);
1400    }
1401
1402    #[test]
1403    fn test_decimal_partial_eq() {
1404        assert_eq!(Decimal::default(), Decimal::from_i32(0, 0, 0));
1405        assert_eq!(Decimal::from_i32(222, 5, 2), Decimal::from_i32(222, 5, 2));
1406        assert_eq!(
1407            Decimal::from_bytes(ByteArray::from(vec![0, 0, 0, 3]), 5, 2),
1408            Decimal::from_i32(3, 5, 2)
1409        );
1410
1411        assert_ne!(Decimal::from_i32(222, 5, 2), Decimal::from_i32(111, 5, 2));
1412        assert_ne!(Decimal::from_i32(222, 5, 2), Decimal::from_i32(222, 6, 2));
1413        assert_ne!(Decimal::from_i32(222, 5, 2), Decimal::from_i32(222, 5, 3));
1414
1415        assert_ne!(Decimal::from_i64(222, 5, 2), Decimal::from_i32(222, 5, 2));
1416    }
1417
1418    #[test]
1419    fn test_byte_array_ord() {
1420        let byte_arr1 = ByteArray::from(vec![1, 2, 3]);
1421        let byte_arr11 = ByteArray::from(vec![1, 2, 3]);
1422        let byte_arr2 = ByteArray::from(vec![3, 4]);
1423        let byte_arr3 = ByteArray::from(vec![1, 2, 4]);
1424        let byte_arr4 = ByteArray::from(vec![]);
1425        let byte_arr5 = ByteArray::from(vec![2, 2, 3]);
1426
1427        assert!(byte_arr1 < byte_arr2);
1428        assert!(byte_arr3 > byte_arr1);
1429        assert!(byte_arr1 > byte_arr4);
1430        assert_eq!(byte_arr1, byte_arr11);
1431        assert!(byte_arr5 > byte_arr1);
1432    }
1433}