1use crate::array::{get_offsets_from_buffer, print_long_array};
19use crate::builder::MapFieldNames;
20use crate::iterator::MapArrayIter;
21use crate::{Array, ArrayAccessor, ArrayRef, ListArray, StringArray, StructArray, make_array};
22use arrow_buffer::{ArrowNativeType, Buffer, NullBuffer, OffsetBuffer, ToByteSlice};
23use arrow_data::{ArrayData, ArrayDataBuilder};
24use arrow_schema::{ArrowError, DataType, Field, FieldRef, Fields};
25use std::any::Any;
26use std::sync::Arc;
27
28#[derive(Clone)]
39pub struct MapArray {
40 data_type: DataType,
41 nulls: Option<NullBuffer>,
42 entries: StructArray,
44 value_offsets: OffsetBuffer<i32>,
46}
47
48impl MapArray {
49 pub fn try_new(
66 field: FieldRef,
67 offsets: OffsetBuffer<i32>,
68 entries: StructArray,
69 nulls: Option<NullBuffer>,
70 ordered: bool,
71 ) -> Result<Self, ArrowError> {
72 let len = offsets.len() - 1; let end_offset = offsets.last().unwrap().as_usize();
74 if end_offset > entries.len() {
77 return Err(ArrowError::InvalidArgumentError(format!(
78 "Max offset of {end_offset} exceeds length of entries {}",
79 entries.len()
80 )));
81 }
82
83 if let Some(n) = nulls.as_ref()
84 && n.len() != len
85 {
86 return Err(ArrowError::InvalidArgumentError(format!(
87 "Incorrect length of null buffer for MapArray, expected {len} got {}",
88 n.len(),
89 )));
90 }
91 if field.is_nullable() || entries.null_count() != 0 {
92 return Err(ArrowError::InvalidArgumentError(
93 "MapArray entries cannot contain nulls".to_string(),
94 ));
95 }
96
97 if field.data_type() != entries.data_type() {
98 return Err(ArrowError::InvalidArgumentError(format!(
99 "MapArray expected data type {} got {} for {:?}",
100 field.data_type(),
101 entries.data_type(),
102 field.name()
103 )));
104 }
105
106 if entries.columns().len() != 2 {
107 return Err(ArrowError::InvalidArgumentError(format!(
108 "MapArray entries must contain two children, got {}",
109 entries.columns().len()
110 )));
111 }
112
113 if entries.fields()[0].is_nullable() {
116 return Err(ArrowError::InvalidArgumentError(
117 "MapArray keys field cannot be nullable".to_string(),
118 ));
119 }
120 Ok(Self {
124 data_type: DataType::Map(field, ordered),
125 nulls,
126 entries,
127 value_offsets: offsets,
128 })
129 }
130
131 pub fn new(
140 field: FieldRef,
141 offsets: OffsetBuffer<i32>,
142 entries: StructArray,
143 nulls: Option<NullBuffer>,
144 ordered: bool,
145 ) -> Self {
146 Self::try_new(field, offsets, entries, nulls, ordered).unwrap()
147 }
148
149 pub unsafe fn new_unchecked(
157 field: FieldRef,
158 offsets: OffsetBuffer<i32>,
159 entries: StructArray,
160 nulls: Option<NullBuffer>,
161 ordered: bool,
162 ) -> Self {
163 if cfg!(feature = "force_validate") {
164 return Self::new(field, offsets, entries, nulls, ordered);
165 }
166 Self {
167 data_type: DataType::Map(field, ordered),
168 nulls,
169 entries,
170 value_offsets: offsets,
171 }
172 }
173
174 pub fn into_parts(
176 self,
177 ) -> (
178 FieldRef,
179 OffsetBuffer<i32>,
180 StructArray,
181 Option<NullBuffer>,
182 bool,
183 ) {
184 let (f, ordered) = match self.data_type {
185 DataType::Map(f, ordered) => (f, ordered),
186 _ => unreachable!(),
187 };
188 (f, self.value_offsets, self.entries, self.nulls, ordered)
189 }
190
191 pub fn entries_field(&self) -> &FieldRef {
196 match &self.data_type {
197 DataType::Map(f, _) => f,
198 _ => unreachable!(),
199 }
200 }
201
202 pub fn ordered(&self) -> bool {
204 match &self.data_type {
205 DataType::Map(_, ordered) => *ordered,
206 _ => unreachable!(),
207 }
208 }
209
210 #[inline]
215 pub fn offsets(&self) -> &OffsetBuffer<i32> {
216 &self.value_offsets
217 }
218
219 pub fn keys(&self) -> &ArrayRef {
221 self.entries.column(0)
222 }
223
224 pub fn values(&self) -> &ArrayRef {
226 self.entries.column(1)
227 }
228
229 pub fn entries(&self) -> &StructArray {
231 &self.entries
232 }
233
234 pub fn entries_fields(&self) -> (&Field, &Field) {
236 (
237 self.entries.field(0).as_ref(),
238 self.entries.field(1).as_ref(),
239 )
240 }
241
242 pub fn key_type(&self) -> &DataType {
244 self.keys().data_type()
245 }
246
247 pub fn value_type(&self) -> &DataType {
249 self.values().data_type()
250 }
251
252 pub unsafe fn value_unchecked(&self, i: usize) -> StructArray {
260 let end = *unsafe { self.value_offsets().get_unchecked(i + 1) };
261 let start = *unsafe { self.value_offsets().get_unchecked(i) };
262 self.entries
263 .slice(start.to_usize().unwrap(), (end - start).to_usize().unwrap())
264 }
265
266 pub fn value(&self, i: usize) -> StructArray {
276 let end = self.value_offsets()[i + 1] as usize;
277 let start = self.value_offsets()[i] as usize;
278 self.entries.slice(start, end - start)
279 }
280
281 #[inline]
283 pub fn value_offsets(&self) -> &[i32] {
284 &self.value_offsets
285 }
286
287 #[inline]
292 pub fn value_length(&self, i: usize) -> i32 {
293 let offsets = self.value_offsets();
294 offsets[i + 1] - offsets[i]
295 }
296
297 pub fn slice(&self, offset: usize, length: usize) -> Self {
302 Self {
303 data_type: self.data_type.clone(),
304 nulls: self.nulls.as_ref().map(|n| n.slice(offset, length)),
305 entries: self.entries.clone(),
306 value_offsets: self.value_offsets.slice(offset, length),
307 }
308 }
309
310 pub fn iter(&self) -> MapArrayIter<'_> {
312 MapArrayIter::new(self)
313 }
314}
315
316impl From<ArrayData> for MapArray {
317 fn from(data: ArrayData) -> Self {
318 Self::try_new_from_array_data(data)
319 .expect("Expected infallible creation of MapArray from ArrayData failed")
320 }
321}
322
323impl From<MapArray> for ArrayData {
324 fn from(array: MapArray) -> Self {
325 let len = array.len();
326 let builder = ArrayDataBuilder::new(array.data_type)
327 .len(len)
328 .nulls(array.nulls)
329 .buffers(vec![array.value_offsets.into_inner().into_inner()])
330 .child_data(vec![array.entries.to_data()]);
331
332 unsafe { builder.build_unchecked() }
333 }
334}
335
336type Entries<Key, Value> = Vec<(Key, Value)>;
337
338impl MapArray {
339 fn try_new_from_array_data(data: ArrayData) -> Result<Self, ArrowError> {
340 let (data_type, len, nulls, offset, mut buffers, mut child_data) = data.into_parts();
341
342 if !matches!(data_type, DataType::Map(_, _)) {
343 return Err(ArrowError::InvalidArgumentError(format!(
344 "MapArray expected ArrayData with DataType::Map got {data_type}",
345 )));
346 }
347
348 if buffers.len() != 1 {
349 return Err(ArrowError::InvalidArgumentError(format!(
350 "MapArray data should contain a single buffer only (value offsets), had {}",
351 buffers.len(),
352 )));
353 }
354 let buffer = buffers.pop().expect("checked above");
355
356 if child_data.len() != 1 {
357 return Err(ArrowError::InvalidArgumentError(format!(
358 "MapArray should contain a single child array (values array), had {}",
359 child_data.len()
360 )));
361 }
362 let entries = child_data.pop().expect("checked above");
363
364 if let DataType::Struct(fields) = entries.data_type() {
365 if fields.len() != 2 {
366 return Err(ArrowError::InvalidArgumentError(format!(
367 "MapArray should contain a struct array with 2 fields, have {} fields",
368 fields.len()
369 )));
370 }
371 } else {
372 return Err(ArrowError::InvalidArgumentError(format!(
373 "MapArray should contain a struct array child, found {:?}",
374 entries.data_type()
375 )));
376 }
377 let entries = entries.into();
378
379 let value_offsets = unsafe { get_offsets_from_buffer(buffer, offset, len) };
382
383 Ok(Self {
384 data_type,
385 nulls,
386 entries,
387 value_offsets,
388 })
389 }
390
391 pub fn new_from_strings<'a>(
393 keys: impl Iterator<Item = &'a str>,
394 values: &dyn Array,
395 entry_offsets: &[u32],
396 ) -> Result<Self, ArrowError> {
397 let entry_offsets_buffer = Buffer::from(entry_offsets.to_byte_slice());
398 let keys_data = StringArray::from_iter_values(keys);
399
400 let keys_field = Arc::new(Field::new(
401 Field::MAP_KEY_FIELD_DEFAULT_NAME,
402 DataType::Utf8,
403 false,
404 ));
405 let values_field = Arc::new(Field::new(
406 Field::MAP_VALUE_FIELD_DEFAULT_NAME,
407 values.data_type().clone(),
408 values.null_count() > 0,
409 ));
410
411 let entry_struct = StructArray::from(vec![
412 (keys_field, Arc::new(keys_data) as ArrayRef),
413 (values_field, make_array(values.to_data())),
414 ]);
415
416 let map_data_type = DataType::Map(
417 Arc::new(Field::new(
418 Field::MAP_ENTRIES_FIELD_DEFAULT_NAME,
419 entry_struct.data_type().clone(),
420 false,
421 )),
422 false,
423 );
424 let map_data = ArrayData::builder(map_data_type)
425 .len(entry_offsets.len() - 1)
426 .add_buffer(entry_offsets_buffer)
427 .add_child_data(entry_struct.into_data())
428 .build()?;
429
430 Ok(MapArray::from(map_data))
431 }
432
433 pub fn from_vec_of_maps<KeyArray, ValueArray, K, V>(
465 input: Vec<Option<Entries<K, Option<V>>>>,
466 ordered: bool,
467 ) -> Self
468 where
469 KeyArray: Array + 'static,
470 ValueArray: Array + 'static,
471 Vec<K>: Into<KeyArray>,
472 Vec<Option<V>>: Into<ValueArray>,
473 {
474 let offsets = OffsetBuffer::<i32>::from_lengths(
475 input.iter().map(|v| v.as_ref().map_or(0, |m| m.len())),
476 );
477 let nulls = NullBuffer::from_iter(input.iter().map(|v| v.is_some()));
478 let nulls = Some(nulls).filter(|b| b.null_count() > 0);
479
480 let (keys, values): (Vec<K>, Vec<Option<V>>) = input
481 .into_iter()
482 .flatten()
483 .flat_map(|m| m.into_iter())
484 .unzip();
485
486 let keys_array: ArrayRef = Arc::new(<Vec<K> as Into<KeyArray>>::into(keys));
487 let values_array: ArrayRef = Arc::new(<Vec<Option<V>> as Into<ValueArray>>::into(values));
488
489 let field_names = MapFieldNames::default();
490
491 let entries = StructArray::new(
492 Fields::from(vec![
493 Field::new(field_names.key, keys_array.data_type().clone(), false),
494 Field::new(
495 field_names.value,
496 values_array.data_type().clone(),
497 values_array.is_nullable(),
498 ),
499 ]),
500 vec![keys_array, values_array],
501 None,
502 );
503
504 MapArray::new(
505 Arc::new(Field::new(
506 field_names.entry,
507 entries.data_type().clone(),
508 false,
509 )),
510 offsets,
511 entries,
512 nulls,
513 ordered,
514 )
515 }
516}
517
518unsafe impl Array for MapArray {
520 fn as_any(&self) -> &dyn Any {
521 self
522 }
523
524 fn to_data(&self) -> ArrayData {
525 self.clone().into_data()
526 }
527
528 fn into_data(self) -> ArrayData {
529 self.into()
530 }
531
532 fn data_type(&self) -> &DataType {
533 &self.data_type
534 }
535
536 fn slice(&self, offset: usize, length: usize) -> ArrayRef {
537 Arc::new(self.slice(offset, length))
538 }
539
540 fn len(&self) -> usize {
541 self.value_offsets.len() - 1
542 }
543
544 fn is_empty(&self) -> bool {
545 self.value_offsets.len() <= 1
546 }
547
548 fn shrink_to_fit(&mut self) {
549 if let Some(nulls) = &mut self.nulls {
550 nulls.shrink_to_fit();
551 }
552 self.entries.shrink_to_fit();
553 self.value_offsets.shrink_to_fit();
554 }
555
556 fn offset(&self) -> usize {
557 0
558 }
559
560 fn nulls(&self) -> Option<&NullBuffer> {
561 self.nulls.as_ref()
562 }
563
564 fn logical_null_count(&self) -> usize {
565 self.null_count()
567 }
568
569 fn get_buffer_memory_size(&self) -> usize {
570 let mut size = self.entries.get_buffer_memory_size();
571 size += self.value_offsets.inner().inner().capacity();
572 if let Some(n) = self.nulls.as_ref() {
573 size += n.buffer().capacity();
574 }
575 size
576 }
577
578 fn get_array_memory_size(&self) -> usize {
579 let mut size = std::mem::size_of::<Self>() + self.entries.get_array_memory_size();
580 size += self.value_offsets.inner().inner().capacity();
581 if let Some(n) = self.nulls.as_ref() {
582 size += n.buffer().capacity();
583 }
584 size
585 }
586
587 #[cfg(feature = "pool")]
588 fn claim(&self, pool: &dyn arrow_buffer::MemoryPool) {
589 self.value_offsets.claim(pool);
590 self.entries.claim(pool);
591 if let Some(nulls) = &self.nulls {
592 nulls.claim(pool);
593 }
594 }
595}
596
597impl ArrayAccessor for &MapArray {
598 type Item = StructArray;
599
600 fn value(&self, index: usize) -> Self::Item {
601 MapArray::value(self, index)
602 }
603
604 unsafe fn value_unchecked(&self, index: usize) -> Self::Item {
605 MapArray::value(self, index)
606 }
607}
608
609impl std::fmt::Debug for MapArray {
610 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
611 write!(f, "MapArray\n[\n")?;
612 print_long_array(self, f, |array, index, f| {
613 std::fmt::Debug::fmt(&array.value(index), f)
614 })?;
615 write!(f, "]")
616 }
617}
618
619impl From<MapArray> for ListArray {
620 fn from(value: MapArray) -> Self {
621 let field = match value.data_type() {
622 DataType::Map(field, _) => field,
623 _ => unreachable!("This should be a map type."),
624 };
625 let data_type = DataType::List(field.clone());
626 let builder = value.into_data().into_builder().data_type(data_type);
627 let array_data = unsafe { builder.build_unchecked() };
628
629 ListArray::from(array_data)
630 }
631}
632
633#[cfg(test)]
634mod tests {
635 use crate::builder::{Int32Builder, MapBuilder, StringBuilder};
636 use crate::cast::AsArray;
637 use crate::types::UInt32Type;
638 use crate::{Int32Array, UInt32Array};
639 use arrow_schema::Fields;
640
641 use super::*;
642
643 fn create_from_buffers() -> MapArray {
644 let keys_data = ArrayData::builder(DataType::Int32)
646 .len(8)
647 .add_buffer(Buffer::from([0, 1, 2, 3, 4, 5, 6, 7].to_byte_slice()))
648 .build()
649 .unwrap();
650 let values_data = ArrayData::builder(DataType::UInt32)
651 .len(8)
652 .add_buffer(Buffer::from(
653 [0u32, 10, 20, 30, 40, 50, 60, 70].to_byte_slice(),
654 ))
655 .build()
656 .unwrap();
657
658 let entry_offsets = Buffer::from([0, 3, 6, 8].to_byte_slice());
661
662 let keys = Arc::new(Field::new(
663 Field::MAP_KEY_FIELD_DEFAULT_NAME,
664 DataType::Int32,
665 false,
666 ));
667 let values = Arc::new(Field::new(
668 Field::MAP_VALUE_FIELD_DEFAULT_NAME,
669 DataType::UInt32,
670 false,
671 ));
672 let entry_struct = StructArray::from(vec![
673 (keys, make_array(keys_data)),
674 (values, make_array(values_data)),
675 ]);
676
677 let map_data_type = DataType::Map(
679 Arc::new(Field::new(
680 Field::MAP_ENTRIES_FIELD_DEFAULT_NAME,
681 entry_struct.data_type().clone(),
682 false,
683 )),
684 false,
685 );
686 let map_data = ArrayData::builder(map_data_type)
687 .len(3)
688 .add_buffer(entry_offsets)
689 .add_child_data(entry_struct.into_data())
690 .build()
691 .unwrap();
692 MapArray::from(map_data)
693 }
694
695 #[test]
696 fn test_map_array() {
697 let key_data = ArrayData::builder(DataType::Int32)
699 .len(8)
700 .add_buffer(Buffer::from([0, 1, 2, 3, 4, 5, 6, 7].to_byte_slice()))
701 .build()
702 .unwrap();
703 let value_data = ArrayData::builder(DataType::UInt32)
704 .len(8)
705 .add_buffer(Buffer::from(
706 [0u32, 10, 20, 0, 40, 0, 60, 70].to_byte_slice(),
707 ))
708 .null_bit_buffer(Some(Buffer::from(&[0b11010110])))
709 .build()
710 .unwrap();
711
712 let entry_offsets = Buffer::from([0, 3, 6, 8].to_byte_slice());
715
716 let keys_field = Arc::new(Field::new(
717 Field::MAP_KEY_FIELD_DEFAULT_NAME,
718 DataType::Int32,
719 false,
720 ));
721 let values_field = Arc::new(Field::new(
722 Field::MAP_VALUE_FIELD_DEFAULT_NAME,
723 DataType::UInt32,
724 true,
725 ));
726 let entry_struct = StructArray::from(vec![
727 (keys_field.clone(), make_array(key_data)),
728 (values_field.clone(), make_array(value_data.clone())),
729 ]);
730
731 let map_data_type = DataType::Map(
733 Arc::new(Field::new(
734 Field::MAP_ENTRIES_FIELD_DEFAULT_NAME,
735 entry_struct.data_type().clone(),
736 false,
737 )),
738 false,
739 );
740 let map_data = ArrayData::builder(map_data_type)
741 .len(3)
742 .add_buffer(entry_offsets)
743 .add_child_data(entry_struct.into_data())
744 .build()
745 .unwrap();
746 let map_array = MapArray::from(map_data);
747
748 assert_eq!(value_data, map_array.values().to_data());
749 assert_eq!(&DataType::UInt32, map_array.value_type());
750 assert_eq!(3, map_array.len());
751 assert_eq!(0, map_array.null_count());
752 assert_eq!(6, map_array.value_offsets()[2]);
753 assert_eq!(2, map_array.value_length(2));
754
755 let key_array = Arc::new(Int32Array::from(vec![0, 1, 2])) as ArrayRef;
756 let value_array =
757 Arc::new(UInt32Array::from(vec![None, Some(10u32), Some(20)])) as ArrayRef;
758 let struct_array = StructArray::from(vec![
759 (keys_field.clone(), key_array),
760 (values_field.clone(), value_array),
761 ]);
762 assert_eq!(
763 struct_array,
764 StructArray::from(map_array.value(0).into_data())
765 );
766 assert_eq!(
767 &struct_array,
768 unsafe { map_array.value_unchecked(0) }
769 .as_any()
770 .downcast_ref::<StructArray>()
771 .unwrap()
772 );
773 for i in 0..3 {
774 assert!(map_array.is_valid(i));
775 assert!(!map_array.is_null(i));
776 }
777
778 let map_array = map_array.slice(1, 2);
780
781 assert_eq!(value_data, map_array.values().to_data());
782 assert_eq!(&DataType::UInt32, map_array.value_type());
783 assert_eq!(2, map_array.len());
784 assert_eq!(0, map_array.null_count());
785 assert_eq!(6, map_array.value_offsets()[1]);
786 assert_eq!(2, map_array.value_length(1));
787
788 let key_array = Arc::new(Int32Array::from(vec![3, 4, 5])) as ArrayRef;
789 let value_array = Arc::new(UInt32Array::from(vec![None, Some(40), None])) as ArrayRef;
790 let struct_array =
791 StructArray::from(vec![(keys_field, key_array), (values_field, value_array)]);
792 assert_eq!(
793 &struct_array,
794 map_array
795 .value(0)
796 .as_any()
797 .downcast_ref::<StructArray>()
798 .unwrap()
799 );
800 assert_eq!(
801 &struct_array,
802 unsafe { map_array.value_unchecked(0) }
803 .as_any()
804 .downcast_ref::<StructArray>()
805 .unwrap()
806 );
807 }
808
809 #[test]
810 #[ignore = "Test fails because slice of <list<struct>> is still buggy"]
811 fn test_map_array_slice() {
812 let map_array = create_from_buffers();
813
814 let sliced_array = map_array.slice(1, 2);
815 assert_eq!(2, sliced_array.len());
816 assert_eq!(1, sliced_array.offset());
817 let sliced_array_data = sliced_array.to_data();
818 for array_data in sliced_array_data.child_data() {
819 assert_eq!(array_data.offset(), 1);
820 }
821
822 let sliced_map_array = sliced_array.as_any().downcast_ref::<MapArray>().unwrap();
824 assert_eq!(3, sliced_map_array.value_offsets()[0]);
825 assert_eq!(3, sliced_map_array.value_length(0));
826 assert_eq!(6, sliced_map_array.value_offsets()[1]);
827 assert_eq!(2, sliced_map_array.value_length(1));
828
829 let keys_data = ArrayData::builder(DataType::Int32)
831 .len(5)
832 .add_buffer(Buffer::from([3, 4, 5, 6, 7].to_byte_slice()))
833 .build()
834 .unwrap();
835 let values_data = ArrayData::builder(DataType::UInt32)
836 .len(5)
837 .add_buffer(Buffer::from([30u32, 40, 50, 60, 70].to_byte_slice()))
838 .build()
839 .unwrap();
840
841 let entry_offsets = Buffer::from([0, 3, 5].to_byte_slice());
844
845 let keys = Arc::new(Field::new(
846 Field::MAP_KEY_FIELD_DEFAULT_NAME,
847 DataType::Int32,
848 false,
849 ));
850 let values = Arc::new(Field::new(
851 Field::MAP_VALUE_FIELD_DEFAULT_NAME,
852 DataType::UInt32,
853 false,
854 ));
855 let entry_struct = StructArray::from(vec![
856 (keys, make_array(keys_data)),
857 (values, make_array(values_data)),
858 ]);
859
860 let map_data_type = DataType::Map(
862 Arc::new(Field::new(
863 Field::MAP_ENTRIES_FIELD_DEFAULT_NAME,
864 entry_struct.data_type().clone(),
865 false,
866 )),
867 false,
868 );
869 let expected_map_data = ArrayData::builder(map_data_type)
870 .len(2)
871 .add_buffer(entry_offsets)
872 .add_child_data(entry_struct.into_data())
873 .build()
874 .unwrap();
875 let expected_map_array = MapArray::from(expected_map_data);
876
877 assert_eq!(&expected_map_array, sliced_map_array)
878 }
879
880 #[test]
881 #[should_panic(expected = "index out of bounds: the len is ")]
882 fn test_map_array_index_out_of_bound() {
883 let map_array = create_from_buffers();
884
885 map_array.value(map_array.len());
886 }
887
888 #[test]
889 #[should_panic(expected = "MapArray expected ArrayData with DataType::Map got Dictionary")]
890 fn test_from_array_data_validation() {
891 let struct_t = DataType::Struct(Fields::from(vec![
894 Field::new(Field::MAP_KEY_FIELD_DEFAULT_NAME, DataType::Int32, true),
895 Field::new(Field::MAP_VALUE_FIELD_DEFAULT_NAME, DataType::UInt32, true),
896 ]));
897 let dict_t = DataType::Dictionary(Box::new(DataType::Int32), Box::new(struct_t));
898 let _ = MapArray::from(ArrayData::new_empty(&dict_t));
899 }
900
901 #[test]
902 fn test_new_from_strings() {
903 let keys = vec!["a", "b", "c", "d", "e", "f", "g", "h"];
904 let values_data = UInt32Array::from(vec![0u32, 10, 20, 30, 40, 50, 60, 70]);
905
906 let entry_offsets = [0, 3, 6, 8];
909
910 let map_array =
911 MapArray::new_from_strings(keys.clone().into_iter(), &values_data, &entry_offsets)
912 .unwrap();
913
914 assert_eq!(
915 &values_data,
916 map_array.values().as_primitive::<UInt32Type>()
917 );
918 assert_eq!(&DataType::UInt32, map_array.value_type());
919 assert_eq!(3, map_array.len());
920 assert_eq!(0, map_array.null_count());
921 assert_eq!(6, map_array.value_offsets()[2]);
922 assert_eq!(2, map_array.value_length(2));
923
924 let key_array = Arc::new(StringArray::from(vec!["a", "b", "c"])) as ArrayRef;
925 let value_array = Arc::new(UInt32Array::from(vec![0u32, 10, 20])) as ArrayRef;
926 let keys_field = Arc::new(Field::new(
927 Field::MAP_KEY_FIELD_DEFAULT_NAME,
928 DataType::Utf8,
929 false,
930 ));
931 let values_field = Arc::new(Field::new(
932 Field::MAP_VALUE_FIELD_DEFAULT_NAME,
933 DataType::UInt32,
934 false,
935 ));
936 let struct_array =
937 StructArray::from(vec![(keys_field, key_array), (values_field, value_array)]);
938 assert_eq!(
939 struct_array,
940 StructArray::from(map_array.value(0).into_data())
941 );
942 assert_eq!(
943 &struct_array,
944 unsafe { map_array.value_unchecked(0) }
945 .as_any()
946 .downcast_ref::<StructArray>()
947 .unwrap()
948 );
949 for i in 0..3 {
950 assert!(map_array.is_valid(i));
951 assert!(!map_array.is_null(i));
952 }
953 }
954
955 #[test]
956 fn test_try_new() {
957 let offsets = OffsetBuffer::new(vec![0, 1, 4, 5].into());
958 let fields = Fields::from(vec![
959 Field::new(Field::MAP_KEY_FIELD_DEFAULT_NAME, DataType::Int32, false),
960 Field::new(Field::MAP_VALUE_FIELD_DEFAULT_NAME, DataType::Int32, false),
961 ]);
962 let columns = vec![
963 Arc::new(Int32Array::from(vec![1, 2, 3, 4, 5])) as _,
964 Arc::new(Int32Array::from(vec![1, 2, 3, 4, 5])) as _,
965 ];
966
967 let entries = StructArray::new(fields.clone(), columns, None);
968 let field = Arc::new(Field::new(
969 Field::MAP_ENTRIES_FIELD_DEFAULT_NAME,
970 DataType::Struct(fields),
971 false,
972 ));
973
974 MapArray::new(field.clone(), offsets.clone(), entries.clone(), None, false);
975
976 let nulls = NullBuffer::new_null(3);
977 MapArray::new(field.clone(), offsets, entries.clone(), Some(nulls), false);
978
979 let nulls = NullBuffer::new_null(3);
980 let offsets = OffsetBuffer::new(vec![0, 1, 2, 4, 5].into());
981 let err = MapArray::try_new(
982 field.clone(),
983 offsets.clone(),
984 entries.clone(),
985 Some(nulls),
986 false,
987 )
988 .unwrap_err();
989
990 assert_eq!(
991 err.to_string(),
992 "Invalid argument error: Incorrect length of null buffer for MapArray, expected 4 got 3"
993 );
994
995 let err = MapArray::try_new(field, offsets.clone(), entries.slice(0, 2), None, false)
996 .unwrap_err();
997
998 assert_eq!(
999 err.to_string(),
1000 "Invalid argument error: Max offset of 5 exceeds length of entries 2"
1001 );
1002
1003 let field = Arc::new(Field::new("element", DataType::Int64, false));
1004 let err = MapArray::try_new(field, offsets.clone(), entries, None, false)
1005 .unwrap_err()
1006 .to_string();
1007
1008 assert!(
1009 err.starts_with("Invalid argument error: MapArray expected data type Int64 got Struct"),
1010 "{err}"
1011 );
1012
1013 let fields = Fields::from(vec![
1014 Field::new("a", DataType::Int32, false),
1015 Field::new("b", DataType::Int32, false),
1016 Field::new("c", DataType::Int32, false),
1017 ]);
1018 let columns = vec![
1019 Arc::new(Int32Array::from(vec![1, 2, 3, 4, 5])) as _,
1020 Arc::new(Int32Array::from(vec![1, 2, 3, 4, 5])) as _,
1021 Arc::new(Int32Array::from(vec![1, 2, 3, 4, 5])) as _,
1022 ];
1023
1024 let s = StructArray::new(fields.clone(), columns, None);
1025 let field = Arc::new(Field::new(
1026 Field::MAP_ENTRIES_FIELD_DEFAULT_NAME,
1027 DataType::Struct(fields),
1028 false,
1029 ));
1030 let err = MapArray::try_new(field, offsets, s, None, false).unwrap_err();
1031
1032 assert_eq!(
1033 err.to_string(),
1034 "Invalid argument error: MapArray entries must contain two children, got 3"
1035 );
1036 }
1037
1038 #[test]
1039 fn test_try_new_nullable_keys_field() {
1040 let keys = Int32Array::from(vec![Some(1), None]);
1042 let values = Int32Array::from(vec![None, Some(2)]);
1043 let fields = Fields::from(vec![
1044 Field::new(Field::MAP_KEY_FIELD_DEFAULT_NAME, DataType::Int32, true),
1045 Field::new(Field::MAP_VALUE_FIELD_DEFAULT_NAME, DataType::Int32, true),
1046 ]);
1047 let entries =
1048 StructArray::new(fields.clone(), vec![Arc::new(keys), Arc::new(values)], None);
1049 let field = Arc::new(Field::new(
1050 Field::MAP_ENTRIES_FIELD_DEFAULT_NAME,
1051 DataType::Struct(fields),
1052 false,
1053 ));
1054
1055 let err = MapArray::try_new(field, OffsetBuffer::from_lengths([2]), entries, None, false)
1056 .unwrap_err();
1057 assert_eq!(
1058 err.to_string(),
1059 "Invalid argument error: MapArray keys field cannot be nullable"
1060 );
1061 }
1062
1063 #[test]
1064 fn test_from_vec_of_maps() {
1065 for ordered in [true, false] {
1066 let map = vec![
1067 Some(vec![]),
1068 None,
1069 Some(vec![("a", Some(1)), ("b", None), ("cd", Some(4))]),
1070 Some(vec![("e", Some(0))]),
1071 ];
1072
1073 let map_array =
1074 MapArray::from_vec_of_maps::<StringArray, Int32Array, _, _>(map, ordered);
1075 assert_eq!(map_array.len(), 4);
1076
1077 let mut builder = MapBuilder::new(None, StringBuilder::new(), Int32Builder::default());
1078
1079 builder.append(true).unwrap();
1081
1082 builder.append_nulls(1).unwrap();
1084
1085 builder.keys().extend(["a", "b", "cd"].map(Some));
1087 builder.values().extend([Some(1), None, Some(4)]);
1088
1089 builder.append(true).unwrap();
1090
1091 builder.keys().append_value("e");
1093 builder.values().append_value(0);
1094
1095 builder.append(true).unwrap();
1096
1097 let (field, offsets, entries, null_buffer, _) = builder.finish().into_parts();
1098
1099 let expected_map = MapArray::new(field, offsets, entries, null_buffer, ordered);
1100
1101 assert_eq!(map_array, expected_map);
1102 }
1103 }
1104}