Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 17 additions & 9 deletions datafusion/functions/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,8 +345,12 @@ macro_rules! make_math_unary_udf {

/// Macro to create a binary math UDF.
///
/// A binary math function takes two arguments of types Float32 or Float64,
/// applies a binary floating function to the argument, and returns a value of the same type.
/// A binary math function takes two numeric arguments. When both arguments are
/// Float32 the function is evaluated in single precision and returns Float32.
/// Any other combination of numeric (or null) argument types is coerced to
/// Float64 and returns Float64; in particular integers are widened to Float64
/// rather than Float32 so that values needing more than 24 bits of mantissa are
/// not silently rounded.
///
/// $UDF: the name of the UDF struct that implements `ScalarUDFImpl`
/// $NAME: the name of the function
Expand All @@ -365,7 +369,6 @@ macro_rules! make_math_binary_udf {
use arrow::datatypes::{DataType, Float32Type, Float64Type};
use datafusion_common::utils::take_function_args;
use datafusion_common::{Result, ScalarValue, internal_err};
use datafusion_expr::TypeSignature;
use datafusion_expr::sort_properties::{ExprProperties, SortProperties};
use datafusion_expr::{
ColumnarValue, Documentation, ScalarFunctionArgs, ScalarUDFImpl,
Expand All @@ -381,11 +384,17 @@ macro_rules! make_math_binary_udf {
pub fn new() -> Self {
use DataType::*;
Self {
signature: Signature::one_of(
vec![
TypeSignature::Exact(vec![Float32, Float32]),
TypeSignature::Exact(vec![Float64, Float64]),
],
// Float64 is listed first so that integer (and other
// non-float) arguments coerce to Float64 rather than
// Float32; genuine Float32 arguments still match
// exactly and stay in single precision. Coercing
// integers to Float64 matters for correctness: Float32
// has only a 24-bit mantissa, so widening a large
// integer to Float32 would round it before the function
// is ever applied.
signature: Signature::uniform(
2,
vec![Float64, Float32],
Volatility::Immutable,
),
}
Expand All @@ -406,7 +415,6 @@ macro_rules! make_math_binary_udf {

match arg_type {
DataType::Float32 => Ok(DataType::Float32),
// For other types (possible values float64/null/int), use Float64
_ => Ok(DataType::Float64),
}
}
Expand Down
10 changes: 5 additions & 5 deletions datafusion/functions/src/math/monotonicity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,11 +262,11 @@ Can be a constant, column, or function, and any combination of arithmetic operat
)
.with_sql_example(r#"```sql
> SELECT atan2(1, 1);
+------------+
| atan2(1,1) |
+------------+
| 0.7853982 |
+------------+
+--------------------+
| atan2(1,1) |
+--------------------+
| 0.7853981633974483 |
+--------------------+
```"#)
.build()
});
Expand Down
21 changes: 20 additions & 1 deletion datafusion/sqllogictest/test_files/scalar.slt
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,26 @@ select round(atanh(a), 5), round(atanh(b), 5), round(atanh(c), 5) from small_flo
query RRR rowsort
select atan2(0, 1), atan2(1, 2), atan2(2, 2);
----
0 0.4636476 0.7853982
0 0.463647609001 0.785398163397

# atan2 returns Float32 only when both arguments are Float32; every other
# numeric combination (integers, Float64, mixed, NULL) is computed in Float64
query TTTTTT
select
arrow_typeof(atan2(arrow_cast(1.0, 'Float32'), arrow_cast(1.0, 'Float32'))),
arrow_typeof(atan2(1, 1)),
arrow_typeof(atan2(arrow_cast(1.0, 'Float32'), arrow_cast(1.0, 'Float64'))),
arrow_typeof(atan2(arrow_cast(1.0, 'Float64'), arrow_cast(1.0, 'Float32'))),
arrow_typeof(atan2(null, null)),
arrow_typeof(atan2(null, 64));
----
Float32 Float64 Float64 Float64 Float64 Float64

# atan2 with integer inputs is computed in double precision
query B
select atan2(1, 1000000) = atan2(1.0, 1000000.0);
----
true

# atan2 scalar nulls
query R rowsort
Expand Down
10 changes: 5 additions & 5 deletions docs/source/user-guide/sql/scalar_functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -227,11 +227,11 @@ atan2(expression_y, expression_x)

```sql
> SELECT atan2(1, 1);
+------------+
| atan2(1,1) |
+------------+
| 0.7853982 |
+------------+
+--------------------+
| atan2(1,1) |
+--------------------+
| 0.7853981633974483 |
+--------------------+
```

### `atanh`
Expand Down
Loading