@@ -60,6 +60,9 @@ const INT_MIN: i32 = -2147483648;
6060const LONG_MAX : i64 = 9223372036854775807 ;
6161const LONG_MIN : i64 = -9223372036854775808 ;
6262
63+ const MICROS_PER_DAY : i64 = 24 * 60 * 60 * 1_000_000 ;
64+ const NANOS_PER_MICRO : i64 = 1000 ;
65+
6366/// Values present in iceberg type
6467#[ derive( Clone , Debug , PartialOrd , PartialEq , Hash , Eq ) ]
6568pub enum PrimitiveLiteral {
@@ -1196,6 +1199,28 @@ impl Datum {
11961199 ( PrimitiveLiteral :: Int ( val) , _, PrimitiveType :: Int ) => Ok ( Datum :: int ( * val) ) ,
11971200 ( PrimitiveLiteral :: Int ( val) , _, PrimitiveType :: Date ) => Ok ( Datum :: date ( * val) ) ,
11981201 ( PrimitiveLiteral :: Int ( val) , _, PrimitiveType :: Long ) => Ok ( Datum :: long ( * val) ) ,
1202+ ( PrimitiveLiteral :: Int ( val) , PrimitiveType :: Date , PrimitiveType :: Timestamp ) => {
1203+ Ok ( Datum :: timestamp_micros ( * val as i64 * MICROS_PER_DAY ) )
1204+ }
1205+ (
1206+ PrimitiveLiteral :: Int ( val) ,
1207+ PrimitiveType :: Date ,
1208+ PrimitiveType :: Timestamptz ,
1209+ ) => Ok ( Datum :: timestamptz_micros ( * val as i64 * MICROS_PER_DAY ) ) ,
1210+ (
1211+ PrimitiveLiteral :: Int ( val) ,
1212+ PrimitiveType :: Date ,
1213+ PrimitiveType :: TimestampNs ,
1214+ ) => Ok ( Datum :: timestamp_nanos (
1215+ * val as i64 * MICROS_PER_DAY * NANOS_PER_MICRO ,
1216+ ) ) ,
1217+ (
1218+ PrimitiveLiteral :: Int ( val) ,
1219+ PrimitiveType :: Date ,
1220+ PrimitiveType :: TimestamptzNs ,
1221+ ) => Ok ( Datum :: timestamptz_nanos (
1222+ * val as i64 * MICROS_PER_DAY * NANOS_PER_MICRO ,
1223+ ) ) ,
11991224 ( PrimitiveLiteral :: Long ( val) , _, PrimitiveType :: Int ) => {
12001225 Ok ( Datum :: i64_to_i32 ( * val) )
12011226 }
@@ -1229,19 +1254,19 @@ impl Datum {
12291254 (
12301255 PrimitiveType :: TimestampNs | PrimitiveType :: TimestamptzNs ,
12311256 PrimitiveType :: Timestamp ,
1232- ) => Ok ( Datum :: timestamp_micros ( val / 1000 ) ) ,
1257+ ) => Ok ( Datum :: timestamp_micros ( val / NANOS_PER_MICRO ) ) ,
12331258 (
12341259 PrimitiveType :: TimestampNs | PrimitiveType :: TimestamptzNs ,
12351260 PrimitiveType :: Timestamptz ,
1236- ) => Ok ( Datum :: timestamptz_micros ( val / 1000 ) ) ,
1261+ ) => Ok ( Datum :: timestamptz_micros ( val / NANOS_PER_MICRO ) ) ,
12371262 (
12381263 PrimitiveType :: Timestamp | PrimitiveType :: Timestamptz ,
12391264 PrimitiveType :: TimestampNs ,
1240- ) => Ok ( Datum :: timestamp_nanos ( val * 1000 ) ) ,
1265+ ) => Ok ( Datum :: timestamp_nanos ( val * NANOS_PER_MICRO ) ) ,
12411266 (
12421267 PrimitiveType :: Timestamp | PrimitiveType :: Timestamptz ,
12431268 PrimitiveType :: TimestamptzNs ,
1244- ) => Ok ( Datum :: timestamptz_nanos ( val * 1000 ) ) ,
1269+ ) => Ok ( Datum :: timestamptz_nanos ( val * NANOS_PER_MICRO ) ) ,
12451270 _ => Err ( Error :: new (
12461271 ErrorKind :: DataInvalid ,
12471272 format ! (
@@ -3990,7 +4015,6 @@ mod tests {
39904015 assert_eq ! ( double_sorted, double_expected) ;
39914016 }
39924017
3993- // Tests for timestamp nanosecond conversions
39944018 #[ test]
39954019 fn test_datum_timestamp_nanos_convert_to_timestamp_micros ( ) {
39964020 let datum = Datum :: timestamp_nanos ( 12345000 ) ;
@@ -4166,4 +4190,77 @@ mod tests {
41664190
41674191 assert_eq ! ( result, expected) ;
41684192 }
4193+
4194+ #[ test]
4195+ fn test_datum_date_convert_to_timestamp ( ) {
4196+ let datum = Datum :: date ( 1 ) ; // 1970-01-02
4197+
4198+ let result = datum. to ( & Primitive ( PrimitiveType :: Timestamp ) ) . unwrap ( ) ;
4199+
4200+ let expected = Datum :: timestamp_from_datetime (
4201+ DateTime :: parse_from_rfc3339 ( "1970-01-02T00:00:00Z" )
4202+ . unwrap ( )
4203+ . naive_utc ( ) ,
4204+ ) ;
4205+
4206+ assert_eq ! ( result, expected) ;
4207+ }
4208+
4209+ #[ test]
4210+ fn test_datum_date_convert_to_timestamptz ( ) {
4211+ let datum = Datum :: date ( 1 ) ;
4212+
4213+ let result = datum. to ( & Primitive ( PrimitiveType :: Timestamptz ) ) . unwrap ( ) ;
4214+
4215+ let expected = Datum :: timestamptz_from_str ( "1970-01-02T00:00:00Z" ) . unwrap ( ) ;
4216+
4217+ assert_eq ! ( result, expected) ;
4218+ }
4219+
4220+ #[ test]
4221+ fn test_datum_date_convert_to_timestamp_nanos ( ) {
4222+ let datum = Datum :: date ( 1 ) ;
4223+
4224+ let result = datum. to ( & Primitive ( PrimitiveType :: TimestampNs ) ) . unwrap ( ) ;
4225+
4226+ let expected = Datum :: timestamp_from_datetime (
4227+ DateTime :: parse_from_rfc3339 ( "1970-01-02T00:00:00Z" )
4228+ . unwrap ( )
4229+ . naive_utc ( ) ,
4230+ )
4231+ . to ( & Primitive ( PrimitiveType :: TimestampNs ) )
4232+ . unwrap ( ) ;
4233+
4234+ assert_eq ! ( result, expected) ;
4235+ }
4236+
4237+ #[ test]
4238+ fn test_datum_date_convert_to_timestamptz_nanos ( ) {
4239+ let datum = Datum :: date ( 1 ) ;
4240+
4241+ let result = datum. to ( & Primitive ( PrimitiveType :: TimestamptzNs ) ) . unwrap ( ) ;
4242+
4243+ let expected = Datum :: timestamptz_from_datetime (
4244+ DateTime :: parse_from_rfc3339 ( "1970-01-02T00:00:00Z" ) . unwrap ( ) ,
4245+ )
4246+ . to ( & Primitive ( PrimitiveType :: TimestamptzNs ) )
4247+ . unwrap ( ) ;
4248+
4249+ assert_eq ! ( result, expected) ;
4250+ }
4251+
4252+ #[ test]
4253+ fn test_datum_date_negative_convert_to_timestamp ( ) {
4254+ let datum = Datum :: date ( -1 ) ;
4255+
4256+ let result = datum. to ( & Primitive ( PrimitiveType :: Timestamp ) ) . unwrap ( ) ;
4257+
4258+ let expected = Datum :: timestamp_from_datetime (
4259+ DateTime :: parse_from_rfc3339 ( "1969-12-31T00:00:00Z" )
4260+ . unwrap ( )
4261+ . naive_utc ( ) ,
4262+ ) ;
4263+
4264+ assert_eq ! ( result, expected) ;
4265+ }
41694266}
0 commit comments