From 1177d27ef88e28a90f746305b72cbfb0c941fae6 Mon Sep 17 00:00:00 2001 From: zclllhhjj Date: Thu, 15 Aug 2024 17:50:24 +0800 Subject: [PATCH] [fix](function) avoid calculating sqrt of negative in agg function CORR (#39324) Issue Number: close #xxx before: ```sql mysql [sqlfunctest]>SELECT CORR(data, 89.999999) FROM DOUBLEDATA_NOT_EMPTY_NULLABLE; +---------------------------------------+ | corr(data, cast(89.999999 as DOUBLE)) | +---------------------------------------+ | NULL | +---------------------------------------+ 1 row in set (0.53 sec) ``` --- actually here's a silent nan by float exception. now sure in all platform. after: ```sql mysql [sqlfunctest]>SELECT CORR(data, 89.999999) FROM DOUBLEDATA_NOT_EMPTY_NULLABLE; +---------------------------------------+ | corr(data, cast(89.999999 as DOUBLE)) | +---------------------------------------+ | 0 | +---------------------------------------+ 1 row in set (0.13 sec) ``` --- is stable --- .../aggregate_function_corr.cpp | 3 ++- .../agg_function/test_corr.out | 17 +++++++++++++++++ .../agg_function/test_corr.groovy | 7 +++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/be/src/vec/aggregate_functions/aggregate_function_corr.cpp b/be/src/vec/aggregate_functions/aggregate_function_corr.cpp index fb84e92e0e669b..8237f588298064 100644 --- a/be/src/vec/aggregate_functions/aggregate_function_corr.cpp +++ b/be/src/vec/aggregate_functions/aggregate_function_corr.cpp @@ -68,7 +68,8 @@ struct CorrMoment { } T get() const { - if ((m0 * x2 - x1 * x1) * (m0 * y2 - y1 * y1) == 0) [[unlikely]] { + // avoid float error(silent nan) when x or y is constant + if (m0 * x2 <= x1 * x1 || m0 * y2 <= y1 * y1) [[unlikely]] { return 0; } return (m0 * xy - x1 * y1) / sqrt((m0 * x2 - x1 * x1) * (m0 * y2 - y1 * y1)); diff --git a/regression-test/data/nereids_function_p0/agg_function/test_corr.out b/regression-test/data/nereids_function_p0/agg_function/test_corr.out index 71293030ba8eb5..c1b7241b3c24fd 100644 --- a/regression-test/data/nereids_function_p0/agg_function/test_corr.out +++ b/regression-test/data/nereids_function_p0/agg_function/test_corr.out @@ -33,5 +33,22 @@ 0.0 0.0 0.0 + +-- !sql_const1 -- +0.0 + +-- !sql_const2 -- +0.0 + +-- !sql_const3 -- +0.0 + +-- !sql_const4 -- +0.0 + +-- !sql_const5 -- +0.0 + +-- !sql_const6 -- 0.0 diff --git a/regression-test/suites/nereids_function_p0/agg_function/test_corr.groovy b/regression-test/suites/nereids_function_p0/agg_function/test_corr.groovy index c752e8cb1334c4..50cd3cac79a50a 100644 --- a/regression-test/suites/nereids_function_p0/agg_function/test_corr.groovy +++ b/regression-test/suites/nereids_function_p0/agg_function/test_corr.groovy @@ -86,4 +86,11 @@ suite("test_corr") { qt_sql1 "select corr(non_nullable(x), non_nullable(y)) ans from test_corr group by id order by ans" qt_sql2 "select corr(x, non_nullable(y)) ans from test_corr group by id order by ans" qt_sql3 "select corr(non_nullable(x), y) ans from test_corr group by id order by ans" + + qt_sql_const1 "select corr(x,1) from test_corr" + qt_sql_const2 "select corr(x,1e100) from test_corr" + qt_sql_const3 "select corr(x,1e-100) from test_corr" + qt_sql_const4 "select corr(1,y) from test_corr" + qt_sql_const5 "select corr(1e100,y) from test_corr" + qt_sql_const6 "select corr(1e-100,y) from test_corr" }