Skip to content

Commit

Permalink
Enable casting from Date64 to Timestamp
Browse files Browse the repository at this point in the history
  • Loading branch information
gruuya committed Nov 7, 2022
1 parent 6dd9dae commit a8b0737
Showing 1 changed file with 72 additions and 2 deletions.
74 changes: 72 additions & 2 deletions arrow-cast/src/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ pub fn can_cast_types(from_type: &DataType, to_type: &DataType) -> bool {
(Timestamp(_, _), Int64) => true,
(Int64, Timestamp(_, _)) => true,
(Timestamp(_, _), Timestamp(_, _) | Date32 | Date64) => true,
// date64 to timestamp might not make sense,
(Date64, Timestamp(_, None)) => true,
(Int64, Duration(_)) => true,
(Duration(_), Int64) => true,
(Interval(from_type), Int64) => {
Expand Down Expand Up @@ -1484,7 +1484,24 @@ pub fn cast_with_options(
.unary::<_, Date64Type>(|x| x / (NANOSECONDS / MILLISECONDS)),
)),

// date64 to timestamp might not make sense,
(Date64, Timestamp(TimeUnit::Second, None)) => Ok(Arc::new(
as_primitive_array::<Date64Type>(array)
.unary::<_, TimestampSecondType>(|x| x / MILLISECONDS),
)),
(Date64, Timestamp(TimeUnit::Millisecond, None)) => {
cast_reinterpret_arrays::<Date64Type, TimestampMillisecondType>(array)
}
(Date64, Timestamp(TimeUnit::Microsecond, None)) => Ok(Arc::new(
as_primitive_array::<Date64Type>(array).unary::<_, TimestampMicrosecondType>(
|x| x * (MICROSECONDS / MILLISECONDS),
),
)),
(Date64, Timestamp(TimeUnit::Nanosecond, None)) => Ok(Arc::new(
as_primitive_array::<Date64Type>(array).unary::<_, TimestampNanosecondType>(
|x| x * (NANOSECONDS / MILLISECONDS),
),
)),

(Int64, Duration(TimeUnit::Second)) => {
cast_reinterpret_arrays::<Int64Type, DurationSecondType>(array)
}
Expand Down Expand Up @@ -4073,6 +4090,59 @@ mod tests {
assert!(c.is_null(2));
}

#[test]
fn test_cast_date64_to_timestamp() {
let a = Date64Array::from(vec![Some(864000000005), Some(1545696000001), None]);
let array = Arc::new(a) as ArrayRef;
let b = cast(&array, &DataType::Timestamp(TimeUnit::Second, None)).unwrap();
let c = b.as_any().downcast_ref::<TimestampSecondArray>().unwrap();
assert_eq!(864000000, c.value(0));
assert_eq!(1545696000, c.value(1));
assert!(c.is_null(2));
}

#[test]
fn test_cast_date64_to_timestamp_ms() {
let a = Date64Array::from(vec![Some(864000000005), Some(1545696000001), None]);
let array = Arc::new(a) as ArrayRef;
let b = cast(&array, &DataType::Timestamp(TimeUnit::Millisecond, None)).unwrap();
let c = b
.as_any()
.downcast_ref::<TimestampMillisecondArray>()
.unwrap();
assert_eq!(864000000005, c.value(0));
assert_eq!(1545696000001, c.value(1));
assert!(c.is_null(2));
}

#[test]
fn test_cast_date64_to_timestamp_us() {
let a = Date64Array::from(vec![Some(864000000005), Some(1545696000001), None]);
let array = Arc::new(a) as ArrayRef;
let b = cast(&array, &DataType::Timestamp(TimeUnit::Microsecond, None)).unwrap();
let c = b
.as_any()
.downcast_ref::<TimestampMicrosecondArray>()
.unwrap();
assert_eq!(864000000005000, c.value(0));
assert_eq!(1545696000001000, c.value(1));
assert!(c.is_null(2));
}

#[test]
fn test_cast_date64_to_timestamp_ns() {
let a = Date64Array::from(vec![Some(864000000005), Some(1545696000001), None]);
let array = Arc::new(a) as ArrayRef;
let b = cast(&array, &DataType::Timestamp(TimeUnit::Nanosecond, None)).unwrap();
let c = b
.as_any()
.downcast_ref::<TimestampNanosecondArray>()
.unwrap();
assert_eq!(864000000005000000, c.value(0));
assert_eq!(1545696000001000000, c.value(1));
assert!(c.is_null(2));
}

#[test]
fn test_cast_timestamp_to_i64() {
let a = TimestampMillisecondArray::from(vec![
Expand Down

0 comments on commit a8b0737

Please sign in to comment.