@@ -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 MICROS_PER_NANO : 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 * MICROS_PER_NANO ,
1216+ ) ) ,
1217+ (
1218+ PrimitiveLiteral :: Int ( val) ,
1219+ PrimitiveType :: Date ,
1220+ PrimitiveType :: TimestamptzNs ,
1221+ ) => Ok ( Datum :: timestamptz_nanos (
1222+ * val as i64 * MICROS_PER_DAY * MICROS_PER_NANO ,
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 / MICROS_PER_NANO ) ) ,
12331258 (
12341259 PrimitiveType :: TimestampNs | PrimitiveType :: TimestamptzNs ,
12351260 PrimitiveType :: Timestamptz ,
1236- ) => Ok ( Datum :: timestamptz_micros ( val / 1000 ) ) ,
1261+ ) => Ok ( Datum :: timestamptz_micros ( val / MICROS_PER_NANO ) ) ,
12371262 (
12381263 PrimitiveType :: Timestamp | PrimitiveType :: Timestamptz ,
12391264 PrimitiveType :: TimestampNs ,
1240- ) => Ok ( Datum :: timestamp_nanos ( val * 1000 ) ) ,
1265+ ) => Ok ( Datum :: timestamp_nanos ( val * MICROS_PER_NANO ) ) ,
12411266 (
12421267 PrimitiveType :: Timestamp | PrimitiveType :: Timestamptz ,
12431268 PrimitiveType :: TimestamptzNs ,
1244- ) => Ok ( Datum :: timestamptz_nanos ( val * 1000 ) ) ,
1269+ ) => Ok ( Datum :: timestamptz_nanos ( val * MICROS_PER_NANO ) ) ,
12451270 _ => Err ( Error :: new (
12461271 ErrorKind :: DataInvalid ,
12471272 format ! (
@@ -4166,4 +4191,77 @@ mod tests {
41664191
41674192 assert_eq ! ( result, expected) ;
41684193 }
4194+
4195+ #[ test]
4196+ fn test_datum_date_convert_to_timestamp ( ) {
4197+ let datum = Datum :: date ( 1 ) ; // 1970-01-02
4198+
4199+ let result = datum. to ( & Primitive ( PrimitiveType :: Timestamp ) ) . unwrap ( ) ;
4200+
4201+ let expected = Datum :: timestamp_from_datetime (
4202+ DateTime :: parse_from_rfc3339 ( "1970-01-02T00:00:00Z" )
4203+ . unwrap ( )
4204+ . naive_utc ( ) ,
4205+ ) ;
4206+
4207+ assert_eq ! ( result, expected) ;
4208+ }
4209+
4210+ #[ test]
4211+ fn test_datum_date_convert_to_timestamptz ( ) {
4212+ let datum = Datum :: date ( 1 ) ;
4213+
4214+ let result = datum. to ( & Primitive ( PrimitiveType :: Timestamptz ) ) . unwrap ( ) ;
4215+
4216+ let expected = Datum :: timestamptz_from_str ( "1970-01-02T00:00:00Z" ) . unwrap ( ) ;
4217+
4218+ assert_eq ! ( result, expected) ;
4219+ }
4220+
4221+ #[ test]
4222+ fn test_datum_date_convert_to_timestamp_nanos ( ) {
4223+ let datum = Datum :: date ( 1 ) ;
4224+
4225+ let result = datum. to ( & Primitive ( PrimitiveType :: TimestampNs ) ) . unwrap ( ) ;
4226+
4227+ let expected = Datum :: timestamp_from_datetime (
4228+ DateTime :: parse_from_rfc3339 ( "1970-01-02T00:00:00Z" )
4229+ . unwrap ( )
4230+ . naive_utc ( ) ,
4231+ )
4232+ . to ( & Primitive ( PrimitiveType :: TimestampNs ) )
4233+ . unwrap ( ) ;
4234+
4235+ assert_eq ! ( result, expected) ;
4236+ }
4237+
4238+ #[ test]
4239+ fn test_datum_date_convert_to_timestamptz_nanos ( ) {
4240+ let datum = Datum :: date ( 1 ) ;
4241+
4242+ let result = datum. to ( & Primitive ( PrimitiveType :: TimestamptzNs ) ) . unwrap ( ) ;
4243+
4244+ let expected = Datum :: timestamptz_from_datetime (
4245+ DateTime :: parse_from_rfc3339 ( "1970-01-02T00:00:00Z" ) . unwrap ( ) ,
4246+ )
4247+ . to ( & Primitive ( PrimitiveType :: TimestamptzNs ) )
4248+ . unwrap ( ) ;
4249+
4250+ assert_eq ! ( result, expected) ;
4251+ }
4252+
4253+ #[ test]
4254+ fn test_datum_date_negative_convert_to_timestamp ( ) {
4255+ let datum = Datum :: date ( -1 ) ;
4256+
4257+ let result = datum. to ( & Primitive ( PrimitiveType :: Timestamp ) ) . unwrap ( ) ;
4258+
4259+ let expected = Datum :: timestamp_from_datetime (
4260+ DateTime :: parse_from_rfc3339 ( "1969-12-31T00:00:00Z" )
4261+ . unwrap ( )
4262+ . naive_utc ( ) ,
4263+ ) ;
4264+
4265+ assert_eq ! ( result, expected) ;
4266+ }
41694267}
0 commit comments