Skip to content

Commit 24872b2

Browse files
committed
Add a new method to check for compatible datatypes
The new method will look if two datatypes are compatible which each other, ignoring the field order and length and fail if missing and not nullable. Array data type comparison will use the equals_datatype instead of comparing the enums itself.
1 parent 8d787d9 commit 24872b2

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

arrow/src/compute/kernels/concat.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ pub fn concat(arrays: &[&dyn Array]) -> Result<ArrayRef> {
6262

6363
if arrays
6464
.iter()
65-
.any(|array| array.data_type() != arrays[0].data_type())
65+
.any(|array| !array.data_type().equals_datatype(arrays[0].data_type()))
6666
{
6767
return Err(ArrowError::InvalidArgumentError(
6868
"It is not possible to concatenate arrays of different data types."

arrow/src/datatypes/datatype.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,45 @@ impl DataType {
669669
)
670670
}
671671

672+
/// Compares the datatype with another for compatibility.
673+
pub fn compatible_datatype(&self, other: &DataType) -> bool {
674+
match (&self, other) {
675+
(DataType::List(a), DataType::List(b))
676+
| (DataType::LargeList(a), DataType::LargeList(b)) => {
677+
a.is_nullable() == b.is_nullable()
678+
&& a.data_type().equals_datatype(b.data_type())
679+
}
680+
(DataType::FixedSizeList(a, a_size), DataType::FixedSizeList(b, b_size)) => {
681+
a_size == b_size
682+
&& a.is_nullable() == b.is_nullable()
683+
&& a.data_type().equals_datatype(b.data_type())
684+
}
685+
(DataType::Struct(a), DataType::Struct(b)) => {
686+
a.iter()
687+
.all(|a| match b.iter().find(|f| f.name().eq(a.name())) {
688+
Some(b) => {
689+
a.is_nullable() == b.is_nullable()
690+
&& a.data_type().equals_datatype(b.data_type())
691+
}
692+
None => a.is_nullable(),
693+
})
694+
&& b.iter()
695+
.all(|b| match a.iter().find(|f| f.name().eq(b.name())) {
696+
Some(a) => {
697+
a.is_nullable() == b.is_nullable()
698+
&& a.data_type().equals_datatype(b.data_type())
699+
}
700+
None => b.is_nullable(),
701+
})
702+
}
703+
(
704+
DataType::Map(a_field, a_is_sorted),
705+
DataType::Map(b_field, b_is_sorted),
706+
) => a_field == b_field && a_is_sorted == b_is_sorted,
707+
_ => self == other,
708+
}
709+
}
710+
672711
/// Compares the datatype with another, ignoring nested field names
673712
/// and metadata.
674713
pub(crate) fn equals_datatype(&self, other: &DataType) -> bool {

0 commit comments

Comments
 (0)