Skip to content

Commit eec0e17

Browse files
0ax1joseph-isaacs
andauthored
fix: unify duckdb timestamps on i64 (#4004)
Signed-off-by: Alexander Droste <[email protected]> Signed-off-by: Joe Isaacs <[email protected]> Co-authored-by: Joe Isaacs <[email protected]>
1 parent afed074 commit eec0e17

File tree

4 files changed

+699
-109
lines changed

4 files changed

+699
-109
lines changed

vortex-duckdb/src/convert/dtype.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,12 +190,12 @@ impl FromLogicalType for DType {
190190
))),
191191
DUCKDB_TYPE::DUCKDB_TYPE_TIMESTAMP_S => DType::Extension(Arc::new(ExtDType::new(
192192
TIMESTAMP_ID.clone(),
193-
Arc::new(DType::Primitive(I32, nullability)),
193+
Arc::new(DType::Primitive(I64, nullability)),
194194
Some(TemporalMetadata::Timestamp(TimeUnit::S, None).into()),
195195
))),
196196
DUCKDB_TYPE::DUCKDB_TYPE_TIMESTAMP_MS => DType::Extension(Arc::new(ExtDType::new(
197197
TIMESTAMP_ID.clone(),
198-
Arc::new(DType::Primitive(I32, nullability)),
198+
Arc::new(DType::Primitive(I64, nullability)),
199199
Some(TemporalMetadata::Timestamp(TimeUnit::Ms, None).into()),
200200
))),
201201
DUCKDB_TYPE::DUCKDB_TYPE_TIMESTAMP => DType::Extension(Arc::new(ExtDType::new(

vortex-duckdb/src/convert/scalar.rs

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -272,18 +272,18 @@ impl TryFrom<&Value> for Scalar {
272272
Val::TimestampMs(millis) => Ok(Scalar::extension(
273273
Arc::new(ExtDType::new(
274274
TIMESTAMP_ID.clone(),
275-
Arc::new(DType::Primitive(I32, Nullable)),
275+
Arc::new(DType::Primitive(I64, Nullable)),
276276
Some(TemporalMetadata::Timestamp(TimeUnit::Ms, None).into()),
277277
)),
278-
Scalar::new(DType::Primitive(I32, Nullable), ScalarValue::from(millis)),
278+
Scalar::new(DType::Primitive(I64, Nullable), ScalarValue::from(millis)),
279279
)),
280280
Val::TimestampS(seconds) => Ok(Scalar::extension(
281281
Arc::new(ExtDType::new(
282282
TIMESTAMP_ID.clone(),
283-
Arc::new(DType::Primitive(I32, Nullable)),
283+
Arc::new(DType::Primitive(I64, Nullable)),
284284
Some(TemporalMetadata::Timestamp(TimeUnit::S, None).into()),
285285
)),
286-
Scalar::new(DType::Primitive(I32, Nullable), ScalarValue::from(seconds)),
286+
Scalar::new(DType::Primitive(I64, Nullable), ScalarValue::from(seconds)),
287287
)),
288288
Val::Decimal(precision, scale, value) => Ok(Scalar::decimal(
289289
DecimalValue::I128(value),
@@ -320,4 +320,41 @@ mod tests {
320320
value.try_to_duckdb_scalar().unwrap().try_into().unwrap()
321321
);
322322
}
323+
324+
#[test]
325+
fn test_timestamp_roundtrip() {
326+
use std::sync::Arc;
327+
328+
use vortex::dtype::datetime::{TIMESTAMP_ID, TemporalMetadata, TimeUnit};
329+
use vortex::dtype::{DType, ExtDType, Nullability, PType};
330+
use vortex::scalar::{Scalar, ScalarValue};
331+
332+
let test_cases = [
333+
(TimeUnit::S, 1703980800i64), // 2023-12-30 16:00:00 UTC
334+
(TimeUnit::Ms, 1703980800123i64), // 2023-12-30 16:00:00.123 UTC
335+
(TimeUnit::Us, 1703980800123456i64), // 2023-12-30 16:00:00.123456 UTC
336+
(TimeUnit::Ns, 1703980800123456789i64), // 2023-12-30 16:00:00.123456789 UTC
337+
];
338+
339+
for (time_unit, timestamp_value) in test_cases {
340+
let ext_dtype = Arc::new(ExtDType::new(
341+
TIMESTAMP_ID.clone(),
342+
Arc::new(DType::Primitive(PType::I64, Nullability::NonNullable)),
343+
Some(TemporalMetadata::Timestamp(time_unit, None).into()),
344+
));
345+
346+
let original_scalar = Scalar::extension(
347+
ext_dtype,
348+
Scalar::new(
349+
DType::Primitive(PType::I64, Nullability::NonNullable),
350+
ScalarValue::from(timestamp_value),
351+
),
352+
);
353+
354+
let duckdb_value = original_scalar.try_to_duckdb_scalar().unwrap();
355+
let roundtrip_scalar: Scalar = duckdb_value.try_into().unwrap();
356+
357+
assert_eq!(original_scalar, roundtrip_scalar);
358+
}
359+
}
323360
}

0 commit comments

Comments
 (0)