From b7a640edf1e5052ed64047ae0167f7e5ebf9f3af Mon Sep 17 00:00:00 2001 From: chenmiao Date: Fri, 28 Feb 2025 18:41:22 +0000 Subject: [PATCH] [feat](nereids)(regression) support the math fold constants for sinh etc. but for input string: inf, should be fix it (#48476) --- fe/fe-core/pom.xml | 4 ++ .../executable/NumericArithmetic.java | 50 +++++++++++++++++++ fe/pom.xml | 7 +++ .../fold_constant_numeric_arithmatic.groovy | 47 ++++++++++++++++- 4 files changed, 107 insertions(+), 1 deletion(-) diff --git a/fe/fe-core/pom.xml b/fe/fe-core/pom.xml index 52bb3ef73293d46..f7048b9f03d073c 100644 --- a/fe/fe-core/pom.xml +++ b/fe/fe-core/pom.xml @@ -131,6 +131,10 @@ under the License. org.apache.commons commons-lang3 + + org.apache.commons + commons-math3 + org.apache.commons diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/NumericArithmetic.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/NumericArithmetic.java index 41a0bf2bdba247e..8aabf39b450efbe 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/NumericArithmetic.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/NumericArithmetic.java @@ -36,6 +36,8 @@ import org.apache.doris.nereids.types.DecimalV3Type; import org.apache.doris.nereids.types.DoubleType; +import org.apache.commons.math3.util.FastMath; + import java.math.BigDecimal; import java.math.BigInteger; import java.nio.charset.StandardCharsets; @@ -892,6 +894,17 @@ public static Expression sin(DoubleLiteral first) { return checkOutputBoundary(new DoubleLiteral(Math.sin(first.getValue()))); } + /** + * sinh + */ + @ExecFunction(name = "sinh") + public static Expression sinh(DoubleLiteral first) { + if (inputOutOfBound(first, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, false, false)) { + return new NullLiteral(DoubleType.INSTANCE); + } + return checkOutputBoundary(new DoubleLiteral(FastMath.sinh(first.getValue()))); + } + /** * cos */ @@ -941,9 +954,46 @@ public static Expression acos(DoubleLiteral first) { */ @ExecFunction(name = "atan") public static Expression atan(DoubleLiteral first) { + if (inputOutOfBound(first, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, false, false)) { + return new NullLiteral(DoubleType.INSTANCE); + } return checkOutputBoundary(new DoubleLiteral(Math.atan(first.getValue()))); } + /** + * asinh + */ + @ExecFunction(name = "asinh") + public static Expression asinh(DoubleLiteral first) { + if (inputOutOfBound(first, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, false, false)) { + return new NullLiteral(DoubleType.INSTANCE); + } + return checkOutputBoundary(new DoubleLiteral(FastMath.asinh(first.getValue()))); + } + + /** + * acosh + */ + @ExecFunction(name = "acosh") + public static Expression acosh(DoubleLiteral first) { + if (inputOutOfBound(first, Double.NEGATIVE_INFINITY, 1.0, false, false)) { + return new NullLiteral(DoubleType.INSTANCE); + } + return checkOutputBoundary(new DoubleLiteral(FastMath.acosh(first.getValue()))); + } + + /** + * atanh + */ + @ExecFunction(name = "atanh") + public static Expression atanh(DoubleLiteral first) { + if (inputOutOfBound(first, 1.0, Double.POSITIVE_INFINITY, true, false) + || inputOutOfBound(first, Double.NEGATIVE_INFINITY, -1.0, false, true)) { + return new NullLiteral(DoubleType.INSTANCE); + } + return checkOutputBoundary(new DoubleLiteral(FastMath.atanh(first.getValue()))); + } + /** * atan2 */ diff --git a/fe/pom.xml b/fe/pom.xml index 68cfff27e898815..55d2763ac523031 100644 --- a/fe/pom.xml +++ b/fe/pom.xml @@ -253,6 +253,7 @@ under the License. 2.2 1.5.1 1.10.0 + 3.6.1 1.7 2.10.1 33.2.1-jre @@ -793,6 +794,12 @@ under the License. commons-lang3 ${commons-lang3.version} + + + org.apache.commons + commons-math3 + ${commons-math3.version} + org.apache.commons diff --git a/regression-test/suites/nereids_p0/expression/fold_constant/fold_constant_numeric_arithmatic.groovy b/regression-test/suites/nereids_p0/expression/fold_constant/fold_constant_numeric_arithmatic.groovy index c725c8f50308e6c..2e03569b4eb4e87 100644 --- a/regression-test/suites/nereids_p0/expression/fold_constant/fold_constant_numeric_arithmatic.groovy +++ b/regression-test/suites/nereids_p0/expression/fold_constant/fold_constant_numeric_arithmatic.groovy @@ -51,6 +51,17 @@ suite("fold_constant_numeric_arithmatic") { testFoldConst("SELECT ACOS(1E308)") testFoldConst("SELECT ACOS(-1E308)") +//Acosh function cases + testFoldConst("SELECT ACOSH(1) AS acosh_case_1"); // acosh(1) = 0 + testFoldConst("SELECT ACOSH(2) AS acosh_case_2"); // acosh(2) ≈ 1.316957897 + testFoldConst("SELECT ACOSH(10) AS acosh_case_3"); // acosh(10) ≈ 2.993222846 + testFoldConst("SELECT ACOSH(0.5)"); // Invalid input (x < 1) + testFoldConst("SELECT ACOSH(-1)"); // Invalid input (x < 1) + testFoldConst("SELECT ACOSH(NULL)"); // NULL handling + testFoldConst("SELECT ACOSH(1E308)"); // Large value + testFoldConst("SELECT ACOSH(-1E308)"); // Invalid input (x < 1) + testFoldConst("SELECT ACOSH(1), ACOSH(2), ACOSH(10)"); // Multiple values + //Asin function cases testFoldConst("SELECT ASIN(1) AS asin_case_1") //asin(1) = π/2 testFoldConst("SELECT ASIN(0) AS asin_case_2") //asin(0) = 0 @@ -65,6 +76,17 @@ suite("fold_constant_numeric_arithmatic") { testFoldConst("SELECT ASIN(1E308)") testFoldConst("SELECT ASIN(-1E308)") +//Asinh function cases + testFoldConst("SELECT ASINH(0) AS asinh_case_1"); // asinh(0) = 0 + testFoldConst("SELECT ASINH(1) AS asinh_case_2"); // asinh(1) ≈ 0.881373587 + testFoldConst("SELECT ASINH(-1) AS asinh_case_3"); // asinh(-1) ≈ -0.881373587 + testFoldConst("SELECT ASINH(0.5)"); // Common value + testFoldConst("SELECT ASINH(-0.5)"); // Negative common value + testFoldConst("SELECT ASINH(NULL)"); // NULL handling + testFoldConst("SELECT ASINH(1E308)"); // Large value + testFoldConst("SELECT ASINH(-1E308)"); // Large negative value + testFoldConst("SELECT ASINH(0), ASINH(1), ASINH(-1)"); // Multiple values + //Atan function cases testFoldConst("SELECT ATAN(1) AS atan_case_1") //atan(1) = π/4 testFoldConst("SELECT ATAN(0) AS atan_case_2") //atan(0) = 0 @@ -77,7 +99,22 @@ suite("fold_constant_numeric_arithmatic") { testFoldConst("SELECT ATAN(PI())") // PI input testFoldConst("SELECT ATAN(-PI())") // Negative PI input testFoldConst("SELECT ATAN(1E-308)") // Very small positive number - testFoldConst("SELECT ATAN(-1E-308)") // Very small negative number + testFoldConst("SELECT ATAN(-1E-308)") // Very small negative + +//Atanh function cases + testFoldConst("SELECT ATANH(0) AS atanh_case_1"); // atanh(0) = 0 + testFoldConst("SELECT ATANH(0.5) AS atanh_case_2"); // atanh(0.5) ≈ 0.549306144 + testFoldConst("SELECT ATANH(-0.5) AS atanh_case_3"); // atanh(-0.5) ≈ -0.549306144 + testFoldConst("SELECT ATANH(0.9)"); // Common value + testFoldConst("SELECT ATANH(-0.9)"); // Negative common value + testFoldConst("SELECT ATANH(NULL)"); // NULL handling + testFoldConst("SELECT ATANH(1)"); // Boundary value (invalid) + testFoldConst("SELECT ATANH(-1)"); // Boundary value (invalid) + testFoldConst("SELECT ATANH(1.5)"); // Invalid input (x > 1) + testFoldConst("SELECT ATANH(-1.5)"); // Invalid input (x < -1) + testFoldConst("SELECT ATANH(1E-308)"); // Very small positive number + testFoldConst("SELECT ATANH(-1E-308)"); // Very small negative number + testFoldConst("SELECT ATANH(0), ATANH(0.5), ATANH(-0.5)"); // Multiple values //Atan2 function cases testFoldConst("SELECT ATAN2(1, 1) AS atan2_case_1") //atan2(1, 1) = π/4 @@ -440,6 +477,14 @@ suite("fold_constant_numeric_arithmatic") { testFoldConst("SELECT SIN(1E308) AS sin_case_overflow") testFoldConst("SELECT sin(0), sin(pi()/2), sin(pi()), sin(3*pi()/2)") +// Sinh function cases + testFoldConst("SELECT SINH(0) AS sinh_case_1"); // sinh(0) = 0 + testFoldConst("SELECT SINH(1) AS sinh_case_2"); // sinh(1) ≈ 1.175201194 + testFoldConst("SELECT SINH(-1) AS sinh_case_3"); // sinh(-1) ≈ -1.175201194 + testFoldConst("SELECT SINH(2) AS sinh_case_4"); // sinh(2) ≈ 3.626860408 + testFoldConst("SELECT SINH(1E308) AS sinh_case_overflow"); + testFoldConst("SELECT SINH(0), SINH(1), SINH(-1), SINH(2)"); // Multi value + //Sqrt function cases testFoldConst("SELECT SQRT(16) AS sqrt_case_1") //sqrt(16) = 4 testFoldConst("SELECT SQRT(0) AS sqrt_case_2") //sqrt(0) = 0