Skip to content

Commit aecac9a

Browse files
jimexistmcheshkov
authored andcommitted
allow null array to be cased to all other types (apache#884)
Can drop this after rebase on commit 81ffa240, first released in 7.0.0
1 parent ba01704 commit aecac9a

File tree

1 file changed

+107
-14
lines changed

1 file changed

+107
-14
lines changed

arrow/src/compute/kernels/cast.rs

+107-14
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,44 @@ pub fn can_cast_types(from_type: &DataType, to_type: &DataType) -> bool {
6868
}
6969

7070
match (from_type, to_type) {
71+
(
72+
Null,
73+
Boolean
74+
| Int8
75+
| UInt8
76+
| Int16
77+
| UInt16
78+
| Int32
79+
| UInt32
80+
| Float32
81+
| Date32
82+
| Time32(_)
83+
| Int64
84+
| UInt64
85+
| Float64
86+
| Date64
87+
| List(_)
88+
| Dictionary(_, _),
89+
)
90+
| (
91+
Boolean
92+
| Int8
93+
| UInt8
94+
| Int16
95+
| UInt16
96+
| Int32
97+
| UInt32
98+
| Float32
99+
| Date32
100+
| Time32(_)
101+
| Int64
102+
| UInt64
103+
| Float64
104+
| Date64
105+
| List(_)
106+
| Dictionary(_, _),
107+
Null,
108+
) => true,
71109
(Struct(_), _) => false,
72110
(_, Struct(_)) => false,
73111
(LargeList(list_from), LargeList(list_to)) => {
@@ -306,7 +344,6 @@ pub fn can_cast_types(from_type: &DataType, to_type: &DataType) -> bool {
306344
(Timestamp(_, _), Date64) => true,
307345
// date64 to timestamp might not make sense,
308346
(Int64, Duration(_)) => true,
309-
(Null, Int32) => true,
310347
(_, _) => false,
311348
}
312349
}
@@ -867,6 +904,44 @@ pub fn cast_with_options(
867904
return Ok(array.clone());
868905
}
869906
match (from_type, to_type) {
907+
(
908+
Null,
909+
Boolean
910+
| Int8
911+
| UInt8
912+
| Int16
913+
| UInt16
914+
| Int32
915+
| UInt32
916+
| Float32
917+
| Date32
918+
| Time32(_)
919+
| Int64
920+
| UInt64
921+
| Float64
922+
| Date64
923+
| List(_)
924+
| Dictionary(_, _),
925+
)
926+
| (
927+
Boolean
928+
| Int8
929+
| UInt8
930+
| Int16
931+
| UInt16
932+
| Int32
933+
| UInt32
934+
| Float32
935+
| Date32
936+
| Time32(_)
937+
| Int64
938+
| UInt64
939+
| Float64
940+
| Date64
941+
| List(_)
942+
| Dictionary(_, _),
943+
Null,
944+
) => Ok(new_null_array(to_type, array.len())),
870945
(Struct(_), _) => Err(ArrowError::CastError(
871946
"Cannot cast from struct to other types".to_string(),
872947
)),
@@ -1706,10 +1781,6 @@ pub fn cast_with_options(
17061781
}
17071782
}
17081783
}
1709-
1710-
// null to primitive/flat types
1711-
(Null, Int32) => Ok(Arc::new(Int32Array::from(vec![None; array.len()]))),
1712-
17131784
(_, _) => Err(ArrowError::CastError(format!(
17141785
"Casting from {:?} to {:?} not supported",
17151786
from_type, to_type,
@@ -4268,17 +4339,39 @@ mod tests {
42684339
}
42694340

42704341
#[test]
4271-
fn test_cast_null_array_to_int32() {
4272-
let array = Arc::new(NullArray::new(6)) as ArrayRef;
4342+
fn test_cast_null_array_from_and_to_others() {
4343+
macro_rules! typed_test {
4344+
($ARR_TYPE:ident, $DATATYPE:ident, $TYPE:tt) => {{
4345+
{
4346+
let array = Arc::new(NullArray::new(6)) as ArrayRef;
4347+
let expected = $ARR_TYPE::from(vec![None; 6]);
4348+
let cast_type = DataType::$DATATYPE;
4349+
let cast_array = cast(&array, &cast_type).expect("cast failed");
4350+
let cast_array = as_primitive_array::<$TYPE>(&cast_array);
4351+
assert_eq!(cast_array.data_type(), &cast_type);
4352+
assert_eq!(cast_array, &expected);
4353+
}
4354+
{
4355+
let array = Arc::new($ARR_TYPE::from(vec![None; 4])) as ArrayRef;
4356+
let expected = NullArray::new(4);
4357+
let cast_array = cast(&array, &DataType::Null).expect("cast failed");
4358+
let cast_array = as_null_array(&cast_array);
4359+
assert_eq!(cast_array.data_type(), &DataType::Null);
4360+
assert_eq!(cast_array, &expected);
4361+
}
4362+
}};
4363+
}
42734364

4274-
let expected = Int32Array::from(vec![None; 6]);
4365+
typed_test!(Int16Array, Int16, Int16Type);
4366+
typed_test!(Int32Array, Int32, Int32Type);
4367+
typed_test!(Int64Array, Int64, Int64Type);
42754368

4276-
// Cast to a dictionary (same value type, Utf8)
4277-
let cast_type = DataType::Int32;
4278-
let cast_array = cast(&array, &cast_type).expect("cast failed");
4279-
let cast_array = as_primitive_array::<Int32Type>(&cast_array);
4280-
assert_eq!(cast_array.data_type(), &cast_type);
4281-
assert_eq!(cast_array, &expected);
4369+
typed_test!(UInt16Array, UInt16, UInt16Type);
4370+
typed_test!(UInt32Array, UInt32, UInt32Type);
4371+
typed_test!(UInt64Array, UInt64, UInt64Type);
4372+
4373+
typed_test!(Float32Array, Float32, Float32Type);
4374+
typed_test!(Float64Array, Float64, Float64Type);
42824375
}
42834376

42844377
/// Print the `DictionaryArray` `array` as a vector of strings

0 commit comments

Comments
 (0)