@@ -312,7 +312,7 @@ pub fn can_cast_types(from_type: &DataType, to_type: &DataType) -> bool {
312312 // temporal casts
313313 ( Int32 , Date32 | Date64 | Time32 ( _) ) => true ,
314314 ( Date32 , Int32 | Int64 ) => true ,
315- ( Time32 ( _) , Int32 ) => true ,
315+ ( Time32 ( _) , Int32 | Int64 ) => true ,
316316 ( Int64 , Date64 | Date32 | Time64 ( _) ) => true ,
317317 ( Date64 , Int64 | Int32 ) => true ,
318318 ( Time64 ( _) , Int64 ) => true ,
@@ -1698,6 +1698,16 @@ pub fn cast_with_options(
16981698 ( Time32 ( TimeUnit :: Millisecond ) , Int32 ) => {
16991699 cast_reinterpret_arrays :: < Time32MillisecondType , Int32Type > ( array)
17001700 }
1701+ ( Time32 ( TimeUnit :: Second ) , Int64 ) => cast_with_options (
1702+ & cast_with_options ( array, & Int32 , cast_options) ?,
1703+ & Int64 ,
1704+ cast_options,
1705+ ) ,
1706+ ( Time32 ( TimeUnit :: Millisecond ) , Int64 ) => cast_with_options (
1707+ & cast_with_options ( array, & Int32 , cast_options) ?,
1708+ & Int64 ,
1709+ cast_options,
1710+ ) ,
17011711 ( Int64 , Date64 ) => cast_reinterpret_arrays :: < Int64Type , Date64Type > ( array) ,
17021712 ( Int64 , Date32 ) => cast_with_options (
17031713 & cast_with_options ( array, & Int32 , cast_options) ?,
@@ -12079,4 +12089,83 @@ mod tests {
1207912089 // Verify the run-ends were cast correctly (run ends at 3, 6, 9)
1208012090 assert_eq ! ( run_array. run_ends( ) . values( ) , & [ 3i64 , 6i64 , 9i64 ] ) ;
1208112091 }
12092+
12093+ #[ test]
12094+ fn test_cast_time32_second_to_int64 ( ) {
12095+ let array = Time32SecondArray :: from ( vec ! [ 1000 , 2000 , 3000 ] ) ;
12096+ let array = Arc :: new ( array) as Arc < dyn Array > ;
12097+ let to_type = DataType :: Int64 ;
12098+ let cast_options = CastOptions :: default ( ) ;
12099+
12100+ assert ! ( can_cast_types( array. data_type( ) , & to_type) ) ;
12101+
12102+ let result = cast_with_options ( & array, & to_type, & cast_options) ;
12103+ assert ! (
12104+ result. is_ok( ) ,
12105+ "Failed to cast Time32(Second) to Int64: {:?}" ,
12106+ result. err( )
12107+ ) ;
12108+
12109+ let cast_array = result. unwrap ( ) ;
12110+ let cast_array = cast_array. as_any ( ) . downcast_ref :: < Int64Array > ( ) . unwrap ( ) ;
12111+
12112+ assert_eq ! ( cast_array. value( 0 ) , 1000 ) ;
12113+ assert_eq ! ( cast_array. value( 1 ) , 2000 ) ;
12114+ assert_eq ! ( cast_array. value( 2 ) , 3000 ) ;
12115+ }
12116+
12117+ #[ test]
12118+ fn test_cast_time32_millisecond_to_int64 ( ) {
12119+ let array = Time32MillisecondArray :: from ( vec ! [ 1000 , 2000 , 3000 ] ) ;
12120+ let array = Arc :: new ( array) as Arc < dyn Array > ;
12121+ let to_type = DataType :: Int64 ;
12122+ let cast_options = CastOptions :: default ( ) ;
12123+
12124+ assert ! ( can_cast_types( array. data_type( ) , & to_type) ) ;
12125+
12126+ let result = cast_with_options ( & array, & to_type, & cast_options) ;
12127+ assert ! (
12128+ result. is_ok( ) ,
12129+ "Failed to cast Time32(Millisecond) to Int64: {:?}" ,
12130+ result. err( )
12131+ ) ;
12132+
12133+ let cast_array = result. unwrap ( ) ;
12134+ let cast_array = cast_array. as_any ( ) . downcast_ref :: < Int64Array > ( ) . unwrap ( ) ;
12135+
12136+ assert_eq ! ( cast_array. value( 0 ) , 1000 ) ;
12137+ assert_eq ! ( cast_array. value( 1 ) , 2000 ) ;
12138+ assert_eq ! ( cast_array. value( 2 ) , 3000 ) ;
12139+ }
12140+
12141+ #[ test]
12142+ fn test_cast_string_to_time32_second_to_int64 ( ) {
12143+ // Mimic: select arrow_cast('03:12:44'::time, 'Time32(Second)')::bigint;
12144+ // raised in https://github.com/apache/datafusion/issues/19036
12145+ let array = StringArray :: from ( vec ! [ "03:12:44" ] ) ;
12146+ let array = Arc :: new ( array) as Arc < dyn Array > ;
12147+ let cast_options = CastOptions :: default ( ) ;
12148+
12149+ // 1. Cast String to Time32(Second)
12150+ let time32_type = DataType :: Time32 ( TimeUnit :: Second ) ;
12151+ let time32_array = cast_with_options ( & array, & time32_type, & cast_options) . unwrap ( ) ;
12152+
12153+ // 2. Cast Time32(Second) to Int64
12154+ let int64_type = DataType :: Int64 ;
12155+ assert ! ( can_cast_types( time32_array. data_type( ) , & int64_type) ) ;
12156+
12157+ let result = cast_with_options ( & time32_array, & int64_type, & cast_options) ;
12158+
12159+ assert ! (
12160+ result. is_ok( ) ,
12161+ "Failed to cast Time32(Second) to Int64: {:?}" ,
12162+ result. err( )
12163+ ) ;
12164+
12165+ let cast_array = result. unwrap ( ) ;
12166+ let cast_array = cast_array. as_any ( ) . downcast_ref :: < Int64Array > ( ) . unwrap ( ) ;
12167+
12168+ // 03:12:44 = 3*3600 + 12*60 + 44 = 10800 + 720 + 44 = 11564
12169+ assert_eq ! ( cast_array. value( 0 ) , 11564 ) ;
12170+ }
1208212171}
0 commit comments