@@ -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 MICROS_PER_NANO : 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 * 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
+ ) ) ,
1199
1224
( PrimitiveLiteral :: Long ( val) , _, PrimitiveType :: Int ) => {
1200
1225
Ok ( Datum :: i64_to_i32 ( * val) )
1201
1226
}
@@ -1229,19 +1254,19 @@ 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 / MICROS_PER_NANO ) ) ,
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 / MICROS_PER_NANO ) ) ,
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 * MICROS_PER_NANO ) ) ,
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 * MICROS_PER_NANO ) ) ,
1245
1270
_ => Err ( Error :: new (
1246
1271
ErrorKind :: DataInvalid ,
1247
1272
format ! (
@@ -4166,4 +4191,77 @@ mod tests {
4166
4191
4167
4192
assert_eq ! ( result, expected) ;
4168
4193
}
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
+ }
4169
4267
}
0 commit comments