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

morrysnow pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new 88ef595e39a [fix](Nereids) decimalv3 cast in fe produce wrong data 
(#29808)
88ef595e39a is described below

commit 88ef595e39a11be96c0b4338dcba1ed08c3a199e
Author: morrySnow <[email protected]>
AuthorDate: Thu Jan 11 13:54:05 2024 +0800

    [fix](Nereids) decimalv3 cast in fe produce wrong data (#29808)
    
    case:
    ```
    MySQL [email protected]:test> select cast(12 as decimalv3(2,1))
    +-----------------------------+
    | cast(12 as DECIMALV3(2, 1)) |
    +-----------------------------+
    | 12.0                        |
    +-----------------------------+
    ```
    
    decimalv2 literal will generate wrong result too. But it is not only
    bugs in planner, but also have bugs in executor. So we need fix executor
    bug in another PR.
---
 .../doris/nereids/rules/expression/rules/SimplifyCastRule.java   | 9 +++++----
 .../doris/nereids/trees/expressions/literal/DecimalLiteral.java  | 1 +
 .../nereids/trees/expressions/literal/DecimalV3Literal.java      | 2 +-
 .../doris/nereids/rules/expression/ExpressionRewriteTest.java    | 8 ++++----
 regression-test/suites/nereids_syntax_p0/cast.groovy             | 5 +++++
 5 files changed, 16 insertions(+), 9 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/SimplifyCastRule.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/SimplifyCastRule.java
index d88489084df..34143043a07 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/SimplifyCastRule.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/SimplifyCastRule.java
@@ -82,14 +82,15 @@ public class SimplifyCastRule extends 
AbstractExpressionRewriteRule {
                                 ((VarcharType) castType).getLen());
                     }
                 } else if (castType instanceof DecimalV2Type) {
+                    DecimalV2Type decimalV2Type = (DecimalV2Type) castType;
                     if (child instanceof TinyIntLiteral) {
-                        return new DecimalLiteral(new 
BigDecimal(((TinyIntLiteral) child).getValue()));
+                        return new DecimalLiteral(decimalV2Type, new 
BigDecimal(((TinyIntLiteral) child).getValue()));
                     } else if (child instanceof SmallIntLiteral) {
-                        return new DecimalLiteral(new 
BigDecimal(((SmallIntLiteral) child).getValue()));
+                        return new DecimalLiteral(decimalV2Type, new 
BigDecimal(((SmallIntLiteral) child).getValue()));
                     } else if (child instanceof IntegerLiteral) {
-                        return new DecimalLiteral(new 
BigDecimal(((IntegerLiteral) child).getValue()));
+                        return new DecimalLiteral(decimalV2Type, new 
BigDecimal(((IntegerLiteral) child).getValue()));
                     } else if (child instanceof BigIntLiteral) {
-                        return new DecimalLiteral(new 
BigDecimal(((BigIntLiteral) child).getValue()));
+                        return new DecimalLiteral(decimalV2Type, new 
BigDecimal(((BigIntLiteral) child).getValue()));
                     }
                 } else if (castType instanceof DecimalV3Type) {
                     DecimalV3Type decimalV3Type = (DecimalV3Type) castType;
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DecimalLiteral.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DecimalLiteral.java
index 711673cc2ff..03973fe6b03 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DecimalLiteral.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DecimalLiteral.java
@@ -81,6 +81,7 @@ public class DecimalLiteral extends Literal {
         boolean valid = true;
         if (precision != -1 && scale != -1) {
             if (precision < realPrecision || scale < realScale
+                    || realPrecision - realScale > precision - scale
                     || realPrecision - realScale > DecimalV2Type.MAX_PRECISION 
- DecimalV2Type.MAX_SCALE) {
                 valid = false;
             }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DecimalV3Literal.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DecimalV3Literal.java
index 65296b4f79b..2a10196e056 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DecimalV3Literal.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DecimalV3Literal.java
@@ -93,7 +93,7 @@ public class DecimalV3Literal extends Literal {
         int realScale = value.scale();
         boolean valid = true;
         if (precision != -1 && scale != -1) {
-            if (precision < realPrecision || scale < realScale) {
+            if (precision < realPrecision || scale < realScale || precision - 
scale < realPrecision - realScale) {
                 valid = false;
             }
         } else {
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/ExpressionRewriteTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/ExpressionRewriteTest.java
index 646174c9eb7..de859058ecc 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/ExpressionRewriteTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/ExpressionRewriteTest.java
@@ -200,13 +200,13 @@ class ExpressionRewriteTest extends 
ExpressionRewriteTestHelper {
 
         // decimal literal
         assertRewrite(new Cast(new TinyIntLiteral((byte) 1), 
DecimalV2Type.createDecimalV2Type(15, 9)),
-                new DecimalLiteral(new BigDecimal(1)));
+                new DecimalLiteral(new BigDecimal("1.000000000")));
         assertRewrite(new Cast(new SmallIntLiteral((short) 1), 
DecimalV2Type.createDecimalV2Type(15, 9)),
-                new DecimalLiteral(new BigDecimal(1)));
+                new DecimalLiteral(new BigDecimal("1.000000000")));
         assertRewrite(new Cast(new IntegerLiteral(1), 
DecimalV2Type.createDecimalV2Type(15, 9)),
-                new DecimalLiteral(new BigDecimal(1)));
+                new DecimalLiteral(new BigDecimal("1.000000000")));
         assertRewrite(new Cast(new BigIntLiteral(1L), 
DecimalV2Type.createDecimalV2Type(15, 9)),
-                new DecimalLiteral(new BigDecimal(1)));
+                new DecimalLiteral(new BigDecimal("1.000000000")));
     }
 
     @Test
diff --git a/regression-test/suites/nereids_syntax_p0/cast.groovy 
b/regression-test/suites/nereids_syntax_p0/cast.groovy
index 0589ec5275d..4a4192175b1 100644
--- a/regression-test/suites/nereids_syntax_p0/cast.groovy
+++ b/regression-test/suites/nereids_syntax_p0/cast.groovy
@@ -233,6 +233,11 @@ suite("cast") {
         sql """select cast(k5 as time) ct from test order by ct;"""
         exception "cannot cast"
     }
+    test {
+        sql "select cast(12 as decimalv3(2,1))"
+        exception "Arithmetic overflow"
+    }
+
     // date
     test {
         sql """select cast(k10 as time) ct from test order by ct;"""


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to