This is an automated email from the ASF dual-hosted git repository.

ppa pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git


The following commit(s) were added to refs/heads/main by this push:
     new fbe35cc641 IGNITE-20725 Sql. Fix TRUNCATE function (#2887)
fbe35cc641 is described below

commit fbe35cc64165fa4e45e172130d1d6f3a8afee71b
Author: Max Zhuravkov <shh...@gmail.com>
AuthorDate: Mon Dec 4 16:25:48 2023 +0200

    IGNITE-20725 Sql. Fix TRUNCATE function (#2887)
---
 .../internal/sql/engine/ItFunctionsTest.java       |  66 +++++++++-
 .../internal/sql/engine/ItSqlOperatorsTest.java    |   3 +-
 .../sql/engine/exec/exp/IgniteSqlFunctions.java    |  97 ++++++++++++++-
 .../internal/sql/engine/exec/exp/RexImpTable.java  |  11 +-
 .../sql/engine/sql/fun/IgniteSqlOperatorTable.java |  51 ++++----
 .../internal/sql/engine/util/IgniteMethod.java     |   7 +-
 .../engine/exec/exp/IgniteSqlFunctionsTest.java    | 133 ++++++++++++++++++++-
 7 files changed, 333 insertions(+), 35 deletions(-)

diff --git 
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItFunctionsTest.java
 
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItFunctionsTest.java
index ee103610b8..e947a3f80a 100644
--- 
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItFunctionsTest.java
+++ 
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItFunctionsTest.java
@@ -359,7 +359,7 @@ public class ItFunctionsTest extends BaseSqlIntegrationTest 
{
 
     @ParameterizedTest(name = "{0}")
     @MethodSource("integralTypes")
-    public void testIntType(ParseNum parse, MetadataMatcher matcher) {
+    public void testRoundIntTypes(ParseNum parse, MetadataMatcher matcher) {
         String v1 = parse.value("42");
         String v2 = parse.value("45");
         String v3 = parse.value("47");
@@ -393,9 +393,13 @@ public class ItFunctionsTest extends 
BaseSqlIntegrationTest {
     @MethodSource("nonIntegerTypes")
     public void testRoundNonIntegralTypes(ParseNum parse, MetadataMatcher 
round1, MetadataMatcher round2) {
         String v1 = parse.value("42.123");
-        String v2 = parse.value("45.123");
+        String v2 = parse.value("45.000");
         String v3 = parse.value("47.123");
 
+        assertQuery(format("SELECT ROUND(1.5::{})", parse.typeName))
+                .returns(parse.apply("2"))
+                .check();
+
         assertQuery(format("SELECT ROUND({}), ROUND({}, 0)", v1, v1))
                 .returns(parse.apply("42"), parse.apply("42.000"))
                 .columnMetadata(round1, round2)
@@ -421,6 +425,64 @@ public class ItFunctionsTest extends 
BaseSqlIntegrationTest {
                 .check();
     }
 
+    @ParameterizedTest(name = "{0}")
+    @MethodSource("integralTypes")
+    public void testTruncateIntTypes(ParseNum parse, MetadataMatcher matcher) {
+        String v1 = parse.value("42");
+        String v2 = parse.value("45");
+        String v3 = parse.value("47");
+
+        assertQuery(format("SELECT TRUNCATE({}), TRUNCATE({}, 0)", v1, v1))
+                .returns(parse.apply("42"), parse.apply("42"))
+                .columnMetadata(matcher, matcher)
+                .check();
+
+        String query = format(
+                "SELECT TRUNCATE({}, -2), TRUNCATE({}, -1), TRUNCATE({}, -1), 
TRUNCATE({}, -1)",
+                v1, v1, v2, v3);
+
+        assertQuery(query)
+                .returns(parse.apply("0"), parse.apply("40"), 
parse.apply("40"), parse.apply("40"))
+                .columnMetadata(matcher, matcher, matcher, matcher)
+                .check();
+    }
+
+    @ParameterizedTest(name = "{0}")
+    @MethodSource("nonIntegerTypes")
+    public void testTruncateNonIntegralTypes(ParseNum parse, MetadataMatcher 
round1, MetadataMatcher round2) {
+        String v1 = parse.value("42.123");
+        String v2 = parse.value("45.000");
+        String v3 = parse.value("47.123");
+
+        assertQuery(format("SELECT TRUNCATE(1.6::{})", parse.typeName))
+                .returns(parse.apply("1"))
+                .check();
+
+        assertQuery(format("SELECT TRUNCATE({}), TRUNCATE({}, 0)", v1, v1))
+                .returns(parse.apply("42"), parse.apply("42.000"))
+                .columnMetadata(round1, round2)
+                .check();
+
+        assertQuery(format("SELECT TRUNCATE({}, -2), TRUNCATE({}, -1), 
TRUNCATE({}, -1),  TRUNCATE({}, -1)", v1, v1, v2, v3))
+                .returns(parse.apply("0.000"), parse.apply("40.000"), 
parse.apply("40.000"), parse.apply("40.000"))
+                .columnMetadata(round2, round2, round2, round2)
+                .check();
+
+        String v4 = parse.value("1.123");
+
+        assertQuery(format("SELECT TRUNCATE({}, s) FROM (VALUES (-2), (-1), 
(0), (1), (2), (3), (4), (100) ) t(s)", v4))
+                .returns(parse.apply("0.000"))
+                .returns(parse.apply("0.000"))
+                .returns(parse.apply("1.000"))
+                .returns(parse.apply("1.100"))
+                .returns(parse.apply("1.120"))
+                .returns(parse.apply("1.123"))
+                .returns(parse.apply("1.123"))
+                .returns(parse.apply("1.123"))
+                .columnMetadata(round2)
+                .check();
+    }
+
     private static Stream<Arguments> nonIntegerTypes() {
         MetadataMatcher matchFloat = new 
MetadataMatcher().type(ColumnType.FLOAT);
         MetadataMatcher matchDouble = new 
MetadataMatcher().type(ColumnType.DOUBLE);
diff --git 
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItSqlOperatorsTest.java
 
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItSqlOperatorsTest.java
index add835868e..420b7046a4 100644
--- 
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItSqlOperatorsTest.java
+++ 
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItSqlOperatorsTest.java
@@ -200,8 +200,7 @@ public class ItSqlOperatorsTest extends 
BaseSqlIntegrationTest {
         assertExpression("SINH(1)").returns(Math.sinh(1)).check();
         assertExpression("TAN(1)").returns(Math.tan(1)).check();
         assertExpression("TANH(1)").returns(Math.tanh(1)).check();
-        // TODO https://issues.apache.org/jira/browse/IGNITE-20725
-        // 
assertExpression("TRUNCATE(1.7)").returns(BigDecimal.valueOf(1)).check();
+        
assertExpression("TRUNCATE(1.7)").returns(BigDecimal.valueOf(1)).check();
         assertExpression("PI").returns(Math.PI).check();
     }
 
diff --git 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/IgniteSqlFunctions.java
 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/IgniteSqlFunctions.java
index da90432e0f..cbf1f537c5 100644
--- 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/IgniteSqlFunctions.java
+++ 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/IgniteSqlFunctions.java
@@ -220,7 +220,6 @@ public class IgniteSqlFunctions {
 
     /** SQL {@code ROUND} operator applied to BigDecimal values. */
     public static BigDecimal sround(BigDecimal b0, int b1) {
-        // b0.movePointRight(b1).setScale(0, 
RoundingMode.DOWN).movePointLeft(b1);
         int originalScale = b0.scale();
 
         if (b1 >= originalScale) {
@@ -232,6 +231,99 @@ public class IgniteSqlFunctions {
         return roundedValue.setScale(originalScale, RoundingMode.UNNECESSARY);
     }
 
+    // TRUNCATE function
+
+    /** SQL {@code TRUNCATE} operator applied to byte values. */
+    public static byte struncate(byte b0) {
+        return (byte) struncate(b0, 0);
+    }
+
+    /** SQL {@code TRUNCATE} operator applied to byte values. */
+    public static byte struncate(byte b0, int b1) {
+        return (byte) struncate((int) b0, b1);
+    }
+
+    /** SQL {@code TRUNCATE} operator applied to short values. */
+    public static byte struncate(short b0) {
+        return (byte) struncate(b0, 0);
+    }
+
+    /** SQL {@code TRUNCATE} operator applied to short values. */
+    public static short struncate(short b0, int b1) {
+        return (short) struncate((int) b0, b1);
+    }
+
+    /** SQL {@code TRUNCATE} operator applied to int values. */
+    public static int struncate(int b0) {
+        return sround(b0, 0);
+    }
+
+    /** SQL {@code TRUNCATE} operator applied to int values. */
+    public static int struncate(int b0, int b1) {
+        if (b1 == 0) {
+            return b0;
+        } else if (b1 > 0) {
+            return b0;
+        } else {
+            return (int) struncate((long) b0, b1);
+        }
+    }
+
+    /** SQL {@code TRUNCATE} operator applied to long values. */
+    public static long struncate(long b0) {
+        return sround(b0, 0);
+    }
+
+    /** SQL {@code TRUNCATE} operator applied to long values. */
+    public static long struncate(long b0, int b1) {
+        if (b1 == 0) {
+            return b0;
+        } else if (b1 > 0) {
+            return b0;
+        } else {
+            long abs = (long) Math.pow(10, Math.abs(b1));
+            return divide(b0, abs, RoundingMode.DOWN) * abs;
+        }
+    }
+
+    /** SQL {@code TRUNCATE} operator applied to double values. */
+    public static double struncate(double b0) {
+        return struncate(BigDecimal.valueOf(b0)).doubleValue();
+    }
+
+    /** SQL {@code TRUNCATE} operator applied to double values. */
+    public static double struncate(double b0, int b1) {
+        return struncate(BigDecimal.valueOf(b0), b1).doubleValue();
+    }
+
+    /** SQL {@code TRUNCATE} operator applied to float values. */
+    public static float struncate(float b0) {
+        return struncate(BigDecimal.valueOf(b0)).floatValue();
+    }
+
+    /** SQL {@code TRUNCATE} operator applied to float values. */
+    public static float struncate(float b0, int b1) {
+        return struncate(BigDecimal.valueOf(b0), b1).floatValue();
+    }
+
+    /** SQL {@code TRUNCATE} operator applied to BigDecimal values. */
+    public static BigDecimal struncate(BigDecimal b0) {
+        return b0.setScale(0, RoundingMode.DOWN);
+    }
+
+    /** SQL {@code TRUNCATE} operator applied to BigDecimal values. */
+    public static BigDecimal struncate(BigDecimal b0, int b1) {
+        int originalScale = b0.scale();
+
+        if (b1 >= originalScale) {
+            return b0;
+        }
+
+        BigDecimal roundedValue = b0.setScale(b1, RoundingMode.DOWN);
+        // Pad with zeros to match the original scale
+        return roundedValue.setScale(originalScale, RoundingMode.UNNECESSARY);
+    }
+
     /** CAST(DOUBLE AS DECIMAL). */
     public static BigDecimal toBigDecimal(double val, int precision, int 
scale) {
         return toBigDecimal((Double) val, precision, scale);
@@ -554,6 +646,9 @@ public class IgniteSqlFunctions {
                     increment = cmpRemToHalfDivisor > 0; // closer to the UP 
value
                 }
                 break;
+            case DOWN:
+                increment = false;
+                break;
             default:
                 throw new AssertionError();
         }
diff --git 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/RexImpTable.java
 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/RexImpTable.java
index 4a6e3011c3..6038764d19 100644
--- 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/RexImpTable.java
+++ 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/RexImpTable.java
@@ -432,6 +432,7 @@ import org.checkerframework.checker.nullness.qual.Nullable;
  * Changes in comparison with original code:
  * 1. AbstractRexCallImplementor#genValueStatement() -> append op instanceof 
SqlTableFunction)
  * 2. populateIgnite()
+ * 3. Replaces implementation of ROUND, TRUNCATE operators and removes TRUNC 
operator.
  *
  * <p>Immutable.
  */
@@ -599,7 +600,8 @@ public class RexImpTable {
       defineMethod(DEGREES, "degrees", NullPolicy.STRICT);
       defineMethod(POW, "power", NullPolicy.STRICT);
       defineMethod(RADIANS, "radians", NullPolicy.STRICT);
-//      defineMethod(ROUND, "sround", NullPolicy.STRICT);
+      // Uses ignite version
+      //defineMethod(ROUND, "sround", NullPolicy.STRICT);
       defineMethod(SEC, "sec", NullPolicy.STRICT);
       defineMethod(SECH, "sech", NullPolicy.STRICT);
       defineMethod(SIGN, "sign", NullPolicy.STRICT);
@@ -607,8 +609,10 @@ public class RexImpTable {
       defineMethod(SINH, "sinh", NullPolicy.STRICT);
       defineMethod(TAN, "tan", NullPolicy.STRICT);
       defineMethod(TANH, "tanh", NullPolicy.STRICT);
-      defineMethod(TRUNC, "struncate", NullPolicy.STRICT);
-      defineMethod(TRUNCATE, "struncate", NullPolicy.STRICT);
+      // Removed.
+      //defineMethod(TRUNC, "struncate", NullPolicy.STRICT);
+      // Uses ignite version
+      //defineMethod(TRUNCATE, "struncate", NullPolicy.STRICT);
 
       map.put(PI, new PiImplementor());
       return populate2();
@@ -996,6 +1000,7 @@ public class RexImpTable {
       defineMethod(IgniteSqlOperatorTable.OCTET_LENGTH, 
IgniteMethod.OCTET_LENGTH.method(), NullPolicy.STRICT);
       defineMethod(SUBSTR, IgniteMethod.SUBSTR.method(), NullPolicy.STRICT);
       defineMethod(ROUND, IgniteMethod.ROUND.method(), NullPolicy.STRICT);
+      defineMethod(TRUNCATE, IgniteMethod.TRUNCATE.method(), 
NullPolicy.STRICT);
 
       map.put(TYPEOF, systemFunctionImplementor);
       map.put(NULL_BOUND, systemFunctionImplementor);
diff --git 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/fun/IgniteSqlOperatorTable.java
 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/fun/IgniteSqlOperatorTable.java
index d667371faa..bc572b27aa 100644
--- 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/fun/IgniteSqlOperatorTable.java
+++ 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/fun/IgniteSqlOperatorTable.java
@@ -169,26 +169,13 @@ public class IgniteSqlOperatorTable extends 
ReflectiveSqlOperatorTable {
 
     /** The {@code ROUND(numeric [, numeric])} function. */
     public static final SqlFunction ROUND = SqlBasicFunction.create("ROUND",
-            new SqlReturnTypeInference() {
-                @Override
-                public @Nullable RelDataType 
inferReturnType(SqlOperatorBinding opBinding) {
-                    RelDataType operandType = opBinding.getOperandType(0);
-
-                    // If there is only one argument and it supports precision 
and scale, set scale 0.
-                    if (opBinding.getOperandCount() == 1 && 
operandType.getSqlTypeName().allowsPrecScale(true, true)) {
-                        int precision = operandType.getPrecision();
-                        IgniteTypeFactory typeFactory = Commons.typeFactory();
-
-                        RelDataType returnType = 
typeFactory.createSqlType(operandType.getSqlTypeName(), precision, 0);
-                        // Preserve nullability
-                        boolean nullable = operandType.isNullable();
-
-                        return 
typeFactory.createTypeWithNullability(returnType, nullable);
-                    } else {
-                        return operandType;
-                    }
-                }
-            },
+            new SetScaleToZeroIfSingleArgument(),
+            OperandTypes.NUMERIC_OPTIONAL_INTEGER,
+            SqlFunctionCategory.NUMERIC);
+
+    /** The {@code TRUNCATE(numeric [, numeric])} function. */
+    public static final SqlFunction TRUNCATE = 
SqlBasicFunction.create("TRUNCATE",
+            new SetScaleToZeroIfSingleArgument(),
             OperandTypes.NUMERIC_OPTIONAL_INTEGER,
             SqlFunctionCategory.NUMERIC);
 
@@ -334,7 +321,7 @@ public class IgniteSqlOperatorTable extends 
ReflectiveSqlOperatorTable {
         register(SqlLibraryOperators.SINH); // Hyperbolic sine.
         register(SqlStdOperatorTable.TAN); // Tangent.
         register(SqlLibraryOperators.TANH); // Hyperbolic tangent.
-        register(SqlStdOperatorTable.TRUNCATE);
+        register(TRUNCATE); // Fixes return type scale.
         register(SqlStdOperatorTable.PI);
 
         // Date and time.
@@ -471,4 +458,26 @@ public class IgniteSqlOperatorTable extends 
ReflectiveSqlOperatorTable {
         register(RAND_UUID);
         register(GEN_RANDOM_UUID);
     }
+
+    /** Sets scale to {@code 0} for single argument variants of ROUND/TRUNCATE 
operators. */
+    private static class SetScaleToZeroIfSingleArgument implements 
SqlReturnTypeInference {
+        @Override
+        public @Nullable RelDataType inferReturnType(SqlOperatorBinding 
opBinding) {
+            RelDataType operandType = opBinding.getOperandType(0);
+
+            // If there is only one argument and it supports precision and 
scale, set scale 0.
+            if (opBinding.getOperandCount() == 1 && 
operandType.getSqlTypeName().allowsPrecScale(true, true)) {
+                int precision = operandType.getPrecision();
+                IgniteTypeFactory typeFactory = Commons.typeFactory();
+
+                RelDataType returnType = 
typeFactory.createSqlType(operandType.getSqlTypeName(), precision, 0);
+                // Preserve nullability
+                boolean nullable = operandType.isNullable();
+
+                return typeFactory.createTypeWithNullability(returnType, 
nullable);
+            } else {
+                return operandType;
+            }
+        }
+    }
 }
diff --git 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/IgniteMethod.java
 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/IgniteMethod.java
index a36da794d2..44f82932d4 100644
--- 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/IgniteMethod.java
+++ 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/IgniteMethod.java
@@ -117,7 +117,12 @@ public enum IgniteMethod {
     SUBSTR(SqlFunctions.class, "substring", String.class, int.class, 
int.class),
 
     /** ROUND function. See {@link IgniteSqlFunctions#sround(double)}, {@link 
IgniteSqlFunctions#sround(double, int)} and variants. */
-    ROUND(IgniteSqlFunctions.class, "sround", true);
+    ROUND(IgniteSqlFunctions.class, "sround", true),
+
+    /**
+     * TRUNCATE function. See {@link IgniteSqlFunctions#struncate(double)}, 
{@link IgniteSqlFunctions#struncate(double, int)} and variants.
+     */
+    TRUNCATE(IgniteSqlFunctions.class, "struncate", true);
 
     private final Method method;
 
diff --git 
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/exp/IgniteSqlFunctionsTest.java
 
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/exp/IgniteSqlFunctionsTest.java
index 024a10dc18..596b510f0d 100644
--- 
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/exp/IgniteSqlFunctionsTest.java
+++ 
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/exp/IgniteSqlFunctionsTest.java
@@ -250,10 +250,11 @@ public class IgniteSqlFunctionsTest {
     @Test
     public void testRound() {
         assertEquals(new BigDecimal("1"), IgniteSqlFunctions.sround(new 
BigDecimal("1.000")));
-        assertEquals(new BigDecimal("1"), IgniteSqlFunctions.sround(new 
BigDecimal("1.123")));
+        assertEquals(new BigDecimal("2"), IgniteSqlFunctions.sround(new 
BigDecimal("1.5")));
         assertEquals(1, IgniteSqlFunctions.sround(1), "int");
         assertEquals(1L, IgniteSqlFunctions.sround(1L), "long");
-        assertEquals(1.0d, IgniteSqlFunctions.sround(1.123d), "double");
+        assertEquals(2.0f, IgniteSqlFunctions.sround(1.5f), "float");
+        assertEquals(2.0d, IgniteSqlFunctions.sround(1.5d), "double");
     }
 
     /** Tests for ROUND(x, s) function, where x is a BigDecimal value. */
@@ -263,17 +264,19 @@ public class IgniteSqlFunctionsTest {
             "1.123, 0, 1.000",
             "1.123, 1, 1.100",
             "1.123, 2, 1.120",
-            "1.127, 2, 1.130",
+            "1.125, 2, 1.130",
             "1.123, 3, 1.123",
             "1.123, 4, 1.123",
             "10.123, 0, 10.000",
+            "10.500, 0, 11.000",
+            "10.800, 0, 11.000",
             "10.123, -1, 10.000",
             "10.123, -2, 0.000",
             "10.123, 3, 10.123",
             "10.123, 4, 10.123",
     })
     public void testRound2Decimal(String input, int scale, String result) {
-        assertEquals(new BigDecimal(result), IgniteSqlFunctions.sround(new 
BigDecimal(result), scale));
+        assertEquals(new BigDecimal(result), IgniteSqlFunctions.sround(new 
BigDecimal(input), scale));
     }
 
     /** Tests for ROUND(x, s) function, where x is a double value. */
@@ -281,9 +284,11 @@ public class IgniteSqlFunctionsTest {
     @CsvSource({
             "1.123, 3, 1.123",
             "1.123, 2, 1.12",
-            "1.127, 2, 1.13",
+            "1.125, 2, 1.13",
             "1.245, 1, 1.2",
             "1.123, 0, 1.0",
+            "1.500, 0, 2.0",
+            "1.800, 0, 2.0",
             "1.123, -1, 0.0",
             "10.123, 0, 10.000",
             "10.123, -1, 10.000",
@@ -358,4 +363,122 @@ public class IgniteSqlFunctionsTest {
     public void testRound2LongType(long input, int scale, long result) {
         assertEquals(result, IgniteSqlFunctions.sround(input, scale));
     }
+
+    /** Tests for TRUNCATE(x) function. */
+    @Test
+    public void testTruncate() {
+        assertEquals(new BigDecimal("1"), IgniteSqlFunctions.struncate(new 
BigDecimal("1.000")));
+        assertEquals(new BigDecimal("1"), IgniteSqlFunctions.struncate(new 
BigDecimal("1.5")));
+        assertEquals(1, IgniteSqlFunctions.struncate(1), "int");
+        assertEquals(1L, IgniteSqlFunctions.struncate(1L), "long");
+        assertEquals(1.0d, IgniteSqlFunctions.struncate(1.5d), "double");
+        assertEquals(1.0f, IgniteSqlFunctions.struncate(1.5f), "float");
+    }
+
+    /** Tests for TRUNCATE(x, s) function, where x is a BigDecimal value. */
+    @ParameterizedTest
+    @CsvSource({
+            "1.123, -1, 0.000",
+            "1.123, 0, 1.000",
+            "1.123, 1, 1.100",
+            "1.123, 2, 1.120",
+            "1.125, 2, 1.120",
+            "1.123, 3, 1.123",
+            "1.123, 4, 1.123",
+            "10.123, 0, 10.000",
+            "10.500, 0, 10.000",
+            "10.800, 0, 10.000",
+            "10.123, -1, 10.000",
+            "10.123, -2, 0.000",
+            "10.123, 3, 10.123",
+            "10.123, 4, 10.123",
+    })
+    public void testTruncate2Decimal(String input, int scale, String result) {
+        assertEquals(new BigDecimal(result), IgniteSqlFunctions.struncate(new 
BigDecimal(input), scale));
+    }
+
+    /** Tests for TRUNCATE(x, s) function, where x is a double value. */
+    @ParameterizedTest
+    @CsvSource({
+            "1.123, 3, 1.123",
+            "1.123, 2, 1.12",
+            "1.125, 2, 1.12",
+            "1.245, 1, 1.2",
+            "1.123, 0, 1.0",
+            "1.500, 0, 1.0",
+            "1.800, 0, 1.0",
+            "1.123, -1, 0.0",
+            "10.123, 0, 10.000",
+            "10.123, -1, 10.000",
+            "10.123, -2, 0.000",
+            "10.123, 3, 10.123",
+            "10.123, 4, 10.123",
+    })
+    public void testTruncate2Double(double input, int scale, double result) {
+        assertEquals(result, IgniteSqlFunctions.struncate(input, scale));
+    }
+
+    /** Tests for TRUNCATE(x, s) function, where x is an byte. */
+    @ParameterizedTest
+    @CsvSource({
+            "42, -2, 0",
+            "42, -1, 40",
+            "47, -1, 40",
+            "42, 0, 42",
+            "42, 1, 42",
+            "42, 2, 42",
+            "-42, -1, -40",
+            "-47, -1, -40",
+    })
+    public void testTruncate2ByteType(byte input, int scale, byte result) {
+        assertEquals(result, IgniteSqlFunctions.struncate(input, scale));
+    }
+
+    /** Tests for TRUNCATE(x, s) function, where x is an short. */
+    @ParameterizedTest
+    @CsvSource({
+            "42, -2, 0",
+            "42, -1, 40",
+            "47, -1, 40",
+            "42, 0, 42",
+            "42, 1, 42",
+            "42, 2, 42",
+            "-42, -1, -40",
+            "-47, -1, -40",
+    })
+    public void testTruncateShortType(short input, int scale, short result) {
+        assertEquals(result, IgniteSqlFunctions.struncate(input, scale));
+    }
+
+    /** Tests for TRUNCATE(x, s) function, where x is an int. */
+    @ParameterizedTest
+    @CsvSource({
+            "42, -2, 0",
+            "42, -1, 40",
+            "47, -1, 40",
+            "42, 0, 42",
+            "42, 1, 42",
+            "42, 2, 42",
+            "-42, -1, -40",
+            "-47, -1, -40",
+    })
+    public void testTruncate2IntType(int input, int scale, int result) {
+        assertEquals(result, IgniteSqlFunctions.struncate(input, scale));
+    }
+
+    /** Tests for TRUNCATE(x, s) function, where x is a long. */
+    @ParameterizedTest
+    @CsvSource({
+            "42, -2, 0",
+            "42, -1, 40",
+            "47, -1, 40",
+            "42, 0, 42",
+            "42, 1, 42",
+            "42, 2, 42",
+            "-42, -1, -40",
+            "-47, -1, -40",
+    })
+    public void testTruncate2LongType(long input, int scale, long result) {
+        assertEquals(result, IgniteSqlFunctions.struncate(input, scale));
+    }
 }

Reply via email to