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.