diff --git a/src/query/functions/src/aggregates/aggregate_kurtosis.rs b/src/query/functions/src/aggregates/aggregate_kurtosis.rs index 84d1b64fb2b9..876564b19d21 100644 --- a/src/query/functions/src/aggregates/aggregate_kurtosis.rs +++ b/src/query/functions/src/aggregates/aggregate_kurtosis.rs @@ -32,10 +32,10 @@ use crate::aggregates::AggregateFunctionRef; #[derive(Default, BorshSerialize, BorshDeserialize)] struct KurtosisState { pub n: u64, - pub sum: f64, - pub sum_sqr: f64, - pub sum_cub: f64, - pub sum_four: f64, + pub sum: F64, + pub sum_sqr: F64, + pub sum_cub: F64, + pub sum_four: F64, } impl UnaryState for KurtosisState @@ -78,27 +78,34 @@ where builder.push(F64::from(0_f64)); return Ok(()); } - let n = self.n as f64; + + let (n, sum, sum_sqr, sum_cub, sum_four) = ( + self.n as f64, + *self.sum, + *self.sum_sqr, + *self.sum_cub, + *self.sum_four, + ); + let temp = 1.0 / n; - if self.sum_sqr - self.sum * self.sum * temp == 0.0 { + if sum_sqr - sum * sum * temp == 0.0 { builder.push(F64::from(0_f64)); return Ok(()); } let m4 = temp - * (self.sum_four - 4.0 * self.sum_cub * self.sum * temp - + 6.0 * self.sum_sqr * self.sum * self.sum * temp * temp - - 3.0 * self.sum.powi(4) * temp.powi(3)); - let m2 = temp * (self.sum_sqr - self.sum * self.sum * temp); + * (sum_four - 4.0 * sum_cub * sum * temp + 6.0 * sum_sqr * sum * sum * temp * temp + - 3.0 * sum.powi(4) * temp.powi(3)); + let m2 = temp * (sum_sqr - sum * sum * temp); if m2 <= 0.0 || (n - 2.0) * (n - 3.0) == 0.0 { builder.push(F64::from(0_f64)); return Ok(()); } let value = (n - 1.0) * ((n + 1.0) * m4 / (m2 * m2) - 3.0 * (n - 1.0)) / ((n - 2.0) * (n - 3.0)); - if value.is_infinite() || value.is_nan() { - return Err(ErrorCode::SemanticError("Kurtosis is out of range!")); - } else { + if value.is_finite() { builder.push(F64::from(value)); + } else { + builder.push(F64::from(f64::NAN)); } Ok(()) } diff --git a/src/query/functions/src/aggregates/aggregate_skewness.rs b/src/query/functions/src/aggregates/aggregate_skewness.rs index b71d5292b1fd..1a798c954104 100644 --- a/src/query/functions/src/aggregates/aggregate_skewness.rs +++ b/src/query/functions/src/aggregates/aggregate_skewness.rs @@ -32,9 +32,9 @@ use crate::aggregates::aggregate_unary::UnaryState; #[derive(Default, BorshSerialize, BorshDeserialize)] pub struct SkewnessStateV2 { pub n: u64, - pub sum: f64, - pub sum_sqr: f64, - pub sum_cub: f64, + pub sum: F64, + pub sum_sqr: F64, + pub sum_cub: F64, } impl UnaryState for SkewnessStateV2 @@ -75,25 +75,23 @@ where builder.push(F64::from(0_f64)); return Ok(()); } - let n = self.n as f64; + + let (n, sum, sum_sqr, sum_cub) = (self.n as f64, *self.sum, *self.sum_sqr, *self.sum_cub); let temp = 1.0 / n; - let div = (temp * (self.sum_sqr - self.sum * self.sum * temp)) - .powi(3) - .sqrt(); + let div = (temp * (sum_sqr - sum * sum * temp)).powi(3).sqrt(); if div == 0.0 { builder.push(F64::from(0_f64)); return Ok(()); } let temp1 = (n * (n - 1.0)).sqrt() / (n - 2.0); - let value = temp1 - * temp - * (self.sum_cub - 3.0 * self.sum_sqr * self.sum * temp - + 2.0 * self.sum.powi(3) * temp * temp) - / div; - if value.is_infinite() || value.is_nan() { - return Err(ErrorCode::SemanticError("Skew is out of range!")); - } else { + let value = + temp1 * temp * (sum_cub - 3.0 * sum_sqr * sum * temp + 2.0 * sum.powi(3) * temp * temp) + / div; + + if value.is_finite() { builder.push(F64::from(value)); + } else { + builder.push(F64::from(f64::NAN)); } Ok(()) } diff --git a/tests/sqllogictests/suites/query/functions/02_0000_function_aggregate_mix.test b/tests/sqllogictests/suites/query/functions/02_0000_function_aggregate_mix.test index 9c3a5d8a7911..b170af49fb42 100644 --- a/tests/sqllogictests/suites/query/functions/02_0000_function_aggregate_mix.test +++ b/tests/sqllogictests/suites/query/functions/02_0000_function_aggregate_mix.test @@ -317,6 +317,16 @@ select skewness (10) from numbers(5) ---- 0.0 +query I +select skewness(number), kurtosis(number) from (select if(number > 5, number::double, 'NAN'::Double) as number from numbers(100)); +---- +NaN NaN + +query I +select skewness(number), kurtosis(number) from (select if(number > 5, number::double, 'INF'::Double) as number from numbers(100)); +---- +NaN NaN + query III select skewness(k), skewness(v), skewness(v2) from aggr ----