diff --git a/arrow-array/src/array/primitive_array.rs b/arrow-array/src/array/primitive_array.rs index 3550e291c03..e362f0d7e84 100644 --- a/arrow-array/src/array/primitive_array.rs +++ b/arrow-array/src/array/primitive_array.rs @@ -769,11 +769,16 @@ impl PrimitiveArray { /// Construct a timestamp array with new timezone pub fn with_timezone(&self, timezone: String) -> Self { + self.with_timezone_opt(Some(timezone)) + } + + /// Construct a timestamp array with an optional timezone + pub fn with_timezone_opt(&self, timezone: Option) -> Self { let array_data = unsafe { self.data .clone() .into_builder() - .data_type(DataType::Timestamp(T::get_time_unit(), Some(timezone))) + .data_type(DataType::Timestamp(T::get_time_unit(), timezone)) .build_unchecked() }; PrimitiveArray::from(array_data) diff --git a/arrow/src/compute/kernels/cast.rs b/arrow/src/compute/kernels/cast.rs index 31ac738fa93..912ea28830e 100644 --- a/arrow/src/compute/kernels/cast.rs +++ b/arrow/src/compute/kernels/cast.rs @@ -43,12 +43,10 @@ use std::str; use std::sync::Arc; use crate::buffer::MutableBuffer; -use crate::compute::divide_scalar; -use crate::compute::kernels::arithmetic::{divide, multiply}; -use crate::compute::kernels::arity::unary; use crate::compute::kernels::cast_utils::string_to_timestamp_nanos; use crate::compute::kernels::temporal::extract_component_from_array; use crate::compute::kernels::temporal::return_compute_error_with; +use crate::compute::{divide_scalar, multiply_scalar}; use crate::compute::{try_unary, using_chrono_tz_and_utc_naive_date_time}; use crate::datatypes::*; use crate::error::{ArrowError, Result}; @@ -315,7 +313,7 @@ fn cast_primitive_to_decimal( op: F, precision: u8, scale: u8, -) -> Result> +) -> Result where F: Fn(T::Item) -> i128, { @@ -332,7 +330,7 @@ fn cast_integer_to_decimal( array: &PrimitiveArray, precision: u8, scale: u8, -) -> Result> +) -> Result where ::Native: AsPrimitive, { @@ -347,7 +345,7 @@ fn cast_floating_point_to_decimal( array: &PrimitiveArray, precision: u8, scale: u8, -) -> Result> +) -> Result where ::Native: AsPrimitive, { @@ -365,6 +363,18 @@ where ) } +/// Cast the primitive array using [`PrimitiveArray::reinterpret_cast`] +fn cast_reinterpret_arrays< + I: ArrowPrimitiveType, + O: ArrowPrimitiveType, +>( + array: &dyn Array, +) -> Result { + Ok(Arc::new( + as_primitive_array::(array).reinterpret_cast::(), + )) +} + // cast the decimal array to integer array macro_rules! cast_decimal_to_integer { ($ARRAY:expr, $SCALE : ident, $VALUE_BUILDER: ident, $NATIVE_TYPE : ident, $DATA_TYPE : expr) => {{ @@ -430,6 +440,35 @@ macro_rules! cast_list_to_string { }}; } +fn make_timestamp_array( + array: &PrimitiveArray, + unit: TimeUnit, + tz: Option, +) -> ArrayRef { + match unit { + TimeUnit::Second => Arc::new( + array + .reinterpret_cast::() + .with_timezone_opt(tz), + ), + TimeUnit::Millisecond => Arc::new( + array + .reinterpret_cast::() + .with_timezone_opt(tz), + ), + TimeUnit::Microsecond => Arc::new( + array + .reinterpret_cast::() + .with_timezone_opt(tz), + ), + TimeUnit::Nanosecond => Arc::new( + array + .reinterpret_cast::() + .with_timezone_opt(tz), + ), + } +} + /// Cast `array` to the provided data type and return a new Array with /// type `to_type`, if possible. It accepts `CastOptions` to allow consumers /// to configure cast behavior. @@ -619,50 +658,28 @@ pub fn cast_with_options( cast_primitive_to_list::(array, to, to_type, cast_options) } (Dictionary(index_type, _), _) => match **index_type { - DataType::Int8 => dictionary_cast::(array, to_type, cast_options), - DataType::Int16 => dictionary_cast::(array, to_type, cast_options), - DataType::Int32 => dictionary_cast::(array, to_type, cast_options), - DataType::Int64 => dictionary_cast::(array, to_type, cast_options), - DataType::UInt8 => dictionary_cast::(array, to_type, cast_options), - DataType::UInt16 => { - dictionary_cast::(array, to_type, cast_options) - } - DataType::UInt32 => { - dictionary_cast::(array, to_type, cast_options) - } - DataType::UInt64 => { - dictionary_cast::(array, to_type, cast_options) - } + Int8 => dictionary_cast::(array, to_type, cast_options), + Int16 => dictionary_cast::(array, to_type, cast_options), + Int32 => dictionary_cast::(array, to_type, cast_options), + Int64 => dictionary_cast::(array, to_type, cast_options), + UInt8 => dictionary_cast::(array, to_type, cast_options), + UInt16 => dictionary_cast::(array, to_type, cast_options), + UInt32 => dictionary_cast::(array, to_type, cast_options), + UInt64 => dictionary_cast::(array, to_type, cast_options), _ => Err(ArrowError::CastError(format!( "Casting from dictionary type {:?} to {:?} not supported", from_type, to_type, ))), }, (_, Dictionary(index_type, value_type)) => match **index_type { - DataType::Int8 => { - cast_to_dictionary::(array, value_type, cast_options) - } - DataType::Int16 => { - cast_to_dictionary::(array, value_type, cast_options) - } - DataType::Int32 => { - cast_to_dictionary::(array, value_type, cast_options) - } - DataType::Int64 => { - cast_to_dictionary::(array, value_type, cast_options) - } - DataType::UInt8 => { - cast_to_dictionary::(array, value_type, cast_options) - } - DataType::UInt16 => { - cast_to_dictionary::(array, value_type, cast_options) - } - DataType::UInt32 => { - cast_to_dictionary::(array, value_type, cast_options) - } - DataType::UInt64 => { - cast_to_dictionary::(array, value_type, cast_options) - } + Int8 => cast_to_dictionary::(array, value_type, cast_options), + Int16 => cast_to_dictionary::(array, value_type, cast_options), + Int32 => cast_to_dictionary::(array, value_type, cast_options), + Int64 => cast_to_dictionary::(array, value_type, cast_options), + UInt8 => cast_to_dictionary::(array, value_type, cast_options), + UInt16 => cast_to_dictionary::(array, value_type, cast_options), + UInt32 => cast_to_dictionary::(array, value_type, cast_options), + UInt64 => cast_to_dictionary::(array, value_type, cast_options), _ => Err(ArrowError::CastError(format!( "Casting from type {:?} to dictionary type {:?} not supported", from_type, to_type, @@ -757,20 +774,18 @@ pub fn cast_with_options( Int64 => cast_numeric_to_string::(array), Float32 => cast_numeric_to_string::(array), Float64 => cast_numeric_to_string::(array), - Timestamp(unit, tz) => match unit { - TimeUnit::Nanosecond => { - cast_timestamp_to_string::(array, tz) - } - TimeUnit::Microsecond => { - cast_timestamp_to_string::(array, tz) - } - TimeUnit::Millisecond => { - cast_timestamp_to_string::(array, tz) - } - TimeUnit::Second => { - cast_timestamp_to_string::(array, tz) - } - }, + Timestamp(TimeUnit::Nanosecond, tz) => { + cast_timestamp_to_string::(array, tz) + } + Timestamp(TimeUnit::Microsecond, tz) => { + cast_timestamp_to_string::(array, tz) + } + Timestamp(TimeUnit::Millisecond, tz) => { + cast_timestamp_to_string::(array, tz) + } + Timestamp(TimeUnit::Second, tz) => { + cast_timestamp_to_string::(array, tz) + } Date32 => cast_date32_to_string::(array), Date64 => cast_date64_to_string::(array), Binary => { @@ -813,20 +828,18 @@ pub fn cast_with_options( Int64 => cast_numeric_to_string::(array), Float32 => cast_numeric_to_string::(array), Float64 => cast_numeric_to_string::(array), - Timestamp(unit, tz) => match unit { - TimeUnit::Nanosecond => { - cast_timestamp_to_string::(array, tz) - } - TimeUnit::Microsecond => { - cast_timestamp_to_string::(array, tz) - } - TimeUnit::Millisecond => { - cast_timestamp_to_string::(array, tz) - } - TimeUnit::Second => { - cast_timestamp_to_string::(array, tz) - } - }, + Timestamp(TimeUnit::Nanosecond, tz) => { + cast_timestamp_to_string::(array, tz) + } + Timestamp(TimeUnit::Microsecond, tz) => { + cast_timestamp_to_string::(array, tz) + } + Timestamp(TimeUnit::Millisecond, tz) => { + cast_timestamp_to_string::(array, tz) + } + Timestamp(TimeUnit::Second, tz) => { + cast_timestamp_to_string::(array, tz) + } Date32 => cast_date32_to_string::(array), Date64 => cast_date64_to_string::(array), Binary => { @@ -1160,167 +1173,146 @@ pub fn cast_with_options( // end numeric casts // temporal casts - (Int32, Date32) => cast_array_data::(array, to_type.clone()), + (Int32, Date32) => cast_reinterpret_arrays::(array), (Int32, Date64) => cast_with_options( - &cast_with_options(array, &DataType::Date32, cast_options)?, - &DataType::Date64, + &cast_with_options(array, &Date32, cast_options)?, + &Date64, cast_options, ), (Int32, Time32(TimeUnit::Second)) => { - cast_array_data::(array, to_type.clone()) + cast_reinterpret_arrays::(array) } (Int32, Time32(TimeUnit::Millisecond)) => { - cast_array_data::(array, to_type.clone()) + cast_reinterpret_arrays::(array) } // No support for microsecond/nanosecond with i32 - (Date32, Int32) => cast_array_data::(array, to_type.clone()), + (Date32, Int32) => cast_reinterpret_arrays::(array), (Date32, Int64) => cast_with_options( - &cast_with_options(array, &DataType::Int32, cast_options)?, - &DataType::Int64, + &cast_with_options(array, &Int32, cast_options)?, + &Int64, cast_options, ), - (Time32(_), Int32) => cast_array_data::(array, to_type.clone()), - (Int64, Date64) => cast_array_data::(array, to_type.clone()), + (Time32(TimeUnit::Second), Int32) => { + cast_reinterpret_arrays::(array) + } + (Time32(TimeUnit::Millisecond), Int32) => { + cast_reinterpret_arrays::(array) + } + (Int64, Date64) => cast_reinterpret_arrays::(array), (Int64, Date32) => cast_with_options( - &cast_with_options(array, &DataType::Int32, cast_options)?, - &DataType::Date32, + &cast_with_options(array, &Int32, cast_options)?, + &Date32, cast_options, ), // No support for second/milliseconds with i64 (Int64, Time64(TimeUnit::Microsecond)) => { - cast_array_data::(array, to_type.clone()) + cast_reinterpret_arrays::(array) } (Int64, Time64(TimeUnit::Nanosecond)) => { - cast_array_data::(array, to_type.clone()) + cast_reinterpret_arrays::(array) } - (Date64, Int64) => cast_array_data::(array, to_type.clone()), + (Date64, Int64) => cast_reinterpret_arrays::(array), (Date64, Int32) => cast_with_options( - &cast_with_options(array, &DataType::Int64, cast_options)?, - &DataType::Int32, + &cast_with_options(array, &Int64, cast_options)?, + &Int32, cast_options, ), - (Time64(_), Int64) => cast_array_data::(array, to_type.clone()), - (Date32, Date64) => { - let date_array = array.as_any().downcast_ref::().unwrap(); - - let values = - unary::<_, _, Date64Type>(date_array, |x| x as i64 * MILLISECONDS_IN_DAY); - - Ok(Arc::new(values) as ArrayRef) + (Time64(TimeUnit::Microsecond), Int64) => { + cast_reinterpret_arrays::(array) } - (Date64, Date32) => { - let date_array = array.as_any().downcast_ref::().unwrap(); - - let values = unary::<_, _, Date32Type>(date_array, |x| { - (x / MILLISECONDS_IN_DAY) as i32 - }); - - Ok(Arc::new(values) as ArrayRef) + (Time64(TimeUnit::Nanosecond), Int64) => { + cast_reinterpret_arrays::(array) } - (Time32(TimeUnit::Second), Time32(TimeUnit::Millisecond)) => { - let time_array = array.as_any().downcast_ref::().unwrap(); + (Date32, Date64) => Ok(Arc::new( + as_primitive_array::(array) + .unary::<_, Date64Type>(|x| x as i64 * MILLISECONDS_IN_DAY), + )), + (Date64, Date32) => Ok(Arc::new( + as_primitive_array::(array) + .unary::<_, Date32Type>(|x| (x / MILLISECONDS_IN_DAY) as i32), + )), - let values = unary::<_, _, Time32MillisecondType>(time_array, |x| { - x * MILLISECONDS as i32 - }); + (Time32(TimeUnit::Second), Time32(TimeUnit::Millisecond)) => Ok(Arc::new( + as_primitive_array::(array) + .unary::<_, Time32MillisecondType>(|x| x * MILLISECONDS as i32), + )), + (Time32(TimeUnit::Second), Time64(TimeUnit::Microsecond)) => Ok(Arc::new( + as_primitive_array::(array) + .unary::<_, Time64MicrosecondType>(|x| x as i64 * MICROSECONDS), + )), + (Time32(TimeUnit::Second), Time64(TimeUnit::Nanosecond)) => Ok(Arc::new( + as_primitive_array::(array) + .unary::<_, Time64NanosecondType>(|x| x as i64 * NANOSECONDS), + )), - Ok(Arc::new(values) as ArrayRef) - } - (Time32(TimeUnit::Millisecond), Time32(TimeUnit::Second)) => { - let time_array = array - .as_any() - .downcast_ref::() - .unwrap(); + (Time32(TimeUnit::Millisecond), Time32(TimeUnit::Second)) => Ok(Arc::new( + as_primitive_array::(array) + .unary::<_, Time32SecondType>(|x| x / MILLISECONDS as i32), + )), + (Time32(TimeUnit::Millisecond), Time64(TimeUnit::Microsecond)) => Ok(Arc::new( + as_primitive_array::(array) + .unary::<_, Time64MicrosecondType>(|x| { + x as i64 * (MICROSECONDS / MILLISECONDS) + }), + )), + (Time32(TimeUnit::Millisecond), Time64(TimeUnit::Nanosecond)) => Ok(Arc::new( + as_primitive_array::(array) + .unary::<_, Time64NanosecondType>(|x| { + x as i64 * (MICROSECONDS / NANOSECONDS) + }), + )), - let values = unary::<_, _, Time32SecondType>(time_array, |x| { - x / (MILLISECONDS as i32) - }); + (Time64(TimeUnit::Microsecond), Time32(TimeUnit::Second)) => Ok(Arc::new( + as_primitive_array::(array) + .unary::<_, Time32SecondType>(|x| (x / MICROSECONDS) as i32), + )), + (Time64(TimeUnit::Microsecond), Time32(TimeUnit::Millisecond)) => Ok(Arc::new( + as_primitive_array::(array) + .unary::<_, Time32MillisecondType>(|x| { + (x / (MICROSECONDS / MILLISECONDS)) as i32 + }), + )), + (Time64(TimeUnit::Microsecond), Time64(TimeUnit::Nanosecond)) => Ok(Arc::new( + as_primitive_array::(array) + .unary::<_, Time64NanosecondType>(|x| x * (NANOSECONDS / MICROSECONDS)), + )), - Ok(Arc::new(values) as ArrayRef) - } - //(Time32(TimeUnit::Second), Time64(_)) => {}, - (Time32(from_unit), Time64(to_unit)) => { - let time_array = Int32Array::from(array.data().clone()); - // note: (numeric_cast + SIMD multiply) is faster than (cast & multiply) - let c: Int64Array = numeric_cast(&time_array); - let from_size = time_unit_multiple(from_unit); - let to_size = time_unit_multiple(to_unit); - // from is only smaller than to if 64milli/64second don't exist - let mult = Int64Array::from(vec![to_size / from_size; array.len()]); - let converted = multiply(&c, &mult)?; - let array_ref = Arc::new(converted) as ArrayRef; - use TimeUnit::*; - match to_unit { - Microsecond => cast_array_data::( - &array_ref, - to_type.clone(), - ), - Nanosecond => cast_array_data::( - &array_ref, - to_type.clone(), - ), - _ => unreachable!("array type not supported"), - } - } - (Time64(TimeUnit::Microsecond), Time64(TimeUnit::Nanosecond)) => { - let time_array = array - .as_any() - .downcast_ref::() - .unwrap(); + (Time64(TimeUnit::Nanosecond), Time32(TimeUnit::Second)) => Ok(Arc::new( + as_primitive_array::(array) + .unary::<_, Time32SecondType>(|x| (x / NANOSECONDS) as i32), + )), + (Time64(TimeUnit::Nanosecond), Time32(TimeUnit::Millisecond)) => Ok(Arc::new( + as_primitive_array::(array) + .unary::<_, Time32MillisecondType>(|x| { + (x / (NANOSECONDS / MILLISECONDS)) as i32 + }), + )), + (Time64(TimeUnit::Nanosecond), Time64(TimeUnit::Microsecond)) => Ok(Arc::new( + as_primitive_array::(array) + .unary::<_, Time64MicrosecondType>(|x| x / (NANOSECONDS / MICROSECONDS)), + )), - let values = - unary::<_, _, Time64NanosecondType>(time_array, |x| x * MILLISECONDS); - Ok(Arc::new(values) as ArrayRef) + (Timestamp(TimeUnit::Second, _), Int64) => { + cast_reinterpret_arrays::(array) } - (Time64(TimeUnit::Nanosecond), Time64(TimeUnit::Microsecond)) => { - let time_array = array - .as_any() - .downcast_ref::() - .unwrap(); - - let values = - unary::<_, _, Time64MicrosecondType>(time_array, |x| x / MILLISECONDS); - Ok(Arc::new(values) as ArrayRef) + (Timestamp(TimeUnit::Millisecond, _), Int64) => { + cast_reinterpret_arrays::(array) } - (Time64(from_unit), Time32(to_unit)) => { - let time_array = Int64Array::from(array.data().clone()); - let from_size = time_unit_multiple(from_unit); - let to_size = time_unit_multiple(to_unit); - let divisor = from_size / to_size; - match to_unit { - TimeUnit::Second => { - let values = unary::<_, _, Time32SecondType>(&time_array, |x| { - (x as i64 / divisor) as i32 - }); - Ok(Arc::new(values) as ArrayRef) - } - TimeUnit::Millisecond => { - let values = unary::<_, _, Time32MillisecondType>(&time_array, |x| { - (x as i64 / divisor) as i32 - }); - Ok(Arc::new(values) as ArrayRef) - } - _ => unreachable!("array type not supported"), - } + (Timestamp(TimeUnit::Microsecond, _), Int64) => { + cast_reinterpret_arrays::(array) } - (Timestamp(_, _), Int64) => cast_array_data::(array, to_type.clone()), - (Int64, Timestamp(to_unit, _)) => { - use TimeUnit::*; - match to_unit { - Second => cast_array_data::(array, to_type.clone()), - Millisecond => { - cast_array_data::(array, to_type.clone()) - } - Microsecond => { - cast_array_data::(array, to_type.clone()) - } - Nanosecond => { - cast_array_data::(array, to_type.clone()) - } - } + (Timestamp(TimeUnit::Nanosecond, _), Int64) => { + cast_reinterpret_arrays::(array) } - (Timestamp(from_unit, _), Timestamp(to_unit, _)) => { + + (Int64, Timestamp(unit, tz)) => Ok(make_timestamp_array( + as_primitive_array(array), + unit.clone(), + tz.clone(), + )), + + (Timestamp(from_unit, _), Timestamp(to_unit, to_tz)) => { let time_array = Int64Array::from(array.data().clone()); let from_size = time_unit_multiple(from_unit); let to_size = time_unit_multiple(to_unit); @@ -1329,30 +1321,13 @@ pub fn cast_with_options( let converted = if from_size >= to_size { divide_scalar(&time_array, from_size / to_size)? } else { - multiply( - &time_array, - &Int64Array::from(vec![to_size / from_size; array.len()]), - )? + multiply_scalar(&time_array, to_size / from_size)? }; - let array_ref = Arc::new(converted) as ArrayRef; - use TimeUnit::*; - match to_unit { - Second => { - cast_array_data::(&array_ref, to_type.clone()) - } - Millisecond => cast_array_data::( - &array_ref, - to_type.clone(), - ), - Microsecond => cast_array_data::( - &array_ref, - to_type.clone(), - ), - Nanosecond => cast_array_data::( - &array_ref, - to_type.clone(), - ), - } + Ok(make_timestamp_array( + &converted, + to_unit.clone(), + to_tz.clone(), + )) } (Timestamp(from_unit, _), Date32) => { let time_array = Int64Array::from(array.data().clone()); @@ -1371,80 +1346,61 @@ pub fn cast_with_options( Ok(Arc::new(b.finish()) as ArrayRef) } - (Timestamp(from_unit, _), Date64) => { - let from_size = time_unit_multiple(from_unit); - let to_size = MILLISECONDS; - - // Scale time_array by (to_size / from_size) using a - // single integer operation, but need to avoid integer - // math rounding down to zero - - match to_size.cmp(&from_size) { - std::cmp::Ordering::Less => { - let time_array = Date64Array::from(array.data().clone()); - Ok(Arc::new(divide( - &time_array, - &Date64Array::from(vec![from_size / to_size; array.len()]), - )?) as ArrayRef) - } - std::cmp::Ordering::Equal => { - cast_array_data::(array, to_type.clone()) - } - std::cmp::Ordering::Greater => { - let time_array = Date64Array::from(array.data().clone()); - Ok(Arc::new(multiply( - &time_array, - &Date64Array::from(vec![to_size / from_size; array.len()]), - )?) as ArrayRef) - } - } + (Timestamp(TimeUnit::Second, _), Date64) => Ok(Arc::new( + as_primitive_array::(array) + .unary::<_, Date64Type>(|x| x * MILLISECONDS), + )), + (Timestamp(TimeUnit::Millisecond, _), Date64) => { + cast_reinterpret_arrays::(array) } + (Timestamp(TimeUnit::Microsecond, _), Date64) => Ok(Arc::new( + as_primitive_array::(array) + .unary::<_, Date64Type>(|x| x / (MICROSECONDS / MILLISECONDS)), + )), + (Timestamp(TimeUnit::Nanosecond, _), Date64) => Ok(Arc::new( + as_primitive_array::(array) + .unary::<_, Date64Type>(|x| x / (NANOSECONDS / MILLISECONDS)), + )), + // date64 to timestamp might not make sense, - (Int64, Duration(to_unit)) => { - use TimeUnit::*; - match to_unit { - Second => cast_array_data::(array, to_type.clone()), - Millisecond => { - cast_array_data::(array, to_type.clone()) - } - Microsecond => { - cast_array_data::(array, to_type.clone()) - } - Nanosecond => { - cast_array_data::(array, to_type.clone()) - } - } + (Int64, Duration(TimeUnit::Second)) => { + cast_reinterpret_arrays::(array) + } + (Int64, Duration(TimeUnit::Millisecond)) => { + cast_reinterpret_arrays::(array) + } + (Int64, Duration(TimeUnit::Microsecond)) => { + cast_reinterpret_arrays::(array) + } + (Int64, Duration(TimeUnit::Nanosecond)) => { + cast_reinterpret_arrays::(array) + } + + (Duration(TimeUnit::Second), Int64) => { + cast_reinterpret_arrays::(array) + } + (Duration(TimeUnit::Millisecond), Int64) => { + cast_reinterpret_arrays::(array) + } + (Duration(TimeUnit::Microsecond), Int64) => { + cast_reinterpret_arrays::(array) + } + (Duration(TimeUnit::Nanosecond), Int64) => { + cast_reinterpret_arrays::(array) + } + + (Interval(IntervalUnit::YearMonth), Int64) => { + cast_numeric_arrays::(array, cast_options) + } + (Interval(IntervalUnit::DayTime), Int64) => { + cast_reinterpret_arrays::(array) + } + (Int32, Interval(IntervalUnit::YearMonth)) => { + cast_reinterpret_arrays::(array) + } + (Int64, Interval(IntervalUnit::DayTime)) => { + cast_reinterpret_arrays::(array) } - (Duration(_), Int64) => cast_array_data::(array, to_type.clone()), - (Interval(from_type), Int64) => match from_type { - IntervalUnit::YearMonth => cast_numeric_arrays::< - IntervalYearMonthType, - Int64Type, - >(array, cast_options), - IntervalUnit::DayTime => cast_array_data::(array, to_type.clone()), - IntervalUnit::MonthDayNano => Err(ArrowError::CastError(format!( - "Casting from {:?} to {:?} not supported", - from_type, to_type, - ))), - }, - (Int32, Interval(to_type)) => match to_type { - IntervalUnit::YearMonth => { - cast_array_data::(array, Interval(to_type.clone())) - } - _ => Err(ArrowError::CastError(format!( - "Casting from {:?} to {:?} not supported", - from_type, to_type, - ))), - }, - (Int64, Interval(to_type)) => match to_type { - IntervalUnit::DayTime => { - cast_array_data::(array, Interval(to_type.clone())) - } - _ => Err(ArrowError::CastError(format!( - "Casting from {:?} to {:?} not supported", - from_type, to_type, - ))), - }, (_, _) => Err(ArrowError::CastError(format!( "Casting from {:?} to {:?} not supported", from_type, to_type, @@ -1617,33 +1573,6 @@ fn cast_decimal_to_decimal( } } -/// Cast an array by changing its array_data type to the desired type -/// -/// Arrays should have the same primitive data type, otherwise this should fail. -/// We do not perform this check on primitive data types as we only use this -/// function internally, where it is guaranteed to be infallible. -fn cast_array_data(array: &ArrayRef, to_type: DataType) -> Result -where - TO: ArrowNumericType, -{ - let data = unsafe { - ArrayData::new_unchecked( - to_type, - array.len(), - Some(array.null_count()), - array - .data() - .null_bitmap() - .cloned() - .map(|bitmap| bitmap.into_buffer()), - array.data().offset(), - array.data().buffers().to_vec(), - vec![], - ) - }; - Ok(Arc::new(PrimitiveArray::::from(data)) as ArrayRef) -} - /// Convert Array into a PrimitiveArray of type, and apply numeric cast fn cast_numeric_arrays( from: &ArrayRef, @@ -1652,8 +1581,8 @@ fn cast_numeric_arrays( where FROM: ArrowNumericType, TO: ArrowNumericType, - FROM::Native: num::NumCast, - TO::Native: num::NumCast, + FROM::Native: NumCast, + TO::Native: NumCast, { if cast_options.safe { // If the value can't be casted to the `TO::Native`, return null @@ -1678,8 +1607,8 @@ fn try_numeric_cast(from: &PrimitiveArray) -> Result> where T: ArrowNumericType, R: ArrowNumericType, - T::Native: num::NumCast, - R::Native: num::NumCast, + T::Native: NumCast, + R::Native: NumCast, { try_unary(from, |value| { num::cast::cast::(value).ok_or_else(|| { @@ -1698,8 +1627,8 @@ fn numeric_cast(from: &PrimitiveArray) -> PrimitiveArray where T: ArrowNumericType, R: ArrowNumericType, - T::Native: num::NumCast, - R::Native: num::NumCast, + T::Native: NumCast, + R::Native: NumCast, { let iter = from .iter()