From 5483fbf9d7685d10057c92b42efcdc832295d087 Mon Sep 17 00:00:00 2001 From: Kunal Kundu Date: Sat, 30 Mar 2024 01:02:07 +0530 Subject: [PATCH 1/4] move log2 --- datafusion/expr/src/built_in_function.rs | 7 -- datafusion/expr/src/expr_fn.rs | 2 - datafusion/functions/src/math/log2.rs | 96 +++++++++++++++++++ datafusion/functions/src/math/mod.rs | 3 + datafusion/physical-expr/src/functions.rs | 1 - datafusion/proto/src/generated/pbjson.rs | 2 - datafusion/proto/src/generated/prost.rs | 4 +- .../proto/src/logical_plan/from_proto.rs | 4 +- datafusion/proto/src/logical_plan/to_proto.rs | 1 - 9 files changed, 101 insertions(+), 19 deletions(-) create mode 100644 datafusion/functions/src/math/log2.rs diff --git a/datafusion/expr/src/built_in_function.rs b/datafusion/expr/src/built_in_function.rs index 423fc11c1d8c9..8f89836003e0b 100644 --- a/datafusion/expr/src/built_in_function.rs +++ b/datafusion/expr/src/built_in_function.rs @@ -77,8 +77,6 @@ pub enum BuiltinScalarFunction { Log, /// log10 Log10, - /// log2 - Log2, /// nanvl Nanvl, /// pi @@ -190,7 +188,6 @@ impl BuiltinScalarFunction { BuiltinScalarFunction::Ln => Volatility::Immutable, BuiltinScalarFunction::Log => Volatility::Immutable, BuiltinScalarFunction::Log10 => Volatility::Immutable, - BuiltinScalarFunction::Log2 => Volatility::Immutable, BuiltinScalarFunction::Nanvl => Volatility::Immutable, BuiltinScalarFunction::Pi => Volatility::Immutable, BuiltinScalarFunction::Power => Volatility::Immutable, @@ -294,7 +291,6 @@ impl BuiltinScalarFunction { | BuiltinScalarFunction::Floor | BuiltinScalarFunction::Ln | BuiltinScalarFunction::Log10 - | BuiltinScalarFunction::Log2 | BuiltinScalarFunction::Radians | BuiltinScalarFunction::Round | BuiltinScalarFunction::Signum @@ -414,7 +410,6 @@ impl BuiltinScalarFunction { | BuiltinScalarFunction::Floor | BuiltinScalarFunction::Ln | BuiltinScalarFunction::Log10 - | BuiltinScalarFunction::Log2 | BuiltinScalarFunction::Radians | BuiltinScalarFunction::Signum | BuiltinScalarFunction::Sin @@ -452,7 +447,6 @@ impl BuiltinScalarFunction { | BuiltinScalarFunction::Floor | BuiltinScalarFunction::Ln | BuiltinScalarFunction::Log10 - | BuiltinScalarFunction::Log2 | BuiltinScalarFunction::Radians | BuiltinScalarFunction::Round | BuiltinScalarFunction::Signum @@ -493,7 +487,6 @@ impl BuiltinScalarFunction { BuiltinScalarFunction::Ln => &["ln"], BuiltinScalarFunction::Log => &["log"], BuiltinScalarFunction::Log10 => &["log10"], - BuiltinScalarFunction::Log2 => &["log2"], BuiltinScalarFunction::Nanvl => &["nanvl"], BuiltinScalarFunction::Pi => &["pi"], BuiltinScalarFunction::Power => &["power", "pow"], diff --git a/datafusion/expr/src/expr_fn.rs b/datafusion/expr/src/expr_fn.rs index 09170ae639ff4..6ccad964260ec 100644 --- a/datafusion/expr/src/expr_fn.rs +++ b/datafusion/expr/src/expr_fn.rs @@ -570,7 +570,6 @@ scalar_expr!(Signum, signum, num, "sign of the argument (-1, 0, +1) "); scalar_expr!(Exp, exp, num, "exponential"); scalar_expr!(Gcd, gcd, arg_1 arg_2, "greatest common divisor"); scalar_expr!(Lcm, lcm, arg_1 arg_2, "least common multiple"); -scalar_expr!(Log2, log2, num, "base 2 logarithm of number"); scalar_expr!(Log10, log10, num, "base 10 logarithm of number"); scalar_expr!(Ln, ln, num, "natural logarithm (base e) of number"); scalar_expr!(Power, power, base exponent, "`base` raised to the power of `exponent`"); @@ -1001,7 +1000,6 @@ mod test { test_nary_scalar_expr!(Trunc, trunc, num, precision); test_unary_scalar_expr!(Signum, signum); test_unary_scalar_expr!(Exp, exp); - test_unary_scalar_expr!(Log2, log2); test_unary_scalar_expr!(Log10, log10); test_unary_scalar_expr!(Ln, ln); test_scalar_expr!(Atan2, atan2, y, x); diff --git a/datafusion/functions/src/math/log2.rs b/datafusion/functions/src/math/log2.rs new file mode 100644 index 0000000000000..3c84023888633 --- /dev/null +++ b/datafusion/functions/src/math/log2.rs @@ -0,0 +1,96 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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. + +//! Math function: `log2()`. + +use arrow::datatypes::DataType::{self, Float32, Float64}; +use datafusion_common::{exec_err, DataFusionError, Result}; +use datafusion_expr::{ColumnarValue, FuncMonotonicity}; + +use arrow::array::{ArrayRef, Float32Array, Float64Array}; +use datafusion_expr::{ScalarUDFImpl, Signature, Volatility}; +use std::any::Any; +use std::sync::Arc; + +#[derive(Debug)] +pub(super) struct Log2Func { + signature: Signature, +} + +impl Log2Func { + pub fn new() -> Self { + Self { + signature: Signature::uniform( + 1, + vec![Float64, Float32], + Volatility::Immutable, + ), + } + } +} + +impl ScalarUDFImpl for Log2Func { + fn as_any(&self) -> &dyn Any { + self + } + fn name(&self) -> &str { + "log2" + } + + fn signature(&self) -> &Signature { + &self.signature + } + + fn return_type(&self, arg_types: &[DataType]) -> Result { + match arg_types[0] { + Float32 => Ok(Float32), + _ => Ok(Float64), + } + } + + fn monotonicity(&self) -> Result> { + Ok(Some(vec![Some(true)])) + } + + fn invoke(&self, args: &[ColumnarValue]) -> Result { + let args = ColumnarValue::values_to_arrays(args)?; + + let arr: ArrayRef = match args[0].data_type() { + DataType::Float64 => Arc::new(make_function_scalar_inputs_return_type!( + &args[0], + self.name(), + Float64Array, + Float64Array, + { f64::log2 } + )), + DataType::Float32 => Arc::new(make_function_scalar_inputs_return_type!( + &args[0], + self.name(), + Float32Array, + Float32Array, + { f32::log2 } + )), + other => { + return exec_err!( + "Unsupported data type {other:?} for function {}", + self.name() + ) + } + }; + Ok(ColumnarValue::Array(arr)) + } +} diff --git a/datafusion/functions/src/math/mod.rs b/datafusion/functions/src/math/mod.rs index 27deb7d684272..87d8d23976bbc 100644 --- a/datafusion/functions/src/math/mod.rs +++ b/datafusion/functions/src/math/mod.rs @@ -18,11 +18,13 @@ //! "math" DataFusion functions mod abs; +mod log2; mod nans; // Create UDFs make_udf_function!(nans::IsNanFunc, ISNAN, isnan); make_udf_function!(abs::AbsFunc, ABS, abs); +make_udf_function!(log2::Log2Func, LOG2, log2); make_math_unary_udf!(TanhFunc, TANH, tanh, tanh); make_math_unary_udf!(AcosFunc, ACOS, acos, acos); @@ -37,6 +39,7 @@ export_functions!( "returns true if a given number is +NaN or -NaN otherwise returns false" ), (abs, num, "returns the absolute value of a given number"), + (log2, num, "base 2 logarithm of number"), ( acos, num, diff --git a/datafusion/physical-expr/src/functions.rs b/datafusion/physical-expr/src/functions.rs index 513dd71d40749..756f1a5e6c36c 100644 --- a/datafusion/physical-expr/src/functions.rs +++ b/datafusion/physical-expr/src/functions.rs @@ -223,7 +223,6 @@ pub fn create_physical_fun( } BuiltinScalarFunction::Ln => Arc::new(math_expressions::ln), BuiltinScalarFunction::Log10 => Arc::new(math_expressions::log10), - BuiltinScalarFunction::Log2 => Arc::new(math_expressions::log2), BuiltinScalarFunction::Nanvl => { Arc::new(|args| make_scalar_function_inner(math_expressions::nanvl)(args)) } diff --git a/datafusion/proto/src/generated/pbjson.rs b/datafusion/proto/src/generated/pbjson.rs index 07b91b26d60b4..e95249860bf5b 100644 --- a/datafusion/proto/src/generated/pbjson.rs +++ b/datafusion/proto/src/generated/pbjson.rs @@ -22922,7 +22922,6 @@ impl serde::Serialize for ScalarFunction { Self::Ln => "Ln", Self::Log => "Log", Self::Log10 => "Log10", - Self::Log2 => "Log2", Self::Round => "Round", Self::Signum => "Signum", Self::Sin => "Sin", @@ -23055,7 +23054,6 @@ impl<'de> serde::Deserialize<'de> for ScalarFunction { "Ln" => Ok(ScalarFunction::Ln), "Log" => Ok(ScalarFunction::Log), "Log10" => Ok(ScalarFunction::Log10), - "Log2" => Ok(ScalarFunction::Log2), "Round" => Ok(ScalarFunction::Round), "Signum" => Ok(ScalarFunction::Signum), "Sin" => Ok(ScalarFunction::Sin), diff --git a/datafusion/proto/src/generated/prost.rs b/datafusion/proto/src/generated/prost.rs index babeccec595f3..d384aafd66e99 100644 --- a/datafusion/proto/src/generated/prost.rs +++ b/datafusion/proto/src/generated/prost.rs @@ -2853,7 +2853,7 @@ pub enum ScalarFunction { Ln = 10, Log = 11, Log10 = 12, - Log2 = 13, + /// 13 was Log2 Round = 14, Signum = 15, Sin = 16, @@ -2995,7 +2995,6 @@ impl ScalarFunction { ScalarFunction::Ln => "Ln", ScalarFunction::Log => "Log", ScalarFunction::Log10 => "Log10", - ScalarFunction::Log2 => "Log2", ScalarFunction::Round => "Round", ScalarFunction::Signum => "Signum", ScalarFunction::Sin => "Sin", @@ -3041,7 +3040,6 @@ impl ScalarFunction { "Ln" => Some(Self::Ln), "Log" => Some(Self::Log), "Log10" => Some(Self::Log10), - "Log2" => Some(Self::Log2), "Round" => Some(Self::Round), "Signum" => Some(Self::Signum), "Sin" => Some(Self::Sin), diff --git a/datafusion/proto/src/logical_plan/from_proto.rs b/datafusion/proto/src/logical_plan/from_proto.rs index ff3d6773d512c..800b834bfcfa7 100644 --- a/datafusion/proto/src/logical_plan/from_proto.rs +++ b/datafusion/proto/src/logical_plan/from_proto.rs @@ -40,7 +40,7 @@ use datafusion_expr::{ acosh, asinh, atan, atan2, atanh, cbrt, ceil, coalesce, concat_expr, concat_ws_expr, cos, cosh, cot, degrees, ends_with, exp, expr::{self, InList, Sort, WindowFunction}, - factorial, find_in_set, floor, gcd, initcap, iszero, lcm, ln, log, log10, log2, + factorial, find_in_set, floor, gcd, initcap, iszero, lcm, ln, log, log10, logical_plan::{PlanType, StringifiedPlan}, nanvl, pi, power, radians, random, round, signum, sin, sinh, sqrt, substr_index, translate, trunc, AggregateFunction, Between, BinaryExpr, BuiltInWindowFunction, @@ -449,7 +449,6 @@ impl From<&protobuf::ScalarFunction> for BuiltinScalarFunction { ScalarFunction::Round => Self::Round, ScalarFunction::Trunc => Self::Trunc, ScalarFunction::Concat => Self::Concat, - ScalarFunction::Log2 => Self::Log2, ScalarFunction::Signum => Self::Signum, ScalarFunction::ConcatWithSeparator => Self::ConcatWithSeparator, ScalarFunction::EndsWith => Self::EndsWith, @@ -1348,7 +1347,6 @@ pub fn parse_expr( ScalarFunction::Radians => { Ok(radians(parse_expr(&args[0], registry, codec)?)) } - ScalarFunction::Log2 => Ok(log2(parse_expr(&args[0], registry, codec)?)), ScalarFunction::Ln => Ok(ln(parse_expr(&args[0], registry, codec)?)), ScalarFunction::Log10 => { Ok(log10(parse_expr(&args[0], registry, codec)?)) diff --git a/datafusion/proto/src/logical_plan/to_proto.rs b/datafusion/proto/src/logical_plan/to_proto.rs index 89d49c5658a2e..f7b3c72ecbcfd 100644 --- a/datafusion/proto/src/logical_plan/to_proto.rs +++ b/datafusion/proto/src/logical_plan/to_proto.rs @@ -1440,7 +1440,6 @@ impl TryFrom<&BuiltinScalarFunction> for protobuf::ScalarFunction { BuiltinScalarFunction::Round => Self::Round, BuiltinScalarFunction::Trunc => Self::Trunc, BuiltinScalarFunction::Concat => Self::Concat, - BuiltinScalarFunction::Log2 => Self::Log2, BuiltinScalarFunction::Signum => Self::Signum, BuiltinScalarFunction::ConcatWithSeparator => Self::ConcatWithSeparator, BuiltinScalarFunction::EndsWith => Self::EndsWith, From ca70fb67fe4998892dc4a5abef0b084b441b7f37 Mon Sep 17 00:00:00 2001 From: Kunal Kundu Date: Sat, 30 Mar 2024 01:03:20 +0530 Subject: [PATCH 2/4] move log10, ln --- datafusion/expr/src/built_in_function.rs | 14 --- datafusion/expr/src/expr_fn.rs | 4 - datafusion/functions/src/math/ln.rs | 96 +++++++++++++++++++ datafusion/functions/src/math/log10.rs | 96 +++++++++++++++++++ datafusion/functions/src/math/mod.rs | 8 +- datafusion/physical-expr/src/functions.rs | 2 - datafusion/proto/src/generated/pbjson.rs | 4 - datafusion/proto/src/generated/prost.rs | 8 +- .../proto/src/logical_plan/from_proto.rs | 8 +- datafusion/proto/src/logical_plan/to_proto.rs | 2 - 10 files changed, 202 insertions(+), 40 deletions(-) create mode 100644 datafusion/functions/src/math/ln.rs create mode 100644 datafusion/functions/src/math/log10.rs diff --git a/datafusion/expr/src/built_in_function.rs b/datafusion/expr/src/built_in_function.rs index 8f89836003e0b..f07e840275529 100644 --- a/datafusion/expr/src/built_in_function.rs +++ b/datafusion/expr/src/built_in_function.rs @@ -71,12 +71,8 @@ pub enum BuiltinScalarFunction { Lcm, /// iszero Iszero, - /// ln, Natural logarithm - Ln, /// log, same as log10 Log, - /// log10 - Log10, /// nanvl Nanvl, /// pi @@ -185,9 +181,7 @@ impl BuiltinScalarFunction { BuiltinScalarFunction::Gcd => Volatility::Immutable, BuiltinScalarFunction::Iszero => Volatility::Immutable, BuiltinScalarFunction::Lcm => Volatility::Immutable, - BuiltinScalarFunction::Ln => Volatility::Immutable, BuiltinScalarFunction::Log => Volatility::Immutable, - BuiltinScalarFunction::Log10 => Volatility::Immutable, BuiltinScalarFunction::Nanvl => Volatility::Immutable, BuiltinScalarFunction::Pi => Volatility::Immutable, BuiltinScalarFunction::Power => Volatility::Immutable, @@ -289,8 +283,6 @@ impl BuiltinScalarFunction { | BuiltinScalarFunction::Degrees | BuiltinScalarFunction::Exp | BuiltinScalarFunction::Floor - | BuiltinScalarFunction::Ln - | BuiltinScalarFunction::Log10 | BuiltinScalarFunction::Radians | BuiltinScalarFunction::Round | BuiltinScalarFunction::Signum @@ -408,8 +400,6 @@ impl BuiltinScalarFunction { | BuiltinScalarFunction::Degrees | BuiltinScalarFunction::Exp | BuiltinScalarFunction::Floor - | BuiltinScalarFunction::Ln - | BuiltinScalarFunction::Log10 | BuiltinScalarFunction::Radians | BuiltinScalarFunction::Signum | BuiltinScalarFunction::Sin @@ -445,8 +435,6 @@ impl BuiltinScalarFunction { | BuiltinScalarFunction::Exp | BuiltinScalarFunction::Factorial | BuiltinScalarFunction::Floor - | BuiltinScalarFunction::Ln - | BuiltinScalarFunction::Log10 | BuiltinScalarFunction::Radians | BuiltinScalarFunction::Round | BuiltinScalarFunction::Signum @@ -484,9 +472,7 @@ impl BuiltinScalarFunction { BuiltinScalarFunction::Gcd => &["gcd"], BuiltinScalarFunction::Iszero => &["iszero"], BuiltinScalarFunction::Lcm => &["lcm"], - BuiltinScalarFunction::Ln => &["ln"], BuiltinScalarFunction::Log => &["log"], - BuiltinScalarFunction::Log10 => &["log10"], BuiltinScalarFunction::Nanvl => &["nanvl"], BuiltinScalarFunction::Pi => &["pi"], BuiltinScalarFunction::Power => &["power", "pow"], diff --git a/datafusion/expr/src/expr_fn.rs b/datafusion/expr/src/expr_fn.rs index 6ccad964260ec..e216e4e86dc13 100644 --- a/datafusion/expr/src/expr_fn.rs +++ b/datafusion/expr/src/expr_fn.rs @@ -570,8 +570,6 @@ scalar_expr!(Signum, signum, num, "sign of the argument (-1, 0, +1) "); scalar_expr!(Exp, exp, num, "exponential"); scalar_expr!(Gcd, gcd, arg_1 arg_2, "greatest common divisor"); scalar_expr!(Lcm, lcm, arg_1 arg_2, "least common multiple"); -scalar_expr!(Log10, log10, num, "base 10 logarithm of number"); -scalar_expr!(Ln, ln, num, "natural logarithm (base e) of number"); scalar_expr!(Power, power, base exponent, "`base` raised to the power of `exponent`"); scalar_expr!(Atan2, atan2, y x, "inverse tangent of a division given in the argument"); scalar_expr!(Log, log, base x, "logarithm of a `x` for a particular `base`"); @@ -1000,8 +998,6 @@ mod test { test_nary_scalar_expr!(Trunc, trunc, num, precision); test_unary_scalar_expr!(Signum, signum); test_unary_scalar_expr!(Exp, exp); - test_unary_scalar_expr!(Log10, log10); - test_unary_scalar_expr!(Ln, ln); test_scalar_expr!(Atan2, atan2, y, x); test_scalar_expr!(Nanvl, nanvl, x, y); test_scalar_expr!(Iszero, iszero, input); diff --git a/datafusion/functions/src/math/ln.rs b/datafusion/functions/src/math/ln.rs new file mode 100644 index 0000000000000..ea5c92743f468 --- /dev/null +++ b/datafusion/functions/src/math/ln.rs @@ -0,0 +1,96 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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. + +//! Math function: `ln()`. + +use arrow::datatypes::DataType::{self, Float32, Float64}; +use datafusion_common::{exec_err, DataFusionError, Result}; +use datafusion_expr::{ColumnarValue, FuncMonotonicity}; + +use arrow::array::{ArrayRef, Float32Array, Float64Array}; +use datafusion_expr::{ScalarUDFImpl, Signature, Volatility}; +use std::any::Any; +use std::sync::Arc; + +#[derive(Debug)] +pub(super) struct LnFunc { + signature: Signature, +} + +impl LnFunc { + pub fn new() -> Self { + Self { + signature: Signature::uniform( + 1, + vec![Float64, Float32], + Volatility::Immutable, + ), + } + } +} + +impl ScalarUDFImpl for LnFunc { + fn as_any(&self) -> &dyn Any { + self + } + fn name(&self) -> &str { + "ln" + } + + fn signature(&self) -> &Signature { + &self.signature + } + + fn return_type(&self, arg_types: &[DataType]) -> Result { + match arg_types[0] { + Float32 => Ok(Float32), + _ => Ok(Float64), + } + } + + fn monotonicity(&self) -> Result> { + Ok(Some(vec![Some(true)])) + } + + fn invoke(&self, args: &[ColumnarValue]) -> Result { + let args = ColumnarValue::values_to_arrays(args)?; + + let arr: ArrayRef = match args[0].data_type() { + DataType::Float64 => Arc::new(make_function_scalar_inputs_return_type!( + &args[0], + self.name(), + Float64Array, + Float64Array, + { f64::ln } + )), + DataType::Float32 => Arc::new(make_function_scalar_inputs_return_type!( + &args[0], + self.name(), + Float32Array, + Float32Array, + { f32::ln } + )), + other => { + return exec_err!( + "Unsupported data type {other:?} for function {}", + self.name() + ) + } + }; + Ok(ColumnarValue::Array(arr)) + } +} diff --git a/datafusion/functions/src/math/log10.rs b/datafusion/functions/src/math/log10.rs new file mode 100644 index 0000000000000..ab4d6ef100605 --- /dev/null +++ b/datafusion/functions/src/math/log10.rs @@ -0,0 +1,96 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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. + +//! Math function: `log10()`. + +use arrow::datatypes::DataType::{self, Float32, Float64}; +use datafusion_common::{exec_err, DataFusionError, Result}; +use datafusion_expr::{ColumnarValue, FuncMonotonicity}; + +use arrow::array::{ArrayRef, Float32Array, Float64Array}; +use datafusion_expr::{ScalarUDFImpl, Signature, Volatility}; +use std::any::Any; +use std::sync::Arc; + +#[derive(Debug)] +pub(super) struct Log10Func { + signature: Signature, +} + +impl Log10Func { + pub fn new() -> Self { + Self { + signature: Signature::uniform( + 1, + vec![Float64, Float32], + Volatility::Immutable, + ), + } + } +} + +impl ScalarUDFImpl for Log10Func { + fn as_any(&self) -> &dyn Any { + self + } + fn name(&self) -> &str { + "log10" + } + + fn signature(&self) -> &Signature { + &self.signature + } + + fn return_type(&self, arg_types: &[DataType]) -> Result { + match arg_types[0] { + Float32 => Ok(Float32), + _ => Ok(Float64), + } + } + + fn monotonicity(&self) -> Result> { + Ok(Some(vec![Some(true)])) + } + + fn invoke(&self, args: &[ColumnarValue]) -> Result { + let args = ColumnarValue::values_to_arrays(args)?; + + let arr: ArrayRef = match args[0].data_type() { + DataType::Float64 => Arc::new(make_function_scalar_inputs_return_type!( + &args[0], + self.name(), + Float64Array, + Float64Array, + { f64::log10 } + )), + DataType::Float32 => Arc::new(make_function_scalar_inputs_return_type!( + &args[0], + self.name(), + Float32Array, + Float32Array, + { f32::log10 } + )), + other => { + return exec_err!( + "Unsupported data type {other:?} for function {}", + self.name() + ) + } + }; + Ok(ColumnarValue::Array(arr)) + } +} diff --git a/datafusion/functions/src/math/mod.rs b/datafusion/functions/src/math/mod.rs index 87d8d23976bbc..17d87aca6a0cd 100644 --- a/datafusion/functions/src/math/mod.rs +++ b/datafusion/functions/src/math/mod.rs @@ -18,6 +18,8 @@ //! "math" DataFusion functions mod abs; +mod ln; +mod log10; mod log2; mod nans; @@ -25,6 +27,8 @@ mod nans; make_udf_function!(nans::IsNanFunc, ISNAN, isnan); make_udf_function!(abs::AbsFunc, ABS, abs); make_udf_function!(log2::Log2Func, LOG2, log2); +make_udf_function!(log10::Log10Func, LOG10, log10); +make_udf_function!(ln::LnFunc, LN, ln); make_math_unary_udf!(TanhFunc, TANH, tanh, tanh); make_math_unary_udf!(AcosFunc, ACOS, acos, acos); @@ -39,7 +43,9 @@ export_functions!( "returns true if a given number is +NaN or -NaN otherwise returns false" ), (abs, num, "returns the absolute value of a given number"), - (log2, num, "base 2 logarithm of number"), + (log2, num, "base 2 logarithm of a number"), + (log10, num, "base 10 logarithm of a number"), + (ln, num, "natural logarithm (base e) of a number"), ( acos, num, diff --git a/datafusion/physical-expr/src/functions.rs b/datafusion/physical-expr/src/functions.rs index 756f1a5e6c36c..515511b15fbbf 100644 --- a/datafusion/physical-expr/src/functions.rs +++ b/datafusion/physical-expr/src/functions.rs @@ -221,8 +221,6 @@ pub fn create_physical_fun( BuiltinScalarFunction::Lcm => { Arc::new(|args| make_scalar_function_inner(math_expressions::lcm)(args)) } - BuiltinScalarFunction::Ln => Arc::new(math_expressions::ln), - BuiltinScalarFunction::Log10 => Arc::new(math_expressions::log10), BuiltinScalarFunction::Nanvl => { Arc::new(|args| make_scalar_function_inner(math_expressions::nanvl)(args)) } diff --git a/datafusion/proto/src/generated/pbjson.rs b/datafusion/proto/src/generated/pbjson.rs index e95249860bf5b..d9e4bdded5415 100644 --- a/datafusion/proto/src/generated/pbjson.rs +++ b/datafusion/proto/src/generated/pbjson.rs @@ -22919,9 +22919,7 @@ impl serde::Serialize for ScalarFunction { Self::Cos => "Cos", Self::Exp => "Exp", Self::Floor => "Floor", - Self::Ln => "Ln", Self::Log => "Log", - Self::Log10 => "Log10", Self::Round => "Round", Self::Signum => "Signum", Self::Sin => "Sin", @@ -23051,9 +23049,7 @@ impl<'de> serde::Deserialize<'de> for ScalarFunction { "Cos" => Ok(ScalarFunction::Cos), "Exp" => Ok(ScalarFunction::Exp), "Floor" => Ok(ScalarFunction::Floor), - "Ln" => Ok(ScalarFunction::Ln), "Log" => Ok(ScalarFunction::Log), - "Log10" => Ok(ScalarFunction::Log10), "Round" => Ok(ScalarFunction::Round), "Signum" => Ok(ScalarFunction::Signum), "Sin" => Ok(ScalarFunction::Sin), diff --git a/datafusion/proto/src/generated/prost.rs b/datafusion/proto/src/generated/prost.rs index d384aafd66e99..6f7e8a9789a6d 100644 --- a/datafusion/proto/src/generated/prost.rs +++ b/datafusion/proto/src/generated/prost.rs @@ -2850,9 +2850,9 @@ pub enum ScalarFunction { /// 7 was Digest Exp = 8, Floor = 9, - Ln = 10, + /// 10 was Ln Log = 11, - Log10 = 12, + /// 12 was Log10 /// 13 was Log2 Round = 14, Signum = 15, @@ -2992,9 +2992,7 @@ impl ScalarFunction { ScalarFunction::Cos => "Cos", ScalarFunction::Exp => "Exp", ScalarFunction::Floor => "Floor", - ScalarFunction::Ln => "Ln", ScalarFunction::Log => "Log", - ScalarFunction::Log10 => "Log10", ScalarFunction::Round => "Round", ScalarFunction::Signum => "Signum", ScalarFunction::Sin => "Sin", @@ -3037,9 +3035,7 @@ impl ScalarFunction { "Cos" => Some(Self::Cos), "Exp" => Some(Self::Exp), "Floor" => Some(Self::Floor), - "Ln" => Some(Self::Ln), "Log" => Some(Self::Log), - "Log10" => Some(Self::Log10), "Round" => Some(Self::Round), "Signum" => Some(Self::Signum), "Sin" => Some(Self::Sin), diff --git a/datafusion/proto/src/logical_plan/from_proto.rs b/datafusion/proto/src/logical_plan/from_proto.rs index 800b834bfcfa7..d372cb428c73a 100644 --- a/datafusion/proto/src/logical_plan/from_proto.rs +++ b/datafusion/proto/src/logical_plan/from_proto.rs @@ -40,7 +40,7 @@ use datafusion_expr::{ acosh, asinh, atan, atan2, atanh, cbrt, ceil, coalesce, concat_expr, concat_ws_expr, cos, cosh, cot, degrees, ends_with, exp, expr::{self, InList, Sort, WindowFunction}, - factorial, find_in_set, floor, gcd, initcap, iszero, lcm, ln, log, log10, + factorial, find_in_set, floor, gcd, initcap, iszero, lcm, log, logical_plan::{PlanType, StringifiedPlan}, nanvl, pi, power, radians, random, round, signum, sin, sinh, sqrt, substr_index, translate, trunc, AggregateFunction, Between, BinaryExpr, BuiltInWindowFunction, @@ -437,8 +437,6 @@ impl From<&protobuf::ScalarFunction> for BuiltinScalarFunction { ScalarFunction::Atanh => Self::Atanh, ScalarFunction::Exp => Self::Exp, ScalarFunction::Log => Self::Log, - ScalarFunction::Ln => Self::Ln, - ScalarFunction::Log10 => Self::Log10, ScalarFunction::Degrees => Self::Degrees, ScalarFunction::Radians => Self::Radians, ScalarFunction::Factorial => Self::Factorial, @@ -1347,10 +1345,6 @@ pub fn parse_expr( ScalarFunction::Radians => { Ok(radians(parse_expr(&args[0], registry, codec)?)) } - ScalarFunction::Ln => Ok(ln(parse_expr(&args[0], registry, codec)?)), - ScalarFunction::Log10 => { - Ok(log10(parse_expr(&args[0], registry, codec)?)) - } ScalarFunction::Floor => { Ok(floor(parse_expr(&args[0], registry, codec)?)) } diff --git a/datafusion/proto/src/logical_plan/to_proto.rs b/datafusion/proto/src/logical_plan/to_proto.rs index f7b3c72ecbcfd..1e4e85c51f70f 100644 --- a/datafusion/proto/src/logical_plan/to_proto.rs +++ b/datafusion/proto/src/logical_plan/to_proto.rs @@ -1431,8 +1431,6 @@ impl TryFrom<&BuiltinScalarFunction> for protobuf::ScalarFunction { BuiltinScalarFunction::Gcd => Self::Gcd, BuiltinScalarFunction::Lcm => Self::Lcm, BuiltinScalarFunction::Log => Self::Log, - BuiltinScalarFunction::Ln => Self::Ln, - BuiltinScalarFunction::Log10 => Self::Log10, BuiltinScalarFunction::Degrees => Self::Degrees, BuiltinScalarFunction::Radians => Self::Radians, BuiltinScalarFunction::Floor => Self::Floor, From 862d66312c6342ead5eca0270603f76df276f6d8 Mon Sep 17 00:00:00 2001 From: Kunal Kundu Date: Sat, 30 Mar 2024 01:03:51 +0530 Subject: [PATCH 3/4] refactor log_b functions to use macro --- datafusion/functions/src/macros.rs | 10 ++- datafusion/functions/src/math/ln.rs | 96 -------------------------- datafusion/functions/src/math/log10.rs | 96 -------------------------- datafusion/functions/src/math/log2.rs | 96 -------------------------- datafusion/functions/src/math/mod.rs | 18 +++-- 5 files changed, 16 insertions(+), 300 deletions(-) delete mode 100644 datafusion/functions/src/math/ln.rs delete mode 100644 datafusion/functions/src/math/log10.rs delete mode 100644 datafusion/functions/src/math/log2.rs diff --git a/datafusion/functions/src/macros.rs b/datafusion/functions/src/macros.rs index e735523df6212..b23baeeacf235 100644 --- a/datafusion/functions/src/macros.rs +++ b/datafusion/functions/src/macros.rs @@ -157,14 +157,16 @@ macro_rules! downcast_arg { /// $NAME: the name of the function /// $UNARY_FUNC: the unary function to apply to the argument macro_rules! make_math_unary_udf { - ($UDF:ident, $GNAME:ident, $NAME:ident, $UNARY_FUNC:ident) => { + ($UDF:ident, $GNAME:ident, $NAME:ident, $UNARY_FUNC:ident, $MONOTONICITY:expr) => { make_udf_function!($NAME::$UDF, $GNAME, $NAME); mod $NAME { use arrow::array::{ArrayRef, Float32Array, Float64Array}; use arrow::datatypes::DataType; use datafusion_common::{exec_err, DataFusionError, Result}; - use datafusion_expr::{ColumnarValue, ScalarUDFImpl, Signature, Volatility}; + use datafusion_expr::{ + ColumnarValue, FuncMonotonicity, ScalarUDFImpl, Signature, Volatility, + }; use std::any::Any; use std::sync::Arc; @@ -208,6 +210,10 @@ macro_rules! make_math_unary_udf { } } + fn monotonicity(&self) -> Result> { + Ok($MONOTONICITY) + } + fn invoke(&self, args: &[ColumnarValue]) -> Result { let args = ColumnarValue::values_to_arrays(args)?; diff --git a/datafusion/functions/src/math/ln.rs b/datafusion/functions/src/math/ln.rs deleted file mode 100644 index ea5c92743f468..0000000000000 --- a/datafusion/functions/src/math/ln.rs +++ /dev/null @@ -1,96 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you 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. - -//! Math function: `ln()`. - -use arrow::datatypes::DataType::{self, Float32, Float64}; -use datafusion_common::{exec_err, DataFusionError, Result}; -use datafusion_expr::{ColumnarValue, FuncMonotonicity}; - -use arrow::array::{ArrayRef, Float32Array, Float64Array}; -use datafusion_expr::{ScalarUDFImpl, Signature, Volatility}; -use std::any::Any; -use std::sync::Arc; - -#[derive(Debug)] -pub(super) struct LnFunc { - signature: Signature, -} - -impl LnFunc { - pub fn new() -> Self { - Self { - signature: Signature::uniform( - 1, - vec![Float64, Float32], - Volatility::Immutable, - ), - } - } -} - -impl ScalarUDFImpl for LnFunc { - fn as_any(&self) -> &dyn Any { - self - } - fn name(&self) -> &str { - "ln" - } - - fn signature(&self) -> &Signature { - &self.signature - } - - fn return_type(&self, arg_types: &[DataType]) -> Result { - match arg_types[0] { - Float32 => Ok(Float32), - _ => Ok(Float64), - } - } - - fn monotonicity(&self) -> Result> { - Ok(Some(vec![Some(true)])) - } - - fn invoke(&self, args: &[ColumnarValue]) -> Result { - let args = ColumnarValue::values_to_arrays(args)?; - - let arr: ArrayRef = match args[0].data_type() { - DataType::Float64 => Arc::new(make_function_scalar_inputs_return_type!( - &args[0], - self.name(), - Float64Array, - Float64Array, - { f64::ln } - )), - DataType::Float32 => Arc::new(make_function_scalar_inputs_return_type!( - &args[0], - self.name(), - Float32Array, - Float32Array, - { f32::ln } - )), - other => { - return exec_err!( - "Unsupported data type {other:?} for function {}", - self.name() - ) - } - }; - Ok(ColumnarValue::Array(arr)) - } -} diff --git a/datafusion/functions/src/math/log10.rs b/datafusion/functions/src/math/log10.rs deleted file mode 100644 index ab4d6ef100605..0000000000000 --- a/datafusion/functions/src/math/log10.rs +++ /dev/null @@ -1,96 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you 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. - -//! Math function: `log10()`. - -use arrow::datatypes::DataType::{self, Float32, Float64}; -use datafusion_common::{exec_err, DataFusionError, Result}; -use datafusion_expr::{ColumnarValue, FuncMonotonicity}; - -use arrow::array::{ArrayRef, Float32Array, Float64Array}; -use datafusion_expr::{ScalarUDFImpl, Signature, Volatility}; -use std::any::Any; -use std::sync::Arc; - -#[derive(Debug)] -pub(super) struct Log10Func { - signature: Signature, -} - -impl Log10Func { - pub fn new() -> Self { - Self { - signature: Signature::uniform( - 1, - vec![Float64, Float32], - Volatility::Immutable, - ), - } - } -} - -impl ScalarUDFImpl for Log10Func { - fn as_any(&self) -> &dyn Any { - self - } - fn name(&self) -> &str { - "log10" - } - - fn signature(&self) -> &Signature { - &self.signature - } - - fn return_type(&self, arg_types: &[DataType]) -> Result { - match arg_types[0] { - Float32 => Ok(Float32), - _ => Ok(Float64), - } - } - - fn monotonicity(&self) -> Result> { - Ok(Some(vec![Some(true)])) - } - - fn invoke(&self, args: &[ColumnarValue]) -> Result { - let args = ColumnarValue::values_to_arrays(args)?; - - let arr: ArrayRef = match args[0].data_type() { - DataType::Float64 => Arc::new(make_function_scalar_inputs_return_type!( - &args[0], - self.name(), - Float64Array, - Float64Array, - { f64::log10 } - )), - DataType::Float32 => Arc::new(make_function_scalar_inputs_return_type!( - &args[0], - self.name(), - Float32Array, - Float32Array, - { f32::log10 } - )), - other => { - return exec_err!( - "Unsupported data type {other:?} for function {}", - self.name() - ) - } - }; - Ok(ColumnarValue::Array(arr)) - } -} diff --git a/datafusion/functions/src/math/log2.rs b/datafusion/functions/src/math/log2.rs deleted file mode 100644 index 3c84023888633..0000000000000 --- a/datafusion/functions/src/math/log2.rs +++ /dev/null @@ -1,96 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you 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. - -//! Math function: `log2()`. - -use arrow::datatypes::DataType::{self, Float32, Float64}; -use datafusion_common::{exec_err, DataFusionError, Result}; -use datafusion_expr::{ColumnarValue, FuncMonotonicity}; - -use arrow::array::{ArrayRef, Float32Array, Float64Array}; -use datafusion_expr::{ScalarUDFImpl, Signature, Volatility}; -use std::any::Any; -use std::sync::Arc; - -#[derive(Debug)] -pub(super) struct Log2Func { - signature: Signature, -} - -impl Log2Func { - pub fn new() -> Self { - Self { - signature: Signature::uniform( - 1, - vec![Float64, Float32], - Volatility::Immutable, - ), - } - } -} - -impl ScalarUDFImpl for Log2Func { - fn as_any(&self) -> &dyn Any { - self - } - fn name(&self) -> &str { - "log2" - } - - fn signature(&self) -> &Signature { - &self.signature - } - - fn return_type(&self, arg_types: &[DataType]) -> Result { - match arg_types[0] { - Float32 => Ok(Float32), - _ => Ok(Float64), - } - } - - fn monotonicity(&self) -> Result> { - Ok(Some(vec![Some(true)])) - } - - fn invoke(&self, args: &[ColumnarValue]) -> Result { - let args = ColumnarValue::values_to_arrays(args)?; - - let arr: ArrayRef = match args[0].data_type() { - DataType::Float64 => Arc::new(make_function_scalar_inputs_return_type!( - &args[0], - self.name(), - Float64Array, - Float64Array, - { f64::log2 } - )), - DataType::Float32 => Arc::new(make_function_scalar_inputs_return_type!( - &args[0], - self.name(), - Float32Array, - Float32Array, - { f32::log2 } - )), - other => { - return exec_err!( - "Unsupported data type {other:?} for function {}", - self.name() - ) - } - }; - Ok(ColumnarValue::Array(arr)) - } -} diff --git a/datafusion/functions/src/math/mod.rs b/datafusion/functions/src/math/mod.rs index 17d87aca6a0cd..3a4c1b1e8710d 100644 --- a/datafusion/functions/src/math/mod.rs +++ b/datafusion/functions/src/math/mod.rs @@ -18,22 +18,20 @@ //! "math" DataFusion functions mod abs; -mod ln; -mod log10; -mod log2; mod nans; // Create UDFs make_udf_function!(nans::IsNanFunc, ISNAN, isnan); make_udf_function!(abs::AbsFunc, ABS, abs); -make_udf_function!(log2::Log2Func, LOG2, log2); -make_udf_function!(log10::Log10Func, LOG10, log10); -make_udf_function!(ln::LnFunc, LN, ln); -make_math_unary_udf!(TanhFunc, TANH, tanh, tanh); -make_math_unary_udf!(AcosFunc, ACOS, acos, acos); -make_math_unary_udf!(AsinFunc, ASIN, asin, asin); -make_math_unary_udf!(TanFunc, TAN, tan, tan); +make_math_unary_udf!(Log2Func, LOG2, log2, log2, Some(vec![Some(true)])); +make_math_unary_udf!(Log10Func, LOG10, log10, log10, Some(vec![Some(true)])); +make_math_unary_udf!(LnFunc, LN, ln, ln, Some(vec![Some(true)])); + +make_math_unary_udf!(TanhFunc, TANH, tanh, tanh, None); +make_math_unary_udf!(AcosFunc, ACOS, acos, acos, None); +make_math_unary_udf!(AsinFunc, ASIN, asin, asin, None); +make_math_unary_udf!(TanFunc, TAN, tan, tan, None); // Export the functions out of this package, both as expr_fn as well as a list of functions export_functions!( From 99f81aaa159e70837ca6b648f2f40b69d633f97d Mon Sep 17 00:00:00 2001 From: Kunal Kundu Date: Sat, 30 Mar 2024 01:29:30 +0530 Subject: [PATCH 4/4] update proto --- datafusion/proto/proto/datafusion.proto | 6 +++--- datafusion/proto/src/generated/pbjson.rs | 3 --- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/datafusion/proto/proto/datafusion.proto b/datafusion/proto/proto/datafusion.proto index 3a187eabe836a..81451e40aa50c 100644 --- a/datafusion/proto/proto/datafusion.proto +++ b/datafusion/proto/proto/datafusion.proto @@ -551,10 +551,10 @@ enum ScalarFunction { // 7 was Digest Exp = 8; Floor = 9; - Ln = 10; + // 10 was Ln Log = 11; - Log10 = 12; - Log2 = 13; + // 12 was Log10 + // 13 was Log2 Round = 14; Signum = 15; Sin = 16; diff --git a/datafusion/proto/src/generated/pbjson.rs b/datafusion/proto/src/generated/pbjson.rs index d9e4bdded5415..2949ab807e048 100644 --- a/datafusion/proto/src/generated/pbjson.rs +++ b/datafusion/proto/src/generated/pbjson.rs @@ -22968,10 +22968,7 @@ impl<'de> serde::Deserialize<'de> for ScalarFunction { "Cos", "Exp", "Floor", - "Ln", "Log", - "Log10", - "Log2", "Round", "Signum", "Sin",