@@ -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,29 @@ 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 ) ) ,
1270+ (
1271+ PrimitiveType :: Timestamp | PrimitiveType :: Timestamptz ,
1272+ PrimitiveType :: Date ,
1273+ ) => Ok ( Datum :: date ( ( val / MICROS_PER_DAY ) as i32 ) ) ,
1274+ (
1275+ PrimitiveType :: TimestampNs | PrimitiveType :: TimestamptzNs ,
1276+ PrimitiveType :: Date ,
1277+ ) => Ok ( Datum :: date (
1278+ ( val / ( MICROS_PER_DAY * NANOS_PER_MICRO ) ) as i32 ,
1279+ ) ) ,
12451280 _ => Err ( Error :: new (
12461281 ErrorKind :: DataInvalid ,
12471282 format ! (
@@ -4176,4 +4211,125 @@ mod tests {
41764211
41774212 assert_eq ! ( result, expected) ;
41784213 }
4214+
4215+ #[ test]
4216+ fn test_datum_date_convert_to_timestamp ( ) {
4217+ let datum = Datum :: date ( 1 ) ; // 1970-01-02
4218+
4219+ let result = datum. to ( & Primitive ( PrimitiveType :: Timestamp ) ) . unwrap ( ) ;
4220+
4221+ let expected = Datum :: timestamp_from_datetime (
4222+ DateTime :: parse_from_rfc3339 ( "1970-01-02T00:00:00Z" )
4223+ . unwrap ( )
4224+ . naive_utc ( ) ,
4225+ ) ;
4226+
4227+ assert_eq ! ( result, expected) ;
4228+ }
4229+
4230+ #[ test]
4231+ fn test_datum_date_convert_to_timestamptz ( ) {
4232+ let datum = Datum :: date ( 1 ) ;
4233+
4234+ let result = datum. to ( & Primitive ( PrimitiveType :: Timestamptz ) ) . unwrap ( ) ;
4235+
4236+ let expected = Datum :: timestamptz_from_str ( "1970-01-02T00:00:00Z" ) . unwrap ( ) ;
4237+
4238+ assert_eq ! ( result, expected) ;
4239+ }
4240+
4241+ #[ test]
4242+ fn test_datum_date_convert_to_timestamp_nanos ( ) {
4243+ let datum = Datum :: date ( 1 ) ;
4244+
4245+ let result = datum. to ( & Primitive ( PrimitiveType :: TimestampNs ) ) . unwrap ( ) ;
4246+
4247+ let expected = Datum :: timestamp_from_datetime (
4248+ DateTime :: parse_from_rfc3339 ( "1970-01-02T00:00:00Z" )
4249+ . unwrap ( )
4250+ . naive_utc ( ) ,
4251+ )
4252+ . to ( & Primitive ( PrimitiveType :: TimestampNs ) )
4253+ . unwrap ( ) ;
4254+
4255+ assert_eq ! ( result, expected) ;
4256+ }
4257+
4258+ #[ test]
4259+ fn test_datum_date_convert_to_timestamptz_nanos ( ) {
4260+ let datum = Datum :: date ( 1 ) ;
4261+
4262+ let result = datum. to ( & Primitive ( PrimitiveType :: TimestamptzNs ) ) . unwrap ( ) ;
4263+
4264+ let expected = Datum :: timestamptz_from_datetime (
4265+ DateTime :: parse_from_rfc3339 ( "1970-01-02T00:00:00Z" ) . unwrap ( ) ,
4266+ )
4267+ . to ( & Primitive ( PrimitiveType :: TimestamptzNs ) )
4268+ . unwrap ( ) ;
4269+
4270+ assert_eq ! ( result, expected) ;
4271+ }
4272+
4273+ #[ test]
4274+ fn test_datum_date_negative_convert_to_timestamp ( ) {
4275+ let datum = Datum :: date ( -1 ) ;
4276+
4277+ let result = datum. to ( & Primitive ( PrimitiveType :: Timestamp ) ) . unwrap ( ) ;
4278+
4279+ let expected = Datum :: timestamp_from_datetime (
4280+ DateTime :: parse_from_rfc3339 ( "1969-12-31T00:00:00Z" )
4281+ . unwrap ( )
4282+ . naive_utc ( ) ,
4283+ ) ;
4284+
4285+ assert_eq ! ( result, expected) ;
4286+ }
4287+
4288+ #[ test]
4289+ fn test_datum_timestamp_convert_to_date ( ) {
4290+ let micros = 24 * 60 * 60 * 1_000_000 ; // 1 day in microseconds
4291+ let datum = Datum :: timestamp_micros ( micros) ;
4292+
4293+ let result = datum. to ( & Primitive ( PrimitiveType :: Date ) ) . unwrap ( ) ;
4294+
4295+ let expected = Datum :: date ( 1 ) ;
4296+
4297+ assert_eq ! ( result, expected) ;
4298+ }
4299+
4300+ #[ test]
4301+ fn test_datum_timestamptz_convert_to_date ( ) {
4302+ let micros = 24 * 60 * 60 * 1_000_000 ; // 1 day in microseconds
4303+ let datum = Datum :: timestamptz_micros ( micros) ;
4304+
4305+ let result = datum. to ( & Primitive ( PrimitiveType :: Date ) ) . unwrap ( ) ;
4306+
4307+ let expected = Datum :: date ( 1 ) ;
4308+
4309+ assert_eq ! ( result, expected) ;
4310+ }
4311+
4312+ #[ test]
4313+ fn test_datum_timestamp_nanos_convert_to_date ( ) {
4314+ let nanos = 24 * 60 * 60 * 1_000_000_000 ; // 1 day in nanoseconds
4315+ let datum = Datum :: timestamp_nanos ( nanos) ;
4316+
4317+ let result = datum. to ( & Primitive ( PrimitiveType :: Date ) ) . unwrap ( ) ;
4318+
4319+ let expected = Datum :: date ( 1 ) ;
4320+
4321+ assert_eq ! ( result, expected) ;
4322+ }
4323+
4324+ #[ test]
4325+ fn test_datum_timestamptz_nanos_convert_to_date ( ) {
4326+ let nanos = 24 * 60 * 60 * 1_000_000_000 ; // 1 day in nanoseconds
4327+ let datum = Datum :: timestamptz_nanos ( nanos) ;
4328+
4329+ let result = datum. to ( & Primitive ( PrimitiveType :: Date ) ) . unwrap ( ) ;
4330+
4331+ let expected = Datum :: date ( 1 ) ;
4332+
4333+ assert_eq ! ( result, expected) ;
4334+ }
41794335}
0 commit comments