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]