Skip to content

Commit f91eddf

Browse files
compheadalamb
andauthored
Implement current_date scalar function (#4022)
* current_date impl * Update datafusion/expr/src/expr_fn.rs Co-authored-by: Andrew Lamb <[email protected]> * Update datafusion/physical-expr/src/functions.rs Co-authored-by: Andrew Lamb <[email protected]> Co-authored-by: Andrew Lamb <[email protected]>
1 parent 35f786b commit f91eddf

File tree

11 files changed

+77
-1
lines changed

11 files changed

+77
-1
lines changed

datafusion/core/tests/sql/timestamp.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1619,3 +1619,35 @@ async fn test_cast_to_timetz_should_not_work() -> Result<()> {
16191619
);
16201620
Ok(())
16211621
}
1622+
1623+
#[tokio::test]
1624+
async fn test_current_date() -> Result<()> {
1625+
let ctx = SessionContext::new();
1626+
1627+
let sql = "select current_date() dt";
1628+
let results = execute_to_batches(&ctx, sql).await;
1629+
assert_eq!(
1630+
results[0]
1631+
.schema()
1632+
.field_with_name("dt")
1633+
.unwrap()
1634+
.data_type()
1635+
.to_owned(),
1636+
DataType::Date32
1637+
);
1638+
1639+
let sql = "select case when current_date() = cast(now() as date) then 'OK' else 'FAIL' end result";
1640+
let results = execute_to_batches(&ctx, sql).await;
1641+
1642+
let expected = vec![
1643+
"+--------+",
1644+
"| result |",
1645+
"+--------+",
1646+
"| OK |",
1647+
"+--------+",
1648+
];
1649+
1650+
assert_batches_eq!(expected, &results);
1651+
1652+
Ok(())
1653+
}

datafusion/expr/src/built_in_function.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,8 @@ pub enum BuiltinScalarFunction {
156156
FromUnixtime,
157157
///now
158158
Now,
159+
///current_date
160+
CurrentDate,
159161
/// translate
160162
Translate,
161163
/// trim
@@ -176,7 +178,9 @@ impl BuiltinScalarFunction {
176178
pub fn supports_zero_argument(&self) -> bool {
177179
matches!(
178180
self,
179-
BuiltinScalarFunction::Random | BuiltinScalarFunction::Now
181+
BuiltinScalarFunction::Random
182+
| BuiltinScalarFunction::Now
183+
| BuiltinScalarFunction::CurrentDate
180184
)
181185
}
182186
/// Returns the [Volatility] of the builtin function.
@@ -254,6 +258,7 @@ impl BuiltinScalarFunction {
254258

255259
// Stable builtin functions
256260
BuiltinScalarFunction::Now => Volatility::Stable,
261+
BuiltinScalarFunction::CurrentDate => Volatility::Stable,
257262

258263
// Volatile builtin functions
259264
BuiltinScalarFunction::Random => Volatility::Volatile,
@@ -309,6 +314,7 @@ impl FromStr for BuiltinScalarFunction {
309314
"concat" => BuiltinScalarFunction::Concat,
310315
"concat_ws" => BuiltinScalarFunction::ConcatWithSeparator,
311316
"chr" => BuiltinScalarFunction::Chr,
317+
"current_date" => BuiltinScalarFunction::CurrentDate,
312318
"date_part" | "datepart" => BuiltinScalarFunction::DatePart,
313319
"date_trunc" | "datetrunc" => BuiltinScalarFunction::DateTrunc,
314320
"date_bin" => BuiltinScalarFunction::DateBin,

datafusion/expr/src/expr_fn.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,14 @@ pub fn now() -> Expr {
452452
}
453453
}
454454

455+
/// Returns current UTC date as a [`DataType::Date32`] value
456+
pub fn current_date() -> Expr {
457+
Expr::ScalarFunction {
458+
fun: BuiltinScalarFunction::CurrentDate,
459+
args: vec![],
460+
}
461+
}
462+
455463
/// Create a CASE WHEN statement with literal WHEN expressions for comparison to the base expression.
456464
pub fn case(expr: Expr) -> CaseBuilder {
457465
CaseBuilder::new(Some(Box::new(expr)), vec![], vec![], None)

datafusion/expr/src/function.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ pub fn return_type(
221221
TimeUnit::Nanosecond,
222222
Some("UTC".to_owned()),
223223
)),
224+
BuiltinScalarFunction::CurrentDate => Ok(DataType::Date32),
224225
BuiltinScalarFunction::Translate => {
225226
utf8_to_str_type(&input_expr_types[0], "translate")
226227
}

datafusion/physical-expr/src/datetime_expressions.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,21 @@ pub fn make_now(
184184
}
185185
}
186186

187+
/// Create an implementation of `current_date()` that always returns the
188+
/// specified current date.
189+
///
190+
/// The semantics of `current_date()` require it to return the same value
191+
/// wherever it appears within a single statement. This value is
192+
/// chosen during planning time.
193+
pub fn make_current_date(
194+
now_ts: DateTime<Utc>,
195+
) -> impl Fn(&[ColumnarValue]) -> Result<ColumnarValue> {
196+
let days = Some(
197+
now_ts.num_days_from_ce() - NaiveDate::from_ymd(1970, 1, 1).num_days_from_ce(),
198+
);
199+
move |_arg| Ok(ColumnarValue::Scalar(ScalarValue::Date32(days)))
200+
}
201+
187202
fn quarter_month(date: &NaiveDateTime) -> u32 {
188203
1 + 3 * ((date.month() - 1) / 3)
189204
}

datafusion/physical-expr/src/functions.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,12 @@ pub fn create_physical_fun(
427427
execution_props.query_execution_start_time,
428428
))
429429
}
430+
BuiltinScalarFunction::CurrentDate => {
431+
// bind value for current_date at plan time
432+
Arc::new(datetime_expressions::make_current_date(
433+
execution_props.query_execution_start_time,
434+
))
435+
}
430436
BuiltinScalarFunction::InitCap => Arc::new(|args| match args[0].data_type() {
431437
DataType::Utf8 => {
432438
make_scalar_function(string_expressions::initcap::<i32>)(args)

datafusion/proto/proto/datafusion.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,7 @@ enum ScalarFunction {
495495
Atan2=67;
496496
DateBin=68;
497497
ArrowTypeof=69;
498+
CurrentDate=70;
498499
}
499500

500501
message ScalarFunctionNode {

datafusion/proto/src/from_proto.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,7 @@ impl From<&protobuf::ScalarFunction> for BuiltinScalarFunction {
429429
ScalarFunction::ToTimestampMicros => Self::ToTimestampMicros,
430430
ScalarFunction::ToTimestampSeconds => Self::ToTimestampSeconds,
431431
ScalarFunction::Now => Self::Now,
432+
ScalarFunction::CurrentDate => Self::CurrentDate,
432433
ScalarFunction::Translate => Self::Translate,
433434
ScalarFunction::RegexpMatch => Self::RegexpMatch,
434435
ScalarFunction::Coalesce => Self::Coalesce,

datafusion/proto/src/generated/pbjson.rs

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

datafusion/proto/src/generated/prost.rs

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

datafusion/proto/src/to_proto.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1178,6 +1178,7 @@ impl TryFrom<&BuiltinScalarFunction> for protobuf::ScalarFunction {
11781178
BuiltinScalarFunction::ToTimestampMicros => Self::ToTimestampMicros,
11791179
BuiltinScalarFunction::ToTimestampSeconds => Self::ToTimestampSeconds,
11801180
BuiltinScalarFunction::Now => Self::Now,
1181+
BuiltinScalarFunction::CurrentDate => Self::CurrentDate,
11811182
BuiltinScalarFunction::Translate => Self::Translate,
11821183
BuiltinScalarFunction::RegexpMatch => Self::RegexpMatch,
11831184
BuiltinScalarFunction::Coalesce => Self::Coalesce,

0 commit comments

Comments
 (0)