From ca37c4cf96360adae590201e3659f21ab857d136 Mon Sep 17 00:00:00 2001 From: LiBinfeng Date: Wed, 19 Feb 2025 16:10:08 +0800 Subject: [PATCH] [fix](Nereids) change numeric arithmatic function boundary behavior to match with be execution behavior (#47966) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### What problem does this PR solve? Related PR: #40744, #47228 Problem Summary: When numeric function input or output out of boundary when fe folding constant, it would throw an exception before. Now we change it to match with be execution result, which is NullLiteral --- .../executable/NumericArithmetic.java | 69 ++++++++++----- .../rules/expression/FoldConstantTest.java | 87 ++++++++----------- .../datatype_p0/double/test_double_nan.out | 4 + .../data/datatype_p0/float/test_float_nan.out | 4 + .../datatype_p0/double/test_double_nan.groovy | 10 +-- .../datatype_p0/float/test_float_nan.groovy | 10 +-- .../scalar_function/A.groovy | 5 +- .../fold_constant_numeric_arithmatic.groovy | 60 +++++++------ 8 files changed, 129 insertions(+), 120 deletions(-) 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 3a8894f3e85478..41a0bf2bdba247 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 @@ -17,7 +17,6 @@ package org.apache.doris.nereids.trees.expressions.functions.executable; -import org.apache.doris.nereids.exceptions.NotSupportedException; import org.apache.doris.nereids.trees.expressions.ExecFunction; import org.apache.doris.nereids.trees.expressions.Expression; import org.apache.doris.nereids.trees.expressions.literal.BigIntLiteral; @@ -35,6 +34,7 @@ import org.apache.doris.nereids.trees.expressions.literal.TinyIntLiteral; import org.apache.doris.nereids.trees.expressions.literal.VarcharLiteral; import org.apache.doris.nereids.types.DecimalV3Type; +import org.apache.doris.nereids.types.DoubleType; import java.math.BigDecimal; import java.math.BigInteger; @@ -671,7 +671,7 @@ public static Expression coalesce(Literal first, Literal... second) { /** * Method to check boundary with options for inclusive or exclusive boundaries */ - public static void checkInputBoundary(Literal input, double lowerBound, double upperBound, + public static Boolean inputOutOfBound(Literal input, double lowerBound, double upperBound, boolean isLowerInclusive, boolean isUpperInclusive) { if (input instanceof DoubleLiteral) { double inputValue = ((DoubleLiteral) input).getValue(); @@ -680,15 +680,16 @@ public static void checkInputBoundary(Literal input, double lowerBound, double u boolean upperCheck = isUpperInclusive ? (inputValue <= upperBound) : (inputValue < upperBound); // Return true if both checks are satisfied if (!lowerCheck || !upperCheck) { - throw new NotSupportedException("input " + input.toSql() + " is out of boundary"); + return true; } } + return false; } private static Expression checkOutputBoundary(Literal input) { if (input instanceof DoubleLiteral) { if (((DoubleLiteral) input).getValue().isNaN() || ((DoubleLiteral) input).getValue().isInfinite()) { - throw new NotSupportedException(input.toSql() + " result is invalid"); + return new NullLiteral(DoubleType.INSTANCE); } } return input; @@ -817,7 +818,9 @@ public static Expression exp(DoubleLiteral first) { */ @ExecFunction(name = "ln") public static Expression ln(DoubleLiteral first) { - checkInputBoundary(first, 0.0d, Double.MAX_VALUE, false, true); + if (inputOutOfBound(first, 0.0d, Double.MAX_VALUE, false, true)) { + return new NullLiteral(DoubleType.INSTANCE); + } return checkOutputBoundary(new DoubleLiteral(Math.log(first.getValue()))); } @@ -826,9 +829,9 @@ public static Expression ln(DoubleLiteral first) { */ @ExecFunction(name = "log") public static Expression log(DoubleLiteral first, DoubleLiteral second) { - checkInputBoundary(first, 0.0d, Double.MAX_VALUE, false, true); - if (first.getValue().equals(1.0d)) { - throw new NotSupportedException("the first input of function log can not be 1.0"); + if (inputOutOfBound(first, 0.0d, Double.MAX_VALUE, false, true) + || first.getValue().equals(1.0d)) { + return new NullLiteral(DoubleType.INSTANCE); } return checkOutputBoundary(new DoubleLiteral(Math.log(second.getValue()) / Math.log(first.getValue()))); } @@ -838,7 +841,9 @@ public static Expression log(DoubleLiteral first, DoubleLiteral second) { */ @ExecFunction(name = "log2") public static Expression log2(DoubleLiteral first) { - checkInputBoundary(first, 0.0d, Double.MAX_VALUE, false, true); + if (inputOutOfBound(first, 0.0d, Double.MAX_VALUE, false, true)) { + return new NullLiteral(DoubleType.INSTANCE); + } return checkOutputBoundary(new DoubleLiteral(Math.log(first.getValue()) / Math.log(2.0))); } @@ -847,7 +852,9 @@ public static Expression log2(DoubleLiteral first) { */ @ExecFunction(name = "log10") public static Expression log10(DoubleLiteral first) { - checkInputBoundary(first, 0.0d, Double.MAX_VALUE, false, true); + if (inputOutOfBound(first, 0.0d, Double.MAX_VALUE, false, true)) { + return new NullLiteral(DoubleType.INSTANCE); + } return checkOutputBoundary(new DoubleLiteral(Math.log10(first.getValue()))); } @@ -856,7 +863,9 @@ public static Expression log10(DoubleLiteral first) { */ @ExecFunction(name = "sqrt") public static Expression sqrt(DoubleLiteral first) { - checkInputBoundary(first, 0.0d, Double.MAX_VALUE, true, true); + if (inputOutOfBound(first, 0.0d, Double.MAX_VALUE, true, true)) { + return new NullLiteral(DoubleType.INSTANCE); + } return checkOutputBoundary(new DoubleLiteral(Math.sqrt(first.getValue()))); } @@ -865,9 +874,9 @@ public static Expression sqrt(DoubleLiteral first) { */ @ExecFunction(name = "power") public static Expression power(DoubleLiteral first, DoubleLiteral second) { - checkInputBoundary(second, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, false, false); - if (first.getValue() < 0 && second.getValue() % 1 != 0) { - throw new NotSupportedException("input pair of function power can not be negative number and non-integer"); + if (inputOutOfBound(second, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, false, false) + || (first.getValue() < 0 && second.getValue() % 1 != 0)) { + return new NullLiteral(DoubleType.INSTANCE); } return checkOutputBoundary(new DoubleLiteral(Math.pow(first.getValue(), second.getValue()))); } @@ -877,7 +886,9 @@ public static Expression power(DoubleLiteral first, DoubleLiteral second) { */ @ExecFunction(name = "sin") public static Expression sin(DoubleLiteral first) { - checkInputBoundary(first, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, false, false); + if (inputOutOfBound(first, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, false, false)) { + return new NullLiteral(DoubleType.INSTANCE); + } return checkOutputBoundary(new DoubleLiteral(Math.sin(first.getValue()))); } @@ -886,7 +897,9 @@ public static Expression sin(DoubleLiteral first) { */ @ExecFunction(name = "cos") public static Expression cos(DoubleLiteral first) { - checkInputBoundary(first, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, false, false); + if (inputOutOfBound(first, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, false, false)) { + return new NullLiteral(DoubleType.INSTANCE); + } return checkOutputBoundary(new DoubleLiteral(Math.cos(first.getValue()))); } @@ -895,7 +908,9 @@ public static Expression cos(DoubleLiteral first) { */ @ExecFunction(name = "tan") public static Expression tan(DoubleLiteral first) { - checkInputBoundary(first, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, false, false); + if (inputOutOfBound(first, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, false, false)) { + return new NullLiteral(DoubleType.INSTANCE); + } return checkOutputBoundary(new DoubleLiteral(Math.tan(first.getValue()))); } @@ -904,7 +919,9 @@ public static Expression tan(DoubleLiteral first) { */ @ExecFunction(name = "asin") public static Expression asin(DoubleLiteral first) { - checkInputBoundary(first, -1.0, 1.0, true, true); + if (inputOutOfBound(first, -1.0, 1.0, true, true)) { + return new NullLiteral(DoubleType.INSTANCE); + } return checkOutputBoundary(new DoubleLiteral(Math.asin(first.getValue()))); } @@ -913,7 +930,9 @@ public static Expression asin(DoubleLiteral first) { */ @ExecFunction(name = "acos") public static Expression acos(DoubleLiteral first) { - checkInputBoundary(first, -1.0, 1.0, true, true); + if (inputOutOfBound(first, -1.0, 1.0, true, true)) { + return new NullLiteral(DoubleType.INSTANCE); + } return checkOutputBoundary(new DoubleLiteral(Math.acos(first.getValue()))); } @@ -1049,7 +1068,9 @@ public static Expression dexp(DoubleLiteral first) { */ @ExecFunction(name = "dlog1") public static Expression dlog1(DoubleLiteral first) { - checkInputBoundary(first, 0.0d, Double.MAX_VALUE, false, true); + if (inputOutOfBound(first, 0.0d, Double.MAX_VALUE, false, true)) { + return new NullLiteral(DoubleType.INSTANCE); + } return checkOutputBoundary(new DoubleLiteral(Math.log1p(first.getValue()))); } @@ -1058,7 +1079,9 @@ public static Expression dlog1(DoubleLiteral first) { */ @ExecFunction(name = "dlog10") public static Expression dlog10(DoubleLiteral first) { - checkInputBoundary(first, 0.0d, Double.MAX_VALUE, false, true); + if (inputOutOfBound(first, 0.0d, Double.MAX_VALUE, false, true)) { + return new NullLiteral(DoubleType.INSTANCE); + } return checkOutputBoundary(new DoubleLiteral(Math.log10(first.getValue()))); } @@ -1067,7 +1090,9 @@ public static Expression dlog10(DoubleLiteral first) { */ @ExecFunction(name = "dsqrt") public static Expression dsqrt(DoubleLiteral first) { - checkInputBoundary(first, 0.0d, Double.MAX_VALUE, false, true); + if (inputOutOfBound(first, 0.0d, Double.MAX_VALUE, false, true)) { + return new NullLiteral(DoubleType.INSTANCE); + } return checkOutputBoundary(new DoubleLiteral(Math.sqrt(first.getValue()))); } diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/FoldConstantTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/FoldConstantTest.java index 255a529500190c..a7c16141dd52ab 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/FoldConstantTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/FoldConstantTest.java @@ -21,7 +21,6 @@ import org.apache.doris.common.Config; import org.apache.doris.nereids.analyzer.UnboundRelation; import org.apache.doris.nereids.exceptions.AnalysisException; -import org.apache.doris.nereids.exceptions.NotSupportedException; import org.apache.doris.nereids.parser.NereidsParser; import org.apache.doris.nereids.rules.analysis.ExpressionAnalyzer; import org.apache.doris.nereids.rules.expression.rules.FoldConstantRule; @@ -379,27 +378,23 @@ void testleFoldNumeric() { Exp exp = new Exp(new DoubleLiteral(0d)); rewritten = executor.rewrite(exp, context); Assertions.assertEquals(new DoubleLiteral(1.0), rewritten); - Assertions.assertThrows(NotSupportedException.class, () -> { - Exp exExp = new Exp(new DoubleLiteral(1000d)); - executor.rewrite(exExp, context); - }, "infinite result is invalid"); + Expression exExp = new Exp(new DoubleLiteral(1000d)); + rewritten = executor.rewrite(exExp, context); + Assertions.assertEquals(new NullLiteral(DoubleType.INSTANCE), rewritten); Ln ln = new Ln(new DoubleLiteral(1d)); rewritten = executor.rewrite(ln, context); Assertions.assertEquals(new DoubleLiteral(0.0), rewritten); - Assertions.assertThrows(NotSupportedException.class, () -> { - Ln exExp = new Ln(new DoubleLiteral(0.0d)); - executor.rewrite(exExp, context); - }, "input 0.0 is out of boundary"); - Assertions.assertThrows(NotSupportedException.class, () -> { - Ln exExp = new Ln(new DoubleLiteral(-1d)); - executor.rewrite(exExp, context); - }, "input -1 is out of boundary"); - - Assertions.assertThrows(NotSupportedException.class, () -> { - Log exExp = new Log(new DoubleLiteral(1.0d), new DoubleLiteral(1.0d)); - executor.rewrite(exExp, context); - }, "the first input of function log can not be 1.0"); + exExp = new Ln(new DoubleLiteral(0.0d)); + rewritten = executor.rewrite(exExp, context); + Assertions.assertEquals(new NullLiteral(DoubleType.INSTANCE), rewritten); + + exExp = new Ln(new DoubleLiteral(-1d)); + rewritten = executor.rewrite(exExp, context); + Assertions.assertEquals(new NullLiteral(DoubleType.INSTANCE), rewritten); + exExp = new Log(new DoubleLiteral(1.0d), new DoubleLiteral(1.0d)); + rewritten = executor.rewrite(exExp, context); + Assertions.assertEquals(new NullLiteral(DoubleType.INSTANCE), rewritten); Sqrt sqrt = new Sqrt(new DoubleLiteral(16d)); rewritten = executor.rewrite(sqrt, context); @@ -407,22 +402,19 @@ void testleFoldNumeric() { sqrt = new Sqrt(new DoubleLiteral(0d)); rewritten = executor.rewrite(sqrt, context); Assertions.assertEquals(new DoubleLiteral(0d), rewritten); - Assertions.assertThrows(NotSupportedException.class, () -> { - Sqrt exExp = new Sqrt(new DoubleLiteral(-1d)); - executor.rewrite(exExp, context); - }, "input -1 is out of boundary"); + exExp = new Sqrt(new DoubleLiteral(-1d)); + rewritten = executor.rewrite(exExp, context); + Assertions.assertEquals(new NullLiteral(DoubleType.INSTANCE), rewritten); Power power = new Power(new DoubleLiteral(2d), new DoubleLiteral(3)); rewritten = executor.rewrite(power, context); Assertions.assertEquals(new DoubleLiteral(8d), rewritten); - Assertions.assertThrows(NotSupportedException.class, () -> { - Power exExp = new Power(new DoubleLiteral(2d), new DoubleLiteral(10000d)); - executor.rewrite(exExp, context); - }, "infinite result is invalid"); - Assertions.assertThrows(NotSupportedException.class, () -> { - Power exExp = new Power(new DoubleLiteral(-1d), new DoubleLiteral(1.1d)); - executor.rewrite(exExp, context); - }, "input pair of function power can not be negative number and non-integer"); + exExp = new Power(new DoubleLiteral(2d), new DoubleLiteral(10000d)); + rewritten = executor.rewrite(exExp, context); + Assertions.assertEquals(new NullLiteral(DoubleType.INSTANCE), rewritten); + exExp = new Power(new DoubleLiteral(-1d), new DoubleLiteral(1.1d)); + rewritten = executor.rewrite(exExp, context); + Assertions.assertEquals(new NullLiteral(DoubleType.INSTANCE), rewritten); Sin sin = new Sin(new DoubleLiteral(Math.PI / 2)); rewritten = executor.rewrite(sin, context); @@ -430,42 +422,37 @@ void testleFoldNumeric() { sin = new Sin(new DoubleLiteral(0d)); rewritten = executor.rewrite(sin, context); Assertions.assertEquals(new DoubleLiteral(0d), rewritten); - Assertions.assertThrows(NotSupportedException.class, () -> { - Sin exExp = new Sin(new DoubleLiteral(Double.POSITIVE_INFINITY)); - executor.rewrite(exExp, context); - }, "input infinity is out of boundary"); + exExp = new Sin(new DoubleLiteral(Double.POSITIVE_INFINITY)); + rewritten = executor.rewrite(exExp, context); + Assertions.assertEquals(new NullLiteral(DoubleType.INSTANCE), rewritten); Cos cos = new Cos(new DoubleLiteral(0d)); rewritten = executor.rewrite(cos, context); Assertions.assertEquals(new DoubleLiteral(1d), rewritten); - Assertions.assertThrows(NotSupportedException.class, () -> { - Cos exExp = new Cos(new DoubleLiteral(Double.POSITIVE_INFINITY)); - executor.rewrite(exExp, context); - }, "input infinity is out of boundary"); + exExp = new Cos(new DoubleLiteral(Double.POSITIVE_INFINITY)); + rewritten = executor.rewrite(exExp, context); + Assertions.assertEquals(new NullLiteral(DoubleType.INSTANCE), rewritten); Tan tan = new Tan(new DoubleLiteral(0d)); rewritten = executor.rewrite(tan, context); Assertions.assertEquals(new DoubleLiteral(0d), rewritten); - Assertions.assertThrows(NotSupportedException.class, () -> { - Tan exExp = new Tan(new DoubleLiteral(Double.POSITIVE_INFINITY)); - executor.rewrite(exExp, context); - }, "input infinity is out of boundary"); + exExp = new Tan(new DoubleLiteral(Double.POSITIVE_INFINITY)); + rewritten = executor.rewrite(exExp, context); + Assertions.assertEquals(new NullLiteral(DoubleType.INSTANCE), rewritten); Asin asin = new Asin(new DoubleLiteral(1d)); rewritten = executor.rewrite(asin, context); Assertions.assertEquals(new DoubleLiteral(Math.PI / 2), rewritten); - Assertions.assertThrows(NotSupportedException.class, () -> { - Asin exExp = new Asin(new DoubleLiteral(2d)); - executor.rewrite(exExp, context); - }, "input 2.0 is out of boundary"); + exExp = new Asin(new DoubleLiteral(2d)); + rewritten = executor.rewrite(exExp, context); + Assertions.assertEquals(new NullLiteral(DoubleType.INSTANCE), rewritten); Acos acos = new Acos(new DoubleLiteral(1d)); rewritten = executor.rewrite(acos, context); Assertions.assertEquals(new DoubleLiteral(0), rewritten); - Assertions.assertThrows(NotSupportedException.class, () -> { - Acos exExp = new Acos(new DoubleLiteral(2d)); - executor.rewrite(exExp, context); - }, "input 2.0 is out of boundary"); + exExp = new Acos(new DoubleLiteral(2d)); + rewritten = executor.rewrite(exExp, context); + Assertions.assertEquals(new NullLiteral(DoubleType.INSTANCE), rewritten); Sign sign = new Sign(new DoubleLiteral(1d)); rewritten = executor.rewrite(sign, context); diff --git a/regression-test/data/datatype_p0/double/test_double_nan.out b/regression-test/data/datatype_p0/double/test_double_nan.out index f958424e65c626..327a147e2db2e8 100644 --- a/regression-test/data/datatype_p0/double/test_double_nan.out +++ b/regression-test/data/datatype_p0/double/test_double_nan.out @@ -1,3 +1,7 @@ -- This file is automatically generated. You should know what you did if you want to edit this -- !select -- +1 \N + +-- !select -- +\N diff --git a/regression-test/data/datatype_p0/float/test_float_nan.out b/regression-test/data/datatype_p0/float/test_float_nan.out index f958424e65c626..327a147e2db2e8 100644 --- a/regression-test/data/datatype_p0/float/test_float_nan.out +++ b/regression-test/data/datatype_p0/float/test_float_nan.out @@ -1,3 +1,7 @@ -- This file is automatically generated. You should know what you did if you want to edit this -- !select -- +1 \N + +-- !select -- +\N diff --git a/regression-test/suites/datatype_p0/double/test_double_nan.groovy b/regression-test/suites/datatype_p0/double/test_double_nan.groovy index 3d57fee2990d8c..fbfd2606cb4923 100644 --- a/regression-test/suites/datatype_p0/double/test_double_nan.groovy +++ b/regression-test/suites/datatype_p0/double/test_double_nan.groovy @@ -20,16 +20,10 @@ suite("test_double_nan", "datatype_p0") { sql "DROP TABLE IF EXISTS ${tableName}" sql "CREATE TABLE if NOT EXISTS ${tableName} (k int, value double) DUPLICATE KEY(k) DISTRIBUTED BY HASH (k) BUCKETS 1 PROPERTIES ('replication_num' = '1');" - test { - sql """insert into ${tableName} select 1, sqrt(-1);""" - exception "errCode" - } + sql """insert into ${tableName} select 1, sqrt(-1);""" qt_select "select * from ${tableName} order by 1;" - test { - sql "select sqrt(-1);" - exception "errCode" - } + qt_select "select sqrt(-1);" sql "DROP TABLE IF EXISTS ${tableName}" } diff --git a/regression-test/suites/datatype_p0/float/test_float_nan.groovy b/regression-test/suites/datatype_p0/float/test_float_nan.groovy index cf07006abad4b7..8929e638a866a6 100644 --- a/regression-test/suites/datatype_p0/float/test_float_nan.groovy +++ b/regression-test/suites/datatype_p0/float/test_float_nan.groovy @@ -19,16 +19,10 @@ suite("test_float_nan", "datatype_p0") { def tableName = "tbl_test_float_nan" sql "DROP TABLE IF EXISTS ${tableName}" sql "CREATE TABLE if NOT EXISTS ${tableName} (k int, value float) DUPLICATE KEY(k) DISTRIBUTED BY HASH (k) BUCKETS 1 PROPERTIES ('replication_num' = '1');" - test { - sql """insert into ${tableName} select 1, sqrt(-1);""" - exception "errCode" - } + sql """insert into ${tableName} select 1, sqrt(-1);""" qt_select "select * from ${tableName} order by 1;" - test { - sql "select sqrt(-1);" - exception "errCode" - } + qt_select "select sqrt(-1);" sql "DROP TABLE IF EXISTS ${tableName}" } diff --git a/regression-test/suites/nereids_function_p0/scalar_function/A.groovy b/regression-test/suites/nereids_function_p0/scalar_function/A.groovy index b4df5d9e9c42fc..bc8ffbe71b443d 100644 --- a/regression-test/suites/nereids_function_p0/scalar_function/A.groovy +++ b/regression-test/suites/nereids_function_p0/scalar_function/A.groovy @@ -37,10 +37,7 @@ suite("nereids_scalar_fn_A") { qt_sql_abs_DecimalV2_notnull "select abs(kdcmls1) from fn_test_not_nullable order by kdcmls1" qt_sql_acos_Double "select acos(kdbl) from fn_test order by kdbl" qt_sql_acos_Double_notnull "select acos(kdbl) from fn_test_not_nullable order by kdbl" - test { - sql "select acos(cast(1.1 as double))" - exception "errCode" - } + qt_sql_acos_Double_NAN "select acos(cast(1.1 as double))" qt_sql_acos_Double_NULL "select acos(null)" sql "select aes_decrypt(kvchrs1, kvchrs1) from fn_test order by kvchrs1, kvchrs1" sql "select aes_decrypt(kvchrs1, kvchrs1) from fn_test_not_nullable order by kvchrs1, kvchrs1" 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 942f795d3a3987..c725c8f50308e6 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 @@ -44,12 +44,12 @@ suite("fold_constant_numeric_arithmatic") { testFoldConst("SELECT ACOS(0.5)") // Common value testFoldConst("SELECT ACOS(-0.5)") // Negative common value testFoldConst("SELECT ACOS(NULL)") // NULL handling - expectException({sql "SELECT ACOS(2)"}, "errCode = 2, detailMessage = Not Supported: Not Supported: input 2 is out of boundary") - expectException({sql "SELECT ACOS(-2)"}, "errCode = 2, detailMessage = Not Supported: Not Supported: input -2 is out of boundary") - expectException({sql "SELECT ACOS(1.5)"}, "errCode = 2, detailMessage = Not Supported: Not Supported: input 1.5 is out of boundary") - expectException({sql "SELECT ACOS(-1.5)"}, "errCode = 2, detailMessage = Not Supported: Not Supported: input -1.5 is out of boundary") - expectException({sql "SELECT ACOS(1E308)"}, "errCode = 2, detailMessage = Not Supported: Not Supported: input 1.5 is out of boundary") - expectException({sql "SELECT ACOS(-1E308)"}, "errCode = 2, detailMessage = Not Supported: Not Supported: input 1.5 is out of boundary") + testFoldConst("SELECT ACOS(2)") + testFoldConst("SELECT ACOS(-2)") + testFoldConst("SELECT ACOS(1.5)") + testFoldConst("SELECT ACOS(-1.5)") + testFoldConst("SELECT ACOS(1E308)") + testFoldConst("SELECT ACOS(-1E308)") //Asin function cases testFoldConst("SELECT ASIN(1) AS asin_case_1") //asin(1) = π/2 @@ -58,12 +58,12 @@ suite("fold_constant_numeric_arithmatic") { testFoldConst("SELECT ASIN(0.5)") // Common value testFoldConst("SELECT ASIN(-0.5)") // Negative common value testFoldConst("SELECT ASIN(NULL)") // NULL handling - expectException({sql "SELECT ASIN(2)"}, "errCode = 2, detailMessage = Not Supported: Not Supported: input 2 is out of boundary") - expectException({sql "SELECT ASIN(-2)"}, "errCode = 2, detailMessage = Not Supported: Not Supported: input -2 is out of boundary") - expectException({sql "SELECT ASIN(1.5)"}, "errCode = 2, detailMessage = Not Supported: Not Supported: input 1.5 is out of boundary") - expectException({sql "SELECT ASIN(-1.5)"}, "errCode = 2, detailMessage = Not Supported: Not Supported: input -1.5 is out of boundary") - expectException({sql "SELECT ASIN(1E308)"}, "errCode = 2, detailMessage = Not Supported: Not Supported: input 1.5 is out of boundary") - expectException({sql "SELECT ASIN(-1E308)"}, "errCode = 2, detailMessage = Not Supported: Not Supported: input 1.5 is out of boundary") + testFoldConst("SELECT ASIN(2)") + testFoldConst("SELECT ASIN(-2)") + testFoldConst("SELECT ASIN(1.5)") + testFoldConst("SELECT ASIN(-1.5)") + testFoldConst("SELECT ASIN(1E308)") + testFoldConst("SELECT ASIN(-1E308)") //Atan function cases testFoldConst("SELECT ATAN(1) AS atan_case_1") //atan(1) = π/4 @@ -196,8 +196,9 @@ suite("fold_constant_numeric_arithmatic") { //Cosh function cases testFoldConst("SELECT COSH(0) AS cosh_case_1") //cosh(0) = 1 -// expectException({sql "SELECT COSH(1E308)"}, "errCode = 2, detailMessage = Not Supported: Not Supported: Infinity result is invalid") -// expectException({sql "SELECT COSH(-1E308)"}, "errCode = 2, detailMessage = Not Supported: Not Supported: Infinity result is invalid") +// COSH/POWER/DEGREES functions would meet inf problem when input is to large, be execute need to fix it +// testFoldConst("SELECT COSH(1E308)") +// testFoldConst("SELECT COSH(-1E308)") testFoldConst("SELECT COSH(NULL)") // NULL handling testFoldConst("SELECT COSH(1)") // Common value testFoldConst("SELECT COSH(-1)") // Negative common value @@ -231,8 +232,9 @@ suite("fold_constant_numeric_arithmatic") { testFoldConst("SELECT DEGREES(PI()/6)") // 30 degrees testFoldConst("SELECT DEGREES(PI()/3)") // 60 degrees testFoldConst("SELECT DEGREES(3*PI()/2)") // 270 degrees -// expectException({sql "SELECT DEGREES(1E308)"}, "errCode = 2, detailMessage = Not Supported: Not Supported: Infinity result is invalid") -// expectException({sql "SELECT DEGREES(-1E308)"}, "errCode = 2, detailMessage = Not Supported: Not Supported: Infinity result is invalid") +// COSH/POWER/DEGREES functions would meet inf problem when input is to large, be execute need to fix it +// testFoldConst("SELECT DEGREES(1E308)") +// testFoldConst("SELECT DEGREES(-1E308)") //Exp function cases testFoldConst("SELECT EXP(1) AS exp_case_1") //e^1 @@ -292,9 +294,11 @@ suite("fold_constant_numeric_arithmatic") { testFoldConst("SELECT POWER(NULL, 2)") // NULL base testFoldConst("SELECT POWER(2, NULL)") // NULL exponent testFoldConst("SELECT POWER(0, 0)") // Zero base, zero exponent -// expectException({sql "SELECT POWER(0, -1)"}, "errCode = 2, detailMessage = Not Supported: Not Supported: Infinity result is invalid") +// COSH/POWER/DEGREES functions would meet inf problem when input is to large, be execute need to fix it +// testFoldConst("SELECT POWER(0, -1)") testFoldConst("SELECT POWER(1E308, 0.5)") // Very large base -// expectException({sql "SELECT POWER(2, 1E308)"}, "errCode = 2, detailMessage = Not Supported: Not Supported: Infinity result is invalid") +// COSH/POWER/DEGREES functions would meet inf problem when input is to large, be execute need to fix it +// testFoldConst("SELECT POWER(2, 1E308)") testFoldConst("SELECT POWER(1E-308, 2)") // Very small base testFoldConst("SELECT POWER(2, -1E308)") // Very small negative exponent @@ -304,8 +308,8 @@ suite("fold_constant_numeric_arithmatic") { testFoldConst("SELECT LN(0.5) AS ln_case_3") //ln(0.5) testFoldConst("SELECT ln(1), ln(2.718281828459045), ln(10)") testFoldConst("SELECT LN(NULL)") // NULL handling - expectException({sql "SELECT LN(0)"}, "errCode = 2, detailMessage = Not Supported: Not Supported: input 0.0 is out of boundary") - expectException({sql "SELECT LN(-1)"}, "errCode = 2, detailMessage = Not Supported: Not Supported: input -1 is out of boundary") + testFoldConst("SELECT LN(0)") + testFoldConst("SELECT LN(-1)") testFoldConst("SELECT LN(1E308)") // Very large number testFoldConst("SELECT LN(1E-308)") // Very small positive number testFoldConst("SELECT LN(2)") // ln(2) @@ -316,11 +320,11 @@ suite("fold_constant_numeric_arithmatic") { testFoldConst("SELECT log(100, 10), log(8, 2), log(1000, 10)") testFoldConst("SELECT LOG(NULL, 10)") // NULL number testFoldConst("SELECT LOG(100, NULL)") // NULL base - expectException({sql "SELECT LOG(0, 10)"}, "errCode = 2, detailMessage = Not Supported: Not Supported: input -1 is out of boundary") -// expectException({sql "SELECT LOG(100, 0)"}, "errCode = 2, detailMessage = Not Supported: Not Supported: -Infinity result is invalid") + testFoldConst("SELECT LOG(0, 10)") + testFoldConst("SELECT LOG(100, 0)") testFoldConst("SELECT LOG(100, 1)") // Base 1 - expectException({sql "SELECT LOG(-1, 10)"}, "errCode = 2, detailMessage = Not Supported: Not Supported: input -1.0 is out of boundary") - expectException({sql "SELECT LOG(100, -1)"}, "errCode = 2, detailMessage = Not Supported: Not Supported: NaN result is invalid") + testFoldConst("SELECT LOG(-1, 10)") + testFoldConst("SELECT LOG(100, -1)") testFoldConst("SELECT LOG(1E308, 10)") // Very large number testFoldConst("SELECT LOG(100, 1E308)") // Very large base testFoldConst("SELECT LOG(1E-308, 10)") // Very small number @@ -335,8 +339,8 @@ suite("fold_constant_numeric_arithmatic") { testFoldConst("SELECT LOG10(1000.0) AS dlog10_case_3") //dlog10(1000.0) testFoldConst("SELECT log10(1), log10(10), log10(100), log10(1000)") testFoldConst("SELECT LOG10(NULL)") // NULL handling - expectException({sql "SELECT LOG10(0)"}, "errCode = 2, detailMessage = Not Supported: Not Supported: input 0.0 is out of boundary") - expectException({sql "SELECT LOG10(-1)"}, "errCode = 2, detailMessage = Not Supported: Not Supported: input -1 is out of boundary") + testFoldConst("SELECT LOG10(0)") + testFoldConst("SELECT LOG10(-1)") testFoldConst("SELECT LOG10(1E308)") // Very large number testFoldConst("SELECT LOG10(1E-308)") // Very small positive number testFoldConst("SELECT LOG10(0.1)") // Decimal less than 1 @@ -348,8 +352,8 @@ suite("fold_constant_numeric_arithmatic") { testFoldConst("SELECT LOG2(1) AS log2_case_3") //log2(1) = 0 testFoldConst("SELECT log2(1), log2(2), log2(4), log2(8), log2(16)") testFoldConst("SELECT LOG2(NULL)") // NULL handling - expectException({sql "SELECT LOG2(0)"}, "errCode = 2, detailMessage = Not Supported: Not Supported: input 0.0 is out of boundary") - expectException({sql "SELECT LOG2(-1)"}, "errCode = 2, detailMessage = Not Supported: Not Supported: input -1 is out of boundary") + testFoldConst("SELECT LOG2(0)") + testFoldConst("SELECT LOG2(-1)") testFoldConst("SELECT LOG2(1E308)") // Very large number testFoldConst("SELECT LOG2(1E-308)") // Very small positive number testFoldConst("SELECT LOG2(0.5)") // Fraction