From e8f55b60f2d4d76b9859029d46c65407fceb946a Mon Sep 17 00:00:00 2001 From: Albert Marashi Date: Fri, 2 Aug 2024 22:19:46 +0930 Subject: [PATCH] Fixes division by zero bug by returning NAN for divisions by zero? (#4402) Co-authored-by: Emmanuel Keller --- core/src/dbs/group.rs | 2 +- core/src/fnc/operate.rs | 2 +- lib/tests/group.rs | 60 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 2 deletions(-) diff --git a/core/src/dbs/group.rs b/core/src/dbs/group.rs index 200470b8..9852d02e 100644 --- a/core/src/dbs/group.rs +++ b/core/src/dbs/group.rs @@ -329,7 +329,7 @@ impl Aggregator { OptimisedAggregate::MathSum => self.math_sum.take().unwrap_or(Value::None), OptimisedAggregate::MathMean => { if let Some((v, i)) = self.math_mean.take() { - v.try_div(i.into())? + v.try_div(i.into()).unwrap_or(f64::NAN.into()) } else { Value::None } diff --git a/core/src/fnc/operate.rs b/core/src/fnc/operate.rs index 2f65dbba..11163237 100644 --- a/core/src/fnc/operate.rs +++ b/core/src/fnc/operate.rs @@ -57,7 +57,7 @@ pub fn mul(a: Value, b: Value) -> Result { } pub fn div(a: Value, b: Value) -> Result { - a.try_div(b) + Ok(a.try_div(b).unwrap_or(f64::NAN.into())) } pub fn rem(a: Value, b: Value) -> Result { diff --git a/lib/tests/group.rs b/lib/tests/group.rs index 9ab42f84..7ed028fc 100644 --- a/lib/tests/group.rs +++ b/lib/tests/group.rs @@ -674,3 +674,63 @@ async fn select_array_count_subquery_group_by() -> Result<(), Error> { // Ok(()) } + +#[tokio::test] +async fn select_aggregate_mean_update() -> Result<(), Error> { + let sql = " + CREATE test:a SET a = 3; + DEFINE TABLE foo AS SELECT + math::mean(a) AS avg + FROM test + GROUP ALL; + + UPDATE test:a SET a = 2; + + SELECT avg FROM foo; + "; + let dbs = new_ds().await?; + let ses = Session::owner().with_ns("test").with_db("test"); + let res = &mut dbs.execute(sql, &ses, None).await?; + assert_eq!(res.len(), 4); + // + let tmp = res.remove(0).result?; + let val = Value::parse( + "[ + { + id: test:a, + a: 3 + } + ]", + ); + + assert_eq!(tmp, val); + // + let tmp = res.remove(0).result?; + let val = Value::parse("None"); + + assert_eq!(tmp, val); + + let tmp = res.remove(0).result?; + let val = Value::parse( + "[ + { + id: test:a, + a: 2 + } + ]", + ); + + assert_eq!(tmp, val); + + let tmp = res.remove(0).result?; + let val = Value::parse( + "[ + { + avg: 2 + } + ]", + ); + assert_eq!(tmp, val); + + Ok(()) +}