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

huajianlan 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 172c213fbc [fix](Nereids)get NPE from finalize TimestampArithmeticExpr 
that generated by ExpressionTranslator (#12163)
172c213fbc is described below

commit 172c213fbca5f1be531346b74053208f4c973ef9
Author: morrySnow <[email protected]>
AuthorDate: Tue Aug 30 21:59:28 2022 +0800

    [fix](Nereids)get NPE from finalize TimestampArithmeticExpr that generated 
by ExpressionTranslator (#12163)
    
    This PR:
    1. refactor getDataType in TimestampArithmetic
    2. set TimeUnit correctly when translate TimestampArithmetic to 
TimestampArithmeticExpr
---
 .../doris/analysis/TimestampArithmeticExpr.java    | 49 +++++++++++++++++++++-
 .../glue/translator/ExpressionTranslator.java      | 11 ++++-
 .../trees/expressions/TimestampArithmetic.java     | 11 ++++-
 .../trees/expressions/literal/IntervalLiteral.java | 24 +++++++----
 4 files changed, 83 insertions(+), 12 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/analysis/TimestampArithmeticExpr.java
 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/TimestampArithmeticExpr.java
index 9a9229e741..bc2cbc5090 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/analysis/TimestampArithmeticExpr.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/TimestampArithmeticExpr.java
@@ -36,6 +36,7 @@ import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
 import java.util.HashMap;
+import java.util.Locale;
 import java.util.Map;
 
 /**
@@ -86,6 +87,52 @@ public class TimestampArithmeticExpr extends Expr {
         children.add(e2);
     }
 
+    /**
+     * used for Nereids ONLY.
+     * C'tor for function-call like arithmetic, e.g., 'date_add(a, interval b 
year)'.
+     *
+     * @param funcName timestamp arithmetic function name, used for all 
function except ADD and SUBTRACT.
+     * @param e1 non interval literal child of this function
+     * @param e2 interval literal child of this function
+     * @param timeUnitIdent interval time unit, could be 'year', 'month', 
'day', 'hour', 'minute', 'second'.
+     * @param dataType the return data type of this expression.
+     */
+    public TimestampArithmeticExpr(String funcName, Expr e1, Expr e2, String 
timeUnitIdent, Type dataType) {
+        this.funcName = funcName;
+        this.timeUnitIdent = timeUnitIdent;
+        this.timeUnit = 
TIME_UNITS_MAP.get(timeUnitIdent.toUpperCase(Locale.ROOT));
+        this.intervalFirst = false;
+        children.add(e1);
+        children.add(e2);
+        this.type = dataType;
+    }
+
+    /**
+     * used for Nereids ONLY.
+     * C'tor for non-function-call like arithmetic, e.g., 'a + interval b 
year'.
+     * e1 always refers to the timestamp to be added/subtracted from, and e2
+     * to the time value (even in the interval-first case).
+     *
+     * @param op operator of this function either ADD or SUBTRACT.
+     * @param e1 non interval literal child of this function
+     * @param e2 interval literal child of this function
+     * @param timeUnitIdent interval time unit, could be 'year', 'month', 
'day', 'hour', 'minute', 'second'.
+     * @param intervalFirst true if the left child is interval literal
+     * @param dataType the return data type of this expression.
+     */
+    public TimestampArithmeticExpr(ArithmeticExpr.Operator op, Expr e1, Expr 
e2,
+            String timeUnitIdent, boolean intervalFirst, Type dataType) {
+        Preconditions.checkState(op == Operator.ADD || op == 
Operator.SUBTRACT);
+        this.funcName = null;
+        this.op = op;
+        this.timeUnitIdent = timeUnitIdent;
+        this.timeUnit = 
TIME_UNITS_MAP.get(timeUnitIdent.toUpperCase(Locale.ROOT));
+        this.intervalFirst = intervalFirst;
+        children.add(e1);
+        children.add(e2);
+        this.type = dataType;
+    }
+
     protected TimestampArithmeticExpr(TimestampArithmeticExpr other) {
         super(other);
         funcName = other.funcName;
@@ -424,7 +471,7 @@ public class TimestampArithmeticExpr extends Expr {
         if (StringUtils.isEmpty(funcName)) {
             throw new AnalysisException("function name is null");
         }
-        type = getChild(0).getType();
+        timeUnit = TIME_UNITS_MAP.get(timeUnitIdent.toUpperCase());
         opcode = getOpCode();
         fn = getBuiltinFunction(funcName.toLowerCase(), 
collectChildReturnTypes(),
                 Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF);
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/ExpressionTranslator.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/ExpressionTranslator.java
index 43d9975e43..18b5bea6ef 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/ExpressionTranslator.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/ExpressionTranslator.java
@@ -266,7 +266,14 @@ public class ExpressionTranslator extends 
DefaultExpressionVisitor<Expr, PlanTra
 
     @Override
     public Expr visitTimestampArithmetic(TimestampArithmetic arithmetic, 
PlanTranslatorContext context) {
-        return new TimestampArithmeticExpr(arithmetic.getFuncName(), 
arithmetic.left().accept(this, context),
-                arithmetic.right().accept(this, context), 
arithmetic.getTimeUnit().toString());
+        if (arithmetic.getFuncName() == null) {
+            return new TimestampArithmeticExpr(arithmetic.getOp(), 
arithmetic.left().accept(this, context),
+                    arithmetic.right().accept(this, context), 
arithmetic.getTimeUnit().toString(),
+                    arithmetic.isIntervalFirst(), 
arithmetic.getDataType().toCatalogDataType());
+        } else {
+            return new TimestampArithmeticExpr(arithmetic.getFuncName(), 
arithmetic.left().accept(this, context),
+                    arithmetic.right().accept(this, context), 
arithmetic.getTimeUnit().toString(),
+                    arithmetic.getDataType().toCatalogDataType());
+        }
     }
 }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/TimestampArithmetic.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/TimestampArithmetic.java
index 561d969243..ec5c5ce02f 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/TimestampArithmetic.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/TimestampArithmetic.java
@@ -24,6 +24,7 @@ import 
org.apache.doris.nereids.trees.expressions.shape.BinaryExpression;
 import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
 import org.apache.doris.nereids.types.DataType;
 import org.apache.doris.nereids.types.DateTimeType;
+import org.apache.doris.nereids.types.DateType;
 
 import com.google.common.base.Preconditions;
 import org.apache.logging.log4j.LogManager;
@@ -84,7 +85,15 @@ public class TimestampArithmetic extends Expression 
implements BinaryExpression
 
     @Override
     public DataType getDataType() throws UnboundException {
-        return DateTimeType.INSTANCE;
+        int dateChildIndex = 0;
+        if (intervalFirst) {
+            dateChildIndex = 1;
+        }
+        if (child(dateChildIndex).getDataType() instanceof DateTimeType || 
timeUnit.isDateTimeUnit()) {
+            return DateTimeType.INSTANCE;
+        } else {
+            return DateType.INSTANCE;
+        }
     }
 
     public String getFuncName() {
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/IntervalLiteral.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/IntervalLiteral.java
index 8c70ca162c..54da14e3f5 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/IntervalLiteral.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/IntervalLiteral.java
@@ -51,17 +51,25 @@ public class IntervalLiteral extends Expression {
      * Supported time unit.
      */
     public enum TimeUnit {
-        YEAR("YEAR"),                               // YEARS
-        MONTH("MONTH"),                             // MONTHS
-        WEEK("WEEK"),                               // WEEKS
-        DAY("DAY"),                                 // DAYS
-        HOUR("HOUR"),                               // HOURS
-        MINUTE("MINUTE"),                           // MINUTES
-        SECOND("SECOND");                            // SECONDS
+        YEAR("YEAR", false),
+        MONTH("MONTH", false),
+        WEEK("WEEK", false),
+        DAY("DAY", false),
+        HOUR("HOUR", true),
+        MINUTE("MINUTE", true),
+        SECOND("SECOND", true);
+
         private final String description;
 
-        TimeUnit(String description) {
+        private final boolean isDateTimeUnit;
+
+        TimeUnit(String description, boolean isDateTimeUnit) {
             this.description = description;
+            this.isDateTimeUnit = isDateTimeUnit;
+        }
+
+        public boolean isDateTimeUnit() {
+            return isDateTimeUnit;
         }
 
         @Override


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

Reply via email to