1use crate::builder::{PrimitiveDictionaryBuilder, StringDictionaryBuilder};
6use crate::cast::AsArray;
7use crate::iterator::ArrayIter;
8use crate::types::*;
9use crate::{
10 Array, ArrayAccessor, ArrayRef, ArrowNativeTypeOp, PrimitiveArray, Scalar, StringArray,
11 make_array,
12};
13use arrow_buffer::bit_util::set_bit;
14use arrow_buffer::buffer::NullBuffer;
15use arrow_buffer::{ArrowNativeType, BooleanBuffer, BooleanBufferBuilder, ScalarBuffer};
16use arrow_data::ArrayData;
17use arrow_schema::{ArrowError, DataType};
18use std::any::Any;
19use std::sync::Arc;
20
21pub type Int8DictionaryArray = DictionaryArray<Int8Type>;
36
37pub type Int16DictionaryArray = DictionaryArray<Int16Type>;
52
53pub type Int32DictionaryArray = DictionaryArray<Int32Type>;
68
69pub type Int64DictionaryArray = DictionaryArray<Int64Type>;
84
85pub type UInt8DictionaryArray = DictionaryArray<UInt8Type>;
100
101pub type UInt16DictionaryArray = DictionaryArray<UInt16Type>;
116
117pub type UInt32DictionaryArray = DictionaryArray<UInt32Type>;
132
133pub type UInt64DictionaryArray = DictionaryArray<UInt64Type>;
148
149pub struct DictionaryArray<K: ArrowDictionaryKeyType> {
231 data_type: DataType,
232
233 keys: PrimitiveArray<K>,
238
239 values: ArrayRef,
241
242 is_ordered: bool,
244}
245
246impl<K: ArrowDictionaryKeyType> Clone for DictionaryArray<K> {
247 fn clone(&self) -> Self {
248 Self {
249 data_type: self.data_type.clone(),
250 keys: self.keys.clone(),
251 values: self.values.clone(),
252 is_ordered: self.is_ordered,
253 }
254 }
255}
256
257impl<K: ArrowDictionaryKeyType> DictionaryArray<K> {
258 pub fn new(keys: PrimitiveArray<K>, values: ArrayRef) -> Self {
266 Self::try_new(keys, values).unwrap()
267 }
268
269 pub fn try_new(keys: PrimitiveArray<K>, values: ArrayRef) -> Result<Self, ArrowError> {
277 let data_type = DataType::Dictionary(
278 Box::new(keys.data_type().clone()),
279 Box::new(values.data_type().clone()),
280 );
281
282 let all_null = keys.null_count() == keys.len();
284
285 if !all_null {
286 let zero = K::Native::usize_as(0);
287 let values_len = values.len();
288
289 if let Some((idx, v)) = keys.values().iter().enumerate().find(|(idx, v)| {
290 (v.is_lt(zero) || v.as_usize() >= values_len) && keys.is_valid(*idx)
291 }) {
292 return Err(ArrowError::InvalidArgumentError(format!(
293 "Invalid dictionary key {v:?} at index {idx}, expected 0 <= key < {values_len}",
294 )));
295 }
296 }
297
298 Ok(Self {
299 data_type,
300 keys,
301 values,
302 is_ordered: false,
303 })
304 }
305
306 pub fn new_scalar<T: Array + 'static>(value: Scalar<T>) -> Scalar<Self> {
308 Scalar::new(Self::new(
309 PrimitiveArray::new(vec![K::Native::usize_as(0)].into(), None),
310 Arc::new(value.into_inner()),
311 ))
312 }
313
314 pub unsafe fn new_unchecked(keys: PrimitiveArray<K>, values: ArrayRef) -> Self {
320 if cfg!(feature = "force_validate") {
321 return Self::new(keys, values);
322 }
323
324 let data_type = DataType::Dictionary(
325 Box::new(keys.data_type().clone()),
326 Box::new(values.data_type().clone()),
327 );
328
329 Self {
330 data_type,
331 keys,
332 values,
333 is_ordered: false,
334 }
335 }
336
337 pub fn into_parts(self) -> (PrimitiveArray<K>, ArrayRef) {
339 (self.keys, self.values)
340 }
341
342 pub fn keys(&self) -> &PrimitiveArray<K> {
344 &self.keys
345 }
346
347 pub fn lookup_key(&self, value: &str) -> Option<K::Native> {
354 let rd_buf: &StringArray = self.values.as_any().downcast_ref::<StringArray>().unwrap();
355
356 (0..rd_buf.len())
357 .position(|i| rd_buf.value(i) == value)
358 .and_then(K::Native::from_usize)
359 }
360
361 pub fn values(&self) -> &ArrayRef {
363 &self.values
364 }
365
366 pub fn value_type(&self) -> DataType {
368 self.values.data_type().clone()
369 }
370
371 pub fn len(&self) -> usize {
373 self.keys.len()
374 }
375
376 pub fn is_empty(&self) -> bool {
378 self.keys.is_empty()
379 }
380
381 pub fn is_ordered(&self) -> bool {
383 self.is_ordered
384 }
385
386 pub fn keys_iter(&self) -> impl Iterator<Item = Option<usize>> + '_ {
388 self.keys.iter().map(|key| key.map(|k| k.as_usize()))
389 }
390
391 pub fn key(&self, i: usize) -> Option<usize> {
397 self.keys.is_valid(i).then(|| self.keys.value(i).as_usize())
398 }
399
400 pub fn slice(&self, offset: usize, length: usize) -> Self {
405 Self {
406 data_type: self.data_type.clone(),
407 keys: self.keys.slice(offset, length),
408 values: self.values.clone(),
409 is_ordered: self.is_ordered,
410 }
411 }
412
413 pub fn downcast_dict<V: 'static>(&self) -> Option<TypedDictionaryArray<'_, K, V>> {
427 let values = self.values.as_any().downcast_ref()?;
428 Some(TypedDictionaryArray {
429 dictionary: self,
430 values,
431 })
432 }
433
434 pub fn with_values(&self, values: ArrayRef) -> Self {
472 assert!(values.len() >= self.values.len());
473 let data_type =
474 DataType::Dictionary(Box::new(K::DATA_TYPE), Box::new(values.data_type().clone()));
475 Self {
476 data_type,
477 keys: self.keys.clone(),
478 values,
479 is_ordered: false,
480 }
481 }
482
483 #[expect(clippy::result_large_err)]
486 pub fn into_primitive_dict_builder<V>(self) -> Result<PrimitiveDictionaryBuilder<K, V>, Self>
487 where
488 V: ArrowPrimitiveType,
489 {
490 if !self.value_type().is_primitive() {
491 return Err(self);
492 }
493
494 let key_array = self.keys().clone();
495 let value_array = self.values().as_primitive::<V>().clone();
496
497 drop(self.keys);
498 drop(self.values);
499
500 let key_builder = key_array.into_builder();
501 let value_builder = value_array.into_builder();
502
503 match (key_builder, value_builder) {
504 (Ok(key_builder), Ok(value_builder)) => Ok(unsafe {
505 PrimitiveDictionaryBuilder::new_from_builders(key_builder, value_builder)
506 }),
507 (Err(key_array), Ok(mut value_builder)) => {
508 Err(Self::try_new(key_array, Arc::new(value_builder.finish())).unwrap())
509 }
510 (Ok(mut key_builder), Err(value_array)) => {
511 Err(Self::try_new(key_builder.finish(), Arc::new(value_array)).unwrap())
512 }
513 (Err(key_array), Err(value_array)) => {
514 Err(Self::try_new(key_array, Arc::new(value_array)).unwrap())
515 }
516 }
517 }
518
519 #[expect(clippy::result_large_err)]
543 pub fn unary_mut<F, V>(self, op: F) -> Result<DictionaryArray<K>, DictionaryArray<K>>
544 where
545 V: ArrowPrimitiveType,
546 F: Fn(V::Native) -> V::Native,
547 {
548 let mut builder: PrimitiveDictionaryBuilder<K, V> = self.into_primitive_dict_builder()?;
549 builder
550 .values_slice_mut()
551 .iter_mut()
552 .for_each(|v| *v = op(*v));
553 Ok(builder.finish())
554 }
555
556 pub fn occupancy(&self) -> BooleanBuffer {
561 let len = self.values.len();
562 let mut builder = BooleanBufferBuilder::new(len);
563 builder.resize(len);
564 let slice = builder.as_slice_mut();
565 match self.keys.nulls().filter(|n| n.null_count() > 0) {
566 Some(n) => {
567 let v = self.keys.values();
568 n.valid_indices()
569 .for_each(|idx| set_bit(slice, v[idx].as_usize()))
570 }
571 None => {
572 let v = self.keys.values();
573 v.iter().for_each(|v| set_bit(slice, v.as_usize()))
574 }
575 }
576 builder.finish()
577 }
578}
579
580impl<T: ArrowDictionaryKeyType> From<ArrayData> for DictionaryArray<T> {
582 fn from(data: ArrayData) -> Self {
583 let (data_type, len, nulls, offset, mut buffers, mut child_data) = data.into_parts();
584
585 assert_eq!(
586 buffers.len(),
587 1,
588 "DictionaryArray data should contain a single buffer only (keys)."
589 );
590 let buffer = buffers.pop().expect("checked above");
591 assert_eq!(
592 child_data.len(),
593 1,
594 "DictionaryArray should contain a single child array (values)."
595 );
596 let cd = child_data.pop().expect("checked above");
597
598 if let DataType::Dictionary(key_data_type, _) = &data_type {
599 assert_eq!(
600 &T::DATA_TYPE,
601 key_data_type.as_ref(),
602 "DictionaryArray's data type must match, expected {} got {}",
603 T::DATA_TYPE,
604 key_data_type
605 );
606
607 let values = make_array(cd);
608
609 let keys = PrimitiveArray::<T>::new(ScalarBuffer::new(buffer, offset, len), nulls);
611
612 Self {
613 data_type,
614 keys,
615 values,
616 is_ordered: false,
617 }
618 } else {
619 panic!("DictionaryArray must have Dictionary data type.")
620 }
621 }
622}
623
624impl<T: ArrowDictionaryKeyType> From<DictionaryArray<T>> for ArrayData {
625 fn from(array: DictionaryArray<T>) -> Self {
626 let builder = array
627 .keys
628 .into_data()
629 .into_builder()
630 .data_type(array.data_type)
631 .child_data(vec![array.values.to_data()]);
632
633 unsafe { builder.build_unchecked() }
634 }
635}
636
637impl<'a, T: ArrowDictionaryKeyType> FromIterator<Option<&'a str>> for DictionaryArray<T> {
654 fn from_iter<I: IntoIterator<Item = Option<&'a str>>>(iter: I) -> Self {
655 let it = iter.into_iter();
656 let (lower, _) = it.size_hint();
657 let mut builder = StringDictionaryBuilder::with_capacity(lower, 256, 1024);
658 builder.extend(it);
659 builder.finish()
660 }
661}
662
663impl<'a, T: ArrowDictionaryKeyType> FromIterator<&'a str> for DictionaryArray<T> {
678 fn from_iter<I: IntoIterator<Item = &'a str>>(iter: I) -> Self {
679 let it = iter.into_iter();
680 let (lower, _) = it.size_hint();
681 let mut builder = StringDictionaryBuilder::with_capacity(lower, 256, 1024);
682 it.for_each(|i| {
683 builder
684 .append(i)
685 .expect("Unable to append a value to a dictionary array.");
686 });
687
688 builder.finish()
689 }
690}
691
692unsafe impl<T: ArrowDictionaryKeyType> Array for DictionaryArray<T> {
694 fn as_any(&self) -> &dyn Any {
695 self
696 }
697
698 fn to_data(&self) -> ArrayData {
699 self.clone().into()
700 }
701
702 fn into_data(self) -> ArrayData {
703 self.into()
704 }
705
706 fn data_type(&self) -> &DataType {
707 &self.data_type
708 }
709
710 fn slice(&self, offset: usize, length: usize) -> ArrayRef {
711 Arc::new(self.slice(offset, length))
712 }
713
714 fn len(&self) -> usize {
715 self.keys.len()
716 }
717
718 fn is_empty(&self) -> bool {
719 self.keys.is_empty()
720 }
721
722 fn shrink_to_fit(&mut self) {
723 self.keys.shrink_to_fit();
724 self.values.shrink_to_fit();
725 }
726
727 fn offset(&self) -> usize {
728 self.keys.offset()
729 }
730
731 fn nulls(&self) -> Option<&NullBuffer> {
732 self.keys.nulls()
733 }
734
735 fn logical_nulls(&self) -> Option<NullBuffer> {
736 match self.values.logical_nulls() {
737 None => self.nulls().cloned(),
738 Some(value_nulls) => {
739 let mut builder = BooleanBufferBuilder::new(self.len());
740 match self.keys.nulls() {
741 Some(n) => builder.append_buffer(n.inner()),
742 None => builder.append_n(self.len(), true),
743 }
744 for (idx, k) in self.keys.values().iter().enumerate() {
745 let k = k.as_usize();
746 if k < value_nulls.len() && value_nulls.is_null(k) {
748 builder.set_bit(idx, false);
749 }
750 }
751 Some(builder.finish().into())
752 }
753 }
754 }
755
756 fn logical_null_count(&self) -> usize {
757 match (self.keys.nulls(), self.values.logical_nulls()) {
758 (None, None) => 0,
759 (Some(key_nulls), None) => key_nulls.null_count(),
760 (None, Some(value_nulls)) => self
761 .keys
762 .values()
763 .iter()
764 .filter(|k| value_nulls.is_null(k.as_usize()))
765 .count(),
766 (Some(key_nulls), Some(value_nulls)) => self
767 .keys
768 .values()
769 .iter()
770 .enumerate()
771 .filter(|(idx, k)| key_nulls.is_null(*idx) || value_nulls.is_null(k.as_usize()))
772 .count(),
773 }
774 }
775
776 fn is_nullable(&self) -> bool {
777 !self.is_empty() && (self.nulls().is_some() || self.values.is_nullable())
778 }
779
780 fn get_buffer_memory_size(&self) -> usize {
781 self.keys.get_buffer_memory_size() + self.values.get_buffer_memory_size()
782 }
783
784 fn get_array_memory_size(&self) -> usize {
785 std::mem::size_of::<Self>()
786 + self.keys.get_buffer_memory_size()
787 + self.values.get_array_memory_size()
788 }
789
790 #[cfg(feature = "pool")]
791 fn claim(&self, pool: &dyn arrow_buffer::MemoryPool) {
792 self.keys.claim(pool);
793 self.values.claim(pool);
794 }
795}
796
797impl<T: ArrowDictionaryKeyType> std::fmt::Debug for DictionaryArray<T> {
798 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
799 writeln!(
800 f,
801 "DictionaryArray {{keys: {:?} values: {:?}}}",
802 self.keys, self.values
803 )
804 }
805}
806
807pub struct TypedDictionaryArray<'a, K: ArrowDictionaryKeyType, V> {
825 dictionary: &'a DictionaryArray<K>,
827 values: &'a V,
829}
830
831impl<K: ArrowDictionaryKeyType, V> Clone for TypedDictionaryArray<'_, K, V> {
833 fn clone(&self) -> Self {
834 *self
835 }
836}
837
838impl<K: ArrowDictionaryKeyType, V> Copy for TypedDictionaryArray<'_, K, V> {}
839
840impl<K: ArrowDictionaryKeyType, V> std::fmt::Debug for TypedDictionaryArray<'_, K, V> {
841 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
842 writeln!(f, "TypedDictionaryArray({:?})", self.dictionary)
843 }
844}
845
846impl<'a, K: ArrowDictionaryKeyType, V> TypedDictionaryArray<'a, K, V> {
847 pub fn keys(&self) -> &'a PrimitiveArray<K> {
849 self.dictionary.keys()
850 }
851
852 pub fn values(&self) -> &'a V {
854 self.values
855 }
856}
857
858unsafe impl<K: ArrowDictionaryKeyType, V: Sync> Array for TypedDictionaryArray<'_, K, V> {
859 fn as_any(&self) -> &dyn Any {
860 self.dictionary
861 }
862
863 fn to_data(&self) -> ArrayData {
864 self.dictionary.to_data()
865 }
866
867 fn into_data(self) -> ArrayData {
868 self.dictionary.into_data()
869 }
870
871 fn data_type(&self) -> &DataType {
872 self.dictionary.data_type()
873 }
874
875 fn slice(&self, offset: usize, length: usize) -> ArrayRef {
876 Arc::new(self.dictionary.slice(offset, length))
877 }
878
879 fn len(&self) -> usize {
880 self.dictionary.len()
881 }
882
883 fn is_empty(&self) -> bool {
884 self.dictionary.is_empty()
885 }
886
887 fn offset(&self) -> usize {
888 self.dictionary.offset()
889 }
890
891 fn nulls(&self) -> Option<&NullBuffer> {
892 self.dictionary.nulls()
893 }
894
895 fn logical_nulls(&self) -> Option<NullBuffer> {
896 self.dictionary.logical_nulls()
897 }
898
899 fn logical_null_count(&self) -> usize {
900 self.dictionary.logical_null_count()
901 }
902
903 fn is_nullable(&self) -> bool {
904 self.dictionary.is_nullable()
905 }
906
907 fn get_buffer_memory_size(&self) -> usize {
908 self.dictionary.get_buffer_memory_size()
909 }
910
911 fn get_array_memory_size(&self) -> usize {
912 self.dictionary.get_array_memory_size()
913 }
914
915 #[cfg(feature = "pool")]
916 fn claim(&self, pool: &dyn arrow_buffer::MemoryPool) {
917 self.dictionary.claim(pool);
918 }
919}
920
921impl<K, V> IntoIterator for TypedDictionaryArray<'_, K, V>
922where
923 K: ArrowDictionaryKeyType,
924 Self: ArrayAccessor,
925{
926 type Item = Option<<Self as ArrayAccessor>::Item>;
927 type IntoIter = ArrayIter<Self>;
928
929 fn into_iter(self) -> Self::IntoIter {
930 ArrayIter::new(self)
931 }
932}
933
934impl<'a, K, V> ArrayAccessor for TypedDictionaryArray<'a, K, V>
935where
936 K: ArrowDictionaryKeyType,
937 V: Sync + Send,
938 &'a V: ArrayAccessor,
939 <&'a V as ArrayAccessor>::Item: Default,
940{
941 type Item = <&'a V as ArrayAccessor>::Item;
942
943 fn value(&self, index: usize) -> Self::Item {
944 assert!(
945 index < self.len(),
946 "Trying to access an element at index {} from a TypedDictionaryArray of length {}",
947 index,
948 self.len()
949 );
950 unsafe { self.value_unchecked(index) }
951 }
952
953 unsafe fn value_unchecked(&self, index: usize) -> Self::Item {
954 let val = unsafe { self.dictionary.keys.value_unchecked(index) };
955 let value_idx = val.as_usize();
956
957 match value_idx < self.values.len() {
960 true => unsafe { self.values.value_unchecked(value_idx) },
961 false => Default::default(),
962 }
963 }
964}
965
966pub trait AnyDictionaryArray: Array {
1011 fn keys(&self) -> &dyn Array;
1013
1014 fn values(&self) -> &ArrayRef;
1016
1017 fn normalized_keys(&self) -> Vec<usize>;
1026
1027 fn with_values(&self, values: ArrayRef) -> ArrayRef;
1031}
1032
1033impl<K: ArrowDictionaryKeyType> AnyDictionaryArray for DictionaryArray<K> {
1034 fn keys(&self) -> &dyn Array {
1035 &self.keys
1036 }
1037
1038 fn values(&self) -> &ArrayRef {
1039 self.values()
1040 }
1041
1042 fn normalized_keys(&self) -> Vec<usize> {
1043 let v_len = self.values().len();
1044 assert_ne!(v_len, 0);
1045 let iter = self.keys().values().iter();
1046 iter.map(|x| x.as_usize().min(v_len - 1)).collect()
1047 }
1048
1049 fn with_values(&self, values: ArrayRef) -> ArrayRef {
1050 Arc::new(self.with_values(values))
1051 }
1052}
1053
1054#[cfg(test)]
1055mod tests {
1056 use super::*;
1057 use crate::cast::as_dictionary_array;
1058 use crate::{Decimal128Array, Int8Array, Int16Array, Int32Array, RunArray, UInt8Array};
1059 use arrow_buffer::{Buffer, ToByteSlice};
1060
1061 #[test]
1062 fn test_dictionary_array() {
1063 let value_data = ArrayData::builder(DataType::Int8)
1065 .len(8)
1066 .add_buffer(Buffer::from(
1067 [10_i8, 11, 12, 13, 14, 15, 16, 17].to_byte_slice(),
1068 ))
1069 .build()
1070 .unwrap();
1071
1072 let keys = Buffer::from([2_i16, 3, 4].to_byte_slice());
1074
1075 let key_type = DataType::Int16;
1077 let value_type = DataType::Int8;
1078 let dict_data_type = DataType::Dictionary(Box::new(key_type), Box::new(value_type));
1079 let dict_data = ArrayData::builder(dict_data_type.clone())
1080 .len(3)
1081 .add_buffer(keys.clone())
1082 .add_child_data(value_data.clone())
1083 .build()
1084 .unwrap();
1085 let dict_array = Int16DictionaryArray::from(dict_data);
1086
1087 let values = dict_array.values();
1088 assert_eq!(value_data, values.to_data());
1089 assert_eq!(DataType::Int8, dict_array.value_type());
1090 assert_eq!(3, dict_array.len());
1091
1092 assert_eq!(0, dict_array.null_count());
1094 assert_eq!(0, dict_array.values().null_count());
1095 assert_eq!(dict_array.keys(), &Int16Array::from(vec![2_i16, 3, 4]));
1096
1097 let dict_data = ArrayData::builder(dict_data_type)
1099 .len(2)
1100 .offset(1)
1101 .add_buffer(keys)
1102 .add_child_data(value_data.clone())
1103 .build()
1104 .unwrap();
1105 let dict_array = Int16DictionaryArray::from(dict_data);
1106
1107 let values = dict_array.values();
1108 assert_eq!(value_data, values.to_data());
1109 assert_eq!(DataType::Int8, dict_array.value_type());
1110 assert_eq!(2, dict_array.len());
1111 assert_eq!(dict_array.keys(), &Int16Array::from(vec![3_i16, 4]));
1112 }
1113
1114 #[test]
1115 fn test_dictionary_builder_append_many() {
1116 let mut builder = PrimitiveDictionaryBuilder::<UInt8Type, UInt32Type>::new();
1117
1118 builder.append(1).unwrap();
1119 builder.append_n(2, 2).unwrap();
1120 builder.append_options(None, 2);
1121 builder.append_options(Some(3), 3);
1122
1123 let array = builder.finish();
1124
1125 let values = array
1126 .values()
1127 .as_primitive::<UInt32Type>()
1128 .iter()
1129 .map(Option::unwrap)
1130 .collect::<Vec<_>>();
1131 assert_eq!(values, &[1, 2, 3]);
1132 let keys = array.keys().iter().collect::<Vec<_>>();
1133 assert_eq!(
1134 keys,
1135 &[
1136 Some(0),
1137 Some(1),
1138 Some(1),
1139 None,
1140 None,
1141 Some(2),
1142 Some(2),
1143 Some(2)
1144 ]
1145 );
1146 }
1147
1148 #[test]
1149 fn test_string_dictionary_builder_append_many() {
1150 let mut builder = StringDictionaryBuilder::<Int8Type>::new();
1151
1152 builder.append("a").unwrap();
1153 builder.append_n("b", 2).unwrap();
1154 builder.append_options(None::<&str>, 2);
1155 builder.append_options(Some("c"), 3);
1156
1157 let array = builder.finish();
1158
1159 let values = array
1160 .values()
1161 .as_string::<i32>()
1162 .iter()
1163 .map(Option::unwrap)
1164 .collect::<Vec<_>>();
1165 assert_eq!(values, &["a", "b", "c"]);
1166 let keys = array.keys().iter().collect::<Vec<_>>();
1167 assert_eq!(
1168 keys,
1169 &[
1170 Some(0),
1171 Some(1),
1172 Some(1),
1173 None,
1174 None,
1175 Some(2),
1176 Some(2),
1177 Some(2)
1178 ]
1179 );
1180 }
1181
1182 #[test]
1183 fn test_dictionary_array_fmt_debug() {
1184 let mut builder = PrimitiveDictionaryBuilder::<UInt8Type, UInt32Type>::with_capacity(3, 2);
1185 builder.append(12345678).unwrap();
1186 builder.append_null();
1187 builder.append(22345678).unwrap();
1188 let array = builder.finish();
1189 assert_eq!(
1190 "DictionaryArray {keys: PrimitiveArray<UInt8>\n[\n 0,\n null,\n 1,\n] values: PrimitiveArray<UInt32>\n[\n 12345678,\n 22345678,\n]}\n",
1191 format!("{array:?}")
1192 );
1193
1194 let mut builder = PrimitiveDictionaryBuilder::<UInt8Type, UInt32Type>::with_capacity(20, 2);
1195 for _ in 0..20 {
1196 builder.append(1).unwrap();
1197 }
1198 let array = builder.finish();
1199 assert_eq!(
1200 "DictionaryArray {keys: PrimitiveArray<UInt8>\n[\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n] values: PrimitiveArray<UInt32>\n[\n 1,\n]}\n",
1201 format!("{array:?}")
1202 );
1203 }
1204
1205 #[test]
1206 fn test_dictionary_array_from_iter() {
1207 let test = vec!["a", "a", "b", "c"];
1208 let array: DictionaryArray<Int8Type> = test
1209 .iter()
1210 .map(|&x| if x == "b" { None } else { Some(x) })
1211 .collect();
1212 assert_eq!(
1213 "DictionaryArray {keys: PrimitiveArray<Int8>\n[\n 0,\n 0,\n null,\n 1,\n] values: StringArray\n[\n \"a\",\n \"c\",\n]}\n",
1214 format!("{array:?}")
1215 );
1216
1217 let array: DictionaryArray<Int8Type> = test.into_iter().collect();
1218 assert_eq!(
1219 "DictionaryArray {keys: PrimitiveArray<Int8>\n[\n 0,\n 0,\n 1,\n 2,\n] values: StringArray\n[\n \"a\",\n \"b\",\n \"c\",\n]}\n",
1220 format!("{array:?}")
1221 );
1222 }
1223
1224 #[test]
1225 fn test_dictionary_array_reverse_lookup_key() {
1226 let test = vec!["a", "a", "b", "c"];
1227 let array: DictionaryArray<Int8Type> = test.into_iter().collect();
1228
1229 assert_eq!(array.lookup_key("c"), Some(2));
1230
1231 let test = vec!["t3", "t3", "t2", "t2", "t1", "t3", "t4", "t1", "t0"];
1233 let array: DictionaryArray<Int8Type> = test.into_iter().collect();
1234
1235 assert_eq!(array.lookup_key("t1"), Some(2));
1236 assert_eq!(array.lookup_key("non-existent"), None);
1237 }
1238
1239 #[test]
1240 fn test_dictionary_keys_as_primitive_array() {
1241 let test = vec!["a", "b", "c", "a"];
1242 let array: DictionaryArray<Int8Type> = test.into_iter().collect();
1243
1244 let keys = array.keys();
1245 assert_eq!(&DataType::Int8, keys.data_type());
1246 assert_eq!(0, keys.null_count());
1247 assert_eq!(&[0, 1, 2, 0], keys.values());
1248 }
1249
1250 #[test]
1251 fn test_dictionary_keys_as_primitive_array_with_null() {
1252 let test = vec![Some("a"), None, Some("b"), None, None, Some("a")];
1253 let array: DictionaryArray<Int32Type> = test.into_iter().collect();
1254
1255 let keys = array.keys();
1256 assert_eq!(&DataType::Int32, keys.data_type());
1257 assert_eq!(3, keys.null_count());
1258
1259 assert!(keys.is_valid(0));
1260 assert!(!keys.is_valid(1));
1261 assert!(keys.is_valid(2));
1262 assert!(!keys.is_valid(3));
1263 assert!(!keys.is_valid(4));
1264 assert!(keys.is_valid(5));
1265
1266 assert_eq!(0, keys.value(0));
1267 assert_eq!(1, keys.value(2));
1268 assert_eq!(0, keys.value(5));
1269 }
1270
1271 #[test]
1272 fn test_dictionary_all_nulls() {
1273 let test = vec![None, None, None];
1274 let array: DictionaryArray<Int32Type> = test.into_iter().collect();
1275 array
1276 .into_data()
1277 .validate_full()
1278 .expect("All null array has valid array data");
1279 }
1280
1281 #[test]
1282 fn test_dictionary_iter() {
1283 let values = Int8Array::from_iter_values([10_i8, 11, 12, 13, 14, 15, 16, 17]);
1285 let keys = Int16Array::from_iter_values([2_i16, 3, 4]);
1286
1287 let dict_array = DictionaryArray::new(keys, Arc::new(values));
1289
1290 let mut key_iter = dict_array.keys_iter();
1291 assert_eq!(2, key_iter.next().unwrap().unwrap());
1292 assert_eq!(3, key_iter.next().unwrap().unwrap());
1293 assert_eq!(4, key_iter.next().unwrap().unwrap());
1294 assert!(key_iter.next().is_none());
1295
1296 let mut iter = dict_array
1297 .values()
1298 .as_any()
1299 .downcast_ref::<Int8Array>()
1300 .unwrap()
1301 .take_iter(dict_array.keys_iter());
1302
1303 assert_eq!(12, iter.next().unwrap().unwrap());
1304 assert_eq!(13, iter.next().unwrap().unwrap());
1305 assert_eq!(14, iter.next().unwrap().unwrap());
1306 assert!(iter.next().is_none());
1307 }
1308
1309 #[test]
1310 fn test_dictionary_iter_with_null() {
1311 let test = vec![Some("a"), None, Some("b"), None, None, Some("a")];
1312 let array: DictionaryArray<Int32Type> = test.into_iter().collect();
1313
1314 let mut iter = array
1315 .values()
1316 .as_any()
1317 .downcast_ref::<StringArray>()
1318 .unwrap()
1319 .take_iter(array.keys_iter());
1320
1321 assert_eq!("a", iter.next().unwrap().unwrap());
1322 assert!(iter.next().unwrap().is_none());
1323 assert_eq!("b", iter.next().unwrap().unwrap());
1324 assert!(iter.next().unwrap().is_none());
1325 assert!(iter.next().unwrap().is_none());
1326 assert_eq!("a", iter.next().unwrap().unwrap());
1327 assert!(iter.next().is_none());
1328 }
1329
1330 #[test]
1331 fn test_dictionary_key() {
1332 let keys = Int8Array::from(vec![Some(2), None, Some(1)]);
1333 let values = StringArray::from(vec!["foo", "bar", "baz", "blarg"]);
1334
1335 let array = DictionaryArray::new(keys, Arc::new(values));
1336 assert_eq!(array.key(0), Some(2));
1337 assert_eq!(array.key(1), None);
1338 assert_eq!(array.key(2), Some(1));
1339 }
1340
1341 #[test]
1342 fn test_try_new() {
1343 let values: StringArray = [Some("foo"), Some("bar"), Some("baz")]
1344 .into_iter()
1345 .collect();
1346 let keys: Int32Array = [Some(0), Some(2), None, Some(1)].into_iter().collect();
1347
1348 let array = DictionaryArray::new(keys, Arc::new(values));
1349 assert_eq!(array.keys().data_type(), &DataType::Int32);
1350 assert_eq!(array.values().data_type(), &DataType::Utf8);
1351
1352 assert_eq!(array.null_count(), 1);
1353 assert_eq!(array.logical_null_count(), 1);
1354
1355 assert!(array.keys().is_valid(0));
1356 assert!(array.keys().is_valid(1));
1357 assert!(array.keys().is_null(2));
1358 assert!(array.keys().is_valid(3));
1359
1360 assert_eq!(array.keys().value(0), 0);
1361 assert_eq!(array.keys().value(1), 2);
1362 assert_eq!(array.keys().value(3), 1);
1363
1364 assert_eq!(
1365 "DictionaryArray {keys: PrimitiveArray<Int32>\n[\n 0,\n 2,\n null,\n 1,\n] values: StringArray\n[\n \"foo\",\n \"bar\",\n \"baz\",\n]}\n",
1366 format!("{array:?}")
1367 );
1368 }
1369
1370 #[test]
1371 #[should_panic(expected = "Invalid dictionary key 3 at index 1, expected 0 <= key < 2")]
1372 fn test_try_new_index_too_large() {
1373 let values: StringArray = [Some("foo"), Some("bar")].into_iter().collect();
1374 let keys: Int32Array = [Some(0), Some(3)].into_iter().collect();
1376 DictionaryArray::new(keys, Arc::new(values));
1377 }
1378
1379 #[test]
1380 #[should_panic(expected = "Invalid dictionary key -100 at index 0, expected 0 <= key < 2")]
1381 fn test_try_new_index_too_small() {
1382 let values: StringArray = [Some("foo"), Some("bar")].into_iter().collect();
1383 let keys: Int32Array = std::iter::once(Some(-100)).collect();
1384 DictionaryArray::new(keys, Arc::new(values));
1385 }
1386
1387 #[test]
1388 #[should_panic(expected = "DictionaryArray's data type must match, expected Int64 got Int32")]
1389 fn test_from_array_data_validation() {
1390 let a = DictionaryArray::<Int32Type>::from_iter(["32"]);
1391 let _ = DictionaryArray::<Int64Type>::from(a.into_data());
1392 }
1393
1394 #[test]
1395 fn test_into_primitive_dict_builder() {
1396 let values = Int32Array::from_iter_values([10_i32, 12, 15]);
1397 let keys = Int8Array::from_iter_values([1_i8, 0, 2, 0]);
1398
1399 let dict_array = DictionaryArray::new(keys, Arc::new(values));
1400
1401 let boxed: ArrayRef = Arc::new(dict_array);
1402 let col: DictionaryArray<Int8Type> = as_dictionary_array(&boxed).clone();
1403
1404 drop(boxed);
1405
1406 let mut builder = col.into_primitive_dict_builder::<Int32Type>().unwrap();
1407
1408 let slice = builder.values_slice_mut();
1409 assert_eq!(slice, &[10, 12, 15]);
1410
1411 slice[0] = 4;
1412 slice[1] = 2;
1413 slice[2] = 1;
1414
1415 let values = Int32Array::from_iter_values([4_i32, 2, 1]);
1416 let keys = Int8Array::from_iter_values([1_i8, 0, 2, 0]);
1417
1418 let expected = DictionaryArray::new(keys, Arc::new(values));
1419
1420 let new_array = builder.finish();
1421 assert_eq!(expected, new_array);
1422 }
1423
1424 #[test]
1425 fn test_into_primitive_dict_builder_cloned_array() {
1426 let values = Int32Array::from_iter_values([10_i32, 12, 15]);
1427 let keys = Int8Array::from_iter_values([1_i8, 0, 2, 0]);
1428
1429 let dict_array = DictionaryArray::new(keys, Arc::new(values));
1430
1431 let boxed: ArrayRef = Arc::new(dict_array);
1432
1433 let col: DictionaryArray<Int8Type> = DictionaryArray::<Int8Type>::from(boxed.to_data());
1434 let err = col.into_primitive_dict_builder::<Int32Type>();
1435
1436 let returned = err.unwrap_err();
1437
1438 let values = Int32Array::from_iter_values([10_i32, 12, 15]);
1439 let keys = Int8Array::from_iter_values([1_i8, 0, 2, 0]);
1440
1441 let expected = DictionaryArray::new(keys, Arc::new(values));
1442 assert_eq!(expected, returned);
1443 }
1444
1445 #[test]
1446 fn test_unary_mut_keeps_value_type() {
1447 let values = || {
1448 Decimal128Array::from(vec![123, 456])
1449 .with_precision_and_scale(5, 2)
1450 .unwrap()
1451 };
1452 let keys = Int8Array::from_iter_values([0, 1, 0]);
1453 let dict = DictionaryArray::new(keys, Arc::new(values()));
1454 let data_type = dict.data_type().clone();
1455 let updated = dict.unary_mut::<_, Decimal128Type>(|x| x + 1).unwrap();
1456 assert_eq!(updated.data_type(), &data_type);
1457
1458 let keys = Int8Array::from_iter_values([0, 1, 0]);
1460 let dict = DictionaryArray::new(keys.clone(), Arc::new(values()));
1461 let returned = dict.unary_mut::<_, Decimal128Type>(|x| x + 1).unwrap_err();
1462 assert_eq!(returned, DictionaryArray::new(keys, Arc::new(values())));
1463 }
1464
1465 #[test]
1466 fn test_occupancy() {
1467 let keys = Int32Array::new((100..200).collect(), None);
1468 let values = Int32Array::from(vec![0; 1024]);
1469 let dict = DictionaryArray::new(keys, Arc::new(values));
1470 for (idx, v) in dict.occupancy().iter().enumerate() {
1471 let expected = (100..200).contains(&idx);
1472 assert_eq!(v, expected, "{idx}");
1473 }
1474
1475 let keys = Int32Array::new(
1476 (0..100).collect(),
1477 Some((0..100).map(|x| x % 4 == 0).collect()),
1478 );
1479 let values = Int32Array::from(vec![0; 1024]);
1480 let dict = DictionaryArray::new(keys, Arc::new(values));
1481 for (idx, v) in dict.occupancy().iter().enumerate() {
1482 let expected = idx % 4 == 0 && idx < 100;
1483 assert_eq!(v, expected, "{idx}");
1484 }
1485 }
1486
1487 #[test]
1488 fn test_iterator_nulls() {
1489 let keys = Int32Array::new(
1490 vec![0, 700, 1, 2].into(),
1491 Some(NullBuffer::from(vec![true, false, true, true])),
1492 );
1493 let values = Int32Array::from(vec![Some(50), None, Some(2)]);
1494 let dict = DictionaryArray::new(keys, Arc::new(values));
1495 let values: Vec<_> = dict
1496 .downcast_dict::<Int32Array>()
1497 .unwrap()
1498 .into_iter()
1499 .collect();
1500 assert_eq!(values, &[Some(50), None, None, Some(2)])
1501 }
1502
1503 #[test]
1504 fn test_logical_nulls() -> Result<(), ArrowError> {
1505 let values = Arc::new(RunArray::try_new(
1506 &Int32Array::from(vec![1, 3, 7]),
1507 &Int32Array::from(vec![Some(1), None, Some(3)]),
1508 )?) as ArrayRef;
1509
1510 assert_eq!(values.null_count(), 0);
1512 assert_eq!(values.logical_null_count(), 2);
1513
1514 let dictionary = DictionaryArray::<Int8Type>::try_new(
1516 Int8Array::from((0..values.len()).map(|i| i as i8).collect::<Vec<_>>()),
1517 Arc::clone(&values),
1518 )?;
1519
1520 assert_eq!(dictionary.null_count(), 0);
1522 assert_eq!(dictionary.logical_null_count(), values.logical_null_count());
1524 assert_eq!(dictionary.logical_nulls(), values.logical_nulls());
1525 assert!(dictionary.is_nullable());
1526
1527 let dictionary = DictionaryArray::<Int8Type>::try_new(
1529 Int8Array::from(
1530 (0..values.len())
1531 .map(|i| i as i8)
1532 .map(|i| if i == 0 { None } else { Some(i) })
1533 .collect::<Vec<_>>(),
1534 ),
1535 Arc::clone(&values),
1536 )?;
1537
1538 assert_eq!(dictionary.null_count(), 1);
1540
1541 assert_eq!(
1543 dictionary.logical_null_count(),
1544 values.logical_null_count() + 1
1545 );
1546 assert!(dictionary.is_nullable());
1547
1548 Ok(())
1549 }
1550
1551 #[test]
1552 fn test_normalized_keys() {
1553 let values = vec![132, 0, 1].into();
1554 let nulls = NullBuffer::from(vec![false, true, true]);
1555 let keys = Int32Array::new(values, Some(nulls));
1556 let dictionary = DictionaryArray::new(keys, Arc::new(Int32Array::new_null(2)));
1557 assert_eq!(&dictionary.normalized_keys(), &[1, 0, 1])
1558 }
1559
1560 #[test]
1561 fn test_all_null_dict() {
1562 let all_null_dict_arr = DictionaryArray::try_new(
1563 UInt8Array::new_null(10),
1564 Arc::new(StringArray::from_iter_values(["a"])),
1565 );
1566 assert!(all_null_dict_arr.is_ok())
1567 }
1568}