add round test (#11088)
* add round test
* code style
* handle null val for round function
* handle null val for round function
* support null for round
* fix compatiblity
* fix test
* fix test
* code style
* optimize format
diff --git a/core/src/main/java/org/apache/druid/math/expr/Function.java b/core/src/main/java/org/apache/druid/math/expr/Function.java
index 874d1ed..baa5768 100644
--- a/core/src/main/java/org/apache/druid/math/expr/Function.java
+++ b/core/src/main/java/org/apache/druid/math/expr/Function.java
@@ -1311,6 +1311,9 @@
public ExprEval apply(List<Expr> args, Expr.ObjectBinding bindings)
{
ExprEval value1 = args.get(0).eval(bindings);
+ if (NullHandling.sqlCompatible() && value1.isNumericNull()) {
+ return ExprEval.of(null);
+ }
if (value1.type() != ExprType.LONG && value1.type() != ExprType.DOUBLE) {
throw new IAE(
"The first argument to the function[%s] should be integer or double type but got the type: %s",
diff --git a/core/src/test/java/org/apache/druid/math/expr/FunctionTest.java b/core/src/test/java/org/apache/druid/math/expr/FunctionTest.java
index 0d4fb4d..bd729fe 100644
--- a/core/src/test/java/org/apache/druid/math/expr/FunctionTest.java
+++ b/core/src/test/java/org/apache/druid/math/expr/FunctionTest.java
@@ -23,6 +23,7 @@
import com.google.common.collect.ImmutableSet;
import org.apache.druid.common.config.NullHandling;
import org.apache.druid.java.util.common.Pair;
+import org.apache.druid.java.util.common.StringUtils;
import org.apache.druid.testing.InitializedNullHandlingTest;
import org.junit.Assert;
import org.junit.Before;
@@ -408,11 +409,39 @@
}
@Test
+ public void testRoundWithNullValue()
+ {
+ Set<Pair<String, String>> invalidArguments = ImmutableSet.of(
+ Pair.of("null", "STRING"),
+ Pair.of("x", "STRING")
+ );
+ for (Pair<String, String> argAndType : invalidArguments) {
+ if (NullHandling.sqlCompatible()) {
+ assertExpr(StringUtils.format("round(%s)", argAndType.lhs), null);
+ } else {
+ try {
+ assertExpr(StringUtils.format("round(%s)", argAndType.lhs), null);
+ Assert.fail("Did not throw IllegalArgumentException");
+ }
+ catch (IllegalArgumentException e) {
+ Assert.assertEquals(
+ String.format(
+ Locale.ENGLISH,
+ "The first argument to the function[round] should be integer or double type but got the type: %s",
+ argAndType.rhs
+ ),
+ e.getMessage()
+ );
+ }
+ }
+ }
+ }
+
+ @Test
public void testRoundWithInvalidFirstArgument()
{
Set<Pair<String, String>> invalidArguments = ImmutableSet.of(
Pair.of("b", "LONG_ARRAY"),
- Pair.of("x", "STRING"),
Pair.of("c", "DOUBLE_ARRAY"),
Pair.of("a", "STRING_ARRAY")
diff --git a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteQueryTest.java b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteQueryTest.java
index 86ef6dc..cbd875a 100644
--- a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteQueryTest.java
+++ b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteQueryTest.java
@@ -17552,4 +17552,43 @@
)
);
}
+
+ @Test
+ public void testRoundFuc() throws Exception
+ {
+
+ testQuery(
+ "SELECT f1, round(f1) FROM druid.numfoo",
+ ImmutableList.of(
+ new Druids.ScanQueryBuilder()
+ .dataSource(CalciteTests.DATASOURCE3)
+ .intervals(querySegmentSpec(Filtration.eternity()))
+ .virtualColumns(
+ expressionVirtualColumn("v0", "round(\"f1\")", ValueType.FLOAT)
+ )
+ .columns("f1", "v0")
+ .legacy(false)
+ .resultFormat(ScanQuery.ResultFormat.RESULT_FORMAT_COMPACTED_LIST)
+ .context(QUERY_CONTEXT_DEFAULT)
+ .build()
+ ),
+ NullHandling.sqlCompatible()
+ ? ImmutableList.of(
+ new Object[]{1.0f, 1.0f},
+ new Object[]{0.1f, 0.0f},
+ new Object[]{0.0f, 0.0f},
+ new Object[]{null, null},
+ new Object[]{null, null},
+ new Object[]{null, null}
+ )
+ : ImmutableList.of(
+ new Object[]{1.0f, 1.0f},
+ new Object[]{0.1f, 0.0f},
+ new Object[]{0.0f, 0.0f},
+ new Object[]{0.0f, 0.0f},
+ new Object[]{0.0f, 0.0f},
+ new Object[]{0.0f, 0.0f}
+ )
+ );
+ }
}
diff --git a/sql/src/test/java/org/apache/druid/sql/calcite/expression/ExpressionsTest.java b/sql/src/test/java/org/apache/druid/sql/calcite/expression/ExpressionsTest.java
index 898a64c..9525b75 100644
--- a/sql/src/test/java/org/apache/druid/sql/calcite/expression/ExpressionsTest.java
+++ b/sql/src/test/java/org/apache/druid/sql/calcite/expression/ExpressionsTest.java
@@ -904,15 +904,17 @@
{
final SqlFunction roundFunction = new RoundOperatorConversion().calciteOperator();
- expectException(
- IAE.class,
- "The first argument to the function[round] should be integer or double type but got the type: STRING"
- );
+ if (!NullHandling.sqlCompatible()) {
+ expectException(
+ IAE.class,
+ "The first argument to the function[round] should be integer or double type but got the type: STRING"
+ );
+ }
testHelper.testExpression(
roundFunction,
testHelper.makeInputRef("s"),
DruidExpression.fromExpression("round(\"s\")"),
- "IAE Exception"
+ NullHandling.sqlCompatible() ? null : "IAE Exception"
);
}