You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flink.apache.org by go...@apache.org on 2021/10/29 02:36:35 UTC
[flink] 01/02: [FLINK-23614][table-planner] The resulting scale of
TRUNCATE(DECIMAL) is not correct
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 <xz...@126.com>
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(