datafusion_functions/datetime/
now.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18use arrow::datatypes::DataType;
19use arrow::datatypes::DataType::Timestamp;
20use arrow::datatypes::TimeUnit::Nanosecond;
21use std::any::Any;
22
23use datafusion_common::{internal_err, Result, ScalarValue};
24use datafusion_expr::simplify::{ExprSimplifyResult, SimplifyInfo};
25use datafusion_expr::{
26    ColumnarValue, Documentation, Expr, ReturnInfo, ReturnTypeArgs, ScalarUDFImpl,
27    Signature, Volatility,
28};
29use datafusion_macros::user_doc;
30
31#[user_doc(
32    doc_section(label = "Time and Date Functions"),
33    description = r#"
34Returns the current UTC timestamp.
35
36The `now()` return value is determined at query time and will return the same timestamp, no matter when in the query plan the function executes.
37"#,
38    syntax_example = "now()"
39)]
40#[derive(Debug)]
41pub struct NowFunc {
42    signature: Signature,
43    aliases: Vec<String>,
44}
45
46impl Default for NowFunc {
47    fn default() -> Self {
48        Self::new()
49    }
50}
51
52impl NowFunc {
53    pub fn new() -> Self {
54        Self {
55            signature: Signature::nullary(Volatility::Stable),
56            aliases: vec!["current_timestamp".to_string()],
57        }
58    }
59}
60
61/// Create an implementation of `now()` that always returns the
62/// specified timestamp.
63///
64/// The semantics of `now()` require it to return the same value
65/// wherever it appears within a single statement. This value is
66/// chosen during planning time.
67impl ScalarUDFImpl for NowFunc {
68    fn as_any(&self) -> &dyn Any {
69        self
70    }
71
72    fn name(&self) -> &str {
73        "now"
74    }
75
76    fn signature(&self) -> &Signature {
77        &self.signature
78    }
79
80    fn return_type_from_args(&self, _args: ReturnTypeArgs) -> Result<ReturnInfo> {
81        Ok(ReturnInfo::new_non_nullable(Timestamp(
82            Nanosecond,
83            Some("+00:00".into()),
84        )))
85    }
86
87    fn return_type(&self, _arg_types: &[DataType]) -> Result<DataType> {
88        internal_err!("return_type_from_args should be called instead")
89    }
90
91    fn invoke_with_args(
92        &self,
93        _args: datafusion_expr::ScalarFunctionArgs,
94    ) -> Result<ColumnarValue> {
95        internal_err!("invoke should not be called on a simplified now() function")
96    }
97
98    fn simplify(
99        &self,
100        _args: Vec<Expr>,
101        info: &dyn SimplifyInfo,
102    ) -> Result<ExprSimplifyResult> {
103        let now_ts = info
104            .execution_props()
105            .query_execution_start_time
106            .timestamp_nanos_opt();
107        Ok(ExprSimplifyResult::Simplified(Expr::Literal(
108            ScalarValue::TimestampNanosecond(now_ts, Some("+00:00".into())),
109        )))
110    }
111
112    fn aliases(&self) -> &[String] {
113        &self.aliases
114    }
115
116    fn documentation(&self) -> Option<&Documentation> {
117        self.doc()
118    }
119}