diff --git a/Cargo.lock b/Cargo.lock index 46dd2146115c..30e16283ec70 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1664,6 +1664,7 @@ name = "common-function" version = "0.4.4" dependencies = [ "arc-swap", + "build-data", "chrono-tz 0.6.3", "common-error", "common-macro", diff --git a/src/common/function/Cargo.toml b/src/common/function/Cargo.toml index 31a212d21035..b26637c75042 100644 --- a/src/common/function/Cargo.toml +++ b/src/common/function/Cargo.toml @@ -6,6 +6,7 @@ license.workspace = true [dependencies] arc-swap = "1.0" +build-data = "0.1.4" chrono-tz = "0.6" common-error.workspace = true common-macro.workspace = true diff --git a/src/common/function/src/lib.rs b/src/common/function/src/lib.rs index 5d3ab6d42069..dbadeafd2216 100644 --- a/src/common/function/src/lib.rs +++ b/src/common/function/src/lib.rs @@ -13,5 +13,6 @@ // limitations under the License. pub mod scalars; +pub mod system; pub mod helper; diff --git a/src/common/function/src/scalars/function_registry.rs b/src/common/function/src/scalars/function_registry.rs index 5d6751df7503..346917748b3a 100644 --- a/src/common/function/src/scalars/function_registry.rs +++ b/src/common/function/src/scalars/function_registry.rs @@ -24,6 +24,7 @@ use crate::scalars::function::FunctionRef; use crate::scalars::math::MathFunction; use crate::scalars::numpy::NumpyFunction; use crate::scalars::timestamp::TimestampFunction; +use crate::system::build::SystemFunction; #[derive(Default)] pub struct FunctionRegistry { @@ -79,7 +80,7 @@ pub static FUNCTION_REGISTRY: Lazy> = Lazy::new(|| { DateFunction::register(&function_registry); AggregateFunctions::register(&function_registry); - + SystemFunction::register(&function_registry); Arc::new(function_registry) }); diff --git a/src/common/function/src/system.rs b/src/common/function/src/system.rs new file mode 100644 index 000000000000..86b1e1dc7c8b --- /dev/null +++ b/src/common/function/src/system.rs @@ -0,0 +1,15 @@ +// Copyright 2023 Greptime Team +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +pub mod build; diff --git a/src/common/function/src/system/build.rs b/src/common/function/src/system/build.rs new file mode 100644 index 000000000000..f1a59d6fbbb7 --- /dev/null +++ b/src/common/function/src/system/build.rs @@ -0,0 +1,109 @@ +// Copyright 2023 Greptime Team +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use std::fmt; +use std::sync::Arc; + +use common_query::error::Result; +use common_query::prelude::{Signature, Volatility}; +use datatypes::prelude::*; +use datatypes::vectors::{StringVector, VectorRef}; + +use crate::scalars::function::{Function, FunctionContext}; +use crate::scalars::FunctionRegistry; +const DEFAULT_VALUE: &str = "unknown"; + +pub(crate) struct SystemFunction; +/// generates rates from a sequence of adjacent data points. +#[derive(Clone, Debug, Default)] +pub struct BuildFunction; + +impl SystemFunction { + pub fn register(registry: &FunctionRegistry) { + registry.register(Arc::new(BuildFunction)); + } +} + +impl fmt::Display for BuildFunction { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "BUILD") + } +} + +impl Function for BuildFunction { + fn name(&self) -> &str { + "build" + } + + fn return_type(&self, _input_types: &[ConcreteDataType]) -> Result { + Ok(ConcreteDataType::string_datatype()) + } + + fn signature(&self) -> Signature { + Signature::uniform( + 0, + vec![ConcreteDataType::string_datatype()], + Volatility::Immutable, + ) + } + + fn eval(&self, _func_ctx: FunctionContext, _columns: &[VectorRef]) -> Result { + let build_info = format!( + "branch: {}\ncommit: {}\ncommit short: {}\ndirty: {}\nversion: {}", + build_data::get_git_branch().unwrap_or_else(|_| DEFAULT_VALUE.to_string()), + build_data::get_git_commit().unwrap_or_else(|_| DEFAULT_VALUE.to_string()), + build_data::get_git_commit_short().unwrap_or_else(|_| DEFAULT_VALUE.to_string()), + build_data::get_git_dirty().map_or(DEFAULT_VALUE.to_string(), |v| v.to_string()), + env!("CARGO_PKG_VERSION") + ); + + let v = Arc::new(StringVector::from(vec![build_info])); + Ok(v) + } +} + +#[cfg(test)] +mod tests { + use std::sync::Arc; + + use common_query::prelude::TypeSignature; + + use super::*; + #[test] + fn test_build_function() { + let build = BuildFunction; + assert_eq!("build", build.name()); + assert_eq!( + ConcreteDataType::string_datatype(), + build.return_type(&[]).unwrap() + ); + assert!(matches!(build.signature(), + Signature { + type_signature: TypeSignature::Uniform(0, valid_types), + volatility: Volatility::Immutable + } if valid_types == vec![ConcreteDataType::string_datatype()] + )); + let build_info = format!( + "branch: {}\ncommit: {}\ncommit short: {}\ndirty: {}\nversion: {}", + build_data::get_git_branch().unwrap_or_else(|_| DEFAULT_VALUE.to_string()), + build_data::get_git_commit().unwrap_or_else(|_| DEFAULT_VALUE.to_string()), + build_data::get_git_commit_short().unwrap_or_else(|_| DEFAULT_VALUE.to_string()), + build_data::get_git_dirty().map_or(DEFAULT_VALUE.to_string(), |v| v.to_string()), + env!("CARGO_PKG_VERSION") + ); + let vector = build.eval(FunctionContext::default(), &vec![]).unwrap(); + let expect: VectorRef = Arc::new(StringVector::from(vec![build_info])); + assert_eq!(expect, vector); + } +}