Skip to main content

datafusion_functions/core/
version.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
18//! [`VersionFunc`]: Implementation of the `version` function.
19
20use arrow::datatypes::DataType;
21use datafusion_common::{Result, ScalarValue, utils::take_function_args};
22use datafusion_expr::{
23    ColumnarValue, Documentation, ScalarFunctionArgs, ScalarUDFImpl, Signature,
24    Volatility,
25};
26use datafusion_macros::user_doc;
27
28#[user_doc(
29    doc_section(label = "Other Functions"),
30    description = "Returns the version of DataFusion.",
31    syntax_example = "version()",
32    sql_example = r#"```sql
33> select version();
34+--------------------------------------------+
35| version()                                  |
36+--------------------------------------------+
37| Apache DataFusion 42.0.0, aarch64 on macos |
38+--------------------------------------------+
39```"#
40)]
41#[derive(Debug, PartialEq, Eq, Hash)]
42pub struct VersionFunc {
43    signature: Signature,
44}
45
46impl Default for VersionFunc {
47    fn default() -> Self {
48        Self::new()
49    }
50}
51
52impl VersionFunc {
53    pub fn new() -> Self {
54        Self {
55            signature: Signature::nullary(Volatility::Immutable),
56        }
57    }
58}
59
60impl ScalarUDFImpl for VersionFunc {
61    fn name(&self) -> &str {
62        "version"
63    }
64
65    fn signature(&self) -> &Signature {
66        &self.signature
67    }
68
69    fn return_type(&self, args: &[DataType]) -> Result<DataType> {
70        let [] = take_function_args(self.name(), args)?;
71        Ok(DataType::Utf8)
72    }
73
74    fn invoke_with_args(&self, args: ScalarFunctionArgs) -> Result<ColumnarValue> {
75        let [] = take_function_args(self.name(), args.args)?;
76        // TODO it would be great to add rust version and arrow version,
77        // but that requires a `build.rs` script and/or adding a version const to arrow-rs
78        let version = format!(
79            "Apache DataFusion {}, {} on {}",
80            env!("CARGO_PKG_VERSION"),
81            std::env::consts::ARCH,
82            std::env::consts::OS,
83        );
84        Ok(ColumnarValue::Scalar(ScalarValue::Utf8(Some(version))))
85    }
86
87    fn documentation(&self) -> Option<&Documentation> {
88        self.doc()
89    }
90}
91
92#[cfg(test)]
93mod test {
94    use super::*;
95    use arrow::datatypes::Field;
96    use datafusion_common::config::ConfigOptions;
97    use datafusion_expr::ScalarFunctionArgs;
98    use datafusion_expr::ScalarUDF;
99    use std::sync::Arc;
100
101    #[tokio::test]
102    async fn test_version_udf() {
103        let version_udf = ScalarUDF::from(VersionFunc::new());
104        let version = version_udf
105            .invoke_with_args(ScalarFunctionArgs {
106                args: vec![],
107                arg_fields: vec![],
108                number_rows: 0,
109                return_field: Field::new("f", DataType::Utf8, true).into(),
110                config_options: Arc::new(ConfigOptions::default()),
111            })
112            .unwrap();
113
114        if let ColumnarValue::Scalar(ScalarValue::Utf8(Some(version))) = version {
115            assert!(version.starts_with("Apache DataFusion"));
116        } else {
117            panic!("Expected version string");
118        }
119    }
120}