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::Timestamp;
19use arrow::datatypes::TimeUnit::Nanosecond;
20use arrow::datatypes::{DataType, Field, FieldRef};
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, ReturnFieldArgs, ScalarUDFImpl, Signature,
27    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_field_from_args(&self, _args: ReturnFieldArgs) -> Result<FieldRef> {
81        Ok(Field::new(
82            self.name(),
83            Timestamp(Nanosecond, Some("+00:00".into())),
84            false,
85        )
86        .into())
87    }
88
89    fn return_type(&self, _arg_types: &[DataType]) -> Result<DataType> {
90        internal_err!("return_field_from_args should be called instead")
91    }
92
93    fn invoke_with_args(
94        &self,
95        _args: datafusion_expr::ScalarFunctionArgs,
96    ) -> Result<ColumnarValue> {
97        internal_err!("invoke should not be called on a simplified now() function")
98    }
99
100    fn simplify(
101        &self,
102        _args: Vec<Expr>,
103        info: &dyn SimplifyInfo,
104    ) -> Result<ExprSimplifyResult> {
105        let now_ts = info
106            .execution_props()
107            .query_execution_start_time
108            .timestamp_nanos_opt();
109        Ok(ExprSimplifyResult::Simplified(Expr::Literal(
110            ScalarValue::TimestampNanosecond(now_ts, Some("+00:00".into())),
111            None,
112        )))
113    }
114
115    fn aliases(&self) -> &[String] {
116        &self.aliases
117    }
118
119    fn documentation(&self) -> Option<&Documentation> {
120        self.doc()
121    }
122}