This is an automated email from the ASF dual-hosted git repository.
alamb pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git
The following commit(s) were added to refs/heads/main by this push:
new d4ff12fbb6 Fix `can_cast_types` for temporal to `Utf8View` (#8328)
d4ff12fbb6 is described below
commit d4ff12fbb6d61d188919a3a9edcff53f2168aae8
Author: Piotr Findeisen <[email protected]>
AuthorDate: Sat Sep 13 05:56:34 2025 -0700
Fix `can_cast_types` for temporal to `Utf8View` (#8328)
`cast` and `cast_with_options` gained support for casting from temporal
values to `Utf8View` in e613622fb69a7cc941bfb97bf1020bee580cfb86. This
updates `can_cast_types` to match. This is necessary for DataFusion to
use this casts, as DF consults `can_cast_types` first.
---
arrow-cast/src/cast/mod.rs | 83 ++++++++++++++++++++++++++++------------------
1 file changed, 51 insertions(+), 32 deletions(-)
diff --git a/arrow-cast/src/cast/mod.rs b/arrow-cast/src/cast/mod.rs
index e2bb3db859..117ad10b11 100644
--- a/arrow-cast/src/cast/mod.rs
+++ b/arrow-cast/src/cast/mod.rs
@@ -268,8 +268,7 @@ pub fn can_cast_types(from_type: &DataType, to_type:
&DataType) -> bool {
(Utf8 | LargeUtf8, Utf8View) => true,
(BinaryView, Binary | LargeBinary | Utf8 | LargeUtf8 | Utf8View) =>
true,
(Utf8View | Utf8 | LargeUtf8, _) => to_type.is_numeric() && to_type !=
&Float16,
- (_, Utf8 | LargeUtf8) => from_type.is_primitive(),
- (_, Utf8View) => from_type.is_numeric(),
+ (_, Utf8 | Utf8View | LargeUtf8) => from_type.is_primitive(),
(_, Binary | LargeBinary) => from_type.is_integer(),
@@ -5775,28 +5774,9 @@ mod tests {
assert!(c.is_null(2));
}
- #[test]
- fn test_cast_date32_to_string() {
- let array = Date32Array::from(vec![10000, 17890]);
- let b = cast(&array, &DataType::Utf8).unwrap();
- let c = b.as_any().downcast_ref::<StringArray>().unwrap();
- assert_eq!(&DataType::Utf8, c.data_type());
- assert_eq!("1997-05-19", c.value(0));
- assert_eq!("2018-12-25", c.value(1));
- }
-
- #[test]
- fn test_cast_date64_to_string() {
- let array = Date64Array::from(vec![10000 * 86400000, 17890 *
86400000]);
- let b = cast(&array, &DataType::Utf8).unwrap();
- let c = b.as_any().downcast_ref::<StringArray>().unwrap();
- assert_eq!(&DataType::Utf8, c.data_type());
- assert_eq!("1997-05-19T00:00:00", c.value(0));
- assert_eq!("2018-12-25T00:00:00", c.value(1));
- }
-
- macro_rules! assert_cast_timestamp_to_string {
+ macro_rules! assert_cast {
($array:expr, $datatype:expr, $output_array_type: ty, $expected:expr)
=> {{
+ assert!(can_cast_types($array.data_type(), &$datatype));
let out = cast(&$array, &$datatype).unwrap();
let actual = out
.as_any()
@@ -5807,6 +5787,7 @@ mod tests {
assert_eq!(actual, $expected);
}};
($array:expr, $datatype:expr, $output_array_type: ty, $options:expr,
$expected:expr) => {{
+ assert!(can_cast_types($array.data_type(), &$datatype));
let out = cast_with_options(&$array, &$datatype,
&$options).unwrap();
let actual = out
.as_any()
@@ -5818,6 +5799,44 @@ mod tests {
}};
}
+ #[test]
+ fn test_cast_date32_to_string() {
+ let array = Date32Array::from(vec![Some(0), Some(10000), Some(13036),
Some(17890), None]);
+ let expected = vec![
+ Some("1970-01-01"),
+ Some("1997-05-19"),
+ Some("2005-09-10"),
+ Some("2018-12-25"),
+ None,
+ ];
+
+ assert_cast!(array, DataType::Utf8View, StringViewArray, expected);
+ assert_cast!(array, DataType::Utf8, StringArray, expected);
+ assert_cast!(array, DataType::LargeUtf8, LargeStringArray, expected);
+ }
+
+ #[test]
+ fn test_cast_date64_to_string() {
+ let array = Date64Array::from(vec![
+ Some(0),
+ Some(10000 * 86400000),
+ Some(13036 * 86400000),
+ Some(17890 * 86400000),
+ None,
+ ]);
+ let expected = vec![
+ Some("1970-01-01T00:00:00"),
+ Some("1997-05-19T00:00:00"),
+ Some("2005-09-10T00:00:00"),
+ Some("2018-12-25T00:00:00"),
+ None,
+ ];
+
+ assert_cast!(array, DataType::Utf8View, StringViewArray, expected);
+ assert_cast!(array, DataType::Utf8, StringArray, expected);
+ assert_cast!(array, DataType::LargeUtf8, LargeStringArray, expected);
+ }
+
#[test]
fn test_cast_date32_to_timestamp_and_timestamp_with_timezone() {
let tz = "+0545"; // UTC + 0545 is Asia/Kathmandu
@@ -6020,9 +6039,9 @@ mod tests {
None,
];
- assert_cast_timestamp_to_string!(array, DataType::Utf8View,
StringViewArray, expected);
- assert_cast_timestamp_to_string!(array, DataType::Utf8, StringArray,
expected);
- assert_cast_timestamp_to_string!(array, DataType::LargeUtf8,
LargeStringArray, expected);
+ assert_cast!(array, DataType::Utf8View, StringViewArray, expected);
+ assert_cast!(array, DataType::Utf8, StringArray, expected);
+ assert_cast!(array, DataType::LargeUtf8, LargeStringArray, expected);
}
#[test]
@@ -6044,21 +6063,21 @@ mod tests {
Some("2018-12-25 00:00:02.001000"),
None,
];
- assert_cast_timestamp_to_string!(
+ assert_cast!(
array_without_tz,
DataType::Utf8View,
StringViewArray,
cast_options,
expected
);
- assert_cast_timestamp_to_string!(
+ assert_cast!(
array_without_tz,
DataType::Utf8,
StringArray,
cast_options,
expected
);
- assert_cast_timestamp_to_string!(
+ assert_cast!(
array_without_tz,
DataType::LargeUtf8,
LargeStringArray,
@@ -6074,21 +6093,21 @@ mod tests {
Some("2018-12-25 05:45:02.001000"),
None,
];
- assert_cast_timestamp_to_string!(
+ assert_cast!(
array_with_tz,
DataType::Utf8View,
StringViewArray,
cast_options,
expected
);
- assert_cast_timestamp_to_string!(
+ assert_cast!(
array_with_tz,
DataType::Utf8,
StringArray,
cast_options,
expected
);
- assert_cast_timestamp_to_string!(
+ assert_cast!(
array_with_tz,
DataType::LargeUtf8,
LargeStringArray,