@@ -60,6 +60,9 @@ const INT_MIN: i32 = -2147483648;
60
60
const LONG_MAX : i64 = 9223372036854775807 ;
61
61
const LONG_MIN : i64 = -9223372036854775808 ;
62
62
63
+ const MICROS_PER_DAY : i64 = 24 * 60 * 60 * 1_000_000 ;
64
+ const NANOS_PER_MICRO : i64 = 1000 ;
65
+
63
66
/// Values present in iceberg type
64
67
#[ derive( Clone , Debug , PartialOrd , PartialEq , Hash , Eq ) ]
65
68
pub enum PrimitiveLiteral {
@@ -1196,6 +1199,28 @@ impl Datum {
1196
1199
( PrimitiveLiteral :: Int ( val) , _, PrimitiveType :: Int ) => Ok ( Datum :: int ( * val) ) ,
1197
1200
( PrimitiveLiteral :: Int ( val) , _, PrimitiveType :: Date ) => Ok ( Datum :: date ( * val) ) ,
1198
1201
( 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
+ ) ) ,
1199
1224
( PrimitiveLiteral :: Long ( val) , _, PrimitiveType :: Int ) => {
1200
1225
Ok ( Datum :: i64_to_i32 ( * val) )
1201
1226
}
@@ -1229,19 +1254,29 @@ impl Datum {
1229
1254
(
1230
1255
PrimitiveType :: TimestampNs | PrimitiveType :: TimestamptzNs ,
1231
1256
PrimitiveType :: Timestamp ,
1232
- ) => Ok ( Datum :: timestamp_micros ( val / 1000 ) ) ,
1257
+ ) => Ok ( Datum :: timestamp_micros ( val / NANOS_PER_MICRO ) ) ,
1233
1258
(
1234
1259
PrimitiveType :: TimestampNs | PrimitiveType :: TimestamptzNs ,
1235
1260
PrimitiveType :: Timestamptz ,
1236
- ) => Ok ( Datum :: timestamptz_micros ( val / 1000 ) ) ,
1261
+ ) => Ok ( Datum :: timestamptz_micros ( val / NANOS_PER_MICRO ) ) ,
1237
1262
(
1238
1263
PrimitiveType :: Timestamp | PrimitiveType :: Timestamptz ,
1239
1264
PrimitiveType :: TimestampNs ,
1240
- ) => Ok ( Datum :: timestamp_nanos ( val * 1000 ) ) ,
1265
+ ) => Ok ( Datum :: timestamp_nanos ( val * NANOS_PER_MICRO ) ) ,
1241
1266
(
1242
1267
PrimitiveType :: Timestamp | PrimitiveType :: Timestamptz ,
1243
1268
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
+ ) ) ,
1245
1280
_ => Err ( Error :: new (
1246
1281
ErrorKind :: DataInvalid ,
1247
1282
format ! (
@@ -4176,4 +4211,125 @@ mod tests {
4176
4211
4177
4212
assert_eq ! ( result, expected) ;
4178
4213
}
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
+ }
4179
4335
}
0 commit comments