Skip to content

Commit 3fb79c3

Browse files
izveigorMazterQyou
authored andcommitted
feat: implementation of the constant "Pi" (apache#5965)
1 parent be967a6 commit 3fb79c3

File tree

9 files changed

+55
-4
lines changed

9 files changed

+55
-4
lines changed

datafusion/core/src/logical_plan/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ pub use expr::{
4848
count, count_distinct, create_udaf, create_udf, create_udtf, date_part, date_trunc,
4949
digest, exp, exprlist_to_fields, floor, in_list, initcap, left, length, lit,
5050
lit_timestamp_nano, ln, log10, log2, lower, lpad, ltrim, max, md5, min, now,
51-
now_expr, nullif, octet_length, or, random, regexp_match, regexp_replace, repeat,
51+
now_expr, nullif, octet_length, or, pi, random, regexp_match, regexp_replace, repeat,
5252
replace, reverse, right, round, rpad, rtrim, sha224, sha256, sha384, sha512, signum,
5353
sin, split_part, sqrt, starts_with, strpos, substr, sum, tan, to_hex,
5454
to_timestamp_micros, to_timestamp_millis, to_timestamp_seconds, translate, trim,

datafusion/core/src/physical_plan/functions.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ pub fn return_type(
140140
BuiltinScalarFunction::OctetLength => {
141141
utf8_to_int_type(&input_expr_types[0], "octet_length")
142142
}
143+
BuiltinScalarFunction::Pi => Ok(DataType::Float64),
143144
BuiltinScalarFunction::Random => Ok(DataType::Float64),
144145
BuiltinScalarFunction::RegexpReplace => {
145146
utf8_to_str_type(&input_expr_types[0], "regex_replace")
@@ -646,6 +647,7 @@ fn signature(fun: &BuiltinScalarFunction) -> Signature {
646647
],
647648
fun.volatility(),
648649
),
650+
BuiltinScalarFunction::Pi => Signature::exact(vec![], fun.volatility()),
649651
BuiltinScalarFunction::Random => Signature::exact(vec![], fun.volatility()),
650652
// math expressions expect 1 argument of type f64 or f32
651653
// priority is given to f64 because e.g. `sqrt(1i32)` is in IR (real numbers) and thus we
@@ -803,6 +805,7 @@ pub fn create_physical_fun(
803805
BuiltinScalarFunction::Sqrt => Arc::new(math_expressions::sqrt),
804806
BuiltinScalarFunction::Tan => Arc::new(math_expressions::tan),
805807
BuiltinScalarFunction::Trunc => Arc::new(math_expressions::trunc),
808+
BuiltinScalarFunction::Pi => Arc::new(math_expressions::pi),
806809
// string functions
807810
BuiltinScalarFunction::MakeArray => Arc::new(array_expressions::array),
808811
BuiltinScalarFunction::Ascii => Arc::new(|args| match args[0].data_type() {
@@ -3549,7 +3552,11 @@ mod tests {
35493552
let execution_props = ExecutionProps::new();
35503553
let schema = Schema::new(vec![Field::new("a", DataType::Int32, false)]);
35513554

3552-
let funs = [BuiltinScalarFunction::Now, BuiltinScalarFunction::Random];
3555+
let funs = [
3556+
BuiltinScalarFunction::Now,
3557+
BuiltinScalarFunction::Pi,
3558+
BuiltinScalarFunction::Random,
3559+
];
35533560

35543561
for fun in funs.iter() {
35553562
create_physical_expr(fun, &[], &schema, &execution_props)?;

datafusion/core/tests/sql/functions.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,3 +594,19 @@ async fn case_builtin_math_expression() {
594594
// .unwrap();
595595
// assert_batches_sorted_eq!(expected, &results);
596596
// }
597+
598+
#[tokio::test]
599+
async fn pi_function() -> Result<()> {
600+
let ctx = SessionContext::new();
601+
let sql = "select pi(), pi() / 2, pi() / 3";
602+
let actual = execute_to_batches(&ctx, sql).await;
603+
let expected = vec![
604+
"+-------------------+--------------------+--------------------+",
605+
"| pi() | pi() / Int64(2) | pi() / Int64(3) |",
606+
"+-------------------+--------------------+--------------------+",
607+
"| 3.141592653589793 | 1.5707963267948966 | 1.0471975511965976 |",
608+
"+-------------------+--------------------+--------------------+",
609+
];
610+
assert_batches_eq!(expected, &actual);
611+
Ok(())
612+
}

datafusion/expr/src/built_in_function.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ pub enum BuiltinScalarFunction {
5454
Log10,
5555
/// log2
5656
Log2,
57+
/// pi
58+
Pi,
5759
/// round
5860
Round,
5961
/// signum
@@ -170,7 +172,8 @@ impl BuiltinScalarFunction {
170172
pub fn supports_zero_argument(&self) -> bool {
171173
matches!(
172174
self,
173-
BuiltinScalarFunction::Random
175+
BuiltinScalarFunction::Pi
176+
| BuiltinScalarFunction::Random
174177
| BuiltinScalarFunction::Now
175178
| BuiltinScalarFunction::UtcTimestamp
176179
| BuiltinScalarFunction::CurrentDate
@@ -193,6 +196,7 @@ impl BuiltinScalarFunction {
193196
BuiltinScalarFunction::Log => Volatility::Immutable,
194197
BuiltinScalarFunction::Log10 => Volatility::Immutable,
195198
BuiltinScalarFunction::Log2 => Volatility::Immutable,
199+
BuiltinScalarFunction::Pi => Volatility::Immutable,
196200
BuiltinScalarFunction::Round => Volatility::Immutable,
197201
BuiltinScalarFunction::Signum => Volatility::Immutable,
198202
BuiltinScalarFunction::Sin => Volatility::Immutable,
@@ -280,6 +284,7 @@ impl FromStr for BuiltinScalarFunction {
280284
"log" => BuiltinScalarFunction::Log,
281285
"log10" => BuiltinScalarFunction::Log10,
282286
"log2" => BuiltinScalarFunction::Log2,
287+
"pi" => BuiltinScalarFunction::Pi,
283288
"round" => BuiltinScalarFunction::Round,
284289
"signum" => BuiltinScalarFunction::Signum,
285290
"sin" => BuiltinScalarFunction::Sin,

datafusion/expr/src/expr_fn.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,14 @@ pub fn concat_ws(sep: impl Into<String>, values: &[Expr]) -> Expr {
134134
}
135135
}
136136

137+
/// Returns an approximate value of π
138+
pub fn pi() -> Expr {
139+
Expr::ScalarFunction {
140+
fun: built_in_function::BuiltinScalarFunction::Pi,
141+
args: vec![],
142+
}
143+
}
144+
137145
/// Returns a random value in the range 0.0 <= x < 1.0
138146
pub fn random() -> Expr {
139147
Expr::ScalarFunction {

datafusion/physical-expr/src/math_expressions.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,17 @@ math_unary_function!("ln", ln);
104104
math_unary_function!("log2", log2);
105105
math_unary_function!("log10", log10);
106106

107+
/// Pi SQL function
108+
pub fn pi(args: &[ColumnarValue]) -> Result<ColumnarValue> {
109+
if !matches!(&args[0], ColumnarValue::Array(_)) {
110+
return Err(DataFusionError::Internal(
111+
"Expect pi function to take no param".to_string(),
112+
));
113+
}
114+
let array = Float64Array::from_value(std::f64::consts::PI, 1);
115+
Ok(ColumnarValue::Array(Arc::new(array)))
116+
}
117+
107118
/// random SQL function
108119
pub fn random(args: &[ColumnarValue]) -> Result<ColumnarValue> {
109120
let len: usize = match &args[0] {

datafusion/proto/proto/datafusion.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ enum ScalarFunction {
191191
Coalesce=63;
192192
// Upstream
193193
CurrentDate=70;
194+
Pi=80;
194195
// Cubesql
195196
UtcTimestamp=101;
196197
ToDayInterval=102;

datafusion/proto/src/from_proto.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use datafusion::{
2424
logical_plan::{
2525
abs, acos, ascii, asin, atan, ceil, character_length, chr, concat_expr,
2626
concat_ws_expr, cos, digest, exp, floor, left, ln, log10, log2, now_expr, nullif,
27-
random, regexp_replace, repeat, replace, reverse, right, round, signum, sin,
27+
pi, random, regexp_replace, repeat, replace, reverse, right, round, signum, sin,
2828
split_part, sqrt, starts_with, strpos, substr, tan, to_hex, to_timestamp_micros,
2929
to_timestamp_millis, to_timestamp_seconds, translate, trunc,
3030
window_frames::{WindowFrame, WindowFrameBound, WindowFrameUnits},
@@ -432,6 +432,7 @@ impl From<&protobuf::ScalarFunction> for BuiltinScalarFunction {
432432
ScalarFunction::Translate => Self::Translate,
433433
ScalarFunction::RegexpMatch => Self::RegexpMatch,
434434
ScalarFunction::Coalesce => Self::Coalesce,
435+
ScalarFunction::Pi => Self::Pi,
435436
// Cube SQL
436437
ScalarFunction::UtcTimestamp => Self::UtcTimestamp,
437438
ScalarFunction::ToDayInterval => Self::ToDayInterval,
@@ -1233,6 +1234,7 @@ pub fn parse_expr(
12331234
.map(|expr| parse_expr(expr, registry))
12341235
.collect::<Result<Vec<_>, _>>()?,
12351236
)),
1237+
ScalarFunction::Pi => Ok(pi()),
12361238
_ => Err(proto_error(
12371239
"Protobuf deserialization error: Unsupported scalar function",
12381240
)),

datafusion/proto/src/to_proto.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1088,6 +1088,7 @@ impl TryFrom<&BuiltinScalarFunction> for protobuf::ScalarFunction {
10881088
BuiltinScalarFunction::Translate => Self::Translate,
10891089
BuiltinScalarFunction::RegexpMatch => Self::RegexpMatch,
10901090
BuiltinScalarFunction::Coalesce => Self::Coalesce,
1091+
BuiltinScalarFunction::Pi => Self::Pi,
10911092
// Cube SQL
10921093
BuiltinScalarFunction::UtcTimestamp => Self::UtcTimestamp,
10931094
BuiltinScalarFunction::ToDayInterval => Self::ToDayInterval,

0 commit comments

Comments
 (0)