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 74c0677d62 [fix](planner) fix bugs in uncheckedCastChild (#15905)
74c0677d62 is described below

commit 74c0677d623340111f4fa918352f7ec00227d447
Author: minghong <engle...@gmail.com>
AuthorDate: Thu Jan 19 15:51:08 2023 +0800

    [fix](planner) fix bugs in uncheckedCastChild (#15905)
    
    1. `uncheckedCastChild` may generate redundant `CastExpr` like `cast( 
cast(XXX as Date) as Date)`
    2. generate DateLiteral to replace cast(IntLiteral as Date)
---
 .../main/java/org/apache/doris/catalog/Type.java   |  7 ++++
 .../main/java/org/apache/doris/analysis/Expr.java  |  7 +++-
 .../java/org/apache/doris/analysis/IntLiteral.java | 47 ++++++++++++++--------
 .../java/org/apache/doris/analysis/ExprTest.java   | 10 +++++
 .../org/apache/doris/analysis/InsertStmtTest.java  |  5 ++-
 .../org/apache/doris/analysis/IntLiteralTest.java  | 35 ++++++++++++++++
 6 files changed, 90 insertions(+), 21 deletions(-)

diff --git a/fe/fe-common/src/main/java/org/apache/doris/catalog/Type.java 
b/fe/fe-common/src/main/java/org/apache/doris/catalog/Type.java
index c94552d1f2..0fb6a779b6 100644
--- a/fe/fe-common/src/main/java/org/apache/doris/catalog/Type.java
+++ b/fe/fe-common/src/main/java/org/apache/doris/catalog/Type.java
@@ -283,6 +283,13 @@ public abstract class Type {
         return isScalarType(PrimitiveType.DATETIMEV2);
     }
 
+    public boolean isDateLike() {
+        return isScalarType(PrimitiveType.DATETIME)
+                || isScalarType(PrimitiveType.DATETIMEV2)
+                || isScalarType(PrimitiveType.DATE)
+                || isScalarType(PrimitiveType.DATEV2);
+    }
+
     public boolean isTimeV2() {
         return isScalarType(PrimitiveType.TIMEV2);
     }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/Expr.java 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/Expr.java
index 35bd80e9a3..50194d22ce 100755
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/Expr.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/Expr.java
@@ -1448,8 +1448,11 @@ public abstract class Expr extends TreeNode<Expr> 
implements ParseNode, Cloneabl
     public void uncheckedCastChild(Type targetType, int childIndex)
             throws AnalysisException {
         Expr child = getChild(childIndex);
-        Expr newChild = child.uncheckedCastTo(targetType);
-        setChild(childIndex, newChild);
+        //avoid to generate Expr like cast (cast(... as date) as date)
+        if (!child.getType().equals(targetType)) {
+            Expr newChild = child.uncheckedCastTo(targetType);
+            setChild(childIndex, newChild);
+        }
     }
 
     /**
diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/IntLiteral.java 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/IntLiteral.java
index 0d3749fa86..8933ec496e 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/IntLiteral.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/IntLiteral.java
@@ -294,28 +294,41 @@ public class IntLiteral extends LiteralExpr {
 
     @Override
     protected Expr uncheckedCastTo(Type targetType) throws AnalysisException {
-        if (!targetType.isNumericType()) {
-            return super.uncheckedCastTo(targetType);
-        }
-        if (targetType.isFixedPointType()) {
-            if (!targetType.isScalarType(PrimitiveType.LARGEINT)) {
-                if (!type.equals(targetType)) {
-                    IntLiteral intLiteral = new IntLiteral(this);
-                    intLiteral.setType(targetType);
-                    return intLiteral;
+        if (targetType.isNumericType()) {
+            if (targetType.isFixedPointType()) {
+                if (!targetType.isScalarType(PrimitiveType.LARGEINT)) {
+                    if (!type.equals(targetType)) {
+                        IntLiteral intLiteral = new IntLiteral(this);
+                        intLiteral.setType(targetType);
+                        return intLiteral;
+                    }
+                    return this;
+                } else {
+                    return new LargeIntLiteral(Long.toString(value));
                 }
-                return this;
-            } else {
-                return new LargeIntLiteral(Long.toString(value));
+            } else if (targetType.isFloatingPointType()) {
+                return new FloatLiteral(new Double(value), targetType);
+            } else if (targetType.isDecimalV2() || targetType.isDecimalV3()) {
+                DecimalLiteral res = new DecimalLiteral(new BigDecimal(value));
+                res.setType(targetType);
+                return res;
+            }
+            return this;
+        } else if (targetType.isDateLike()) {
+            try {
+                //int like 20200101 can be cast to date(2020,01,01)
+                DateLiteral res = new DateLiteral("" + value, targetType);
+                res.setType(targetType);
+                return res;
+            } catch (AnalysisException e) {
+                //invalid date format. leave it to BE to cast it as NULL
             }
-        } else if (targetType.isFloatingPointType()) {
-            return new FloatLiteral(new Double(value), targetType);
-        } else if (targetType.isDecimalV2() || targetType.isDecimalV3()) {
-            DecimalLiteral res = new DecimalLiteral(new BigDecimal(value));
+        } else if (targetType.isStringType()) {
+            StringLiteral res = new StringLiteral("" + value);
             res.setType(targetType);
             return res;
         }
-        return this;
+        return super.uncheckedCastTo(targetType);
     }
 
     @Override
diff --git a/fe/fe-core/src/test/java/org/apache/doris/analysis/ExprTest.java 
b/fe/fe-core/src/test/java/org/apache/doris/analysis/ExprTest.java
index ad4a3c21d6..475d9dc8fb 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/analysis/ExprTest.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/analysis/ExprTest.java
@@ -32,6 +32,7 @@ import mockit.Injectable;
 import mockit.Mocked;
 import org.junit.Assert;
 import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
 
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
@@ -202,6 +203,15 @@ public class ExprTest {
         Assert.assertFalse(Expr.equalSets(list1, list2));
     }
 
+    @Test
+    public void testUncheckedCastChildAvoidDoubleCast() throws 
AnalysisException {
+        Expr cast = new CastExpr(Type.DATETIME, new IntLiteral(10000101));
+        FunctionCallExpr call = new FunctionCallExpr("leap", 
Lists.newArrayList(cast));
+        call.uncheckedCastChild(Type.DATETIME, 0);
+        //do not cast a castExpr
+        Assertions.assertTrue(call.getChild(0).getChild(0) instanceof 
IntLiteral);
+    }
+
     @Test
     public void testSrcSlotRef(@Injectable SlotDescriptor slotDescriptor) {
         TableName tableName = new TableName(internalCtl, "db1", "table1");
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/analysis/InsertStmtTest.java 
b/fe/fe-core/src/test/java/org/apache/doris/analysis/InsertStmtTest.java
index b16abaf470..0b19e54f51 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/analysis/InsertStmtTest.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/analysis/InsertStmtTest.java
@@ -202,9 +202,10 @@ public class InsertStmtTest {
         FunctionCallExpr expr4 = (FunctionCallExpr) 
queryStmtSubstitute.getResultExprs().get(4);
         Assert.assertEquals(expr4.getFnName().getFunction(), "to_bitmap");
         List<Expr> slots = Lists.newArrayList();
-        expr4.collect(IntLiteral.class, slots);
+        expr4.collect(StringLiteral.class, slots);
         Assert.assertEquals(1, slots.size());
-        Assert.assertEquals(queryStmtSubstitute.getResultExprs().get(0), 
slots.get(0));
+        
Assert.assertEquals(queryStmtSubstitute.getResultExprs().get(0).getStringValue(),
+                slots.get(0).getStringValue());
 
         Assert.assertTrue(queryStmtSubstitute.getResultExprs().get(5) 
instanceof FunctionCallExpr);
         FunctionCallExpr expr5 = (FunctionCallExpr) 
queryStmtSubstitute.getResultExprs().get(5);
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/analysis/IntLiteralTest.java 
b/fe/fe-core/src/test/java/org/apache/doris/analysis/IntLiteralTest.java
new file mode 100644
index 0000000000..a3c9b48282
--- /dev/null
+++ b/fe/fe-core/src/test/java/org/apache/doris/analysis/IntLiteralTest.java
@@ -0,0 +1,35 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.analysis;
+
+import org.apache.doris.catalog.Type;
+import org.apache.doris.common.AnalysisException;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class IntLiteralTest {
+    @Test
+    public void testUncheckedCastTo() throws AnalysisException {
+        IntLiteral intLiteral = new IntLiteral(20200101);
+        Expr expr = intLiteral.uncheckedCastTo(Type.DATETIME);
+        Assertions.assertTrue(expr instanceof DateLiteral);
+        expr = intLiteral.uncheckedCastTo(Type.STRING);
+        Assertions.assertTrue(expr instanceof StringLiteral);
+    }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to