Skip to content

Commit 75367c5

Browse files
authored
chore: add StructFields::merge (#3584)
1 parent fdccca6 commit 75367c5

File tree

1 file changed

+58
-2
lines changed

1 file changed

+58
-2
lines changed

vortex-dtype/src/struct_.rs

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
use std::hash::Hash;
22
use std::sync::Arc;
33

4-
use vortex_error::{VortexExpect, VortexResult, VortexUnwrap, vortex_err, vortex_panic};
4+
use itertools::Itertools;
5+
use vortex_error::{
6+
VortexExpect, VortexResult, VortexUnwrap, vortex_bail, vortex_err, vortex_panic,
7+
};
58

69
use crate::flatbuffers::ViewedDType;
710
use crate::{DType, FieldName, FieldNames, PType};
@@ -283,6 +286,33 @@ impl StructFields {
283286

284287
StructFields::from_fields(names, dtypes)
285288
}
289+
290+
/// Merge two [`StructFields`] instances into a new one.
291+
/// Order of fields in arguments is preserved
292+
///
293+
/// # Errors
294+
/// Returns an error if the merged struct would have duplicate field names.
295+
pub fn disjoint_merge(&self, other: &Self) -> VortexResult<Self> {
296+
let names = self
297+
.names
298+
.iter()
299+
.chain(other.names.iter())
300+
.cloned()
301+
.collect::<FieldNames>();
302+
303+
if !names.iter().all_unique() {
304+
vortex_bail!("Can't merge struct fields with duplicate names");
305+
}
306+
307+
let dtypes = self
308+
.dtypes
309+
.iter()
310+
.chain(other.dtypes.iter())
311+
.cloned()
312+
.collect::<Vec<_>>();
313+
314+
Ok(Self::from_fields(names, dtypes))
315+
}
286316
}
287317

288318
impl<T, V> FromIterator<(T, V)> for StructFields
@@ -301,8 +331,10 @@ where
301331

302332
#[cfg(test)]
303333
mod test {
334+
use itertools::Itertools;
335+
304336
use crate::dtype::DType;
305-
use crate::{Nullability, PType, StructFields};
337+
use crate::{FieldNames, Nullability, PType, StructFields};
306338

307339
#[test]
308340
fn nullability() {
@@ -356,4 +388,28 @@ mod test {
356388
assert_eq!(without_a.field_by_index(0).unwrap(), b_type);
357389
assert_eq!(without_a.nfields(), 1);
358390
}
391+
392+
#[test]
393+
fn test_merge() {
394+
let child_a = DType::Primitive(PType::I32, Nullability::NonNullable);
395+
let child_b = DType::Bool(Nullability::Nullable);
396+
let child_c = DType::Utf8(Nullability::NonNullable);
397+
398+
let sf1 = StructFields::from_iter([("A", child_a.clone()), ("B", child_b.clone())]);
399+
400+
let sf2 = StructFields::from_iter([("C", child_c.clone())]);
401+
402+
let merged = StructFields::disjoint_merge(&sf1, &sf2).unwrap();
403+
assert_eq!(
404+
merged.names(),
405+
&FieldNames::from_iter(["A".into(), "B".into(), "C".into()])
406+
);
407+
assert_eq!(
408+
merged.fields().collect_vec(),
409+
vec![child_a, child_b, child_c]
410+
);
411+
412+
let err = StructFields::disjoint_merge(&sf1, &sf1).err().unwrap();
413+
assert!(err.to_string().contains("duplicate names"),);
414+
}
359415
}

0 commit comments

Comments
 (0)