You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by al...@apache.org on 2023/04/12 19:44:37 UTC
[arrow-datafusion] branch main updated: feat: implementation of the constant "Pi" (#5965)
This is an automated email from the ASF dual-hosted git repository.
alamb pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-datafusion.git
The following commit(s) were added to refs/heads/main by this push:
new 777b166282 feat: implementation of the constant "Pi" (#5965)
777b166282 is described below
commit 777b166282e447c973688e83951f690dd000df32
Author: Igor Izvekov <iz...@gmail.com>
AuthorDate: Wed Apr 12 22:44:30 2023 +0300
feat: implementation of the constant "Pi" (#5965)
---
datafusion/core/tests/sqllogictests/test_files/scalar.slt | 6 ++++++
datafusion/expr/src/built_in_function.rs | 7 ++++++-
datafusion/expr/src/expr_fn.rs | 8 ++++++++
datafusion/expr/src/function.rs | 2 ++
datafusion/physical-expr/src/functions.rs | 2 ++
datafusion/physical-expr/src/math_expressions.rs | 11 +++++++++++
datafusion/proto/proto/datafusion.proto | 1 +
datafusion/proto/src/generated/pbjson.rs | 3 +++
datafusion/proto/src/generated/prost.rs | 3 +++
datafusion/proto/src/logical_plan/from_proto.rs | 4 +++-
datafusion/proto/src/logical_plan/to_proto.rs | 1 +
docs/source/user-guide/expressions.md | 1 +
docs/source/user-guide/sql/scalar_functions.md | 9 +++++++++
13 files changed, 56 insertions(+), 2 deletions(-)
diff --git a/datafusion/core/tests/sqllogictests/test_files/scalar.slt b/datafusion/core/tests/sqllogictests/test_files/scalar.slt
index 348789bd06..911aeb37fc 100644
--- a/datafusion/core/tests/sqllogictests/test_files/scalar.slt
+++ b/datafusion/core/tests/sqllogictests/test_files/scalar.slt
@@ -31,6 +31,12 @@ CREATE TABLE t1(
(3, 10000, 978, 2048)
;
+# pi scalar function
+query RRR rowsort
+select pi(), pi() / 2, pi() / 3;
+----
+3.14159265359 1.570796326795 1.047197551197
+
# log scalar function
query RR rowsort
select log(2, 64) a, log(100) b union all select log(2, 8), log(10);
diff --git a/datafusion/expr/src/built_in_function.rs b/datafusion/expr/src/built_in_function.rs
index becde961c6..72033de834 100644
--- a/datafusion/expr/src/built_in_function.rs
+++ b/datafusion/expr/src/built_in_function.rs
@@ -66,6 +66,8 @@ pub enum BuiltinScalarFunction {
Log10,
/// log2
Log2,
+ /// pi
+ Pi,
/// power
Power,
/// round
@@ -196,7 +198,8 @@ impl BuiltinScalarFunction {
pub fn supports_zero_argument(&self) -> bool {
matches!(
self,
- BuiltinScalarFunction::Random
+ BuiltinScalarFunction::Pi
+ | BuiltinScalarFunction::Random
| BuiltinScalarFunction::Now
| BuiltinScalarFunction::CurrentDate
| BuiltinScalarFunction::CurrentTime
@@ -225,6 +228,7 @@ impl BuiltinScalarFunction {
BuiltinScalarFunction::Log => Volatility::Immutable,
BuiltinScalarFunction::Log10 => Volatility::Immutable,
BuiltinScalarFunction::Log2 => Volatility::Immutable,
+ BuiltinScalarFunction::Pi => Volatility::Immutable,
BuiltinScalarFunction::Power => Volatility::Immutable,
BuiltinScalarFunction::Round => Volatility::Immutable,
BuiltinScalarFunction::Signum => Volatility::Immutable,
@@ -324,6 +328,7 @@ impl FromStr for BuiltinScalarFunction {
"log" => BuiltinScalarFunction::Log,
"log10" => BuiltinScalarFunction::Log10,
"log2" => BuiltinScalarFunction::Log2,
+ "pi" => BuiltinScalarFunction::Pi,
"power" | "pow" => BuiltinScalarFunction::Power,
"round" => BuiltinScalarFunction::Round,
"signum" => BuiltinScalarFunction::Signum,
diff --git a/datafusion/expr/src/expr_fn.rs b/datafusion/expr/src/expr_fn.rs
index 521801bd95..d2305462fa 100644
--- a/datafusion/expr/src/expr_fn.rs
+++ b/datafusion/expr/src/expr_fn.rs
@@ -226,6 +226,14 @@ pub fn concat_ws(sep: Expr, values: Vec<Expr>) -> Expr {
}
}
+/// Returns an approximate value of π
+pub fn pi() -> Expr {
+ Expr::ScalarFunction {
+ fun: built_in_function::BuiltinScalarFunction::Pi,
+ args: vec![],
+ }
+}
+
/// Returns a random value in the range 0.0 <= x < 1.0
pub fn random() -> Expr {
Expr::ScalarFunction {
diff --git a/datafusion/expr/src/function.rs b/datafusion/expr/src/function.rs
index 3b335b477c..eff5111d05 100644
--- a/datafusion/expr/src/function.rs
+++ b/datafusion/expr/src/function.rs
@@ -169,6 +169,7 @@ pub fn return_type(
BuiltinScalarFunction::OctetLength => {
utf8_to_int_type(&input_expr_types[0], "octet_length")
}
+ BuiltinScalarFunction::Pi => Ok(DataType::Float64),
BuiltinScalarFunction::Random => Ok(DataType::Float64),
BuiltinScalarFunction::Uuid => Ok(DataType::Utf8),
BuiltinScalarFunction::RegexpReplace => {
@@ -623,6 +624,7 @@ pub fn signature(fun: &BuiltinScalarFunction) -> Signature {
],
fun.volatility(),
),
+ BuiltinScalarFunction::Pi => Signature::exact(vec![], fun.volatility()),
BuiltinScalarFunction::Random => Signature::exact(vec![], fun.volatility()),
BuiltinScalarFunction::Uuid => Signature::exact(vec![], fun.volatility()),
BuiltinScalarFunction::Power => Signature::one_of(
diff --git a/datafusion/physical-expr/src/functions.rs b/datafusion/physical-expr/src/functions.rs
index f2297a5355..15d9810b01 100644
--- a/datafusion/physical-expr/src/functions.rs
+++ b/datafusion/physical-expr/src/functions.rs
@@ -362,6 +362,7 @@ pub fn create_physical_fun(
BuiltinScalarFunction::Tan => Arc::new(math_expressions::tan),
BuiltinScalarFunction::Tanh => Arc::new(math_expressions::tanh),
BuiltinScalarFunction::Trunc => Arc::new(math_expressions::trunc),
+ BuiltinScalarFunction::Pi => Arc::new(math_expressions::pi),
BuiltinScalarFunction::Power => {
Arc::new(|args| make_scalar_function(math_expressions::power)(args))
}
@@ -2763,6 +2764,7 @@ mod tests {
let funs = [
BuiltinScalarFunction::Now,
+ BuiltinScalarFunction::Pi,
BuiltinScalarFunction::Random,
BuiltinScalarFunction::Uuid,
];
diff --git a/datafusion/physical-expr/src/math_expressions.rs b/datafusion/physical-expr/src/math_expressions.rs
index 7c1479c909..ee96b19a5c 100644
--- a/datafusion/physical-expr/src/math_expressions.rs
+++ b/datafusion/physical-expr/src/math_expressions.rs
@@ -165,6 +165,17 @@ math_unary_function!("ln", ln);
math_unary_function!("log2", log2);
math_unary_function!("log10", log10);
+/// Pi SQL function
+pub fn pi(args: &[ColumnarValue]) -> Result<ColumnarValue> {
+ if !matches!(&args[0], ColumnarValue::Array(_)) {
+ return Err(DataFusionError::Internal(
+ "Expect pi function to take no param".to_string(),
+ ));
+ }
+ let array = Float64Array::from_value(std::f64::consts::PI, 1);
+ Ok(ColumnarValue::Array(Arc::new(array)))
+}
+
/// Random SQL function
pub fn random(args: &[ColumnarValue]) -> Result<ColumnarValue> {
let len: usize = match &args[0] {
diff --git a/datafusion/proto/proto/datafusion.proto b/datafusion/proto/proto/datafusion.proto
index 4bbd5a0417..49cf9c9806 100644
--- a/datafusion/proto/proto/datafusion.proto
+++ b/datafusion/proto/proto/datafusion.proto
@@ -530,6 +530,7 @@ enum ScalarFunction {
Sinh = 77;
Cosh = 78;
Tanh = 79;
+ Pi = 80;
}
message ScalarFunctionNode {
diff --git a/datafusion/proto/src/generated/pbjson.rs b/datafusion/proto/src/generated/pbjson.rs
index 9e49eb2f09..3dca53e7b5 100644
--- a/datafusion/proto/src/generated/pbjson.rs
+++ b/datafusion/proto/src/generated/pbjson.rs
@@ -17202,6 +17202,7 @@ impl serde::Serialize for ScalarFunction {
Self::Sinh => "Sinh",
Self::Cosh => "Cosh",
Self::Tanh => "Tanh",
+ Self::Pi => "Pi",
};
serializer.serialize_str(variant)
}
@@ -17293,6 +17294,7 @@ impl<'de> serde::Deserialize<'de> for ScalarFunction {
"Sinh",
"Cosh",
"Tanh",
+ "Pi",
];
struct GeneratedVisitor;
@@ -17415,6 +17417,7 @@ impl<'de> serde::Deserialize<'de> for ScalarFunction {
"Sinh" => Ok(ScalarFunction::Sinh),
"Cosh" => Ok(ScalarFunction::Cosh),
"Tanh" => Ok(ScalarFunction::Tanh),
+ "Pi" => Ok(ScalarFunction::Pi),
_ => Err(serde::de::Error::unknown_variant(value, FIELDS)),
}
}
diff --git a/datafusion/proto/src/generated/prost.rs b/datafusion/proto/src/generated/prost.rs
index 54857f1414..7e2d10ba83 100644
--- a/datafusion/proto/src/generated/prost.rs
+++ b/datafusion/proto/src/generated/prost.rs
@@ -2141,6 +2141,7 @@ pub enum ScalarFunction {
Sinh = 77,
Cosh = 78,
Tanh = 79,
+ Pi = 80,
}
impl ScalarFunction {
/// String value of the enum field names used in the ProtoBuf definition.
@@ -2229,6 +2230,7 @@ impl ScalarFunction {
ScalarFunction::Sinh => "Sinh",
ScalarFunction::Cosh => "Cosh",
ScalarFunction::Tanh => "Tanh",
+ ScalarFunction::Pi => "Pi",
}
}
/// Creates an enum from field names used in the ProtoBuf definition.
@@ -2314,6 +2316,7 @@ impl ScalarFunction {
"Sinh" => Some(Self::Sinh),
"Cosh" => Some(Self::Cosh),
"Tanh" => Some(Self::Tanh),
+ "Pi" => Some(Self::Pi),
_ => None,
}
}
diff --git a/datafusion/proto/src/logical_plan/from_proto.rs b/datafusion/proto/src/logical_plan/from_proto.rs
index eff450c98a..bd544b93bd 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::{
expr::{self, Sort, WindowFunction},
floor, from_unixtime, left, ln, log, log10, log2,
logical_plan::{PlanType, StringifiedPlan},
- lower, lpad, ltrim, md5, now, nullif, octet_length, power, random, regexp_match,
+ lower, lpad, ltrim, md5, now, nullif, octet_length, pi, power, random, regexp_match,
regexp_replace, repeat, replace, reverse, right, round, rpad, rtrim, sha224, sha256,
sha384, sha512, signum, sin, sinh, split_part, sqrt, starts_with, strpos, substr,
substring, tan, tanh, to_hex, to_timestamp_micros, to_timestamp_millis,
@@ -475,6 +475,7 @@ impl From<&protobuf::ScalarFunction> for BuiltinScalarFunction {
ScalarFunction::Translate => Self::Translate,
ScalarFunction::RegexpMatch => Self::RegexpMatch,
ScalarFunction::Coalesce => Self::Coalesce,
+ ScalarFunction::Pi => Self::Pi,
ScalarFunction::Power => Self::Power,
ScalarFunction::StructFun => Self::Struct,
ScalarFunction::FromUnixtime => Self::FromUnixtime,
@@ -1318,6 +1319,7 @@ pub fn parse_expr(
.map(|expr| parse_expr(expr, registry))
.collect::<Result<Vec<_>, _>>()?,
)),
+ ScalarFunction::Pi => Ok(pi()),
ScalarFunction::Power => Ok(power(
parse_expr(&args[0], registry)?,
parse_expr(&args[1], registry)?,
diff --git a/datafusion/proto/src/logical_plan/to_proto.rs b/datafusion/proto/src/logical_plan/to_proto.rs
index 9465c73612..7e6aa6b687 100644
--- a/datafusion/proto/src/logical_plan/to_proto.rs
+++ b/datafusion/proto/src/logical_plan/to_proto.rs
@@ -1325,6 +1325,7 @@ impl TryFrom<&BuiltinScalarFunction> for protobuf::ScalarFunction {
BuiltinScalarFunction::Translate => Self::Translate,
BuiltinScalarFunction::RegexpMatch => Self::RegexpMatch,
BuiltinScalarFunction::Coalesce => Self::Coalesce,
+ BuiltinScalarFunction::Pi => Self::Pi,
BuiltinScalarFunction::Power => Self::Power,
BuiltinScalarFunction::Struct => Self::StructFun,
BuiltinScalarFunction::FromUnixtime => Self::FromUnixtime,
diff --git a/docs/source/user-guide/expressions.md b/docs/source/user-guide/expressions.md
index c8eb8f2f58..339bfadfe9 100644
--- a/docs/source/user-guide/expressions.md
+++ b/docs/source/user-guide/expressions.md
@@ -84,6 +84,7 @@ expressions such as `col("a") + col("b")` to be used.
| log(base, x) | logarithm of x for a particular base |
| log10(x) | base 10 logarithm |
| log2(x) | base 2 logarithm |
+| pi(base, exponent) | approximate value of π |
| power(base, exponent) | base raised to the power of exponent |
| round(x) | round to nearest integer |
| signum(x) | sign of the argument (-1, 0, +1) |
diff --git a/docs/source/user-guide/sql/scalar_functions.md b/docs/source/user-guide/sql/scalar_functions.md
index 3fe0f4647d..0414ffdd31 100644
--- a/docs/source/user-guide/sql/scalar_functions.md
+++ b/docs/source/user-guide/sql/scalar_functions.md
@@ -38,6 +38,7 @@
- [ln](#ln)
- [log10](#log10)
- [log2](#log2)
+- [pi](#pi)
- [power](#power)
- [random](#random)
- [round](#round)
@@ -272,6 +273,14 @@ log2(numeric_expression)
- **numeric_expression**: Numeric expression to operate on.
Can be a constant, column, or function, and any combination of arithmetic operators.
+### `pi`
+
+Returns an approximate value of π.
+
+```
+pi()
+```
+
### `power`
Returns a base number raised to the power of an exponent.