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 d80976a6efe [chore](parser) remove useless class TimestampArithmetic
(#59049)
d80976a6efe is described below
commit d80976a6efe6892e9e227b0b1b274a94cb6c27eb
Author: morrySnow <[email protected]>
AuthorDate: Wed Dec 17 10:41:38 2025 +0800
[chore](parser) remove useless class TimestampArithmetic (#59049)
This pull request removes the `TimestampArithmetic` expression node from
the Nereids planner in favor of using unbound function calls for
timestamp arithmetic operations. The changes simplify the codebase by
eliminating the custom handling and pattern matching for
`TimestampArithmetic`, and instead treating timestamp arithmetic as
regular function calls. This affects parsing, analysis, expression
rewriting, statistics estimation, and evaluation.
Key changes include:
**Removal of `TimestampArithmetic` Expression:**
- Deleted the `TimestampArithmetic` class and all related code,
including its visitor methods and pattern matchers.
**Parser and Expression Construction Updates:**
- Updated the parser (`LogicalPlanBuilder`) to construct unbound
function calls (e.g., `YEARS_ADD`, `DAYS_SUB`) instead of
`TimestampArithmetic` nodes for timestamp arithmetic expressions.
**Refactoring and Cleanup:**
- Removed all imports, references, and usages of `TimestampArithmetic`
across the codebase, including in translators, analyzers, statistics,
and expression evaluation.
These changes make timestamp arithmetic handling more uniform and
maintainable by leveraging the function call mechanism already present
in the planner.
---
.../glue/translator/ExpressionTranslator.java | 15 --
.../doris/nereids/parser/LogicalPlanBuilder.java | 13 +-
.../nereids/rules/analysis/ExpressionAnalyzer.java | 28 ----
.../expression/rules/FoldConstantRuleOnFE.java | 12 --
.../doris/nereids/stats/ExpressionEstimation.java | 15 --
.../trees/expressions/ExpressionEvaluator.java | 3 -
.../trees/expressions/TimestampArithmetic.java | 174 ---------------------
.../expressions/visitor/ExpressionVisitor.java | 5 -
.../doris/nereids/util/TypeCoercionUtils.java | 30 ----
.../nereids/rules/expression/FoldConstantTest.java | 82 ----------
.../shape_check/tpcds_sf100/rf_prune/query72.out | 2 +-
.../data/shape_check/tpcds_sf100/shape/query72.out | 2 +-
.../data/shape_check/tpcds_sf1000/hint/query72.out | 2 +-
.../shape_check/tpcds_sf1000/shape/query72.out | 2 +-
.../test_timestamp_arithmetic.groovy | 4 +-
15 files changed, 13 insertions(+), 376 deletions(-)
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 dc62966f6b8..6a5c5703c61 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
@@ -38,7 +38,6 @@ import org.apache.doris.analysis.MatchPredicate;
import org.apache.doris.analysis.OrderByElement;
import org.apache.doris.analysis.SearchPredicate;
import org.apache.doris.analysis.SlotRef;
-import org.apache.doris.analysis.TimestampArithmeticExpr;
import org.apache.doris.analysis.TryCastExpr;
import org.apache.doris.catalog.ArrayType;
import org.apache.doris.catalog.Column;
@@ -78,7 +77,6 @@ import
org.apache.doris.nereids.trees.expressions.OrderExpression;
import org.apache.doris.nereids.trees.expressions.SearchExpression;
import org.apache.doris.nereids.trees.expressions.SessionVarGuardExpr;
import org.apache.doris.nereids.trees.expressions.SlotReference;
-import org.apache.doris.nereids.trees.expressions.TimestampArithmetic;
import org.apache.doris.nereids.trees.expressions.TryCast;
import org.apache.doris.nereids.trees.expressions.UnaryArithmetic;
import org.apache.doris.nereids.trees.expressions.WhenClause;
@@ -111,7 +109,6 @@ import org.apache.doris.nereids.types.DataType;
import org.apache.doris.thrift.TDictFunction;
import org.apache.doris.thrift.TFunctionBinaryType;
-import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
@@ -757,18 +754,6 @@ public class ExpressionTranslator extends
DefaultExpressionVisitor<Expr, PlanTra
return arithmeticExpr;
}
- @Override
- public Expr visitTimestampArithmetic(TimestampArithmetic arithmetic,
PlanTranslatorContext context) {
- Preconditions.checkNotNull(arithmetic.getFuncName(),
- "funcName in TimestampArithmetic should not be null");
- TimestampArithmeticExpr timestampArithmeticExpr = new
TimestampArithmeticExpr(
- arithmetic.getFuncName(), arithmetic.getOp(),
- arithmetic.left().accept(this, context),
arithmetic.right().accept(this, context),
- arithmetic.getTimeUnit().toString(),
arithmetic.getDataType().toCatalogDataType(),
- arithmetic.nullable());
- return timestampArithmeticExpr;
- }
-
@Override
public Expr visitIsNull(IsNull isNull, PlanTranslatorContext context) {
IsNullPredicate isNullPredicate = new
IsNullPredicate(isNull.child().accept(this, context), false);
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java
index f045d79250f..864dea25a4e 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java
@@ -555,7 +555,6 @@ import
org.apache.doris.nereids.trees.expressions.ScalarSubquery;
import org.apache.doris.nereids.trees.expressions.Slot;
import org.apache.doris.nereids.trees.expressions.StatementScopeIdGenerator;
import org.apache.doris.nereids.trees.expressions.Subtract;
-import org.apache.doris.nereids.trees.expressions.TimestampArithmetic;
import org.apache.doris.nereids.trees.expressions.TryCast;
import org.apache.doris.nereids.trees.expressions.WhenClause;
import org.apache.doris.nereids.trees.expressions.WindowExpression;
@@ -2983,20 +2982,22 @@ public class LogicalPlanBuilder extends
DorisParserBaseVisitor<Object> {
throw new ParseException("Only supported: " +
Operator.ADD, ctx);
}
Interval interval = (Interval) left;
- return new TimestampArithmetic(Operator.ADD, right,
interval.value(), interval.timeUnit());
+ String funcOpName = String.format("%sS_ADD",
interval.timeUnit());
+ return new UnboundFunction(funcOpName, ImmutableList.of(right,
interval.value()));
}
if (right instanceof Interval) {
- Operator op;
+ String op;
if (type == DorisParser.PLUS) {
- op = Operator.ADD;
+ op = "ADD";
} else if (type == DorisParser.SUBTRACT) {
- op = Operator.SUBTRACT;
+ op = "SUB";
} else {
throw new ParseException("Only supported: " + Operator.ADD
+ " and " + Operator.SUBTRACT, ctx);
}
Interval interval = (Interval) right;
- return new TimestampArithmetic(op, left, interval.value(),
interval.timeUnit());
+ String funcOpName = String.format("%sS_%s",
interval.timeUnit(), op);
+ return new UnboundFunction(funcOpName, ImmutableList.of(left,
interval.value()));
}
return ParserUtils.withOrigin(ctx, () -> {
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/ExpressionAnalyzer.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/ExpressionAnalyzer.java
index 5dbd43801fb..a4fb7f3ae76 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/ExpressionAnalyzer.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/ExpressionAnalyzer.java
@@ -17,7 +17,6 @@
package org.apache.doris.nereids.rules.analysis;
-import org.apache.doris.analysis.ArithmeticExpr.Operator;
import org.apache.doris.analysis.SetType;
import org.apache.doris.catalog.Env;
import org.apache.doris.catalog.FunctionRegistry;
@@ -66,7 +65,6 @@ import org.apache.doris.nereids.trees.expressions.Or;
import org.apache.doris.nereids.trees.expressions.Placeholder;
import org.apache.doris.nereids.trees.expressions.Slot;
import org.apache.doris.nereids.trees.expressions.SlotReference;
-import org.apache.doris.nereids.trees.expressions.TimestampArithmetic;
import org.apache.doris.nereids.trees.expressions.Variable;
import org.apache.doris.nereids.trees.expressions.WhenClause;
import org.apache.doris.nereids.trees.expressions.WindowExpression;
@@ -121,7 +119,6 @@ import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.List;
-import java.util.Locale;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
@@ -603,31 +600,6 @@ public class ExpressionAnalyzer extends
SubExprAnalyzer<ExpressionRewriteContext
return windowExpression;
}
- /**
- * gets the method for calculating the time.
- * e.g. YEARS_ADD、YEARS_SUB、DAYS_ADD 、DAYS_SUB
- */
- @Override
- public Expression visitTimestampArithmetic(TimestampArithmetic arithmetic,
ExpressionRewriteContext context) {
- Expression left = arithmetic.left().accept(this, context);
- Expression right = arithmetic.right().accept(this, context);
-
- arithmetic = (TimestampArithmetic) arithmetic.withChildren(left,
right);
- // bind function
- String funcOpName;
- if (arithmetic.getFuncName() == null) {
- // e.g. YEARS_ADD, MONTHS_SUB
- funcOpName = String.format("%sS_%s", arithmetic.getTimeUnit(),
- (arithmetic.getOp() == Operator.ADD) ? "ADD" : "SUB");
- } else {
- funcOpName = arithmetic.getFuncName();
- }
- arithmetic = (TimestampArithmetic)
arithmetic.withFuncName(funcOpName.toLowerCase(Locale.ROOT));
-
- // type coercion
- return TypeCoercionUtils.processTimestampArithmetic(arithmetic);
- }
-
/*
********************************************************************************************
* type coercion
*
********************************************************************************************
*/
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/FoldConstantRuleOnFE.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/FoldConstantRuleOnFE.java
index 1560ab55370..14ba60b9d64 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/FoldConstantRuleOnFE.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/FoldConstantRuleOnFE.java
@@ -56,7 +56,6 @@ import org.apache.doris.nereids.trees.expressions.Not;
import org.apache.doris.nereids.trees.expressions.NullSafeEqual;
import org.apache.doris.nereids.trees.expressions.Or;
import org.apache.doris.nereids.trees.expressions.Slot;
-import org.apache.doris.nereids.trees.expressions.TimestampArithmetic;
import org.apache.doris.nereids.trees.expressions.TryCast;
import org.apache.doris.nereids.trees.expressions.Variable;
import org.apache.doris.nereids.trees.expressions.WhenClause;
@@ -178,7 +177,6 @@ public class FoldConstantRuleOnFE extends
AbstractExpressionRewriteRule
matches(If.class, this::visitIf),
matches(InPredicate.class, this::visitInPredicate),
matches(IsNull.class, this::visitIsNull),
- matches(TimestampArithmetic.class,
this::visitTimestampArithmetic),
matches(Password.class, this::visitPassword),
matches(Array.class, this::visitArray),
matches(Date.class, this::visitDate),
@@ -671,16 +669,6 @@ public class FoldConstantRuleOnFE extends
AbstractExpressionRewriteRule
return Literal.of(isNull.child().nullable());
}
- @Override
- public Expression visitTimestampArithmetic(TimestampArithmetic arithmetic,
ExpressionRewriteContext context) {
- arithmetic = rewriteChildren(arithmetic, context);
- Optional<Expression> checkedExpr = preProcess(arithmetic);
- if (checkedExpr.isPresent()) {
- return checkedExpr.get();
- }
- return ExpressionEvaluator.INSTANCE.eval(arithmetic);
- }
-
@Override
public Expression visitPassword(Password password,
ExpressionRewriteContext context) {
Preconditions.checkArgument(password.child(0) instanceof
StringLikeLiteral,
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/stats/ExpressionEstimation.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/stats/ExpressionEstimation.java
index cb3234461b3..a6e620b8efc 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/stats/ExpressionEstimation.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/stats/ExpressionEstimation.java
@@ -17,7 +17,6 @@
package org.apache.doris.nereids.stats;
-import org.apache.doris.analysis.ArithmeticExpr.Operator;
import org.apache.doris.analysis.NumericLiteralExpr;
import org.apache.doris.analysis.StringLiteral;
import org.apache.doris.nereids.exceptions.AnalysisException;
@@ -38,7 +37,6 @@ import org.apache.doris.nereids.trees.expressions.Multiply;
import org.apache.doris.nereids.trees.expressions.Or;
import org.apache.doris.nereids.trees.expressions.SlotReference;
import org.apache.doris.nereids.trees.expressions.Subtract;
-import org.apache.doris.nereids.trees.expressions.TimestampArithmetic;
import org.apache.doris.nereids.trees.expressions.WhenClause;
import org.apache.doris.nereids.trees.expressions.functions.BoundFunction;
import org.apache.doris.nereids.trees.expressions.functions.agg.Avg;
@@ -534,19 +532,6 @@ public class ExpressionEstimation extends
ExpressionVisitor<ColumnStatistic, Sta
return new
ColumnStatisticBuilder(firstChild).setNumNulls(maxNull).setNdv(2).build();
}
- @Override
- public ColumnStatistic visitTimestampArithmetic(TimestampArithmetic
arithmetic, Statistics context) {
- Operator operator = arithmetic.getOp();
- switch (operator) {
- case ADD:
- return dateAdd(arithmetic, context);
- case SUBTRACT:
- return dateSub(arithmetic, context);
- default:
- return arithmetic.left().accept(this, context);
- }
- }
-
@Override
public ColumnStatistic visitMarkJoinReference(
MarkJoinSlotReference markJoinSlotReference, Statistics context) {
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/ExpressionEvaluator.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/ExpressionEvaluator.java
index 96bdb3ba257..17504ceb8e2 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/ExpressionEvaluator.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/ExpressionEvaluator.java
@@ -63,9 +63,6 @@ public enum ExpressionEvaluator {
if (expression instanceof BinaryArithmetic) {
BinaryArithmetic arithmetic = (BinaryArithmetic) expression;
fnName = arithmetic.getLegacyOperator().getName();
- } else if (expression instanceof TimestampArithmetic) {
- TimestampArithmetic arithmetic = (TimestampArithmetic) expression;
- fnName = arithmetic.getFuncName();
} else if (expression instanceof BoundFunction) {
BoundFunction function = ((BoundFunction) expression);
fnName = function.getName();
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
deleted file mode 100644
index c7789b968c6..00000000000
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/TimestampArithmetic.java
+++ /dev/null
@@ -1,174 +0,0 @@
-// 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.nereids.trees.expressions;
-
-import org.apache.doris.analysis.ArithmeticExpr.Operator;
-import org.apache.doris.nereids.exceptions.AnalysisException;
-import org.apache.doris.nereids.exceptions.UnboundException;
-import org.apache.doris.nereids.trees.expressions.functions.PropagateNullable;
-import org.apache.doris.nereids.trees.expressions.literal.Interval.TimeUnit;
-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.DateTimeV2Type;
-import org.apache.doris.nereids.types.DateV2Type;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
-
-import java.util.List;
-import java.util.Objects;
-
-/**
- * Describes the addition and subtraction of time units from timestamps.
- * Arithmetic expressions on timestamps are syntactic sugar.
- * They are executed as function call exprs in the BE.
- * Example: '1996-01-01' + INTERVAL '3' month;
- * TODO: we need to rethink this, and maybe need to add a new type of Interval
then implement IntervalLiteral as others
- */
-public class TimestampArithmetic extends Expression
- implements BinaryExpression, PropagateNullable {
-
- private final String funcName;
- private final Operator op;
- private final TimeUnit timeUnit;
-
- public TimestampArithmetic(Operator op, Expression e1, Expression e2,
TimeUnit timeUnit) {
- this(null, op, e1, e2, timeUnit);
- }
-
- /**
- * Full parameter constructor.
- */
- public TimestampArithmetic(String funcName, Operator op, Expression e1,
Expression e2, TimeUnit timeUnit) {
- super(ImmutableList.of(e1, e2));
- Preconditions.checkState(op == Operator.ADD || op ==
Operator.SUBTRACT);
- this.funcName = funcName;
- this.op = op;
- this.timeUnit = timeUnit;
- }
-
- @Override
- public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
- return visitor.visitTimestampArithmetic(this, context);
- }
-
- @Override
- public TimestampArithmetic withChildren(List<Expression> children) {
- Preconditions.checkArgument(children.size() == 2);
- return new TimestampArithmetic(this.funcName, this.op,
children.get(0), children.get(1),
- this.timeUnit);
- }
-
- public Expression withFuncName(String funcName) {
- return new TimestampArithmetic(funcName, this.op, children.get(0),
children.get(1), this.timeUnit);
- }
-
- @Override
- public DataType getDataType() throws UnboundException {
- DataType childType = child(0).getDataType();
- if (childType instanceof DateTimeV2Type) {
- return childType;
- }
- // datev2
- if (timeUnit.isDateTimeUnit()) {
- return DateTimeV2Type.SYSTEM_DEFAULT;
- }
- return DateV2Type.INSTANCE;
- }
-
- public String getFuncName() {
- return funcName;
- }
-
- public Operator getOp() {
- return op;
- }
-
- public TimeUnit getTimeUnit() {
- return timeUnit;
- }
-
- @Override
- public void checkLegalityBeforeTypeCoercion() {
- children().forEach(c -> {
- if (c.getDataType().isObjectType()) {
- throw new AnalysisException("timestamp arithmetic could not
contains object type: " + this.toSql());
- }
- if (c.getDataType().isComplexType()) {
- throw new AnalysisException("timestamp arithmetic could not
contains complex type: " + this.toSql());
- }
- });
- }
-
- @Override
- public String toString() {
- return toSql();
- }
-
- @Override
- public String toDigest() {
- StringBuilder sb = new StringBuilder();
- if (funcName != null) {
- sb.append(funcName.toUpperCase()).append("(");
- sb.append(child(0).toDigest()).append(", ");
- sb.append(child(1).toDigest()).append(")");
- } else {
- sb.append(child(0).toDigest());
- sb.append(" ").append(op.toString()).append(" ");
- sb.append(child(1).toDigest());
- }
- return sb.toString();
- }
-
- @Override
- public String computeToSql() {
- StringBuilder strBuilder = new StringBuilder();
- if (funcName != null) {
- // Function-call like version.
- strBuilder.append(funcName).append("(");
- strBuilder.append(child(0).toSql()).append(", ");
- strBuilder.append("INTERVAL ");
- strBuilder.append(child(1).toSql());
- strBuilder.append(" ").append(timeUnit);
- strBuilder.append(")");
- return strBuilder.toString();
- }
- // Non-function-call like version with interval as second operand.
- strBuilder.append(child(0).toSql());
- strBuilder.append(" ").append(op.toString()).append(" ");
- strBuilder.append("INTERVAL ");
- strBuilder.append(child(1).toSql()).append(" ");
- strBuilder.append(timeUnit);
- return strBuilder.toString();
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- TimestampArithmetic other = (TimestampArithmetic) o;
- return Objects.equals(funcName, other.funcName) &&
Objects.equals(timeUnit, other.timeUnit)
- && op.equals(other.op)
- && Objects.equals(left(), other.left()) &&
Objects.equals(right(), other.right());
- }
-}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ExpressionVisitor.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ExpressionVisitor.java
index 420c61d6c9c..0b0c85d34c5 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ExpressionVisitor.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ExpressionVisitor.java
@@ -78,7 +78,6 @@ import org.apache.doris.nereids.trees.expressions.Slot;
import org.apache.doris.nereids.trees.expressions.SlotReference;
import org.apache.doris.nereids.trees.expressions.SubqueryExpr;
import org.apache.doris.nereids.trees.expressions.Subtract;
-import org.apache.doris.nereids.trees.expressions.TimestampArithmetic;
import org.apache.doris.nereids.trees.expressions.TryCast;
import org.apache.doris.nereids.trees.expressions.UnaryArithmetic;
import org.apache.doris.nereids.trees.expressions.UnaryOperator;
@@ -456,10 +455,6 @@ public abstract class ExpressionVisitor<R, C>
return visit(subqueryExpr, context);
}
- public R visitTimestampArithmetic(TimestampArithmetic arithmetic, C
context) {
- return visit(arithmetic, context);
- }
-
public R visitScalarSubquery(ScalarSubquery scalar, C context) {
return visitSubqueryExpr(scalar, context);
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/TypeCoercionUtils.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/TypeCoercionUtils.java
index 0e1689caf72..641dd4f76dc 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/TypeCoercionUtils.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/TypeCoercionUtils.java
@@ -17,8 +17,6 @@
package org.apache.doris.nereids.util;
-import org.apache.doris.catalog.Env;
-import org.apache.doris.catalog.FunctionSignature;
import org.apache.doris.common.Pair;
import org.apache.doris.nereids.annotation.Developing;
import org.apache.doris.nereids.exceptions.AnalysisException;
@@ -43,9 +41,7 @@ import org.apache.doris.nereids.trees.expressions.Mod;
import org.apache.doris.nereids.trees.expressions.Multiply;
import org.apache.doris.nereids.trees.expressions.SubqueryExpr;
import org.apache.doris.nereids.trees.expressions.Subtract;
-import org.apache.doris.nereids.trees.expressions.TimestampArithmetic;
import org.apache.doris.nereids.trees.expressions.functions.BoundFunction;
-import org.apache.doris.nereids.trees.expressions.functions.FunctionBuilder;
import
org.apache.doris.nereids.trees.expressions.functions.executable.DateTimeExtractAndTransform;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Array;
import org.apache.doris.nereids.trees.expressions.functions.scalar.CreateMap;
@@ -941,32 +937,6 @@ public class TypeCoercionUtils {
return castChildren(binaryArithmetic, left, right,
commonType.promotion());
}
- /**
- * process timestamp arithmetic type coercion.
- */
- public static Expression processTimestampArithmetic(TimestampArithmetic
timestampArithmetic) {
- timestampArithmetic.checkLegalityBeforeTypeCoercion();
-
- String name = timestampArithmetic.getFuncName().toLowerCase();
- List<Expression> children = timestampArithmetic.children();
- Expression left = timestampArithmetic.left();
- Expression right = timestampArithmetic.right();
-
- // get right signature by normal function resolution
- FunctionBuilder functionBuilder =
Env.getCurrentEnv().getFunctionRegistry().findFunctionBuilder(name,
- children);
- Pair<? extends Expression, ? extends BoundFunction>
targetExpressionPair = functionBuilder.build(name,
- children);
- FunctionSignature signature =
targetExpressionPair.second.getSignature();
- DataType leftType = signature.getArgType(0);
- DataType rightType = signature.getArgType(1);
-
- left = castIfNotSameType(left, leftType);
- right = castIfNotSameType(right, rightType);
-
- return timestampArithmetic.withChildren(left, right);
- }
-
/**
* left type must be DateType or DateV2Type.
*/
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/FoldConstantTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/FoldConstantTest.java
index e35312aa1f3..0cd32e91710 100644
---
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/FoldConstantTest.java
+++
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/FoldConstantTest.java
@@ -17,7 +17,6 @@
package org.apache.doris.nereids.rules.expression;
-import org.apache.doris.analysis.ArithmeticExpr.Operator;
import org.apache.doris.nereids.analyzer.UnboundRelation;
import org.apache.doris.nereids.exceptions.AnalysisException;
import org.apache.doris.nereids.exceptions.NotSupportedException;
@@ -36,7 +35,6 @@ import org.apache.doris.nereids.trees.expressions.Multiply;
import org.apache.doris.nereids.trees.expressions.Slot;
import org.apache.doris.nereids.trees.expressions.SlotReference;
import org.apache.doris.nereids.trees.expressions.Subtract;
-import org.apache.doris.nereids.trees.expressions.TimestampArithmetic;
import
org.apache.doris.nereids.trees.expressions.functions.executable.DateTimeArithmetic;
import
org.apache.doris.nereids.trees.expressions.functions.executable.DateTimeExtractAndTransform;
import
org.apache.doris.nereids.trees.expressions.functions.executable.TimeRoundSeries;
@@ -114,7 +112,6 @@ import
org.apache.doris.nereids.trees.expressions.literal.DecimalV3Literal;
import org.apache.doris.nereids.trees.expressions.literal.DoubleLiteral;
import org.apache.doris.nereids.trees.expressions.literal.FloatLiteral;
import org.apache.doris.nereids.trees.expressions.literal.IntegerLiteral;
-import org.apache.doris.nereids.trees.expressions.literal.Interval.TimeUnit;
import org.apache.doris.nereids.trees.expressions.literal.Literal;
import org.apache.doris.nereids.trees.expressions.literal.NullLiteral;
import org.apache.doris.nereids.trees.expressions.literal.StringLiteral;
@@ -137,7 +134,6 @@ import org.junit.jupiter.api.Test;
import java.math.BigDecimal;
import java.time.LocalDateTime;
-import java.util.Locale;
class FoldConstantTest extends ExpressionRewriteTestHelper {
@@ -1163,84 +1159,6 @@ class FoldConstantTest extends
ExpressionRewriteTestHelper {
assertRewrite(one, one);
}
- @Test
- void testTimestampFold() {
- executor = new ExpressionRuleExecutor(ImmutableList.of(
- bottomUp(FoldConstantRuleOnFE.VISITOR_INSTANCE)
- ));
- String interval = "'1991-05-01' - interval 1 day";
- Expression e7 = process((TimestampArithmetic)
PARSER.parseExpression(interval));
- Expression e8 = new DateV2Literal(1991, 4, 30);
- assertRewrite(e7, e8);
-
- interval = "'1991-05-01' + interval '1' day";
- e7 = process((TimestampArithmetic) PARSER.parseExpression(interval));
- e8 = new DateV2Literal(1991, 5, 2);
- assertRewrite(e7, e8);
-
- interval = "'1991-05-01' + interval 1+1 day";
- e7 = process((TimestampArithmetic) PARSER.parseExpression(interval));
- e8 = new DateV2Literal(1991, 5, 3);
- assertRewrite(e7, e8);
-
- interval = "date '1991-05-01' + interval 10 / 2 + 1 day";
- e7 = process((TimestampArithmetic) PARSER.parseExpression(interval));
- e8 = new DateV2Literal(1991, 5, 7);
- assertRewrite(e7, e8);
-
- interval = "interval '1' day + '1991-05-01'";
- e7 = process((TimestampArithmetic) PARSER.parseExpression(interval));
- e8 = new DateV2Literal(1991, 5, 2);
- assertRewrite(e7, e8);
-
- interval = "interval '3' month + '1991-05-01'";
- e7 = process((TimestampArithmetic) PARSER.parseExpression(interval));
- e8 = new DateV2Literal(1991, 8, 1);
- assertRewrite(e7, e8);
-
- interval = "interval 3 + 1 month + '1991-05-01'";
- e7 = process((TimestampArithmetic) PARSER.parseExpression(interval));
- e8 = new DateV2Literal(1991, 9, 1);
- assertRewrite(e7, e8);
-
- interval = "interval 3 + 1 year + '1991-05-01'";
- e7 = process((TimestampArithmetic) PARSER.parseExpression(interval));
- e8 = new DateV2Literal(1995, 5, 1);
- assertRewrite(e7, e8);
-
- interval = "interval 3 + 3 / 3 hour + '1991-05-01 10:00:00'";
- e7 = process((TimestampArithmetic) PARSER.parseExpression(interval));
- e8 = new DateTimeV2Literal(1991, 5, 1, 14, 0, 0);
- assertRewrite(e7, e8);
-
- interval = "interval 3 * 2 / 3 minute + '1991-05-01 10:00:00'";
- e7 = process((TimestampArithmetic) PARSER.parseExpression(interval));
- e8 = new DateTimeV2Literal(1991, 5, 1, 10, 2, 0);
- assertRewrite(e7, e8);
-
- interval = "interval 3 / 3 + 1 second + '1991-05-01 10:00:00'";
- e7 = process((TimestampArithmetic) PARSER.parseExpression(interval));
- e8 = new DateTimeV2Literal(1991, 5, 1, 10, 0, 2);
- assertRewrite(e7, e8);
-
- // a + interval 1 day
- Slot a = SlotReference.of("a", DateTimeV2Type.SYSTEM_DEFAULT);
- TimestampArithmetic arithmetic = new TimestampArithmetic(Operator.ADD,
a, Literal.of(1), TimeUnit.DAY);
- Expression process = process(arithmetic);
- assertRewrite(process, process);
- }
-
- Expression process(TimestampArithmetic arithmetic) {
- String funcOpName;
- if (arithmetic.getFuncName() == null) {
- funcOpName = String.format("%sS_%s", arithmetic.getTimeUnit(),
- (arithmetic.getOp() == Operator.ADD) ? "ADD" : "SUB");
- } else {
- funcOpName = arithmetic.getFuncName();
- }
- return arithmetic.withFuncName(funcOpName.toLowerCase(Locale.ROOT));
- }
-
@Test
void testDateV2TypeDateTimeArithmeticFunctions() {
DateV2Literal dateLiteral = new DateV2Literal("1999-12-31");
diff --git a/regression-test/data/shape_check/tpcds_sf100/rf_prune/query72.out
b/regression-test/data/shape_check/tpcds_sf100/rf_prune/query72.out
index 6b1d29b746c..972612d05e0 100644
--- a/regression-test/data/shape_check/tpcds_sf100/rf_prune/query72.out
+++ b/regression-test/data/shape_check/tpcds_sf100/rf_prune/query72.out
@@ -21,7 +21,7 @@ PhysicalResultSink
----------------------------------PhysicalProject
------------------------------------hashJoin[INNER_JOIN shuffle]
hashCondition=((item.i_item_sk = catalog_sales.cs_item_sk)) otherCondition=()
--------------------------------------PhysicalProject
-----------------------------------------hashJoin[INNER_JOIN broadcast]
hashCondition=((catalog_sales.cs_ship_date_sk = d3.d_date_sk))
otherCondition=((d3.d_date > days_add(d_date, INTERVAL 5 DAY)))
+----------------------------------------hashJoin[INNER_JOIN broadcast]
hashCondition=((catalog_sales.cs_ship_date_sk = d3.d_date_sk))
otherCondition=((d3.d_date > days_add(d_date, 5)))
------------------------------------------PhysicalProject
--------------------------------------------hashJoin[INNER_JOIN broadcast]
hashCondition=((catalog_sales.cs_bill_cdemo_sk =
customer_demographics.cd_demo_sk)) otherCondition=() build RFs:RF2
cd_demo_sk->[cs_bill_cdemo_sk]
----------------------------------------------PhysicalProject
diff --git a/regression-test/data/shape_check/tpcds_sf100/shape/query72.out
b/regression-test/data/shape_check/tpcds_sf100/shape/query72.out
index a1148117340..de210e70c05 100644
--- a/regression-test/data/shape_check/tpcds_sf100/shape/query72.out
+++ b/regression-test/data/shape_check/tpcds_sf100/shape/query72.out
@@ -21,7 +21,7 @@ PhysicalResultSink
----------------------------------PhysicalProject
------------------------------------hashJoin[INNER_JOIN shuffle]
hashCondition=((item.i_item_sk = catalog_sales.cs_item_sk)) otherCondition=()
build RFs:RF4 i_item_sk->[cs_item_sk]
--------------------------------------PhysicalProject
-----------------------------------------hashJoin[INNER_JOIN broadcast]
hashCondition=((catalog_sales.cs_ship_date_sk = d3.d_date_sk))
otherCondition=((d3.d_date > days_add(d_date, INTERVAL 5 DAY))) build RFs:RF3
d_date_sk->[cs_ship_date_sk]
+----------------------------------------hashJoin[INNER_JOIN broadcast]
hashCondition=((catalog_sales.cs_ship_date_sk = d3.d_date_sk))
otherCondition=((d3.d_date > days_add(d_date, 5))) build RFs:RF3
d_date_sk->[cs_ship_date_sk]
------------------------------------------PhysicalProject
--------------------------------------------hashJoin[INNER_JOIN broadcast]
hashCondition=((catalog_sales.cs_bill_cdemo_sk =
customer_demographics.cd_demo_sk)) otherCondition=() build RFs:RF2
cd_demo_sk->[cs_bill_cdemo_sk]
----------------------------------------------PhysicalProject
diff --git a/regression-test/data/shape_check/tpcds_sf1000/hint/query72.out
b/regression-test/data/shape_check/tpcds_sf1000/hint/query72.out
index 33094a1fc42..0ce74757cb9 100644
--- a/regression-test/data/shape_check/tpcds_sf1000/hint/query72.out
+++ b/regression-test/data/shape_check/tpcds_sf1000/hint/query72.out
@@ -31,7 +31,7 @@ PhysicalResultSink
--------------------------------------------------PhysicalProject
----------------------------------------------------PhysicalOlapScan[catalog_sales]
apply RFs: RF0 RF1 RF2 RF3 RF4
--------------------------------------------------PhysicalProject
-----------------------------------------------------NestedLoopJoin[INNER_JOIN](d3.d_date
> days_add(d_date, INTERVAL 5 DAY))
+----------------------------------------------------NestedLoopJoin[INNER_JOIN](d3.d_date
> days_add(d_date, 5))
------------------------------------------------------PhysicalProject
--------------------------------------------------------PhysicalOlapScan[date_dim(d3)]
------------------------------------------------------PhysicalProject
diff --git a/regression-test/data/shape_check/tpcds_sf1000/shape/query72.out
b/regression-test/data/shape_check/tpcds_sf1000/shape/query72.out
index 316fa087d86..92fd2650882 100644
--- a/regression-test/data/shape_check/tpcds_sf1000/shape/query72.out
+++ b/regression-test/data/shape_check/tpcds_sf1000/shape/query72.out
@@ -30,7 +30,7 @@ PhysicalResultSink
--------------------------------------------------PhysicalProject
----------------------------------------------------PhysicalOlapScan[catalog_sales]
apply RFs: RF0 RF1 RF2 RF3 RF7 RF9
--------------------------------------------------PhysicalProject
-----------------------------------------------------NestedLoopJoin[INNER_JOIN](d3.d_date
> days_add(d_date, INTERVAL 5 DAY))
+----------------------------------------------------NestedLoopJoin[INNER_JOIN](d3.d_date
> days_add(d_date, 5))
------------------------------------------------------PhysicalProject
--------------------------------------------------------PhysicalOlapScan[date_dim(d3)]
------------------------------------------------------PhysicalProject
diff --git
a/regression-test/suites/nereids_syntax_p0/test_timestamp_arithmetic.groovy
b/regression-test/suites/nereids_syntax_p0/test_timestamp_arithmetic.groovy
index fed30af473a..aafbf160743 100644
--- a/regression-test/suites/nereids_syntax_p0/test_timestamp_arithmetic.groovy
+++ b/regression-test/suites/nereids_syntax_p0/test_timestamp_arithmetic.groovy
@@ -22,12 +22,12 @@ suite("nereids_timestamp_arithmetic") {
test {
sql = "select bitmap_empty() + interval 1 year;"
- exception = "timestamp arithmetic could not contains object type"
+ exception = " Can not find the compatibility function signature:
years_add(BITMAP, TINYINT)"
}
test {
sql = "select date '20200808' + interval array() day;"
- exception = "timestamp arithmetic could not contains complex type"
+ exception = "Can not find the compatibility function signature:
days_add(DATEV2, ARRAY<NULL>)"
}
sql """
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]