1use crate::array::print_long_array;
19use crate::iterator::FixedSizeBinaryIter;
20use crate::{Array, ArrayAccessor, ArrayRef, FixedSizeListArray, Scalar};
21use arrow_buffer::buffer::NullBuffer;
22use arrow_buffer::{ArrowNativeType, Buffer, MutableBuffer, bit_util};
23use arrow_data::{ArrayData, ArrayDataBuilder};
24use arrow_schema::{ArrowError, DataType};
25use std::any::Any;
26use std::sync::Arc;
27
28#[derive(Clone)]
90pub struct FixedSizeBinaryArray {
91 data_type: DataType,
93 value_data: Buffer,
95 nulls: Option<NullBuffer>,
97 len: usize,
99 value_size: usize,
108}
109
110impl FixedSizeBinaryArray {
111 pub fn new(value_length: i32, values: Buffer, nulls: Option<NullBuffer>) -> Self {
118 Self::try_new(value_length, values, nulls).unwrap()
119 }
120
121 pub unsafe fn new_unchecked(
128 value_length: i32,
129 values: Buffer,
130 nulls: Option<NullBuffer>,
131 len: usize,
132 ) -> Self {
133 if cfg!(feature = "force_validate") {
134 return Self::try_new_with_len(value_length, values, nulls, len).unwrap();
135 }
136 Self {
137 data_type: DataType::FixedSizeBinary(value_length),
138 value_data: values,
139 value_size: value_length as usize,
140 nulls,
141 len,
142 }
143 }
144
145 pub fn new_scalar(value: impl AsRef<[u8]>) -> Scalar<Self> {
147 let v = value.as_ref();
148 let value_length =
149 i32::try_from(v.len()).expect("FixedSizeBinaryArray value length exceeds i32");
150 Scalar::new(Self::new(value_length, Buffer::from(v), None))
151 }
152
153 pub fn try_new(
165 value_length: i32,
166 values: Buffer,
167 nulls: Option<NullBuffer>,
168 ) -> Result<Self, ArrowError> {
169 let value_size = value_length.to_usize().ok_or_else(|| {
170 ArrowError::InvalidArgumentError(format!(
171 "Value length cannot be negative, got {value_length}"
172 ))
173 })?;
174
175 let len = match values.len().checked_div(value_size) {
176 Some(len) => len,
177 None => nulls.as_ref().map(|n| n.len()).unwrap_or(0),
178 };
179
180 Self::try_new_with_len(value_length, values, nulls, len)
181 }
182
183 pub fn try_new_with_len(
195 value_length: i32,
196 values: Buffer,
197 nulls: Option<NullBuffer>,
198 len: usize,
199 ) -> Result<Self, ArrowError> {
200 let data_type = DataType::FixedSizeBinary(value_length);
201 let value_size = value_length.to_usize().ok_or_else(|| {
202 ArrowError::InvalidArgumentError(format!(
203 "Value length cannot be negative, got {value_length}"
204 ))
205 })?;
206
207 if let Some(nulls) = &nulls {
208 if nulls.len() != len {
209 return Err(ArrowError::InvalidArgumentError(format!(
210 "Incorrect length of null buffer for FixedSizeBinaryArray, expected {} got {}",
211 len,
212 nulls.len(),
213 )));
214 }
215 }
216
217 if value_size != 0 && values.len() / value_size != len {
218 return Err(ArrowError::InvalidArgumentError(format!(
219 "Incorrect length of values buffer for FixedSizeBinaryArray, expected {} got {}",
220 len,
221 values.len() / value_size,
222 )));
223 }
224
225 if value_size == 0 && !values.is_empty() {
226 return Err(ArrowError::InvalidArgumentError(
227 "Buffer cannot have non-zero length if the value length is zero".to_owned(),
228 ));
229 }
230
231 Ok(Self {
232 data_type,
233 value_data: values,
234 value_size,
235 nulls,
236 len,
237 })
238 }
239
240 pub fn new_null(value_length: i32, len: usize) -> Self {
250 const BITS_IN_A_BYTE: usize = 8;
251 let value_size = value_length.to_usize().unwrap();
252 let capacity_in_bytes = value_size.checked_mul(len).unwrap();
253 let capacity_in_bits = capacity_in_bytes.checked_mul(BITS_IN_A_BYTE).unwrap();
254 Self {
255 data_type: DataType::FixedSizeBinary(value_length),
256 value_data: MutableBuffer::new_null(capacity_in_bits).into(),
257 nulls: Some(NullBuffer::new_null(len)),
258 value_size,
259 len,
260 }
261 }
262
263 pub fn into_parts(self) -> (i32, Buffer, Option<NullBuffer>) {
265 let value_length = self.value_length();
266 (value_length, self.value_data, self.nulls)
267 }
268
269 pub fn value(&self, i: usize) -> &[u8] {
277 let len = self.len();
278 assert!(
279 i < len,
280 "Trying to access an element at index {i} from a FixedSizeBinaryArray of length {len}",
281 );
282 let position = i * self.value_size;
283 unsafe {
284 std::slice::from_raw_parts(self.value_data.as_ptr().add(position), self.value_size)
285 }
286 }
287
288 pub unsafe fn value_unchecked(&self, i: usize) -> &[u8] {
298 let position = i * self.value_size;
299 unsafe {
300 std::slice::from_raw_parts(self.value_data.as_ptr().add(position), self.value_size)
301 }
302 }
303
304 #[deprecated(since = "59.0.0", note = "Use i * value_size() instead")]
312 #[inline]
313 pub fn value_offset(&self, i: usize) -> i32 {
314 self.value_length() * i as i32
315 }
316
317 #[inline]
325 pub fn value_length(&self) -> i32 {
326 self.value_size as i32
328 }
329
330 #[inline]
336 pub fn value_size(&self) -> usize {
337 self.value_size
338 }
339
340 #[inline]
345 pub fn values(&self) -> &Buffer {
346 &self.value_data
347 }
348
349 pub fn value_data(&self) -> &[u8] {
351 self.value_data.as_slice()
352 }
353
354 pub fn slice(&self, offset: usize, len: usize) -> Self {
356 assert!(
357 offset.saturating_add(len) <= self.len,
358 "the length + offset of the sliced FixedSizeBinaryArray cannot exceed the existing length"
359 );
360 let offset_bytes = offset
361 .checked_mul(self.value_size)
362 .expect("offset overflow");
363 let len_bytes = len.checked_mul(self.value_size).expect("offset overflow");
364
365 Self {
366 data_type: self.data_type.clone(),
367 nulls: self.nulls.as_ref().map(|n| n.slice(offset, len)),
368 value_size: self.value_size,
369 value_data: self.value_data.slice_with_length(offset_bytes, len_bytes),
370 len,
371 }
372 }
373
374 #[deprecated(
397 since = "28.0.0",
398 note = "This function will fail if the iterator produces only None values; prefer `try_from_sparse_iter_with_size`"
399 )]
400 pub fn try_from_sparse_iter<T, U>(mut iter: T) -> Result<Self, ArrowError>
401 where
402 T: Iterator<Item = Option<U>>,
403 U: AsRef<[u8]>,
404 {
405 let mut len = 0;
406 let mut value_size = None;
407 let mut byte = 0;
408
409 let iter_size_hint = iter.size_hint().0;
410 let mut null_buf = MutableBuffer::new(bit_util::ceil(iter_size_hint, 8));
411 let mut buffer = MutableBuffer::new(0);
412
413 let mut prepend = 0;
414 iter.try_for_each(|item| -> Result<(), ArrowError> {
415 if byte == 0 {
417 null_buf.push(0u8);
418 byte = 8;
419 }
420 byte -= 1;
421
422 if let Some(slice) = item {
423 let slice = slice.as_ref();
424 if let Some(size) = value_size {
425 if size != slice.len() {
426 return Err(ArrowError::InvalidArgumentError(format!(
427 "Nested array size mismatch: one is {}, and the other is {}",
428 size,
429 slice.len()
430 )));
431 }
432 } else {
433 let len = slice.len();
434 value_size = Some(len);
435 if let Some(capacity) = iter_size_hint.checked_mul(len) {
439 buffer.reserve(capacity);
440 }
441 let prepend_zeros = slice.len().checked_mul(prepend).ok_or_else(|| {
442 ArrowError::InvalidArgumentError(format!(
443 "FixedSizeBinaryArray error: value size {} * prepend {prepend} exceeds usize",
444 slice.len()
445 ))
446 })?;
447 buffer.extend_zeros(prepend_zeros);
448 }
449 bit_util::set_bit(null_buf.as_slice_mut(), len);
450 buffer.extend_from_slice(slice);
451 } else if let Some(size) = value_size {
452 buffer.extend_zeros(size);
453 } else {
454 prepend += 1;
455 }
456
457 len += 1;
458
459 Ok(())
460 })?;
461
462 if len == 0 {
463 return Err(ArrowError::InvalidArgumentError(
464 "Input iterable argument has no data".to_owned(),
465 ));
466 }
467
468 let nulls = NullBuffer::from_unsliced_buffer(null_buf, len);
469
470 let value_size = value_size.unwrap_or(0);
471 let value_length = value_size.try_into().map_err(|_| {
472 ArrowError::InvalidArgumentError(format!(
473 "FixedSizeBinaryArray value length exceeds i32, got {value_size}"
474 ))
475 })?;
476 Ok(Self {
477 data_type: DataType::FixedSizeBinary(value_length),
478 value_data: buffer.into(),
479 nulls,
480 value_size,
481 len,
482 })
483 }
484
485 pub fn try_from_sparse_iter_with_size<T, U>(
510 mut iter: T,
511 value_length: i32,
512 ) -> Result<Self, ArrowError>
513 where
514 T: Iterator<Item = Option<U>>,
515 U: AsRef<[u8]>,
516 {
517 let value_size = value_length.to_usize().ok_or_else(|| {
518 ArrowError::InvalidArgumentError(format!(
519 "Value length cannot be negative, got {value_length}"
520 ))
521 })?;
522 let mut len = 0;
523 let mut byte = 0;
524
525 let iter_size_hint = iter.size_hint().0;
526 let mut null_buf = MutableBuffer::new(bit_util::ceil(iter_size_hint, 8));
527 let capacity = iter_size_hint.checked_mul(value_size).ok_or_else(|| {
528 ArrowError::InvalidArgumentError(format!(
529 "FixedSizeBinaryArray error: value size {value_size} * len hint {iter_size_hint} exceeds usize"
530 ))
531 })?;
532 let mut buffer = MutableBuffer::new(capacity);
533
534 iter.try_for_each(|item| -> Result<(), ArrowError> {
535 if byte == 0 {
537 null_buf.push(0u8);
538 byte = 8;
539 }
540 byte -= 1;
541
542 if let Some(slice) = item {
543 let slice = slice.as_ref();
544 if value_size != slice.len() {
545 return Err(ArrowError::InvalidArgumentError(format!(
546 "Nested array size mismatch: one is {}, and the other is {}",
547 value_length,
548 slice.len()
549 )));
550 }
551
552 bit_util::set_bit(null_buf.as_slice_mut(), len);
553 buffer.extend_from_slice(slice);
554 } else {
555 buffer.extend_zeros(value_size);
556 }
557
558 len += 1;
559
560 Ok(())
561 })?;
562
563 let nulls = NullBuffer::from_unsliced_buffer(null_buf, len);
564
565 Ok(Self {
566 data_type: DataType::FixedSizeBinary(value_length),
567 value_data: buffer.into(),
568 nulls,
569 len,
570 value_size,
571 })
572 }
573
574 pub fn try_from_iter<T, U>(mut iter: T) -> Result<Self, ArrowError>
592 where
593 T: Iterator<Item = U>,
594 U: AsRef<[u8]>,
595 {
596 let mut len = 0;
597 let mut value_size = None;
598 let iter_size_hint = iter.size_hint().0;
599 let mut buffer = MutableBuffer::new(0);
600
601 iter.try_for_each(|item| -> Result<(), ArrowError> {
602 let slice = item.as_ref();
603 if let Some(value_size) = value_size {
604 if value_size != slice.len() {
605 return Err(ArrowError::InvalidArgumentError(format!(
606 "Nested array size mismatch: one is {value_size}, and the other is {}",
607 slice.len()
608 )));
609 }
610 } else {
611 let len = slice.len();
612 value_size = Some(len);
613 if let Some(capacity) = iter_size_hint.checked_mul(len) {
614 buffer.reserve(capacity);
615 }
616 }
617
618 buffer.extend_from_slice(slice);
619
620 len += 1;
621
622 Ok(())
623 })?;
624
625 if len == 0 {
626 return Err(ArrowError::InvalidArgumentError(
627 "Input iterable argument has no data".to_owned(),
628 ));
629 }
630
631 let value_size = value_size.unwrap_or(0);
632 let value_length = value_size.try_into().map_err(|_| {
633 ArrowError::InvalidArgumentError(format!(
634 "FixedSizeBinaryArray value length exceeds i32, got {value_size}"
635 ))
636 })?;
637 Ok(Self {
638 data_type: DataType::FixedSizeBinary(value_length),
639 value_data: buffer.into(),
640 nulls: None,
641 value_size,
642 len,
643 })
644 }
645
646 pub fn iter(&self) -> FixedSizeBinaryIter<'_> {
648 FixedSizeBinaryIter::new(self)
649 }
650}
651
652impl From<ArrayData> for FixedSizeBinaryArray {
653 fn from(data: ArrayData) -> Self {
654 let (data_type, len, nulls, offset, buffers, _child_data) = data.into_parts();
655
656 assert_eq!(
657 buffers.len(),
658 1,
659 "FixedSizeBinaryArray data should contain 1 buffer only (values)"
660 );
661 let value_length = match data_type {
662 DataType::FixedSizeBinary(len) => len,
663 _ => panic!("Expected data type to be FixedSizeBinary"),
664 };
665
666 let value_size = value_length
667 .to_usize()
668 .expect("FixedSizeBinaryArray value length must be non-negative");
669 let value_data = buffers[0].slice_with_length(
670 offset.checked_mul(value_size).expect("offset overflow"),
671 len.checked_mul(value_size).expect("length overflow"),
672 );
673
674 Self {
675 data_type,
676 nulls,
677 len,
678 value_data,
679 value_size,
680 }
681 }
682}
683
684impl From<FixedSizeBinaryArray> for ArrayData {
685 fn from(array: FixedSizeBinaryArray) -> Self {
686 let builder = ArrayDataBuilder::new(array.data_type)
687 .len(array.len)
688 .buffers(vec![array.value_data])
689 .nulls(array.nulls);
690
691 unsafe { builder.build_unchecked() }
692 }
693}
694
695impl From<FixedSizeListArray> for FixedSizeBinaryArray {
697 fn from(v: FixedSizeListArray) -> Self {
698 let value_len = v.value_length();
699 let v = v.into_data();
700 assert_eq!(
701 v.child_data().len(),
702 1,
703 "FixedSizeBinaryArray can only be created from list array of u8 values \
704 (i.e. FixedSizeList<PrimitiveArray<u8>>)."
705 );
706 let child_data = &v.child_data()[0];
707
708 assert_eq!(
709 child_data.child_data().len(),
710 0,
711 "FixedSizeBinaryArray can only be created from list array of u8 values \
712 (i.e. FixedSizeList<PrimitiveArray<u8>>)."
713 );
714 assert_eq!(
715 child_data.data_type(),
716 &DataType::UInt8,
717 "FixedSizeBinaryArray can only be created from FixedSizeList<u8> arrays, mismatched data types."
718 );
719 assert_eq!(
720 child_data.null_count(),
721 0,
722 "The child array cannot contain null values."
723 );
724
725 let builder = ArrayData::builder(DataType::FixedSizeBinary(value_len))
726 .len(v.len())
727 .offset(v.offset())
728 .add_buffer(child_data.buffers()[0].slice(child_data.offset()))
729 .nulls(v.nulls().cloned());
730
731 let data = unsafe { builder.build_unchecked() };
732 Self::from(data)
733 }
734}
735
736impl TryFrom<Vec<Option<&[u8]>>> for FixedSizeBinaryArray {
737 type Error = ArrowError;
738
739 fn try_from(v: Vec<Option<&[u8]>>) -> Result<Self, Self::Error> {
740 #[allow(deprecated)]
741 Self::try_from_sparse_iter(v.into_iter())
742 }
743}
744
745impl TryFrom<Vec<&[u8]>> for FixedSizeBinaryArray {
746 type Error = ArrowError;
747
748 fn try_from(v: Vec<&[u8]>) -> Result<Self, Self::Error> {
749 Self::try_from_iter(v.into_iter())
750 }
751}
752
753impl<const N: usize> TryFrom<Vec<Option<&[u8; N]>>> for FixedSizeBinaryArray {
754 type Error = ArrowError;
755
756 fn try_from(v: Vec<Option<&[u8; N]>>) -> Result<Self, Self::Error> {
757 N.try_into()
758 .map_err(|_| {
759 ArrowError::InvalidArgumentError(format!(
760 "FixedSizeBinaryArray value length exceeds i32, got {N}"
761 ))
762 })
763 .and_then(|x| Self::try_from_sparse_iter_with_size(v.into_iter(), x))
764 }
765}
766
767impl<const N: usize> TryFrom<Vec<&[u8; N]>> for FixedSizeBinaryArray {
768 type Error = ArrowError;
769
770 fn try_from(v: Vec<&[u8; N]>) -> Result<Self, Self::Error> {
771 Self::try_from_iter(v.into_iter())
772 }
773}
774
775impl std::fmt::Debug for FixedSizeBinaryArray {
776 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
777 write!(f, "FixedSizeBinaryArray<{}>\n[\n", self.value_length())?;
778 print_long_array(self, f, |array, index, f| {
779 std::fmt::Debug::fmt(&array.value(index), f)
780 })?;
781 write!(f, "]")
782 }
783}
784
785unsafe impl Array for FixedSizeBinaryArray {
787 fn as_any(&self) -> &dyn Any {
788 self
789 }
790
791 fn to_data(&self) -> ArrayData {
792 self.clone().into()
793 }
794
795 fn into_data(self) -> ArrayData {
796 self.into()
797 }
798
799 fn data_type(&self) -> &DataType {
800 &self.data_type
801 }
802
803 fn slice(&self, offset: usize, length: usize) -> ArrayRef {
804 Arc::new(self.slice(offset, length))
805 }
806
807 fn len(&self) -> usize {
808 self.len
809 }
810
811 fn is_empty(&self) -> bool {
812 self.len == 0
813 }
814
815 fn shrink_to_fit(&mut self) {
816 self.value_data.shrink_to_fit();
817 if let Some(nulls) = &mut self.nulls {
818 nulls.shrink_to_fit();
819 }
820 }
821
822 fn offset(&self) -> usize {
823 0
826 }
827
828 fn nulls(&self) -> Option<&NullBuffer> {
829 self.nulls.as_ref()
830 }
831
832 fn logical_null_count(&self) -> usize {
833 self.null_count()
835 }
836
837 fn get_buffer_memory_size(&self) -> usize {
838 let mut sum = self.value_data.capacity();
839 if let Some(n) = &self.nulls {
840 sum += n.buffer().capacity();
841 }
842 sum
843 }
844
845 fn get_array_memory_size(&self) -> usize {
846 std::mem::size_of::<Self>() + self.get_buffer_memory_size()
847 }
848
849 #[cfg(feature = "pool")]
850 fn claim(&self, pool: &dyn arrow_buffer::MemoryPool) {
851 self.value_data.claim(pool);
852 if let Some(nulls) = &self.nulls {
853 nulls.claim(pool);
854 }
855 }
856}
857
858impl<'a> ArrayAccessor for &'a FixedSizeBinaryArray {
859 type Item = &'a [u8];
860
861 fn value(&self, index: usize) -> Self::Item {
862 FixedSizeBinaryArray::value(self, index)
863 }
864
865 unsafe fn value_unchecked(&self, index: usize) -> Self::Item {
866 unsafe { FixedSizeBinaryArray::value_unchecked(self, index) }
867 }
868}
869
870impl<'a> IntoIterator for &'a FixedSizeBinaryArray {
871 type Item = Option<&'a [u8]>;
872 type IntoIter = FixedSizeBinaryIter<'a>;
873
874 fn into_iter(self) -> Self::IntoIter {
875 FixedSizeBinaryIter::<'a>::new(self)
876 }
877}
878
879#[cfg(test)]
880mod tests {
881 use super::*;
882 use crate::RecordBatch;
883 use arrow_schema::{Field, Schema};
884
885 #[test]
886 fn test_fixed_size_binary_array() {
887 let values = b"hellotherearrow";
888
889 let array_data = ArrayData::builder(DataType::FixedSizeBinary(5))
890 .len(3)
891 .add_buffer(Buffer::from(values))
892 .build()
893 .unwrap();
894 let fixed_size_binary_array = FixedSizeBinaryArray::from(array_data);
895 assert_eq!(3, fixed_size_binary_array.len());
896 assert_eq!(0, fixed_size_binary_array.null_count());
897 assert_eq!(
898 [b'h', b'e', b'l', b'l', b'o'],
899 fixed_size_binary_array.value(0)
900 );
901 assert_eq!(
902 [b't', b'h', b'e', b'r', b'e'],
903 fixed_size_binary_array.value(1)
904 );
905 assert_eq!(
906 [b'a', b'r', b'r', b'o', b'w'],
907 fixed_size_binary_array.value(2)
908 );
909 assert_eq!(5, fixed_size_binary_array.value_length());
910 for i in 0..3 {
911 assert!(fixed_size_binary_array.is_valid(i));
912 assert!(!fixed_size_binary_array.is_null(i));
913 }
914
915 let array_data = ArrayData::builder(DataType::FixedSizeBinary(5))
917 .len(2)
918 .offset(1)
919 .add_buffer(Buffer::from(values))
920 .build()
921 .unwrap();
922 let fixed_size_binary_array = FixedSizeBinaryArray::from(array_data);
923 assert_eq!(
924 [b't', b'h', b'e', b'r', b'e'],
925 fixed_size_binary_array.value(0)
926 );
927 assert_eq!(
928 [b'a', b'r', b'r', b'o', b'w'],
929 fixed_size_binary_array.value(1)
930 );
931 assert_eq!(2, fixed_size_binary_array.len());
932 assert_eq!(5, fixed_size_binary_array.value_length());
933 }
934
935 #[test]
936 fn test_fixed_size_binary_array_from_fixed_size_list_array() {
937 let values = [0_u8, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
938 let values_data = ArrayData::builder(DataType::UInt8)
939 .len(12)
940 .offset(2)
941 .add_buffer(Buffer::from_slice_ref(values))
942 .build()
943 .unwrap();
944 let array_data = unsafe {
946 ArrayData::builder(DataType::FixedSizeList(
947 Arc::new(Field::new_list_field(DataType::UInt8, false)),
948 4,
949 ))
950 .len(2)
951 .offset(1)
952 .add_child_data(values_data)
953 .null_bit_buffer(Some(Buffer::from_slice_ref([0b101])))
954 .build_unchecked()
955 };
956 let list_array = FixedSizeListArray::from(array_data);
957 let binary_array = FixedSizeBinaryArray::from(list_array);
958
959 assert_eq!(2, binary_array.len());
960 assert_eq!(1, binary_array.null_count());
961 assert!(binary_array.is_null(0));
962 assert!(binary_array.is_valid(1));
963 assert_eq!(&[10, 11, 12, 13], binary_array.value(1));
964 }
965
966 #[test]
967 #[should_panic(
968 expected = "FixedSizeBinaryArray can only be created from FixedSizeList<u8> arrays"
969 )]
970 #[cfg(not(feature = "force_validate"))]
973 fn test_fixed_size_binary_array_from_incorrect_fixed_size_list_array() {
974 let values: [u32; 12] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
975 let values_data = ArrayData::builder(DataType::UInt32)
976 .len(12)
977 .add_buffer(Buffer::from_slice_ref(values))
978 .build()
979 .unwrap();
980
981 let array_data = unsafe {
982 ArrayData::builder(DataType::FixedSizeList(
983 Arc::new(Field::new_list_field(DataType::Binary, false)),
984 4,
985 ))
986 .len(3)
987 .add_child_data(values_data)
988 .build_unchecked()
989 };
990 let list_array = FixedSizeListArray::from(array_data);
991 drop(FixedSizeBinaryArray::from(list_array));
992 }
993
994 #[test]
995 #[should_panic(expected = "The child array cannot contain null values.")]
996 fn test_fixed_size_binary_array_from_fixed_size_list_array_with_child_nulls_failed() {
997 let values = [0_u8, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
998 let values_data = ArrayData::builder(DataType::UInt8)
999 .len(12)
1000 .add_buffer(Buffer::from_slice_ref(values))
1001 .null_bit_buffer(Some(Buffer::from_slice_ref([0b101010101010])))
1002 .build()
1003 .unwrap();
1004
1005 let array_data = unsafe {
1006 ArrayData::builder(DataType::FixedSizeList(
1007 Arc::new(Field::new_list_field(DataType::UInt8, false)),
1008 4,
1009 ))
1010 .len(3)
1011 .add_child_data(values_data)
1012 .build_unchecked()
1013 };
1014 let list_array = FixedSizeListArray::from(array_data);
1015 drop(FixedSizeBinaryArray::from(list_array));
1016 }
1017
1018 #[test]
1019 fn test_fixed_size_binary_array_fmt_debug() {
1020 let values = b"hellotherearrow";
1021
1022 let array_data = ArrayData::builder(DataType::FixedSizeBinary(5))
1023 .len(3)
1024 .add_buffer(Buffer::from(values))
1025 .build()
1026 .unwrap();
1027 let arr = FixedSizeBinaryArray::from(array_data);
1028 assert_eq!(
1029 "FixedSizeBinaryArray<5>\n[\n [104, 101, 108, 108, 111],\n [116, 104, 101, 114, 101],\n [97, 114, 114, 111, 119],\n]",
1030 format!("{arr:?}")
1031 );
1032 }
1033
1034 #[test]
1035 fn test_fixed_size_binary_array_from_iter() {
1036 let input_arg = vec![vec![1, 2], vec![3, 4], vec![5, 6]];
1037 let arr = FixedSizeBinaryArray::try_from_iter(input_arg.into_iter()).unwrap();
1038
1039 assert_eq!(2, arr.value_length());
1040 assert_eq!(3, arr.len())
1041 }
1042
1043 #[test]
1044 fn test_all_none_fixed_size_binary_array_from_sparse_iter() {
1045 let none_option: Option<[u8; 32]> = None;
1046 let input_arg = vec![none_option, none_option, none_option];
1047 #[allow(deprecated)]
1048 let arr = FixedSizeBinaryArray::try_from_sparse_iter(input_arg.into_iter()).unwrap();
1049 assert_eq!(0, arr.value_length());
1050 assert_eq!(3, arr.len())
1051 }
1052
1053 #[test]
1054 fn test_fixed_size_binary_array_from_sparse_iter() {
1055 let input_arg = vec![
1056 None,
1057 Some(vec![7, 8]),
1058 Some(vec![9, 10]),
1059 None,
1060 Some(vec![13, 14]),
1061 ];
1062 #[allow(deprecated)]
1063 let arr = FixedSizeBinaryArray::try_from_sparse_iter(input_arg.iter().cloned()).unwrap();
1064 assert_eq!(2, arr.value_length());
1065 assert_eq!(5, arr.len());
1066
1067 let arr =
1068 FixedSizeBinaryArray::try_from_sparse_iter_with_size(input_arg.into_iter(), 2).unwrap();
1069 assert_eq!(2, arr.value_length());
1070 assert_eq!(5, arr.len());
1071 }
1072
1073 #[test]
1074 fn test_fixed_size_binary_array_from_sparse_iter_with_size_all_none() {
1075 let input_arg = vec![None, None, None, None, None] as Vec<Option<Vec<u8>>>;
1076
1077 let arr = FixedSizeBinaryArray::try_from_sparse_iter_with_size(input_arg.into_iter(), 16)
1078 .unwrap();
1079 assert_eq!(16, arr.value_length());
1080 assert_eq!(5, arr.len())
1081 }
1082
1083 #[test]
1084 fn test_fixed_size_binary_array_from_vec() {
1085 let values = vec!["one".as_bytes(), b"two", b"six", b"ten"];
1086 let array = FixedSizeBinaryArray::try_from(values).unwrap();
1087 assert_eq!(array.len(), 4);
1088 assert_eq!(array.null_count(), 0);
1089 assert_eq!(array.logical_null_count(), 0);
1090 assert_eq!(array.value(0), b"one");
1091 assert_eq!(array.value(1), b"two");
1092 assert_eq!(array.value(2), b"six");
1093 assert_eq!(array.value(3), b"ten");
1094 assert!(!array.is_null(0));
1095 assert!(!array.is_null(1));
1096 assert!(!array.is_null(2));
1097 assert!(!array.is_null(3));
1098 }
1099
1100 #[test]
1101 fn test_fixed_size_binary_array_from_vec_incorrect_length() {
1102 let values = vec!["one".as_bytes(), b"two", b"three", b"four"];
1103 assert!(FixedSizeBinaryArray::try_from(values).is_err());
1104 }
1105
1106 #[test]
1107 fn test_fixed_size_binary_array_from_opt_vec() {
1108 let values = vec![
1109 Some("one".as_bytes()),
1110 Some(b"two"),
1111 None,
1112 Some(b"six"),
1113 Some(b"ten"),
1114 ];
1115 let array = FixedSizeBinaryArray::try_from(values).unwrap();
1116 assert_eq!(array.len(), 5);
1117 assert_eq!(array.value(0), b"one");
1118 assert_eq!(array.value(1), b"two");
1119 assert_eq!(array.value(3), b"six");
1120 assert_eq!(array.value(4), b"ten");
1121 assert!(!array.is_null(0));
1122 assert!(!array.is_null(1));
1123 assert!(array.is_null(2));
1124 assert!(!array.is_null(3));
1125 assert!(!array.is_null(4));
1126 }
1127
1128 #[test]
1129 fn test_fixed_size_binary_array_from_opt_vec_incorrect_length() {
1130 let values = vec![
1131 Some("one".as_bytes()),
1132 Some(b"two"),
1133 None,
1134 Some(b"three"),
1135 Some(b"four"),
1136 ];
1137 assert!(FixedSizeBinaryArray::try_from(values).is_err());
1138 }
1139
1140 #[test]
1141 fn fixed_size_binary_array_all_null() {
1142 let data = vec![None] as Vec<Option<String>>;
1143 let array =
1144 FixedSizeBinaryArray::try_from_sparse_iter_with_size(data.into_iter(), 0).unwrap();
1145 array
1146 .into_data()
1147 .validate_full()
1148 .expect("All null array has valid array data");
1149 }
1150
1151 #[test]
1152 fn fixed_size_binary_array_all_null_in_batch_with_schema() {
1154 let schema = Schema::new(vec![Field::new("a", DataType::FixedSizeBinary(2), true)]);
1155
1156 let none_option: Option<[u8; 2]> = None;
1157 let item = FixedSizeBinaryArray::try_from_sparse_iter_with_size(
1158 vec![none_option, none_option, none_option].into_iter(),
1159 2,
1160 )
1161 .unwrap();
1162
1163 RecordBatch::try_new(Arc::new(schema), vec![Arc::new(item)]).unwrap();
1165 }
1166
1167 #[test]
1168 #[should_panic(
1169 expected = "Trying to access an element at index 4 from a FixedSizeBinaryArray of length 3"
1170 )]
1171 fn test_fixed_size_binary_array_get_value_index_out_of_bound() {
1172 let values = vec![Some("one".as_bytes()), Some(b"two"), None];
1173 let array = FixedSizeBinaryArray::try_from(values).unwrap();
1174
1175 array.value(4);
1176 }
1177
1178 #[test]
1179 fn test_constructors() {
1180 let buffer = Buffer::from_vec(vec![0_u8; 10]);
1181 let a = FixedSizeBinaryArray::new(2, buffer.clone(), None);
1182 assert_eq!(a.len(), 5);
1183
1184 let nulls = NullBuffer::new_null(5);
1185 FixedSizeBinaryArray::new(2, buffer.clone(), Some(nulls));
1186
1187 let null_array = FixedSizeBinaryArray::new_null(4, 3);
1188 assert_eq!(null_array.len(), 3);
1189 assert_eq!(null_array.values().len(), 12);
1190
1191 let a = FixedSizeBinaryArray::new(3, buffer.clone(), None);
1192 assert_eq!(a.len(), 3);
1193
1194 let nulls = NullBuffer::new_null(3);
1195 FixedSizeBinaryArray::new(3, buffer.clone(), Some(nulls));
1196
1197 let err = FixedSizeBinaryArray::try_new(-1, buffer.clone(), None).unwrap_err();
1198
1199 assert_eq!(
1200 err.to_string(),
1201 "Invalid argument error: Value length cannot be negative, got -1"
1202 );
1203
1204 let nulls = NullBuffer::new_null(3);
1205 let err = FixedSizeBinaryArray::try_new(2, buffer.clone(), Some(nulls)).unwrap_err();
1206 assert_eq!(
1207 err.to_string(),
1208 "Invalid argument error: Incorrect length of null buffer for FixedSizeBinaryArray, expected 5 got 3"
1209 );
1210
1211 let zero_sized = FixedSizeBinaryArray::new(0, Buffer::default(), None);
1212 assert_eq!(zero_sized.len(), 0);
1213 assert_eq!(zero_sized.null_count(), 0);
1214 assert_eq!(zero_sized.values().len(), 0);
1215
1216 let nulls = NullBuffer::new_null(3);
1217 let zero_sized_with_nulls = FixedSizeBinaryArray::new(0, Buffer::default(), Some(nulls));
1218 assert_eq!(zero_sized_with_nulls.len(), 3);
1219 assert_eq!(zero_sized_with_nulls.null_count(), 3);
1220 assert_eq!(zero_sized_with_nulls.values().len(), 0);
1221
1222 let zero_sized_with_non_empty_buffer_err =
1223 FixedSizeBinaryArray::try_new(0, buffer, None).unwrap_err();
1224 assert_eq!(
1225 zero_sized_with_non_empty_buffer_err.to_string(),
1226 "Invalid argument error: Buffer cannot have non-zero length if the value length is zero"
1227 );
1228 }
1229
1230 #[test]
1231 fn test_try_new_with_len() {
1232 let buffer = Buffer::from_vec(vec![0_u8; 10]);
1233
1234 let a = FixedSizeBinaryArray::try_new_with_len(2, buffer.clone(), None, 5).unwrap();
1235 assert_eq!(a.len(), 5);
1236
1237 let nulls = NullBuffer::new_null(5);
1238 let a = FixedSizeBinaryArray::try_new_with_len(2, buffer, Some(nulls), 5).unwrap();
1239 assert_eq!(a.len(), 5);
1240 assert_eq!(a.null_count(), 5);
1241
1242 let a = FixedSizeBinaryArray::try_new_with_len(2, Buffer::default(), None, 0).unwrap();
1243 assert_eq!(a.len(), 0);
1244 }
1245
1246 #[test]
1247 fn test_try_new_with_len_zero_width() {
1248 let a = FixedSizeBinaryArray::try_new_with_len(0, Buffer::default(), None, 5).unwrap();
1250 assert_eq!(a.len(), 5);
1251 assert_eq!(a.null_count(), 0);
1252 assert_eq!(a.values().len(), 0);
1253
1254 let nulls = NullBuffer::new_null(3);
1255 let a =
1256 FixedSizeBinaryArray::try_new_with_len(0, Buffer::default(), Some(nulls), 3).unwrap();
1257 assert_eq!(a.len(), 3);
1258 assert_eq!(a.null_count(), 3);
1259 }
1260
1261 #[test]
1262 fn test_try_new_with_len_negative_value_length() {
1263 let buffer = Buffer::from_vec(vec![0_u8; 10]);
1264 let err = FixedSizeBinaryArray::try_new_with_len(-1, buffer, None, 5).unwrap_err();
1265 assert_eq!(
1266 err.to_string(),
1267 "Invalid argument error: Value length cannot be negative, got -1"
1268 );
1269 }
1270
1271 #[test]
1272 fn test_try_new_with_len_incorrect_null_buffer_length() {
1273 let buffer = Buffer::from_vec(vec![0_u8; 10]);
1274 let nulls = NullBuffer::new_null(3);
1275 let err = FixedSizeBinaryArray::try_new_with_len(2, buffer, Some(nulls), 5).unwrap_err();
1276 assert_eq!(
1277 err.to_string(),
1278 "Invalid argument error: Incorrect length of null buffer for FixedSizeBinaryArray, expected 5 got 3"
1279 );
1280 }
1281
1282 #[test]
1283 fn test_try_new_with_len_incorrect_values_buffer_length() {
1284 let buffer = Buffer::from_vec(vec![0_u8; 10]);
1285 let err = FixedSizeBinaryArray::try_new_with_len(2, buffer, None, 3).unwrap_err();
1286 assert_eq!(
1287 err.to_string(),
1288 "Invalid argument error: Incorrect length of values buffer for FixedSizeBinaryArray, expected 3 got 5"
1289 );
1290 }
1291
1292 #[test]
1293 fn test_try_new_with_len_zero_width_non_empty_buffer() {
1294 let buffer = Buffer::from_vec(vec![0_u8; 10]);
1295 let err = FixedSizeBinaryArray::try_new_with_len(0, buffer, None, 5).unwrap_err();
1296 assert_eq!(
1297 err.to_string(),
1298 "Invalid argument error: Buffer cannot have non-zero length if the value length is zero"
1299 );
1300 }
1301}