@@ -221,6 +221,14 @@ pub fn can_cast_types(from_type: &DataType, to_type: &DataType) -> bool {
221221 ( Timestamp ( _, _) , Timestamp ( _, _) | Date32 | Date64 ) => true ,
222222 // date64 to timestamp might not make sense,
223223 ( Int64 , Duration ( _) ) => true ,
224+ ( Duration ( _) , Int64 ) => true ,
225+ ( Interval ( from_type) , Int64 ) => {
226+ match from_type{
227+ IntervalUnit :: YearMonth => true ,
228+ IntervalUnit :: DayTime => true ,
229+ IntervalUnit :: MonthDayNano => false , // Native type is i128
230+ }
231+ }
224232 ( _, _) => false ,
225233 }
226234}
@@ -358,7 +366,6 @@ macro_rules! cast_decimal_to_float {
358366/// * To or from `StructArray`
359367/// * List to primitive
360368/// * Utf8 to boolean
361- /// * Interval and duration
362369pub fn cast_with_options (
363370 array : & ArrayRef ,
364371 to_type : & DataType ,
@@ -1111,6 +1118,17 @@ pub fn cast_with_options(
11111118 }
11121119 }
11131120 }
1121+ ( Duration ( _) , Int64 ) => cast_array_data :: < Int64Type > ( array, to_type. clone ( ) ) ,
1122+ ( Interval ( from_type) , Int64 ) => match from_type {
1123+ IntervalUnit :: YearMonth => {
1124+ cast_numeric_arrays :: < IntervalYearMonthType , Int64Type > ( array)
1125+ }
1126+ IntervalUnit :: DayTime => cast_array_data :: < Int64Type > ( array, to_type. clone ( ) ) ,
1127+ IntervalUnit :: MonthDayNano => Err ( ArrowError :: CastError ( format ! (
1128+ "Casting from {:?} to {:?} not supported" ,
1129+ from_type, to_type,
1130+ ) ) ) ,
1131+ } ,
11141132 ( _, _) => Err ( ArrowError :: CastError ( format ! (
11151133 "Casting from {:?} to {:?} not supported" ,
11161134 from_type, to_type,
@@ -2765,6 +2783,44 @@ mod tests {
27652783 assert ! ( c. is_null( 2 ) ) ;
27662784 }
27672785
2786+ #[ test]
2787+ fn test_cast_duration_to_i64 ( ) {
2788+ let base = vec ! [ 5 , 6 , 7 , 8 , 100000000 ] ;
2789+
2790+ let duration_arrays = vec ! [
2791+ Arc :: new( DurationNanosecondArray :: from( base. clone( ) ) ) as ArrayRef ,
2792+ Arc :: new( DurationMicrosecondArray :: from( base. clone( ) ) ) as ArrayRef ,
2793+ Arc :: new( DurationMillisecondArray :: from( base. clone( ) ) ) as ArrayRef ,
2794+ Arc :: new( DurationSecondArray :: from( base. clone( ) ) ) as ArrayRef ,
2795+ ] ;
2796+
2797+ for arr in duration_arrays {
2798+ assert ! ( can_cast_types( arr. data_type( ) , & DataType :: Int64 ) ) ;
2799+ let result = cast ( & arr, & DataType :: Int64 ) . unwrap ( ) ;
2800+ let result = result. as_any ( ) . downcast_ref :: < Int64Array > ( ) . unwrap ( ) ;
2801+ assert_eq ! ( base. as_slice( ) , result. values( ) ) ;
2802+ }
2803+ }
2804+
2805+ #[ test]
2806+ fn test_cast_interval_to_i64 ( ) {
2807+ let base = vec ! [ 5 , 6 , 7 , 8 ] ;
2808+
2809+ let interval_arrays = vec ! [
2810+ Arc :: new( IntervalDayTimeArray :: from( base. clone( ) ) ) as ArrayRef ,
2811+ Arc :: new( IntervalYearMonthArray :: from(
2812+ base. iter( ) . map( |x| * x as i32 ) . collect:: <Vec <i32 >>( ) ,
2813+ ) ) as ArrayRef ,
2814+ ] ;
2815+
2816+ for arr in interval_arrays {
2817+ assert ! ( can_cast_types( arr. data_type( ) , & DataType :: Int64 ) ) ;
2818+ let result = cast ( & arr, & DataType :: Int64 ) . unwrap ( ) ;
2819+ let result = result. as_any ( ) . downcast_ref :: < Int64Array > ( ) . unwrap ( ) ;
2820+ assert_eq ! ( base. as_slice( ) , result. values( ) ) ;
2821+ }
2822+ }
2823+
27682824 #[ test]
27692825 fn test_cast_to_strings ( ) {
27702826 let a = Arc :: new ( Int32Array :: from ( vec ! [ 1 , 2 , 3 ] ) ) as ArrayRef ;
0 commit comments