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        self.data
277            .as_ref()
278            .map(|ptr| ptr.as_ref())
279            .ok_or_else(|| general_err!("Can't convert empty byte array to utf8"))
280            .and_then(|bytes| from_utf8(bytes).map_err(|e| e.into()))
281    }
282}
283
284impl From<Vec<u8>> for ByteArray {
285    fn from(buf: Vec<u8>) -> ByteArray {
286        Self {
287            data: Some(buf.into()),
288        }
289    }
290}
291
292impl<'a> From<&'a [u8]> for ByteArray {
293    fn from(b: &'a [u8]) -> ByteArray {
294        let mut v = Vec::new();
295        v.extend_from_slice(b);
296        Self {
297            data: Some(v.into()),
298        }
299    }
300}
301
302impl<'a> From<&'a str> for ByteArray {
303    fn from(s: &'a str) -> ByteArray {
304        let mut v = Vec::new();
305        v.extend_from_slice(s.as_bytes());
306        Self {
307            data: Some(v.into()),
308        }
309    }
310}
311
312impl From<Bytes> for ByteArray {
313    fn from(value: Bytes) -> Self {
314        Self { data: Some(value) }
315    }
316}
317
318impl From<f16> for ByteArray {
319    fn from(value: f16) -> Self {
320        Self::from(value.to_le_bytes().as_slice())
321    }
322}
323
324impl PartialEq for ByteArray {
325    fn eq(&self, other: &ByteArray) -> bool {
326        match (&self.data, &other.data) {
327            (Some(d1), Some(d2)) => d1.as_ref() == d2.as_ref(),
328            (None, None) => true,
329            _ => false,
330        }
331    }
332}
333
334impl fmt::Display for ByteArray {
335    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
336        write!(f, "{:?}", self.data())
337    }
338}
339
340/// Wrapper type for performance reasons, this represents `FIXED_LEN_BYTE_ARRAY` but in all other
341/// considerations behaves the same as `ByteArray`
342///
343/// # Performance notes:
344/// This type is a little unfortunate, without it the compiler generates code that takes quite a
345/// big hit on the CPU pipeline. Essentially the previous version stalls awaiting the result of
346/// `T::get_physical_type() == Type::FIXED_LEN_BYTE_ARRAY`.
347///
348/// Its debatable if this is wanted, it is out of spec for what parquet documents as its base
349/// types, although there are code paths in the Rust (and potentially the C++) versions that
350/// warrant this.
351///
352/// With this wrapper type the compiler generates more targeted code paths matching the higher
353/// level logical types, removing the data-hazard from all decoding and encoding paths.
354#[repr(transparent)]
355#[derive(Clone, Debug, Default)]
356pub struct FixedLenByteArray(ByteArray);
357
358impl PartialEq for FixedLenByteArray {
359    fn eq(&self, other: &FixedLenByteArray) -> bool {
360        self.0.eq(&other.0)
361    }
362}
363
364impl PartialEq<ByteArray> for FixedLenByteArray {
365    fn eq(&self, other: &ByteArray) -> bool {
366        self.0.eq(other)
367    }
368}
369
370impl PartialEq<FixedLenByteArray> for ByteArray {
371    fn eq(&self, other: &FixedLenByteArray) -> bool {
372        self.eq(&other.0)
373    }
374}
375
376impl fmt::Display for FixedLenByteArray {
377    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
378        self.0.fmt(f)
379    }
380}
381
382impl PartialOrd for FixedLenByteArray {
383    fn partial_cmp(&self, other: &FixedLenByteArray) -> Option<Ordering> {
384        self.0.partial_cmp(&other.0)
385    }
386}
387
388impl PartialOrd<FixedLenByteArray> for ByteArray {
389    fn partial_cmp(&self, other: &FixedLenByteArray) -> Option<Ordering> {
390        self.partial_cmp(&other.0)
391    }
392}
393
394impl PartialOrd<ByteArray> for FixedLenByteArray {
395    fn partial_cmp(&self, other: &ByteArray) -> Option<Ordering> {
396        self.0.partial_cmp(other)
397    }
398}
399
400impl Deref for FixedLenByteArray {
401    type Target = ByteArray;
402
403    fn deref(&self) -> &Self::Target {
404        &self.0
405    }
406}
407
408impl DerefMut for FixedLenByteArray {
409    fn deref_mut(&mut self) -> &mut Self::Target {
410        &mut self.0
411    }
412}
413
414impl From<ByteArray> for FixedLenByteArray {
415    fn from(other: ByteArray) -> Self {
416        Self(other)
417    }
418}
419
420impl From<Vec<u8>> for FixedLenByteArray {
421    fn from(buf: Vec<u8>) -> FixedLenByteArray {
422        FixedLenByteArray(ByteArray::from(buf))
423    }
424}
425
426impl From<FixedLenByteArray> for ByteArray {
427    fn from(other: FixedLenByteArray) -> Self {
428        other.0
429    }
430}
431
432/// Rust representation for Decimal values.
433///
434/// This is not a representation of Parquet physical type, but rather a wrapper for
435/// DECIMAL logical type, and serves as container for raw parts of decimal values:
436/// unscaled value in bytes, precision and scale.
437#[derive(Clone, Debug)]
438pub enum Decimal {
439    /// Decimal backed by `i32`.
440    Int32 {
441        /// The underlying value
442        value: [u8; 4],
443        /// The total number of digits in the number
444        precision: i32,
445        /// The number of digits to the right of the decimal point
446        scale: i32,
447    },
448    /// Decimal backed by `i64`.
449    Int64 {
450        /// The underlying value
451        value: [u8; 8],
452        /// The total number of digits in the number
453        precision: i32,
454        /// The number of digits to the right of the decimal point
455        scale: i32,
456    },
457    /// Decimal backed by byte array.
458    Bytes {
459        /// The underlying value
460        value: ByteArray,
461        /// The total number of digits in the number
462        precision: i32,
463        /// The number of digits to the right of the decimal point
464        scale: i32,
465    },
466}
467
468impl Decimal {
469    /// Creates new decimal value from `i32`.
470    pub fn from_i32(value: i32, precision: i32, scale: i32) -> Self {
471        let bytes = value.to_be_bytes();
472        Decimal::Int32 {
473            value: bytes,
474            precision,
475            scale,
476        }
477    }
478
479    /// Creates new decimal value from `i64`.
480    pub fn from_i64(value: i64, precision: i32, scale: i32) -> Self {
481        let bytes = value.to_be_bytes();
482        Decimal::Int64 {
483            value: bytes,
484            precision,
485            scale,
486        }
487    }
488
489    /// Creates new decimal value from `ByteArray`.
490    pub fn from_bytes(value: ByteArray, precision: i32, scale: i32) -> Self {
491        Decimal::Bytes {
492            value,
493            precision,
494            scale,
495        }
496    }
497
498    /// Returns bytes of unscaled value.
499    pub fn data(&self) -> &[u8] {
500        match *self {
501            Decimal::Int32 { ref value, .. } => value,
502            Decimal::Int64 { ref value, .. } => value,
503            Decimal::Bytes { ref value, .. } => value.data(),
504        }
505    }
506
507    /// Returns decimal precision.
508    pub fn precision(&self) -> i32 {
509        match *self {
510            Decimal::Int32 { precision, .. } => precision,
511            Decimal::Int64 { precision, .. } => precision,
512            Decimal::Bytes { precision, .. } => precision,
513        }
514    }
515
516    /// Returns decimal scale.
517    pub fn scale(&self) -> i32 {
518        match *self {
519            Decimal::Int32 { scale, .. } => scale,
520            Decimal::Int64 { scale, .. } => scale,
521            Decimal::Bytes { scale, .. } => scale,
522        }
523    }
524}
525
526impl Default for Decimal {
527    fn default() -> Self {
528        Self::from_i32(0, 0, 0)
529    }
530}
531
532impl PartialEq for Decimal {
533    fn eq(&self, other: &Decimal) -> bool {
534        self.precision() == other.precision()
535            && self.scale() == other.scale()
536            && self.data() == other.data()
537    }
538}
539
540/// Converts an instance of data type to a slice of bytes as `u8`.
541pub trait AsBytes {
542    /// Returns slice of bytes for this data type.
543    fn as_bytes(&self) -> &[u8];
544}
545
546/// Converts an slice of a data type to a slice of bytes.
547pub trait SliceAsBytes: Sized {
548    /// Returns slice of bytes for a slice of this data type.
549    fn slice_as_bytes(self_: &[Self]) -> &[u8];
550    /// Return the internal representation as a mutable slice
551    ///
552    /// # Safety
553    /// If modified you are _required_ to ensure the internal representation
554    /// is valid and correct for the actual raw data
555    unsafe fn slice_as_bytes_mut(self_: &mut [Self]) -> &mut [u8];
556}
557
558impl AsBytes for [u8] {
559    fn as_bytes(&self) -> &[u8] {
560        self
561    }
562}
563
564macro_rules! gen_as_bytes {
565    ($source_ty:ident) => {
566        impl AsBytes for $source_ty {
567            #[allow(clippy::size_of_in_element_count)]
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                        self as *const $source_ty as *const u8,
574                        std::mem::size_of::<$source_ty>(),
575                    )
576                }
577            }
578        }
579
580        impl SliceAsBytes for $source_ty {
581            #[inline]
582            #[allow(clippy::size_of_in_element_count)]
583            fn slice_as_bytes(self_: &[Self]) -> &[u8] {
584                // SAFETY: macro is only used with primitive types that have no padding, so the
585                // resulting slice always refers to initialized memory.
586                unsafe {
587                    std::slice::from_raw_parts(
588                        self_.as_ptr() as *const u8,
589                        std::mem::size_of_val(self_),
590                    )
591                }
592            }
593
594            #[inline]
595            #[allow(clippy::size_of_in_element_count)]
596            unsafe fn slice_as_bytes_mut(self_: &mut [Self]) -> &mut [u8] {
597                // SAFETY: macro is only used with primitive types that have no padding, so the
598                // resulting slice always refers to initialized memory. Moreover, self has no
599                // invalid bit patterns, so all writes to the resulting slice will be valid.
600                unsafe {
601                    std::slice::from_raw_parts_mut(
602                        self_.as_mut_ptr() as *mut u8,
603                        std::mem::size_of_val(self_),
604                    )
605                }
606            }
607        }
608    };
609}
610
611gen_as_bytes!(i8);
612gen_as_bytes!(i16);
613gen_as_bytes!(i32);
614gen_as_bytes!(i64);
615gen_as_bytes!(u8);
616gen_as_bytes!(u16);
617gen_as_bytes!(u32);
618gen_as_bytes!(u64);
619gen_as_bytes!(f32);
620gen_as_bytes!(f64);
621
622macro_rules! unimplemented_slice_as_bytes {
623    ($ty: ty) => {
624        impl SliceAsBytes for $ty {
625            fn slice_as_bytes(_self: &[Self]) -> &[u8] {
626                unimplemented!()
627            }
628
629            unsafe fn slice_as_bytes_mut(_self: &mut [Self]) -> &mut [u8] {
630                unimplemented!()
631            }
632        }
633    };
634}
635
636// TODO - Can Int96 and bool be implemented in these terms?
637unimplemented_slice_as_bytes!(Int96);
638unimplemented_slice_as_bytes!(bool);
639unimplemented_slice_as_bytes!(ByteArray);
640unimplemented_slice_as_bytes!(FixedLenByteArray);
641
642impl AsBytes for bool {
643    fn as_bytes(&self) -> &[u8] {
644        // SAFETY: a bool is guaranteed to be either 0x00 or 0x01 in memory, so the memory is
645        // valid.
646        unsafe { std::slice::from_raw_parts(self as *const bool as *const u8, 1) }
647    }
648}
649
650impl AsBytes for Int96 {
651    fn as_bytes(&self) -> &[u8] {
652        // SAFETY: Int96::data is a &[u32; 3].
653        unsafe { std::slice::from_raw_parts(self.data() as *const [u32] as *const u8, 12) }
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::file::statistics::private::MakeStatistics
722    {
723        const PHYSICAL_TYPE: Type;
724
725        /// Encode the value directly from a higher level encoder
726        fn encode<W: std::io::Write>(
727            values: &[Self],
728            writer: &mut W,
729            bit_writer: &mut BitWriter,
730        ) -> Result<()>;
731
732        /// Establish the data that will be decoded in a buffer
733        fn set_data(decoder: &mut PlainDecoderDetails, data: Bytes, num_values: usize);
734
735        /// Decode the value from a given buffer for a higher level decoder
736        fn decode(buffer: &mut [Self], decoder: &mut PlainDecoderDetails) -> Result<usize>;
737
738        fn skip(decoder: &mut PlainDecoderDetails, num_values: usize) -> Result<usize>;
739
740        /// Return the encoded size for a type
741        fn dict_encoding_size(&self) -> (usize, usize) {
742            (std::mem::size_of::<Self>(), 1)
743        }
744
745        /// Return the number of variable length bytes in a given slice of data
746        ///
747        /// Returns the sum of lengths for BYTE_ARRAY data, and None for all other data types
748        fn variable_length_bytes(_: &[Self]) -> Option<i64> {
749            None
750        }
751
752        /// Return the value as i64 if possible
753        ///
754        /// This is essentially the same as `std::convert::TryInto<i64>` but can't be
755        /// implemented for `f32` and `f64`, types that would fail orphan rules
756        fn as_i64(&self) -> Result<i64> {
757            Err(general_err!("Type cannot be converted to i64"))
758        }
759
760        /// Return the value as u64 if possible
761        ///
762        /// This is essentially the same as `std::convert::TryInto<u64>` but can't be
763        /// implemented for `f32` and `f64`, types that would fail orphan rules
764        fn as_u64(&self) -> Result<u64> {
765            self.as_i64()
766                .map_err(|_| general_err!("Type cannot be converted to u64"))
767                .map(|x| x as u64)
768        }
769
770        /// Return the value as an Any to allow for downcasts without transmutation
771        fn as_any(&self) -> &dyn std::any::Any;
772
773        /// Return the value as an mutable Any to allow for downcasts without transmutation
774        fn as_mut_any(&mut self) -> &mut dyn std::any::Any;
775
776        /// Sets the value of this object from the provided [`Bytes`]
777        ///
778        /// Only implemented for `ByteArray` and `FixedLenByteArray`. Will panic for other types.
779        fn set_from_bytes(&mut self, _data: Bytes) {
780            unimplemented!();
781        }
782    }
783
784    impl ParquetValueType for bool {
785        const PHYSICAL_TYPE: Type = Type::BOOLEAN;
786
787        #[inline]
788        fn encode<W: std::io::Write>(
789            values: &[Self],
790            _: &mut W,
791            bit_writer: &mut BitWriter,
792        ) -> Result<()> {
793            for value in values {
794                bit_writer.put_value(*value as u64, 1)
795            }
796            Ok(())
797        }
798
799        #[inline]
800        fn set_data(decoder: &mut PlainDecoderDetails, data: Bytes, num_values: usize) {
801            decoder.bit_reader.replace(BitReader::new(data));
802            decoder.num_values = num_values;
803        }
804
805        #[inline]
806        fn decode(buffer: &mut [Self], decoder: &mut PlainDecoderDetails) -> Result<usize> {
807            let bit_reader = decoder.bit_reader.as_mut().unwrap();
808            let num_values = std::cmp::min(buffer.len(), decoder.num_values);
809            let values_read = bit_reader.get_batch(&mut buffer[..num_values], 1);
810            decoder.num_values -= values_read;
811            Ok(values_read)
812        }
813
814        fn skip(decoder: &mut PlainDecoderDetails, num_values: usize) -> Result<usize> {
815            let bit_reader = decoder.bit_reader.as_mut().unwrap();
816            let num_values = std::cmp::min(num_values, decoder.num_values);
817            let values_read = bit_reader.skip(num_values, 1);
818            decoder.num_values -= values_read;
819            Ok(values_read)
820        }
821
822        #[inline]
823        fn as_i64(&self) -> Result<i64> {
824            Ok(*self as i64)
825        }
826
827        #[inline]
828        fn as_any(&self) -> &dyn std::any::Any {
829            self
830        }
831
832        #[inline]
833        fn as_mut_any(&mut self) -> &mut dyn std::any::Any {
834            self
835        }
836    }
837
838    macro_rules! impl_from_raw {
839        ($ty: ty, $physical_ty: expr, $self: ident => $as_i64: block) => {
840            impl ParquetValueType for $ty {
841                const PHYSICAL_TYPE: Type = $physical_ty;
842
843                #[inline]
844                fn encode<W: std::io::Write>(values: &[Self], writer: &mut W, _: &mut BitWriter) -> Result<()> {
845                    // SAFETY: Self is one of i32, i64, f32, f64, which have no padding.
846                    let raw = unsafe {
847                        std::slice::from_raw_parts(
848                            values.as_ptr() as *const u8,
849                            std::mem::size_of_val(values),
850                        )
851                    };
852                    writer.write_all(raw)?;
853
854                    Ok(())
855                }
856
857                #[inline]
858                fn set_data(decoder: &mut PlainDecoderDetails, data: Bytes, num_values: usize) {
859                    decoder.data.replace(data);
860                    decoder.start = 0;
861                    decoder.num_values = num_values;
862                }
863
864                #[inline]
865                fn decode(buffer: &mut [Self], decoder: &mut PlainDecoderDetails) -> Result<usize> {
866                    let data = decoder.data.as_ref().expect("set_data should have been called");
867                    let num_values = std::cmp::min(buffer.len(), decoder.num_values);
868                    let bytes_left = data.len() - decoder.start;
869                    let bytes_to_decode = std::mem::size_of::<Self>() * num_values;
870
871                    if bytes_left < bytes_to_decode {
872                        return Err(eof_err!("Not enough bytes to decode"));
873                    }
874
875                    {
876                        // SAFETY: Self has no invalid bit patterns, so writing to the slice
877                        // obtained with slice_as_bytes_mut is always safe.
878                        let raw_buffer = &mut unsafe { Self::slice_as_bytes_mut(buffer) }[..bytes_to_decode];
879                        raw_buffer.copy_from_slice(data.slice(
880                            decoder.start..decoder.start + bytes_to_decode
881                        ).as_ref());
882                    };
883                    decoder.start += bytes_to_decode;
884                    decoder.num_values -= num_values;
885
886                    Ok(num_values)
887                }
888
889                #[inline]
890                fn skip(decoder: &mut PlainDecoderDetails, num_values: usize) -> Result<usize> {
891                    let data = decoder.data.as_ref().expect("set_data should have been called");
892                    let num_values = num_values.min(decoder.num_values);
893                    let bytes_left = data.len() - decoder.start;
894                    let bytes_to_skip = std::mem::size_of::<Self>() * num_values;
895
896                    if bytes_left < bytes_to_skip {
897                        return Err(eof_err!("Not enough bytes to skip"));
898                    }
899
900                    decoder.start += bytes_to_skip;
901                    decoder.num_values -= num_values;
902
903                    Ok(num_values)
904                }
905
906                #[inline]
907                fn as_i64(&$self) -> Result<i64> {
908                    $as_i64
909                }
910
911                #[inline]
912                fn as_any(&self) -> &dyn std::any::Any {
913                    self
914                }
915
916                #[inline]
917                fn as_mut_any(&mut self) -> &mut dyn std::any::Any {
918                    self
919                }
920            }
921        }
922    }
923
924    impl_from_raw!(i32, Type::INT32, self => { Ok(*self as i64) });
925    impl_from_raw!(i64, Type::INT64, self => { Ok(*self) });
926    impl_from_raw!(f32, Type::FLOAT, self => { Err(general_err!("Type cannot be converted to i64")) });
927    impl_from_raw!(f64, Type::DOUBLE, self => { Err(general_err!("Type cannot be converted to i64")) });
928
929    impl ParquetValueType for super::Int96 {
930        const PHYSICAL_TYPE: Type = Type::INT96;
931
932        #[inline]
933        fn encode<W: std::io::Write>(
934            values: &[Self],
935            writer: &mut W,
936            _: &mut BitWriter,
937        ) -> Result<()> {
938            for value in values {
939                let raw = SliceAsBytes::slice_as_bytes(value.data());
940                writer.write_all(raw)?;
941            }
942            Ok(())
943        }
944
945        #[inline]
946        fn set_data(decoder: &mut PlainDecoderDetails, data: Bytes, num_values: usize) {
947            decoder.data.replace(data);
948            decoder.start = 0;
949            decoder.num_values = num_values;
950        }
951
952        #[inline]
953        fn decode(buffer: &mut [Self], decoder: &mut PlainDecoderDetails) -> Result<usize> {
954            // TODO - Remove the duplication between this and the general slice method
955            let data = decoder
956                .data
957                .as_ref()
958                .expect("set_data should have been called");
959            let num_values = std::cmp::min(buffer.len(), decoder.num_values);
960            let bytes_left = data.len() - decoder.start;
961            let bytes_to_decode = 12 * num_values;
962
963            if bytes_left < bytes_to_decode {
964                return Err(eof_err!("Not enough bytes to decode"));
965            }
966
967            let data_range = data.slice(decoder.start..decoder.start + bytes_to_decode);
968            let bytes: &[u8] = &data_range;
969            decoder.start += bytes_to_decode;
970
971            let mut pos = 0; // position in byte array
972            for item in buffer.iter_mut().take(num_values) {
973                let elem0 = u32::from_le_bytes(bytes[pos..pos + 4].try_into().unwrap());
974                let elem1 = u32::from_le_bytes(bytes[pos + 4..pos + 8].try_into().unwrap());
975                let elem2 = u32::from_le_bytes(bytes[pos + 8..pos + 12].try_into().unwrap());
976
977                item.set_data(elem0, elem1, elem2);
978                pos += 12;
979            }
980            decoder.num_values -= num_values;
981
982            Ok(num_values)
983        }
984
985        fn skip(decoder: &mut PlainDecoderDetails, num_values: usize) -> Result<usize> {
986            let data = decoder
987                .data
988                .as_ref()
989                .expect("set_data should have been called");
990            let num_values = std::cmp::min(num_values, decoder.num_values);
991            let bytes_left = data.len() - decoder.start;
992            let bytes_to_skip = 12 * num_values;
993
994            if bytes_left < bytes_to_skip {
995                return Err(eof_err!("Not enough bytes to skip"));
996            }
997            decoder.start += bytes_to_skip;
998            decoder.num_values -= num_values;
999
1000            Ok(num_values)
1001        }
1002
1003        #[inline]
1004        fn as_any(&self) -> &dyn std::any::Any {
1005            self
1006        }
1007
1008        #[inline]
1009        fn as_mut_any(&mut self) -> &mut dyn std::any::Any {
1010            self
1011        }
1012    }
1013
1014    impl HeapSize for super::Int96 {
1015        fn heap_size(&self) -> usize {
1016            0 // no heap allocations
1017        }
1018    }
1019
1020    impl ParquetValueType for super::ByteArray {
1021        const PHYSICAL_TYPE: Type = Type::BYTE_ARRAY;
1022
1023        #[inline]
1024        fn encode<W: std::io::Write>(
1025            values: &[Self],
1026            writer: &mut W,
1027            _: &mut BitWriter,
1028        ) -> Result<()> {
1029            for value in values {
1030                let len: u32 = value.len().try_into().unwrap();
1031                writer.write_all(&len.to_ne_bytes())?;
1032                let raw = value.data();
1033                writer.write_all(raw)?;
1034            }
1035            Ok(())
1036        }
1037
1038        #[inline]
1039        fn set_data(decoder: &mut PlainDecoderDetails, data: Bytes, num_values: usize) {
1040            decoder.data.replace(data);
1041            decoder.start = 0;
1042            decoder.num_values = num_values;
1043        }
1044
1045        #[inline]
1046        fn decode(buffer: &mut [Self], decoder: &mut PlainDecoderDetails) -> Result<usize> {
1047            let data = decoder
1048                .data
1049                .as_mut()
1050                .expect("set_data should have been called");
1051            let num_values = std::cmp::min(buffer.len(), decoder.num_values);
1052            for val_array in buffer.iter_mut().take(num_values) {
1053                let len: usize =
1054                    read_num_bytes::<u32>(4, data.slice(decoder.start..).as_ref()) as usize;
1055                decoder.start += std::mem::size_of::<u32>();
1056
1057                if data.len() < decoder.start + len {
1058                    return Err(eof_err!("Not enough bytes to decode"));
1059                }
1060
1061                val_array.set_data(data.slice(decoder.start..decoder.start + len));
1062                decoder.start += len;
1063            }
1064            decoder.num_values -= num_values;
1065
1066            Ok(num_values)
1067        }
1068
1069        fn variable_length_bytes(values: &[Self]) -> Option<i64> {
1070            Some(values.iter().map(|x| x.len() as i64).sum())
1071        }
1072
1073        fn skip(decoder: &mut PlainDecoderDetails, num_values: usize) -> Result<usize> {
1074            let data = decoder
1075                .data
1076                .as_mut()
1077                .expect("set_data should have been called");
1078            let num_values = num_values.min(decoder.num_values);
1079
1080            for _ in 0..num_values {
1081                let len: usize =
1082                    read_num_bytes::<u32>(4, data.slice(decoder.start..).as_ref()) as usize;
1083                decoder.start += std::mem::size_of::<u32>() + len;
1084            }
1085            decoder.num_values -= num_values;
1086
1087            Ok(num_values)
1088        }
1089
1090        #[inline]
1091        fn dict_encoding_size(&self) -> (usize, usize) {
1092            (std::mem::size_of::<u32>(), self.len())
1093        }
1094
1095        #[inline]
1096        fn as_any(&self) -> &dyn std::any::Any {
1097            self
1098        }
1099
1100        #[inline]
1101        fn as_mut_any(&mut self) -> &mut dyn std::any::Any {
1102            self
1103        }
1104
1105        #[inline]
1106        fn set_from_bytes(&mut self, data: Bytes) {
1107            self.set_data(data);
1108        }
1109    }
1110
1111    impl HeapSize for super::ByteArray {
1112        fn heap_size(&self) -> usize {
1113            // note: this is an estimate, not exact, so just return the size
1114            // of the actual data used, don't try to handle the fact that it may
1115            // be shared.
1116            self.data.as_ref().map(|data| data.len()).unwrap_or(0)
1117        }
1118    }
1119
1120    impl ParquetValueType for super::FixedLenByteArray {
1121        const PHYSICAL_TYPE: Type = Type::FIXED_LEN_BYTE_ARRAY;
1122
1123        #[inline]
1124        fn encode<W: std::io::Write>(
1125            values: &[Self],
1126            writer: &mut W,
1127            _: &mut BitWriter,
1128        ) -> Result<()> {
1129            for value in values {
1130                let raw = value.data();
1131                writer.write_all(raw)?;
1132            }
1133            Ok(())
1134        }
1135
1136        #[inline]
1137        fn set_data(decoder: &mut PlainDecoderDetails, data: Bytes, num_values: usize) {
1138            decoder.data.replace(data);
1139            decoder.start = 0;
1140            decoder.num_values = num_values;
1141        }
1142
1143        #[inline]
1144        fn decode(buffer: &mut [Self], decoder: &mut PlainDecoderDetails) -> Result<usize> {
1145            assert!(decoder.type_length > 0);
1146
1147            let data = decoder
1148                .data
1149                .as_mut()
1150                .expect("set_data should have been called");
1151            let num_values = std::cmp::min(buffer.len(), decoder.num_values);
1152
1153            for item in buffer.iter_mut().take(num_values) {
1154                let len = decoder.type_length as usize;
1155
1156                if data.len() < decoder.start + len {
1157                    return Err(eof_err!("Not enough bytes to decode"));
1158                }
1159
1160                item.set_data(data.slice(decoder.start..decoder.start + len));
1161                decoder.start += len;
1162            }
1163            decoder.num_values -= num_values;
1164
1165            Ok(num_values)
1166        }
1167
1168        fn skip(decoder: &mut PlainDecoderDetails, num_values: usize) -> Result<usize> {
1169            assert!(decoder.type_length > 0);
1170
1171            let data = decoder
1172                .data
1173                .as_mut()
1174                .expect("set_data should have been called");
1175            let num_values = std::cmp::min(num_values, decoder.num_values);
1176            for _ in 0..num_values {
1177                let len = decoder.type_length as usize;
1178
1179                if data.len() < decoder.start + len {
1180                    return Err(eof_err!("Not enough bytes to skip"));
1181                }
1182
1183                decoder.start += len;
1184            }
1185            decoder.num_values -= num_values;
1186
1187            Ok(num_values)
1188        }
1189
1190        #[inline]
1191        fn dict_encoding_size(&self) -> (usize, usize) {
1192            (std::mem::size_of::<u32>(), self.len())
1193        }
1194
1195        #[inline]
1196        fn as_any(&self) -> &dyn std::any::Any {
1197            self
1198        }
1199
1200        #[inline]
1201        fn as_mut_any(&mut self) -> &mut dyn std::any::Any {
1202            self
1203        }
1204
1205        #[inline]
1206        fn set_from_bytes(&mut self, data: Bytes) {
1207            self.set_data(data);
1208        }
1209    }
1210
1211    impl HeapSize for super::FixedLenByteArray {
1212        fn heap_size(&self) -> usize {
1213            self.0.heap_size()
1214        }
1215    }
1216}
1217
1218/// Contains the Parquet physical type information as well as the Rust primitive type
1219/// presentation.
1220pub trait DataType: 'static + Send {
1221    /// The physical type of the Parquet data type.
1222    type T: private::ParquetValueType;
1223
1224    /// Returns Parquet physical type.
1225    fn get_physical_type() -> Type {
1226        <Self::T as private::ParquetValueType>::PHYSICAL_TYPE
1227    }
1228
1229    /// Returns size in bytes for Rust representation of the physical type.
1230    fn get_type_size() -> usize;
1231
1232    /// Returns the underlying [`ColumnReaderImpl`] for the given [`ColumnReader`].
1233    fn get_column_reader(column_writer: ColumnReader) -> Option<ColumnReaderImpl<Self>>
1234    where
1235        Self: Sized;
1236
1237    /// Returns the underlying [`ColumnWriterImpl`] for the given [`ColumnWriter`].
1238    fn get_column_writer(column_writer: ColumnWriter<'_>) -> Option<ColumnWriterImpl<'_, Self>>
1239    where
1240        Self: Sized;
1241
1242    /// Returns a reference to the underlying [`ColumnWriterImpl`] for the given [`ColumnWriter`].
1243    fn get_column_writer_ref<'a, 'b: 'a>(
1244        column_writer: &'b ColumnWriter<'a>,
1245    ) -> Option<&'b ColumnWriterImpl<'a, Self>>
1246    where
1247        Self: Sized;
1248
1249    /// Returns a mutable reference to the underlying [`ColumnWriterImpl`] for the given
1250    fn get_column_writer_mut<'a, 'b: 'a>(
1251        column_writer: &'a mut ColumnWriter<'b>,
1252    ) -> Option<&'a mut ColumnWriterImpl<'b, Self>>
1253    where
1254        Self: Sized;
1255}
1256
1257macro_rules! make_type {
1258    ($name:ident, $reader_ident: ident, $writer_ident: ident, $native_ty:ty, $size:expr) => {
1259        #[doc = concat!("Parquet physical type: ", stringify!($name))]
1260        #[derive(Clone)]
1261        pub struct $name {}
1262
1263        impl DataType for $name {
1264            type T = $native_ty;
1265
1266            fn get_type_size() -> usize {
1267                $size
1268            }
1269
1270            fn get_column_reader(column_reader: ColumnReader) -> Option<ColumnReaderImpl<Self>> {
1271                match column_reader {
1272                    ColumnReader::$reader_ident(w) => Some(w),
1273                    _ => None,
1274                }
1275            }
1276
1277            fn get_column_writer(
1278                column_writer: ColumnWriter<'_>,
1279            ) -> Option<ColumnWriterImpl<'_, Self>> {
1280                match column_writer {
1281                    ColumnWriter::$writer_ident(w) => Some(w),
1282                    _ => None,
1283                }
1284            }
1285
1286            fn get_column_writer_ref<'a, 'b: 'a>(
1287                column_writer: &'a ColumnWriter<'b>,
1288            ) -> Option<&'a ColumnWriterImpl<'b, Self>> {
1289                match column_writer {
1290                    ColumnWriter::$writer_ident(w) => Some(w),
1291                    _ => None,
1292                }
1293            }
1294
1295            fn get_column_writer_mut<'a, 'b: 'a>(
1296                column_writer: &'a mut ColumnWriter<'b>,
1297            ) -> Option<&'a mut ColumnWriterImpl<'b, Self>> {
1298                match column_writer {
1299                    ColumnWriter::$writer_ident(w) => Some(w),
1300                    _ => None,
1301                }
1302            }
1303        }
1304    };
1305}
1306
1307// Generate struct definitions for all physical types
1308
1309make_type!(BoolType, BoolColumnReader, BoolColumnWriter, bool, 1);
1310make_type!(Int32Type, Int32ColumnReader, Int32ColumnWriter, i32, 4);
1311make_type!(Int64Type, Int64ColumnReader, Int64ColumnWriter, i64, 8);
1312make_type!(
1313    Int96Type,
1314    Int96ColumnReader,
1315    Int96ColumnWriter,
1316    Int96,
1317    mem::size_of::<Int96>()
1318);
1319make_type!(FloatType, FloatColumnReader, FloatColumnWriter, f32, 4);
1320make_type!(DoubleType, DoubleColumnReader, DoubleColumnWriter, f64, 8);
1321make_type!(
1322    ByteArrayType,
1323    ByteArrayColumnReader,
1324    ByteArrayColumnWriter,
1325    ByteArray,
1326    mem::size_of::<ByteArray>()
1327);
1328make_type!(
1329    FixedLenByteArrayType,
1330    FixedLenByteArrayColumnReader,
1331    FixedLenByteArrayColumnWriter,
1332    FixedLenByteArray,
1333    mem::size_of::<FixedLenByteArray>()
1334);
1335
1336impl AsRef<[u8]> for ByteArray {
1337    fn as_ref(&self) -> &[u8] {
1338        self.as_bytes()
1339    }
1340}
1341
1342impl AsRef<[u8]> for FixedLenByteArray {
1343    fn as_ref(&self) -> &[u8] {
1344        self.as_bytes()
1345    }
1346}
1347
1348/// Macro to reduce repetition in making type assertions on the physical type against `T`
1349macro_rules! ensure_phys_ty {
1350    ($($ty:pat_param)|+ , $($arg:tt)*) => {
1351        match T::get_physical_type() {
1352            $($ty => (),)*
1353            _ => panic!($($arg)*),
1354        };
1355    }
1356}
1357
1358#[cfg(test)]
1359mod tests {
1360    use super::*;
1361
1362    #[test]
1363    fn test_as_bytes() {
1364        // Test Int96
1365        let i96 = Int96::from(vec![1, 2, 3]);
1366        assert_eq!(i96.as_bytes(), &[1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0]);
1367
1368        // Test ByteArray
1369        let ba = ByteArray::from(vec![1, 2, 3]);
1370        assert_eq!(ba.as_bytes(), &[1, 2, 3]);
1371
1372        // Test Decimal
1373        let decimal = Decimal::from_i32(123, 5, 2);
1374        assert_eq!(decimal.as_bytes(), &[0, 0, 0, 123]);
1375        let decimal = Decimal::from_i64(123, 5, 2);
1376        assert_eq!(decimal.as_bytes(), &[0, 0, 0, 0, 0, 0, 0, 123]);
1377        let decimal = Decimal::from_bytes(ByteArray::from(vec![1, 2, 3]), 5, 2);
1378        assert_eq!(decimal.as_bytes(), &[1, 2, 3]);
1379    }
1380
1381    #[test]
1382    fn test_int96_from() {
1383        assert_eq!(
1384            Int96::from(vec![1, 12345, 1234567890]).data(),
1385            &[1, 12345, 1234567890]
1386        );
1387    }
1388
1389    #[test]
1390    fn test_byte_array_from() {
1391        assert_eq!(ByteArray::from(b"ABC".to_vec()).data(), b"ABC");
1392        assert_eq!(ByteArray::from("ABC").data(), b"ABC");
1393        assert_eq!(
1394            ByteArray::from(Bytes::from(vec![1u8, 2u8, 3u8, 4u8, 5u8])).data(),
1395            &[1u8, 2u8, 3u8, 4u8, 5u8]
1396        );
1397        let buf = vec![6u8, 7u8, 8u8, 9u8, 10u8];
1398        assert_eq!(ByteArray::from(buf).data(), &[6u8, 7u8, 8u8, 9u8, 10u8]);
1399    }
1400
1401    #[test]
1402    fn test_decimal_partial_eq() {
1403        assert_eq!(Decimal::default(), Decimal::from_i32(0, 0, 0));
1404        assert_eq!(Decimal::from_i32(222, 5, 2), Decimal::from_i32(222, 5, 2));
1405        assert_eq!(
1406            Decimal::from_bytes(ByteArray::from(vec![0, 0, 0, 3]), 5, 2),
1407            Decimal::from_i32(3, 5, 2)
1408        );
1409
1410        assert!(Decimal::from_i32(222, 5, 2) != Decimal::from_i32(111, 5, 2));
1411        assert!(Decimal::from_i32(222, 5, 2) != Decimal::from_i32(222, 6, 2));
1412        assert!(Decimal::from_i32(222, 5, 2) != Decimal::from_i32(222, 5, 3));
1413
1414        assert!(Decimal::from_i64(222, 5, 2) != Decimal::from_i32(222, 5, 2));
1415    }
1416
1417    #[test]
1418    fn test_byte_array_ord() {
1419        let ba1 = ByteArray::from(vec![1, 2, 3]);
1420        let ba11 = ByteArray::from(vec![1, 2, 3]);
1421        let ba2 = ByteArray::from(vec![3, 4]);
1422        let ba3 = ByteArray::from(vec![1, 2, 4]);
1423        let ba4 = ByteArray::from(vec![]);
1424        let ba5 = ByteArray::from(vec![2, 2, 3]);
1425
1426        assert!(ba1 < ba2);
1427        assert!(ba3 > ba1);
1428        assert!(ba1 > ba4);
1429        assert_eq!(ba1, ba11);
1430        assert!(ba5 > ba1);
1431    }
1432}