You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@datafusion.apache.org by gi...@apache.org on 2026/05/23 12:31:21 UTC
(datafusion) branch gh-readonly-queue/main/pr-22308-de08117b295e21df4bd2c5e55b22e98bef6d10a3 created (now 0594a8265e)
This is an automated email from the ASF dual-hosted git repository.
github-merge-queue[bot] pushed a change to branch gh-readonly-queue/main/pr-22308-de08117b295e21df4bd2c5e55b22e98bef6d10a3
in repository https://gitbox.apache.org/repos/asf/datafusion.git
at 0594a8265e fix sqrt(-1.0::float8) should error, not return NaN (#22308)
This branch includes the following new commits:
new 0594a8265e fix sqrt(-1.0::float8) should error, not return NaN (#22308)
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@datafusion.apache.org
For additional commands, e-mail: commits-help@datafusion.apache.org
(datafusion) 01/01: fix sqrt(-1.0::float8) should error, not return NaN (#22308)
Posted by gi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
github-merge-queue[bot] pushed a commit to branch gh-readonly-queue/main/pr-22308-de08117b295e21df4bd2c5e55b22e98bef6d10a3
in repository https://gitbox.apache.org/repos/asf/datafusion.git
commit 0594a8265e8e1c43880857df1ee2079647b58a43
Author: Zhen Chen <cz...@163.com>
AuthorDate: Sat May 23 20:31:01 2026 +0800
fix sqrt(-1.0::float8) should error, not return NaN (#22308)
## Which issue does this PR close?
- Closes #22260.
## Rationale for this change
DataFusion previously returned `NaN` for `sqrt` on negative
floating-point inputs, for example `sqrt((-1.0)::float8)`. This differs
from PostgreSQL semantics, which raise an error for square root of a
negative number.
This change makes `sqrt` return an execution error for out-of-domain
negative inputs so its behavior is closer to PostgreSQL and avoids
silently producing `NaN` for invalid inputs.
## What changes are included in this PR?
- Updated the unary math UDF helper to support an optional validator
callback for runtime input validation.
- Switched `sqrt` to use a named validator helper instead of inline
predicate and error-string arguments.
- Added runtime validation for `sqrt` so negative inputs now raise
`cannot take square root of a negative number`.
- Updated sqllogictests for `sqrt`:
- negative literal inputs now expect an error
- negative column inputs now expect an error
- positive column coverage was retained using in-domain inputs
## Are these changes tested?
Yes.
The change is covered by existing SQL logic tests and targeted
validation runs:
- `cargo test -p datafusion-functions sqrt`
- `cargo test -p datafusion-sqllogictest --test sqllogictests scalar`
## Are there any user-facing changes?
Yes.
`sqrt` now raises an execution error for negative inputs instead of
returning `NaN`. This changes user-visible query behavior to better
align with PostgreSQL semantics.
---------
Co-authored-by: Copilot <co...@github.com>
---
datafusion/functions/src/macros.rs | 50 ++++++++++++++++++++++-----
datafusion/functions/src/math/mod.rs | 12 ++++++-
datafusion/sqllogictest/test_files/scalar.slt | 20 +++++++----
3 files changed, 66 insertions(+), 16 deletions(-)
diff --git a/datafusion/functions/src/macros.rs b/datafusion/functions/src/macros.rs
index 71528b4d16..79e1931369 100644
--- a/datafusion/functions/src/macros.rs
+++ b/datafusion/functions/src/macros.rs
@@ -210,6 +210,17 @@ macro_rules! downcast_arg {
/// $GET_DOC: the function to get the documentation of the UDF
macro_rules! make_math_unary_udf {
($UDF:ident, $NAME:ident, $UNARY_FUNC:ident, $OUTPUT_ORDERING:expr, $EVALUATE_BOUNDS:expr, $GET_DOC:expr) => {
+ make_math_unary_udf!(
+ $UDF,
+ $NAME,
+ $UNARY_FUNC,
+ $OUTPUT_ORDERING,
+ $EVALUATE_BOUNDS,
+ $GET_DOC,
+ None::<fn(f64) -> Result<()>>
+ );
+ };
+ ($UDF:ident, $NAME:ident, $UNARY_FUNC:ident, $OUTPUT_ORDERING:expr, $EVALUATE_BOUNDS:expr, $GET_DOC:expr, $VALIDATOR:expr) => {
$crate::make_udf_function!($NAME::$UDF, $NAME);
mod $NAME {
@@ -218,6 +229,7 @@ macro_rules! make_math_unary_udf {
use arrow::array::{ArrayRef, AsArray};
use arrow::datatypes::{DataType, Float32Type, Float64Type};
+ use arrow::error::ArrowError;
use datafusion_common::{Result, exec_err};
use datafusion_expr::interval_arithmetic::Interval;
use datafusion_expr::sort_properties::{ExprProperties, SortProperties};
@@ -280,16 +292,38 @@ macro_rules! make_math_unary_udf {
) -> Result<ColumnarValue> {
let args = ColumnarValue::values_to_arrays(&args.args)?;
let arr: ArrayRef = match args[0].data_type() {
- DataType::Float64 => Arc::new(
- args[0]
+ DataType::Float64 => {
+ let values = args[0]
.as_primitive::<Float64Type>()
- .unary::<_, Float64Type>(|x: f64| f64::$UNARY_FUNC(x)),
- ) as ArrayRef,
- DataType::Float32 => Arc::new(
- args[0]
+ .try_unary::<_, Float64Type, _>(
+ |x: f64| -> std::result::Result<f64, ArrowError> {
+ if let Some(validate) = $VALIDATOR {
+ validate(x).map_err(|error| {
+ ArrowError::ComputeError(error.to_string())
+ })?;
+ }
+
+ Ok(f64::$UNARY_FUNC(x))
+ },
+ )?;
+ Arc::new(values) as ArrayRef
+ }
+ DataType::Float32 => {
+ let values = args[0]
.as_primitive::<Float32Type>()
- .unary::<_, Float32Type>(|x: f32| f32::$UNARY_FUNC(x)),
- ) as ArrayRef,
+ .try_unary::<_, Float32Type, _>(
+ |x: f32| -> std::result::Result<f32, ArrowError> {
+ if let Some(validate) = $VALIDATOR {
+ validate(x as f64).map_err(|error| {
+ ArrowError::ComputeError(error.to_string())
+ })?;
+ }
+
+ Ok(f32::$UNARY_FUNC(x))
+ },
+ )?;
+ Arc::new(values) as ArrayRef
+ }
other => {
return exec_err!(
"Unsupported data type {other:?} for function {}",
diff --git a/datafusion/functions/src/math/mod.rs b/datafusion/functions/src/math/mod.rs
index 610e773d68..1754ccb434 100644
--- a/datafusion/functions/src/math/mod.rs
+++ b/datafusion/functions/src/math/mod.rs
@@ -18,6 +18,7 @@
//! "math" DataFusion functions
use crate::math::monotonicity::*;
+use datafusion_common::{Result, exec_err};
use datafusion_expr::ScalarUDF;
use std::sync::Arc;
@@ -42,6 +43,14 @@ pub mod round;
pub mod signum;
pub mod trunc;
+fn validate_sqrt_input(value: f64) -> Result<()> {
+ if value < 0.0 {
+ exec_err!("cannot take square root of a negative number")
+ } else {
+ Ok(())
+ }
+}
+
// Create UDFs
make_udf_function!(abs::AbsFunc, abs);
make_math_unary_udf!(
@@ -208,7 +217,8 @@ make_math_unary_udf!(
sqrt,
super::sqrt_order,
super::bounds::sqrt_bounds,
- super::get_sqrt_doc
+ super::get_sqrt_doc,
+ Some(super::validate_sqrt_input)
);
make_math_unary_udf!(
TanFunc,
diff --git a/datafusion/sqllogictest/test_files/scalar.slt b/datafusion/sqllogictest/test_files/scalar.slt
index 2ac7a9ef36..38f76f1315 100644
--- a/datafusion/sqllogictest/test_files/scalar.slt
+++ b/datafusion/sqllogictest/test_files/scalar.slt
@@ -1107,12 +1107,16 @@ NULL
# sqrt with columns (round is needed to normalize the outputs of different operating systems)
query RRR rowsort
-select round(sqrt(a), 5), round(sqrt(b), 5), round(sqrt(c), 5) from signed_integers;
+select round(sqrt(abs(a)), 5), round(sqrt(abs(b)), 5), round(sqrt(abs(c)), 5) from signed_integers;
----
-1.41421 NaN 11.09054
+1 10 23.81176
+1.41421 31.62278 11.09054
+1.73205 100 31.27299
2 NULL NULL
-NaN 10 NaN
-NaN 100 NaN
+
+# sqrt with negative column values should error
+query error cannot take square root of a negative number
+select round(sqrt(a), 5), round(sqrt(b), 5), round(sqrt(c), 5) from signed_integers;
# sqrt scalar fraction
query RR rowsort
@@ -1128,10 +1132,12 @@ select sqrt(cast(10e8 as double));
# sqrt scalar negative
-query R rowsort
+query error cannot take square root of a negative number
select sqrt(-1);
-----
-NaN
+
+# sqrt scalar negative float8
+query error cannot take square root of a negative number
+select sqrt((-1.0)::float8);
## tan
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@datafusion.apache.org
For additional commands, e-mail: commits-help@datafusion.apache.org