@@ -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,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 / 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 ) ) ,
1245
1270
_ => Err ( Error :: new (
1246
1271
ErrorKind :: DataInvalid ,
1247
1272
format ! (
@@ -3990,7 +4015,6 @@ mod tests {
3990
4015
assert_eq ! ( double_sorted, double_expected) ;
3991
4016
}
3992
4017
3993
- // Tests for timestamp nanosecond conversions
3994
4018
#[ test]
3995
4019
fn test_datum_timestamp_nanos_convert_to_timestamp_micros ( ) {
3996
4020
let datum = Datum :: timestamp_nanos ( 12345000 ) ;
@@ -4166,4 +4190,77 @@ mod tests {
4166
4190
4167
4191
assert_eq ! ( result, expected) ;
4168
4192
}
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
+ }
4169
4266
}
0 commit comments