1use std::ops::Deref;
19use std::sync::Arc;
20
21use crate::{ArrowError, DataType, Field, FieldRef};
22
23#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
58#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
59#[cfg_attr(feature = "serde", serde(transparent))]
60pub struct Fields(Arc<[FieldRef]>);
61
62impl std::fmt::Debug for Fields {
63 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
64 self.0.as_ref().fmt(f)
65 }
66}
67
68impl Fields {
69 pub fn empty() -> Self {
71 Self(Arc::new([]))
72 }
73
74 pub fn size(&self) -> usize {
76 self.iter()
77 .map(|field| field.size() + std::mem::size_of::<FieldRef>())
78 .sum()
79 }
80
81 pub fn find(&self, name: &str) -> Option<(usize, &FieldRef)> {
83 self.0.iter().enumerate().find(|(_, b)| b.name() == name)
84 }
85
86 pub fn contains(&self, other: &Fields) -> bool {
93 if Arc::ptr_eq(&self.0, &other.0) {
94 return true;
95 }
96 self.len() == other.len()
97 && self
98 .iter()
99 .zip(other.iter())
100 .all(|(a, b)| Arc::ptr_eq(a, b) || a.contains(b))
101 }
102
103 pub fn filter_leaves<F: FnMut(usize, &FieldRef) -> bool>(&self, mut filter: F) -> Self {
140 self.try_filter_leaves(|idx, field| Ok(filter(idx, field)))
141 .unwrap()
142 }
143
144 pub fn try_filter_leaves<F: FnMut(usize, &FieldRef) -> Result<bool, ArrowError>>(
149 &self,
150 mut filter: F,
151 ) -> Result<Self, ArrowError> {
152 fn filter_field<F: FnMut(&FieldRef) -> Result<bool, ArrowError>>(
153 f: &FieldRef,
154 filter: &mut F,
155 ) -> Result<Option<FieldRef>, ArrowError> {
156 use DataType::*;
157
158 let v = match f.data_type() {
159 Dictionary(_, v) => v.as_ref(), RunEndEncoded(_, v) => v.data_type(), d => d,
162 };
163 let d = match v {
164 List(child) => {
165 let fields = filter_field(child, filter)?;
166 if let Some(fields) = fields {
167 List(fields)
168 } else {
169 return Ok(None);
170 }
171 }
172 LargeList(child) => {
173 let fields = filter_field(child, filter)?;
174 if let Some(fields) = fields {
175 LargeList(fields)
176 } else {
177 return Ok(None);
178 }
179 }
180 Map(child, ordered) => {
181 let fields = filter_field(child, filter)?;
182 if let Some(fields) = fields {
183 Map(fields, *ordered)
184 } else {
185 return Ok(None);
186 }
187 }
188 FixedSizeList(child, size) => {
189 let fields = filter_field(child, filter)?;
190 if let Some(fields) = fields {
191 FixedSizeList(fields, *size)
192 } else {
193 return Ok(None);
194 }
195 }
196 Struct(fields) => {
197 let filtered: Result<Vec<_>, _> =
198 fields.iter().map(|f| filter_field(f, filter)).collect();
199 let filtered: Fields = filtered?.iter().filter_map(|f| f.clone()).collect();
200
201 if filtered.is_empty() {
202 return Ok(None);
203 }
204
205 Struct(filtered)
206 }
207 Union(fields, mode) => {
208 let filtered: Result<Vec<_>, _> = fields
209 .iter()
210 .map(|(id, f)| filter_field(f, filter).map(|f| f.map(|f| (id, f))))
211 .collect();
212 let filtered: UnionFields =
213 filtered?.iter().filter_map(|f| f.clone()).collect();
214
215 if filtered.is_empty() {
216 return Ok(None);
217 }
218
219 Union(filtered, *mode)
220 }
221 _ => {
222 let filtered = filter(f)?;
223 return Ok(filtered.then(|| f.clone()));
224 }
225 };
226 let d = match f.data_type() {
227 Dictionary(k, _) => Dictionary(k.clone(), Box::new(d)),
228 RunEndEncoded(v, f) => {
229 RunEndEncoded(v.clone(), Arc::new(f.as_ref().clone().with_data_type(d)))
230 }
231 _ => d,
232 };
233 Ok(Some(Arc::new(f.as_ref().clone().with_data_type(d))))
234 }
235
236 let mut leaf_idx = 0;
237 let mut filter = |f: &FieldRef| {
238 let t = filter(leaf_idx, f)?;
239 leaf_idx += 1;
240 Ok(t)
241 };
242
243 let filtered: Result<Vec<_>, _> = self
244 .0
245 .iter()
246 .map(|f| filter_field(f, &mut filter))
247 .collect();
248 let filtered = filtered?.iter().filter_map(|f| f.clone()).collect();
249 Ok(filtered)
250 }
251}
252
253impl Default for Fields {
254 fn default() -> Self {
255 Self::empty()
256 }
257}
258
259impl FromIterator<Field> for Fields {
260 fn from_iter<T: IntoIterator<Item = Field>>(iter: T) -> Self {
261 iter.into_iter().map(Arc::new).collect()
262 }
263}
264
265impl FromIterator<FieldRef> for Fields {
266 fn from_iter<T: IntoIterator<Item = FieldRef>>(iter: T) -> Self {
267 Self(iter.into_iter().collect())
268 }
269}
270
271impl From<Vec<Field>> for Fields {
272 fn from(value: Vec<Field>) -> Self {
273 value.into_iter().collect()
274 }
275}
276
277impl From<Vec<FieldRef>> for Fields {
278 fn from(value: Vec<FieldRef>) -> Self {
279 Self(value.into())
280 }
281}
282
283impl From<&[FieldRef]> for Fields {
284 fn from(value: &[FieldRef]) -> Self {
285 Self(value.into())
286 }
287}
288
289impl<const N: usize> From<[FieldRef; N]> for Fields {
290 fn from(value: [FieldRef; N]) -> Self {
291 Self(Arc::new(value))
292 }
293}
294
295impl Deref for Fields {
296 type Target = [FieldRef];
297
298 fn deref(&self) -> &Self::Target {
299 self.0.as_ref()
300 }
301}
302
303impl<'a> IntoIterator for &'a Fields {
304 type Item = &'a FieldRef;
305 type IntoIter = std::slice::Iter<'a, FieldRef>;
306
307 fn into_iter(self) -> Self::IntoIter {
308 self.0.iter()
309 }
310}
311
312#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
314#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
315#[cfg_attr(feature = "serde", serde(transparent))]
316pub struct UnionFields(Arc<[(i8, FieldRef)]>);
317
318impl std::fmt::Debug for UnionFields {
319 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
320 self.0.as_ref().fmt(f)
321 }
322}
323
324impl std::ops::Index<usize> for UnionFields {
333 type Output = (i8, FieldRef);
334
335 fn index(&self, index: usize) -> &Self::Output {
336 &self.0[index]
337 }
338}
339
340impl UnionFields {
341 pub fn empty() -> Self {
343 Self(Arc::from([]))
344 }
345
346 pub fn try_new<F, T>(type_ids: T, fields: F) -> Result<Self, ArrowError>
383 where
384 F: IntoIterator,
385 F::Item: Into<FieldRef>,
386 T: IntoIterator<Item = i8>,
387 {
388 let mut type_ids_iter = type_ids.into_iter();
389 let mut fields_iter = fields.into_iter().map(Into::into);
390
391 let mut seen_type_ids = 0u128;
392
393 let mut out = Vec::new();
394
395 loop {
396 match (type_ids_iter.next(), fields_iter.next()) {
397 (None, None) => return Ok(Self(out.into())),
398 (Some(type_id), Some(field)) => {
399 if type_id < 0 {
401 return Err(ArrowError::InvalidArgumentError(format!(
402 "type ids must be non-negative: {type_id}"
403 )));
404 }
405
406 let mask = 1_u128 << type_id;
408 if (seen_type_ids & mask) != 0 {
409 return Err(ArrowError::InvalidArgumentError(format!(
410 "duplicate type id: {type_id}"
411 )));
412 }
413
414 seen_type_ids |= mask;
415
416 out.push((type_id, field));
417 }
418 (None, Some(_)) => {
419 return Err(ArrowError::InvalidArgumentError(
420 "fields iterator has more elements than type_ids iterator".to_string(),
421 ));
422 }
423 (Some(_), None) => {
424 return Err(ArrowError::InvalidArgumentError(
425 "type_ids iterator has more elements than fields iterator".to_string(),
426 ));
427 }
428 }
429 }
430 }
431
432 pub fn from_fields<F>(fields: F) -> Self
460 where
461 F: IntoIterator,
462 F::Item: Into<FieldRef>,
463 {
464 fields
465 .into_iter()
466 .enumerate()
467 .map(|(i, field)| {
468 let id = i8::try_from(i).expect("UnionFields cannot contain more than 128 fields");
469
470 (id, field.into())
471 })
472 .collect()
473 }
474
475 pub fn try_from_fields<F>(fields: F) -> Result<Self, ArrowError>
510 where
511 F: IntoIterator,
512 F::Item: Into<FieldRef>,
513 {
514 let mut out = Vec::with_capacity(i8::MAX as usize + 1);
515
516 for (i, field) in fields.into_iter().enumerate() {
517 let id = i8::try_from(i).map_err(|_| {
518 ArrowError::InvalidArgumentError(
519 "UnionFields cannot contain more than 128 fields".into(),
520 )
521 })?;
522
523 out.push((id, field.into()));
524 }
525
526 Ok(Self(out.into()))
527 }
528
529 pub fn size(&self) -> usize {
531 self.iter()
532 .map(|(_, field)| field.size() + std::mem::size_of::<(i8, FieldRef)>())
533 .sum()
534 }
535
536 pub fn len(&self) -> usize {
538 self.0.len()
539 }
540
541 pub fn is_empty(&self) -> bool {
543 self.0.is_empty()
544 }
545
546 pub fn iter(&self) -> impl Iterator<Item = (i8, &FieldRef)> + '_ {
548 self.0.iter().map(|(id, f)| (*id, f))
549 }
550
551 pub fn get(&self, index: usize) -> Option<&(i8, FieldRef)> {
573 self.0.get(index)
574 }
575
576 pub fn find_by_type_id(&self, type_id: i8) -> Option<(i8, &FieldRef)> {
579 self.iter().find(|&(i, _)| i == type_id)
580 }
581
582 pub fn find_by_field(&self, field: &Field) -> Option<(i8, &FieldRef)> {
585 self.iter().find(|&(_, f)| f.as_ref() == field)
586 }
587
588 pub(crate) fn try_merge(&mut self, other: &Self) -> Result<(), ArrowError> {
592 let mut output: Vec<_> = self.iter().map(|(id, f)| (id, f.clone())).collect();
594 for (field_type_id, from_field) in other.iter() {
595 let mut is_new_field = true;
596 for (self_type_id, self_field) in output.iter_mut() {
597 if from_field == self_field {
598 if *self_type_id != field_type_id {
601 return Err(ArrowError::SchemaError(format!(
602 "Fail to merge schema field '{}' because the self_type_id = {} does not equal field_type_id = {}",
603 self_field.name(),
604 self_type_id,
605 field_type_id
606 )));
607 }
608
609 is_new_field = false;
610 break;
611 }
612 }
613
614 if is_new_field {
615 output.push((field_type_id, from_field.clone()))
616 }
617 }
618 *self = output.into_iter().collect();
619 Ok(())
620 }
621}
622
623impl FromIterator<(i8, FieldRef)> for UnionFields {
624 fn from_iter<T: IntoIterator<Item = (i8, FieldRef)>>(iter: T) -> Self {
625 Self(iter.into_iter().collect())
626 }
627}
628
629#[cfg(test)]
630mod tests {
631 use super::*;
632 use crate::UnionMode;
633
634 #[test]
635 fn test_filter() {
636 let floats = Fields::from(vec![
637 Field::new("a", DataType::Float32, false),
638 Field::new("b", DataType::Float32, false),
639 ]);
640 let fields = Fields::from(vec![
641 Field::new("a", DataType::Int32, true),
642 Field::new("floats", DataType::Struct(floats.clone()), true),
643 Field::new("b", DataType::Int16, true),
644 Field::new(
645 "c",
646 DataType::Dictionary(Box::new(DataType::Int32), Box::new(DataType::Utf8)),
647 false,
648 ),
649 Field::new(
650 "d",
651 DataType::Dictionary(
652 Box::new(DataType::Int32),
653 Box::new(DataType::Struct(floats.clone())),
654 ),
655 false,
656 ),
657 Field::new_list(
658 "e",
659 Field::new("floats", DataType::Struct(floats.clone()), true),
660 true,
661 ),
662 Field::new_fixed_size_list(
663 "f",
664 Field::new_list_field(DataType::Int32, false),
665 3,
666 false,
667 ),
668 Field::new_map(
669 "g",
670 Field::MAP_ENTRIES_FIELD_DEFAULT_NAME,
671 Field::new(
672 Field::MAP_KEY_FIELD_DEFAULT_NAME,
673 DataType::LargeUtf8,
674 false,
675 ),
676 Field::new(Field::MAP_VALUE_FIELD_DEFAULT_NAME, DataType::Int32, true),
677 false,
678 false,
679 ),
680 Field::new(
681 "h",
682 DataType::Union(
683 UnionFields::try_new(
684 vec![1, 3],
685 vec![
686 Field::new("field1", DataType::UInt8, false),
687 Field::new("field3", DataType::Utf8, false),
688 ],
689 )
690 .unwrap(),
691 UnionMode::Dense,
692 ),
693 true,
694 ),
695 Field::new(
696 "i",
697 DataType::RunEndEncoded(
698 Arc::new(Field::new("run_ends", DataType::Int32, false)),
699 Arc::new(Field::new("values", DataType::Struct(floats.clone()), true)),
700 ),
701 false,
702 ),
703 ]);
704
705 let floats_a = DataType::Struct(vec![floats[0].clone()].into());
706
707 let r = fields.filter_leaves(|idx, _| idx == 0 || idx == 1);
708 assert_eq!(r.len(), 2);
709 assert_eq!(r[0], fields[0]);
710 assert_eq!(r[1].data_type(), &floats_a);
711
712 let r = fields.filter_leaves(|_, f| f.name() == "a");
713 assert_eq!(r.len(), 5);
714 assert_eq!(r[0], fields[0]);
715 assert_eq!(r[1].data_type(), &floats_a);
716 assert_eq!(
717 r[2].data_type(),
718 &DataType::Dictionary(Box::new(DataType::Int32), Box::new(floats_a.clone()))
719 );
720 assert_eq!(
721 r[3].as_ref(),
722 &Field::new_list("e", Field::new("floats", floats_a.clone(), true), true)
723 );
724 assert_eq!(
725 r[4].as_ref(),
726 &Field::new(
727 "i",
728 DataType::RunEndEncoded(
729 Arc::new(Field::new("run_ends", DataType::Int32, false)),
730 Arc::new(Field::new("values", floats_a.clone(), true)),
731 ),
732 false,
733 )
734 );
735
736 let r = fields.filter_leaves(|_, f| f.name() == "floats");
737 assert_eq!(r.len(), 0);
738
739 let r = fields.filter_leaves(|idx, _| idx == 9);
740 assert_eq!(r.len(), 1);
741 assert_eq!(r[0], fields[6]);
742
743 let r = fields.filter_leaves(|idx, _| idx == 10 || idx == 11);
744 assert_eq!(r.len(), 1);
745 assert_eq!(r[0], fields[7]);
746
747 let union = DataType::Union(
748 UnionFields::try_new(vec![1], vec![Field::new("field1", DataType::UInt8, false)])
749 .unwrap(),
750 UnionMode::Dense,
751 );
752
753 let r = fields.filter_leaves(|idx, _| idx == 12);
754 assert_eq!(r.len(), 1);
755 assert_eq!(r[0].data_type(), &union);
756
757 let r = fields.filter_leaves(|idx, _| idx == 14 || idx == 15);
758 assert_eq!(r.len(), 1);
759 assert_eq!(r[0], fields[9]);
760
761 let r = fields.try_filter_leaves(|_, _| Err(ArrowError::SchemaError("error".to_string())));
763 assert!(r.is_err());
764 }
765
766 #[test]
767 fn test_union_fields_try_new_valid() {
768 let res = UnionFields::try_new(
769 vec![1, 6, 7],
770 vec![
771 Field::new("f1", DataType::UInt8, false),
772 Field::new("f6", DataType::Utf8, false),
773 Field::new("f7", DataType::Int32, true),
774 ],
775 );
776 assert!(res.is_ok());
777 let union_fields = res.unwrap();
778 assert_eq!(union_fields.len(), 3);
779 assert_eq!(
780 union_fields.iter().map(|(id, _)| id).collect::<Vec<_>>(),
781 vec![1, 6, 7]
782 );
783 }
784
785 #[test]
786 fn test_union_fields_try_new_empty() {
787 let res = UnionFields::try_new(Vec::<i8>::new(), Vec::<Field>::new());
788 assert!(res.is_ok());
789 assert!(res.unwrap().is_empty());
790 }
791
792 #[test]
793 fn test_union_fields_try_new_duplicate_type_id() {
794 let res = UnionFields::try_new(
795 vec![1, 1],
796 vec![
797 Field::new("f1", DataType::UInt8, false),
798 Field::new("f2", DataType::Utf8, false),
799 ],
800 );
801 assert!(res.is_err());
802 assert!(
803 res.unwrap_err()
804 .to_string()
805 .contains("duplicate type id: 1")
806 );
807 }
808
809 #[test]
810 fn test_union_fields_try_new_duplicate_field() {
811 let field = Field::new("field", DataType::UInt8, false);
812 let res = UnionFields::try_new(vec![1, 2], vec![field.clone(), field]);
813 assert!(res.is_ok());
814 }
815
816 #[test]
817 fn test_union_fields_try_new_more_type_ids() {
818 let res = UnionFields::try_new(
819 vec![1, 2, 3],
820 vec![
821 Field::new("f1", DataType::UInt8, false),
822 Field::new("f2", DataType::Utf8, false),
823 ],
824 );
825 assert!(res.is_err());
826 assert!(
827 res.unwrap_err()
828 .to_string()
829 .contains("type_ids iterator has more elements")
830 );
831 }
832
833 #[test]
834 fn test_union_fields_try_new_more_fields() {
835 let res = UnionFields::try_new(
836 vec![1, 2],
837 vec![
838 Field::new("f1", DataType::UInt8, false),
839 Field::new("f2", DataType::Utf8, false),
840 Field::new("f3", DataType::Int32, true),
841 ],
842 );
843 assert!(res.is_err());
844 assert!(
845 res.unwrap_err()
846 .to_string()
847 .contains("fields iterator has more elements")
848 );
849 }
850
851 #[test]
852 fn test_union_fields_try_new_negative_type_ids() {
853 let res = UnionFields::try_new(
854 vec![-128, -1, 0, 127],
855 vec![
856 Field::new("field_min", DataType::UInt8, false),
857 Field::new("field_neg", DataType::Utf8, false),
858 Field::new("field_zero", DataType::Int32, true),
859 Field::new("field_max", DataType::Boolean, false),
860 ],
861 );
862 assert!(res.is_err());
863 assert!(
864 res.unwrap_err()
865 .to_string()
866 .contains("type ids must be non-negative")
867 )
868 }
869
870 #[test]
871 fn test_union_fields_try_new_complex_types() {
872 let res = UnionFields::try_new(
873 vec![0, 1, 2],
874 vec![
875 Field::new(
876 "struct_field",
877 DataType::Struct(Fields::from(vec![
878 Field::new("a", DataType::Int32, false),
879 Field::new("b", DataType::Utf8, true),
880 ])),
881 false,
882 ),
883 Field::new_list(
884 "list_field",
885 Field::new("item", DataType::Float64, true),
886 true,
887 ),
888 Field::new(
889 "dict_field",
890 DataType::Dictionary(Box::new(DataType::Int32), Box::new(DataType::Utf8)),
891 false,
892 ),
893 ],
894 );
895 assert!(res.is_ok());
896 assert_eq!(res.unwrap().len(), 3);
897 }
898
899 #[test]
900 fn test_union_fields_try_new_single_field() {
901 let res = UnionFields::try_new(
902 vec![42],
903 vec![Field::new("only_field", DataType::Int64, false)],
904 );
905 assert!(res.is_ok());
906 let union_fields = res.unwrap();
907 assert_eq!(union_fields.len(), 1);
908 assert_eq!(union_fields.iter().next().unwrap().0, 42);
909 }
910
911 #[test]
912 fn test_union_fields_try_from_fields_empty() {
913 let res = UnionFields::try_from_fields(Vec::<Field>::new());
914 assert!(res.is_ok());
915 assert!(res.unwrap().is_empty());
916 }
917
918 #[test]
919 fn test_union_fields_try_from_fields_single() {
920 let res = UnionFields::try_from_fields(vec![Field::new("only", DataType::Int64, false)]);
921 assert!(res.is_ok());
922 let union_fields = res.unwrap();
923 assert_eq!(union_fields.len(), 1);
924 assert_eq!(union_fields.iter().next().unwrap().0, 0);
925 }
926
927 #[test]
928 fn test_union_fields_try_from_fields_too_many() {
929 let many_fields: Vec<_> = (0..200)
930 .map(|i| Field::new(format!("field{}", i), DataType::Int32, false))
931 .collect();
932 let res = UnionFields::try_from_fields(many_fields);
933 assert!(res.is_err());
934 assert!(
935 res.unwrap_err()
936 .to_string()
937 .contains("UnionFields cannot contain more than 128 fields")
938 );
939 }
940
941 #[test]
942 fn test_union_fields_try_from_fields_max_valid() {
943 let fields: Vec<_> = (0..=i8::MAX)
944 .map(|i| Field::new(format!("field{}", i), DataType::Int32, false))
945 .collect();
946 let res = UnionFields::try_from_fields(fields);
947 assert!(res.is_ok());
948 let union_fields = res.unwrap();
949 assert_eq!(union_fields.len(), 128);
950 assert_eq!(union_fields.iter().map(|(id, _)| id).min().unwrap(), 0);
951 assert_eq!(union_fields.iter().map(|(id, _)| id).max().unwrap(), 127);
952 }
953
954 #[test]
955 fn test_union_fields_try_from_fields_over_max() {
956 let fields: Vec<_> = (0..129)
958 .map(|i| Field::new(format!("field{}", i), DataType::Int32, false))
959 .collect();
960 let res = UnionFields::try_from_fields(fields);
961 assert!(res.is_err());
962 }
963
964 #[test]
965 fn test_union_fields_try_from_fields_complex_types() {
966 let res = UnionFields::try_from_fields(vec![
967 Field::new(
968 "struct_field",
969 DataType::Struct(Fields::from(vec![
970 Field::new("a", DataType::Int32, false),
971 Field::new("b", DataType::Utf8, true),
972 ])),
973 false,
974 ),
975 Field::new_list(
976 "list_field",
977 Field::new("item", DataType::Float64, true),
978 true,
979 ),
980 Field::new(
981 "dict_field",
982 DataType::Dictionary(Box::new(DataType::Int32), Box::new(DataType::Utf8)),
983 false,
984 ),
985 ]);
986 assert!(res.is_ok());
987 assert_eq!(res.unwrap().len(), 3);
988 }
989}