@@ -400,16 +400,40 @@ fn try_cast_literal_to_type(
400400 DataType :: UInt32 => ScalarValue :: UInt32 ( Some ( value as u32 ) ) ,
401401 DataType :: UInt64 => ScalarValue :: UInt64 ( Some ( value as u64 ) ) ,
402402 DataType :: Timestamp ( TimeUnit :: Second , tz) => {
403- ScalarValue :: TimestampSecond ( Some ( value as i64 ) , tz. clone ( ) )
403+ let value = cast_between_timestamp (
404+ lit_data_type,
405+ DataType :: Timestamp ( TimeUnit :: Second , tz. clone ( ) ) ,
406+ value,
407+ )
408+ . unwrap ( ) ;
409+ ScalarValue :: TimestampSecond ( Some ( value) , tz. clone ( ) )
404410 }
405411 DataType :: Timestamp ( TimeUnit :: Millisecond , tz) => {
406- ScalarValue :: TimestampMillisecond ( Some ( value as i64 ) , tz. clone ( ) )
412+ let value = cast_between_timestamp (
413+ lit_data_type,
414+ DataType :: Timestamp ( TimeUnit :: Millisecond , tz. clone ( ) ) ,
415+ value,
416+ )
417+ . unwrap ( ) ;
418+ ScalarValue :: TimestampMillisecond ( Some ( value) , tz. clone ( ) )
407419 }
408420 DataType :: Timestamp ( TimeUnit :: Microsecond , tz) => {
409- ScalarValue :: TimestampMicrosecond ( Some ( value as i64 ) , tz. clone ( ) )
421+ let value = cast_between_timestamp (
422+ lit_data_type,
423+ DataType :: Timestamp ( TimeUnit :: Microsecond , tz. clone ( ) ) ,
424+ value,
425+ )
426+ . unwrap ( ) ;
427+ ScalarValue :: TimestampMicrosecond ( Some ( value) , tz. clone ( ) )
410428 }
411429 DataType :: Timestamp ( TimeUnit :: Nanosecond , tz) => {
412- ScalarValue :: TimestampNanosecond ( Some ( value as i64 ) , tz. clone ( ) )
430+ let value = cast_between_timestamp (
431+ lit_data_type,
432+ DataType :: Timestamp ( TimeUnit :: Nanosecond , tz. clone ( ) ) ,
433+ value,
434+ )
435+ . unwrap ( ) ;
436+ ScalarValue :: TimestampNanosecond ( Some ( value) , tz. clone ( ) )
413437 }
414438 DataType :: Decimal128 ( p, s) => {
415439 ScalarValue :: Decimal128 ( Some ( value) , * p, * s)
@@ -428,6 +452,31 @@ fn try_cast_literal_to_type(
428452 }
429453}
430454
455+ /// Cast a timestamp value from one unit to another
456+ fn cast_between_timestamp ( from : DataType , to : DataType , value : i128 ) -> Option < i64 > {
457+ let seconds = match from {
458+ DataType :: Timestamp ( TimeUnit :: Second , _) => Some ( value * 1000 * 1000 * 1000 ) ,
459+ DataType :: Timestamp ( TimeUnit :: Millisecond , _) => Some ( value * 1000 * 1000 ) ,
460+ DataType :: Timestamp ( TimeUnit :: Microsecond , _) => Some ( value * 1000 ) ,
461+ DataType :: Timestamp ( TimeUnit :: Nanosecond , _) => Some ( value) ,
462+ _ => return Some ( value as i64 ) ,
463+ } ;
464+
465+ match to {
466+ DataType :: Timestamp ( TimeUnit :: Second , _) => {
467+ seconds. map ( |s| ( s / 1000 / 1000 / 1000 ) as i64 )
468+ }
469+ DataType :: Timestamp ( TimeUnit :: Millisecond , _) => {
470+ seconds. map ( |s| ( s / 1000 / 1000 ) as i64 )
471+ }
472+ DataType :: Timestamp ( TimeUnit :: Microsecond , _) => {
473+ seconds. map ( |s| ( s / 1000 ) as i64 )
474+ }
475+ DataType :: Timestamp ( TimeUnit :: Nanosecond , _) => seconds. map ( |s| s as i64 ) ,
476+ _ => None ,
477+ }
478+ }
479+
431480#[ cfg( test) ]
432481mod tests {
433482 use super :: * ;
@@ -1070,4 +1119,19 @@ mod tests {
10701119 }
10711120 }
10721121 }
1122+
1123+ #[ test]
1124+ fn test_try_cast_literal_to_timestamp ( ) {
1125+ let new_scalar = try_cast_literal_to_type (
1126+ & ScalarValue :: TimestampNanosecond ( Some ( 123456 ) , None ) ,
1127+ & DataType :: Timestamp ( TimeUnit :: Microsecond , None ) ,
1128+ )
1129+ . unwrap ( )
1130+ . unwrap ( ) ;
1131+
1132+ assert_eq ! (
1133+ new_scalar,
1134+ ScalarValue :: TimestampMicrosecond ( Some ( 123 ) , None )
1135+ ) ;
1136+ }
10731137}
0 commit comments