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

godfrey pushed a commit to branch release-1.14
in repository https://gitbox.apache.org/repos/asf/flink.git

commit 8c7cbcd9744378dccb4b6ab0493c7d273c69dfef
Author: paul8263 <[email protected]>
AuthorDate: Tue Sep 7 17:13:10 2021 +0800

    [FLINK-23614][table-planner] The resulting scale of TRUNCATE(DECIMAL) is 
not correct
    
    This closes #16740
    
    (cherry picked from commit e55e6649da41621872f3a847dcd1dad2d97b017a)
---
 .../functions/BuiltInFunctionDefinitions.java      |  2 +-
 .../functions/sql/FlinkSqlOperatorTable.java       | 10 +++-
 .../planner/functions/MathFunctionsITCase.java     | 10 +++-
 .../planner/expressions/ScalarFunctionsTest.scala  | 68 ++++++++++++++++++----
 .../validation/ScalarFunctionsValidationTest.scala |  2 +-
 .../planner/runtime/batch/sql/CalcITCase.scala     | 35 +++++++++++
 6 files changed, 112 insertions(+), 15 deletions(-)

diff --git 
a/flink-table/flink-table-common/src/main/java/org/apache/flink/table/functions/BuiltInFunctionDefinitions.java
 
b/flink-table/flink-table-common/src/main/java/org/apache/flink/table/functions/BuiltInFunctionDefinitions.java
index 1cd31cf..022b7b1 100644
--- 
a/flink-table/flink-table-common/src/main/java/org/apache/flink/table/functions/BuiltInFunctionDefinitions.java
+++ 
b/flink-table/flink-table-common/src/main/java/org/apache/flink/table/functions/BuiltInFunctionDefinitions.java
@@ -1136,7 +1136,7 @@ public final class BuiltInFunctionDefinitions {
                                     sequence(
                                             logical(LogicalTypeFamily.NUMERIC),
                                             logical(LogicalTypeRoot.INTEGER))))
-                    .outputTypeStrategy(nullableIfArgs(argument(0)))
+                    
.outputTypeStrategy(nullableIfArgs(SpecificTypeStrategies.ROUND))
                     .build();
 
     // 
--------------------------------------------------------------------------------------------
diff --git 
a/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/planner/functions/sql/FlinkSqlOperatorTable.java
 
b/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/planner/functions/sql/FlinkSqlOperatorTable.java
index 2c6d46e..cd0052d 100644
--- 
a/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/planner/functions/sql/FlinkSqlOperatorTable.java
+++ 
b/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/planner/functions/sql/FlinkSqlOperatorTable.java
@@ -224,6 +224,15 @@ public class FlinkSqlOperatorTable extends 
ReflectiveSqlOperatorTable {
                     OperandTypes.or(OperandTypes.NUMERIC_INTEGER, 
OperandTypes.NUMERIC),
                     SqlFunctionCategory.NUMERIC);
 
+    public static final SqlFunction TRUNCATE =
+            new SqlFunction(
+                    "TRUNCATE",
+                    SqlKind.OTHER_FUNCTION,
+                    FlinkReturnTypes.ROUND_FUNCTION_NULLABLE,
+                    null,
+                    OperandTypes.or(OperandTypes.NUMERIC_INTEGER, 
OperandTypes.NUMERIC),
+                    SqlFunctionCategory.NUMERIC);
+
     public static final SqlFunction BIN =
             new SqlFunction(
                     "BIN",
@@ -1125,7 +1134,6 @@ public class FlinkSqlOperatorTable extends 
ReflectiveSqlOperatorTable {
     public static final SqlFunction PI = SqlStdOperatorTable.PI;
     public static final SqlFunction RAND = SqlStdOperatorTable.RAND;
     public static final SqlFunction RAND_INTEGER = 
SqlStdOperatorTable.RAND_INTEGER;
-    public static final SqlFunction TRUNCATE = SqlStdOperatorTable.TRUNCATE;
 
     // TIME FUNCTIONS
     public static final SqlFunction YEAR = SqlStdOperatorTable.YEAR;
diff --git 
a/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/functions/MathFunctionsITCase.java
 
b/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/functions/MathFunctionsITCase.java
index c7ff747..0d982dc 100644
--- 
a/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/functions/MathFunctionsITCase.java
+++ 
b/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/functions/MathFunctionsITCase.java
@@ -115,6 +115,14 @@ public class MathFunctionsITCase extends 
BuiltInFunctionTestBase {
                                 $("f0").round(2),
                                 "ROUND(f0, 2)",
                                 new BigDecimal("12345.12"),
-                                DataTypes.DECIMAL(8, 2).notNull()));
+                                DataTypes.DECIMAL(8, 2).notNull()),
+                TestSpec.forFunction(BuiltInFunctionDefinitions.TRUNCATE)
+                        .onFieldsWithData(new BigDecimal("123.456"))
+                        // TRUNCATE(DECIMAL(6, 3) NOT NULL, 2) => DECIMAL(6, 
2) NOT NULL
+                        .testResult(
+                                $("f0").truncate(2),
+                                "TRUNCATE(f0, 2)",
+                                new BigDecimal("123.45"),
+                                DataTypes.DECIMAL(6, 2).notNull()));
     }
 }
diff --git 
a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/expressions/ScalarFunctionsTest.scala
 
b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/expressions/ScalarFunctionsTest.scala
index 41514e5..c0bf7f7 100644
--- 
a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/expressions/ScalarFunctionsTest.scala
+++ 
b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/expressions/ScalarFunctionsTest.scala
@@ -1379,39 +1379,71 @@ class ScalarFunctionsTest extends ScalarTypesTestBase {
       "0.4")
 
     testAllApis(
+      'f29.truncate(),
+      "f29.truncate()",
+      "truncate(f29)",
+      "0.0")
+
+    testAllApis(
       'f31.truncate('f7),
       "f31.truncate(f7)",
       "truncate(f31, f7)",
       "-0.123")
 
     testAllApis(
+      'f31.truncate(),
+      "f31.truncate()",
+      "truncate(f31)",
+      "0")
+
+    testAllApis(
       'f4.truncate('f32),
       "f4.truncate(f32)",
       "truncate(f4, f32)",
       "40")
 
     testAllApis(
+      'f4.truncate(),
+      "f4.truncate()",
+      "truncate(f4)",
+      "44")
+
+    testAllApis(
       'f28.cast(DataTypes.DOUBLE).truncate(1),
       "f28.cast(DOUBLE).truncate(1)",
       "truncate(cast(f28 as DOUBLE), 1)",
       "0.4")
 
+    testAllApis(
+      'f28.cast(DataTypes.DOUBLE).truncate(),
+      "f28.cast(DOUBLE).truncate()",
+      "truncate(cast(f28 as DOUBLE))",
+      "0.0")
+
     // TODO: ignore TableApiTest for cast to DECIMAL(p, s) is not support now.
     //  see https://issues.apache.org/jira/browse/FLINK-13651
-//    testAllApis(
-//      'f31.cast(DataTypes.DECIMAL(38, 18)).truncate(2),
-//      "f31.cast(DECIMAL(10, 10)).truncate(2)",
-//      "truncate(cast(f31 as decimal(38, 18)), 2)",
-//      "-0.12")
-//
-//    testAllApis(
-//      'f36.cast(DataTypes.DECIMAL(38, 18)).truncate(),
-//      "f36.cast(DECIMAL(10, 10)).truncate()",
-//      "truncate(42.324)",
-//      "42")
+    //    testAllApis(
+    //      'f31.cast(DataTypes.DECIMAL(38, 18)).truncate(2),
+    //      "f31.cast(DECIMAL(10, 10)).truncate(2)",
+    //      "truncate(cast(f31 as decimal(38, 18)), 2)",
+    //      "-0.12")
+    //
+    //    testAllApis(
+    //      'f36.cast(DataTypes.DECIMAL(38, 18)).truncate(),
+    //      "f36.cast(DECIMAL(10, 10)).truncate()",
+    //      "truncate(42.324)",
+    //      "42")
 
     testSqlApi("truncate(cast(f31 as decimal(38, 18)), 2)", "-0.12")
 
+    testSqlApi("truncate(cast(f31 as decimal(38, 18)))", "0")
+
+    testAllApis(
+      'f28.cast(DataTypes.FLOAT).truncate(1),
+      "f28.cast(FLOAT).truncate(1)",
+      "truncate(cast(f28 as float), 1)",
+      "0.4")
+
     testAllApis(
       'f5.cast(DataTypes.FLOAT).truncate(),
       "f5.cast(FLOAT).truncate()",
@@ -1430,6 +1462,12 @@ class ScalarFunctionsTest extends ScalarTypesTestBase {
       "truncate(42, -3)",
       "0")
 
+    testAllApis(
+      42.truncate(),
+      "42.truncate()",
+      "truncate(42)",
+      "42")
+
     //    The validation parameter is null
     testAllApis(
       'f33.cast(DataTypes.INT).truncate(1),
@@ -1460,6 +1498,14 @@ class ScalarFunctionsTest extends ScalarTypesTestBase {
       "f33.cast(DOUBLE).truncate()",
       "truncate(cast(null as double))",
       "null")
+
+    // TODO: ignore TableApiTest for cast to DECIMAL(p, s) is not support now.
+    //  see https://issues.apache.org/jira/browse/FLINK-13651
+    //    testAllApis(
+    //      'f33.cast(DataTypes.DECIMAL(10, 5)).truncate(),
+    //      "f33.cast(DECIMAL(10, 5)).truncate()",
+    //      "truncate(cast(null as decimal(10, 5)))",
+    //      "null")
   }
 
   // 
----------------------------------------------------------------------------------------------
diff --git 
a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/expressions/validation/ScalarFunctionsValidationTest.scala
 
b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/expressions/validation/ScalarFunctionsValidationTest.scala
index 2634b68..d1760dc 100644
--- 
a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/expressions/validation/ScalarFunctionsValidationTest.scala
+++ 
b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/expressions/validation/ScalarFunctionsValidationTest.scala
@@ -94,7 +94,7 @@ class ScalarFunctionsValidationTest extends 
ScalarTypesTestBase {
 
   @Test
   def testInvalidTruncate2(): Unit = {
-    thrown.expect(classOf[CodeGenException])
+    thrown.expect(classOf[ValidationException])
     // The one argument is of type String
     testSqlApi(
       "TRUNCATE('abc')",
diff --git 
a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/runtime/batch/sql/CalcITCase.scala
 
b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/runtime/batch/sql/CalcITCase.scala
index 1088e89..a357ceb 100644
--- 
a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/runtime/batch/sql/CalcITCase.scala
+++ 
b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/runtime/batch/sql/CalcITCase.scala
@@ -1069,6 +1069,41 @@ class CalcITCase extends BatchTestBase {
   }
 
   @Test
+  def testTruncate(): Unit = {
+    checkResult(
+      "SELECT TRUNCATE(CAST(123.456 AS DOUBLE), 2)",
+      Seq(row(123.45)))
+
+    checkResult(
+      "SELECT TRUNCATE(CAST(123.456 AS DOUBLE))",
+      Seq(row(123.0)))
+
+    checkResult(
+      "SELECT TRUNCATE(CAST(123.456 AS FLOAT), 2)",
+      Seq(row(123.45f)))
+
+    checkResult(
+      "SELECT TRUNCATE(CAST(123.456 AS FLOAT))",
+      Seq(row(123.0f)))
+
+    checkResult(
+      "SELECT TRUNCATE(123, -1)",
+      Seq(row(120)))
+
+    checkResult(
+      "SELECT TRUNCATE(123, -2)",
+      Seq(row(100)))
+
+    checkResult(
+      "SELECT TRUNCATE(CAST(123.456 AS DECIMAL(6, 3)), 2)",
+      Seq(row(new java.math.BigDecimal("123.45"))))
+
+    checkResult(
+      "SELECT TRUNCATE(CAST(123.456 AS DECIMAL(6, 3)))",
+      Seq(row(new java.math.BigDecimal("123"))))
+  }
+
+  @Test
   def testStringUdf(): Unit = {
     registerFunction("myFunc", MyStringFunc)
     checkResult(

Reply via email to