|
18 | 18 | //! DateTime expressions |
19 | 19 |
|
20 | 20 | use arrow::array::{Int64Array, IntervalDayTimeArray, IntervalYearMonthArray}; |
| 21 | +use arrow::compute::cast; |
21 | 22 | use arrow::{ |
22 | 23 | array::{Array, ArrayRef, GenericStringArray, PrimitiveArray, StringOffsetSizeTrait}, |
23 | 24 | compute::kernels::cast_utils::string_to_timestamp_nanos, |
@@ -481,44 +482,44 @@ pub fn date_trunc(args: &[ColumnarValue]) -> Result<ColumnarValue> { |
481 | 482 | } |
482 | 483 |
|
483 | 484 | macro_rules! extract_date_part { |
484 | | - ($ARRAY: expr, $FN:expr) => { |
| 485 | + ($ARRAY: expr, $FN:expr, $RT: expr) => { |
485 | 486 | match $ARRAY.data_type() { |
486 | 487 | DataType::Date32 => { |
487 | 488 | let array = $ARRAY.as_any().downcast_ref::<Date32Array>().unwrap(); |
488 | | - Ok($FN(array)?) |
| 489 | + Ok($FN(array).map(|v| cast(&(Arc::new(v) as ArrayRef), &$RT))?) |
489 | 490 | } |
490 | 491 | DataType::Date64 => { |
491 | 492 | let array = $ARRAY.as_any().downcast_ref::<Date64Array>().unwrap(); |
492 | | - Ok($FN(array)?) |
| 493 | + Ok($FN(array).map(|v| cast(&(Arc::new(v) as ArrayRef), &$RT))?) |
493 | 494 | } |
494 | 495 | DataType::Timestamp(time_unit, None) => match time_unit { |
495 | 496 | TimeUnit::Second => { |
496 | 497 | let array = $ARRAY |
497 | 498 | .as_any() |
498 | 499 | .downcast_ref::<TimestampSecondArray>() |
499 | 500 | .unwrap(); |
500 | | - Ok($FN(array)?) |
| 501 | + Ok($FN(array).map(|v| cast(&(Arc::new(v) as ArrayRef), &$RT))?) |
501 | 502 | } |
502 | 503 | TimeUnit::Millisecond => { |
503 | 504 | let array = $ARRAY |
504 | 505 | .as_any() |
505 | 506 | .downcast_ref::<TimestampMillisecondArray>() |
506 | 507 | .unwrap(); |
507 | | - Ok($FN(array)?) |
| 508 | + Ok($FN(array).map(|v| cast(&(Arc::new(v) as ArrayRef), &$RT))?) |
508 | 509 | } |
509 | 510 | TimeUnit::Microsecond => { |
510 | 511 | let array = $ARRAY |
511 | 512 | .as_any() |
512 | 513 | .downcast_ref::<TimestampMicrosecondArray>() |
513 | 514 | .unwrap(); |
514 | | - Ok($FN(array)?) |
| 515 | + Ok($FN(array).map(|v| cast(&(Arc::new(v) as ArrayRef), &$RT))?) |
515 | 516 | } |
516 | 517 | TimeUnit::Nanosecond => { |
517 | 518 | let array = $ARRAY |
518 | 519 | .as_any() |
519 | 520 | .downcast_ref::<TimestampNanosecondArray>() |
520 | 521 | .unwrap(); |
521 | | - Ok($FN(array)?) |
| 522 | + Ok($FN(array).map(|v| cast(&(Arc::new(v) as ArrayRef), &$RT))?) |
522 | 523 | } |
523 | 524 | }, |
524 | 525 | datatype => Err(DataFusionError::Internal(format!( |
@@ -554,29 +555,29 @@ pub fn date_part(args: &[ColumnarValue]) -> Result<ColumnarValue> { |
554 | 555 | }; |
555 | 556 |
|
556 | 557 | let arr = match date_part.to_lowercase().as_str() { |
557 | | - "doy" => extract_date_part!(array, cube_ext::temporal::doy), |
558 | | - "dow" => extract_date_part!(array, cube_ext::temporal::dow), |
559 | | - "year" => extract_date_part!(array, temporal::year), |
560 | | - "quarter" => extract_date_part!(array, temporal::quarter), |
561 | | - "month" => extract_date_part!(array, temporal::month), |
562 | | - "week" => extract_date_part!(array, temporal::week), |
563 | | - "day" => extract_date_part!(array, temporal::day), |
564 | | - "hour" => extract_date_part!(array, temporal::hour), |
565 | | - "minute" => extract_date_part!(array, temporal::minute), |
566 | | - "second" => extract_date_part!(array, temporal::second), |
| 558 | + "doy" => extract_date_part!(array, cube_ext::temporal::doy, DataType::Int32), |
| 559 | + "dow" => extract_date_part!(array, cube_ext::temporal::dow, DataType::Int32), |
| 560 | + "year" => extract_date_part!(array, temporal::year, DataType::Int32), |
| 561 | + "quarter" => extract_date_part!(array, temporal::quarter, DataType::Int32), |
| 562 | + "month" => extract_date_part!(array, temporal::month, DataType::Int32), |
| 563 | + "week" => extract_date_part!(array, temporal::week, DataType::Int32), |
| 564 | + "day" => extract_date_part!(array, temporal::day, DataType::Int32), |
| 565 | + "hour" => extract_date_part!(array, temporal::hour, DataType::Int32), |
| 566 | + "minute" => extract_date_part!(array, temporal::minute, DataType::Int32), |
| 567 | + "second" => extract_date_part!(array, temporal::second, DataType::Int32), |
| 568 | + "epoch" => { |
| 569 | + extract_date_part!(array, cube_ext::temporal::epoch, DataType::Float64) |
| 570 | + } |
567 | 571 | _ => Err(DataFusionError::Execution(format!( |
568 | 572 | "Date part '{}' not supported", |
569 | 573 | date_part |
570 | 574 | ))), |
571 | 575 | }?; |
572 | 576 |
|
573 | 577 | Ok(if is_scalar { |
574 | | - ColumnarValue::Scalar(ScalarValue::try_from_array( |
575 | | - &(Arc::new(arr) as ArrayRef), |
576 | | - 0, |
577 | | - )?) |
| 578 | + ColumnarValue::Scalar(ScalarValue::try_from_array(&arr?, 0)?) |
578 | 579 | } else { |
579 | | - ColumnarValue::Array(Arc::new(arr)) |
| 580 | + ColumnarValue::Array(arr?) |
580 | 581 | }) |
581 | 582 | } |
582 | 583 |
|
|
0 commit comments