|
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