diff --git a/datafusion/core/tests/sql/expr.rs b/datafusion/core/tests/sql/expr.rs index ad7655f00d2a1..4f02c2d740753 100644 --- a/datafusion/core/tests/sql/expr.rs +++ b/datafusion/core/tests/sql/expr.rs @@ -1296,6 +1296,7 @@ async fn test_extract_date_part() -> Result<()> { "EXTRACT(microsecond FROM to_timestamp('2020-09-08T12:00:12.12345678+00:00'))", "12123456.78" ); + // Depends on https://github.com/apache/arrow-datafusion/issues/4528 // test_expression!( // "EXTRACT(nanosecond FROM to_timestamp('2020-09-08T12:00:12.12345678+00:00'))", // "1212345678" @@ -1319,6 +1320,81 @@ async fn test_extract_date_part() -> Result<()> { Ok(()) } +#[tokio::test] +async fn test_extract_date_part_func() -> Result<()> { + test_expression!( + format!( + "(date_part('{0}', now()) = EXTRACT({0} FROM now()))", + "year" + ), + "true" + ); + test_expression!( + format!( + "(date_part('{0}', now()) = EXTRACT({0} FROM now()))", + "quarter" + ), + "true" + ); + test_expression!( + format!( + "(date_part('{0}', now()) = EXTRACT({0} FROM now()))", + "month" + ), + "true" + ); + test_expression!( + format!( + "(date_part('{0}', now()) = EXTRACT({0} FROM now()))", + "week" + ), + "true" + ); + test_expression!( + format!("(date_part('{0}', now()) = EXTRACT({0} FROM now()))", "day"), + "true" + ); + test_expression!( + format!( + "(date_part('{0}', now()) = EXTRACT({0} FROM now()))", + "hour" + ), + "true" + ); + test_expression!( + format!( + "(date_part('{0}', now()) = EXTRACT({0} FROM now()))", + "minute" + ), + "true" + ); + test_expression!( + format!( + "(date_part('{0}', now()) = EXTRACT({0} FROM now()))", + "second" + ), + "true" + ); + test_expression!( + format!( + "(date_part('{0}', now()) = EXTRACT({0} FROM now()))", + "millisecond" + ), + "true" + ); + test_expression!( + format!( + "(date_part('{0}', now()) = EXTRACT({0} FROM now()))", + "microsecond" + ), + "true" + ); + // Depends on https://github.com/apache/arrow-datafusion/issues/4528 + //test_expression!(format!("(date_part('{0}', now()) = EXTRACT({0} FROM now()))", "nanosecond"), "true"); + + Ok(()) +} + #[tokio::test] async fn test_in_list_scalar() -> Result<()> { test_expression!("'a' IN ('a','b')", "true"); diff --git a/datafusion/expr/src/function.rs b/datafusion/expr/src/function.rs index b57091c3c1b17..459152192bbb0 100644 --- a/datafusion/expr/src/function.rs +++ b/datafusion/expr/src/function.rs @@ -474,6 +474,10 @@ pub fn signature(fun: &BuiltinScalarFunction) -> Signature { DataType::Utf8, DataType::Timestamp(TimeUnit::Nanosecond, None), ]), + TypeSignature::Exact(vec![ + DataType::Utf8, + DataType::Timestamp(TimeUnit::Nanosecond, Some("+00:00".to_owned())), + ]), ], fun.volatility(), ), diff --git a/datafusion/physical-expr/src/datetime_expressions.rs b/datafusion/physical-expr/src/datetime_expressions.rs index 4cef3f5471f19..76ac4c3bc6b74 100644 --- a/datafusion/physical-expr/src/datetime_expressions.rs +++ b/datafusion/physical-expr/src/datetime_expressions.rs @@ -413,7 +413,7 @@ macro_rules! extract_date_part { Ok($FN(array) .map(|v| cast(&(Arc::new(v) as ArrayRef), &DataType::Float64))?) } - DataType::Timestamp(time_unit, None) => match time_unit { + DataType::Timestamp(time_unit, _) => match time_unit { TimeUnit::Second => { let array = as_timestamp_second_array($ARRAY)?; Ok($FN(array)