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 47a6373e0a [feature](Nereids) support datev2 and datetimev2 type 
(#14263)
47a6373e0a is described below

commit 47a6373e0a56046d55fc97296680c8b616d2221b
Author: morrySnow <101034200+morrys...@users.noreply.github.com>
AuthorDate: Wed Nov 16 15:51:48 2022 +0800

    [feature](Nereids) support datev2 and datetimev2 type (#14263)
    
    1. split DateLiteral and DateTimeLiteral into V1 and V2
    2. add a type coercion about DateLikeType: DateTimeV2Type > DateTimeType > 
DateV2Type > DateType
    3. add a rule to remove unnecessary CAST on DateLikeType in 
ComparisonPredicate
---
 .../expression/rewrite/ExpressionOptimization.java |   4 +-
 .../rewrite/rules/SimplifyComparisonPredicate.java | 140 +++++++++++++++++++++
 .../trees/expressions/literal/DateLiteral.java     |  45 ++++---
 .../trees/expressions/literal/DateTimeLiteral.java |  68 ++++++----
 .../expressions/literal/DateTimeV2Literal.java     |  89 +++++++++++++
 .../trees/expressions/literal/DateV2Literal.java   |  49 ++++++++
 .../apache/doris/nereids/types/DateTimeType.java   |   4 +-
 .../apache/doris/nereids/types/DateTimeV2Type.java |   4 +-
 .../org/apache/doris/nereids/types/DateType.java   |   4 +-
 .../org/apache/doris/nereids/types/DateV2Type.java |   4 +-
 .../{DateType.java => coercion/DateLikeType.java}  |  27 +---
 .../doris/nereids/util/TypeCoercionUtils.java      |  19 +++
 .../expression/rewrite/ExpressionRewriteTest.java  |  76 +++++++++++
 13 files changed, 457 insertions(+), 76 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/ExpressionOptimization.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/ExpressionOptimization.java
index be0e7f0763..973af7ab72 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/ExpressionOptimization.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/ExpressionOptimization.java
@@ -19,6 +19,7 @@ package org.apache.doris.nereids.rules.expression.rewrite;
 
 import 
org.apache.doris.nereids.rules.expression.rewrite.rules.DistinctPredicatesRule;
 import 
org.apache.doris.nereids.rules.expression.rewrite.rules.ExtractCommonFactorRule;
+import 
org.apache.doris.nereids.rules.expression.rewrite.rules.SimplifyComparisonPredicate;
 
 import com.google.common.collect.ImmutableList;
 
@@ -30,7 +31,8 @@ import java.util.List;
 public class ExpressionOptimization extends ExpressionRewrite {
     public static final List<ExpressionRewriteRule> OPTIMIZE_REWRITE_RULES = 
ImmutableList.of(
             ExtractCommonFactorRule.INSTANCE,
-            DistinctPredicatesRule.INSTANCE);
+            DistinctPredicatesRule.INSTANCE,
+            SimplifyComparisonPredicate.INSTANCE);
     private static final ExpressionRuleExecutor EXECUTOR = new 
ExpressionRuleExecutor(OPTIMIZE_REWRITE_RULES);
 
     public ExpressionOptimization() {
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/rules/SimplifyComparisonPredicate.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/rules/SimplifyComparisonPredicate.java
new file mode 100644
index 0000000000..c96b924e2c
--- /dev/null
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/rules/SimplifyComparisonPredicate.java
@@ -0,0 +1,140 @@
+// 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.rules.expression.rewrite.rules;
+
+import 
org.apache.doris.nereids.rules.expression.rewrite.AbstractExpressionRewriteRule;
+import 
org.apache.doris.nereids.rules.expression.rewrite.ExpressionRewriteContext;
+import org.apache.doris.nereids.trees.expressions.Cast;
+import org.apache.doris.nereids.trees.expressions.ComparisonPredicate;
+import org.apache.doris.nereids.trees.expressions.EqualTo;
+import org.apache.doris.nereids.trees.expressions.Expression;
+import org.apache.doris.nereids.trees.expressions.GreaterThan;
+import org.apache.doris.nereids.trees.expressions.GreaterThanEqual;
+import org.apache.doris.nereids.trees.expressions.LessThan;
+import org.apache.doris.nereids.trees.expressions.LessThanEqual;
+import org.apache.doris.nereids.trees.expressions.literal.DateLiteral;
+import org.apache.doris.nereids.trees.expressions.literal.DateTimeLiteral;
+import org.apache.doris.nereids.trees.expressions.literal.DateTimeV2Literal;
+import org.apache.doris.nereids.trees.expressions.literal.DateV2Literal;
+import org.apache.doris.nereids.types.DateTimeType;
+import org.apache.doris.nereids.types.DateType;
+import org.apache.doris.nereids.types.DateV2Type;
+import org.apache.doris.nereids.types.coercion.DateLikeType;
+
+/**
+ * simplify comparison
+ * such as: cast(c1 as DateV2) >= DateV2Literal --> c1 >= DateLiteral
+ */
+public class SimplifyComparisonPredicate extends AbstractExpressionRewriteRule 
{
+
+    public static SimplifyComparisonPredicate INSTANCE = new 
SimplifyComparisonPredicate();
+
+    enum AdjustType {
+        LOWER,
+        UPPER,
+        NONE
+    }
+
+    @Override
+    public Expression visitComparisonPredicate(ComparisonPredicate cp, 
ExpressionRewriteContext context) {
+        Expression left = rewrite(cp.left(), context);
+        Expression right = rewrite(cp.right(), context);
+
+        // date like type
+        if (left.getDataType() instanceof DateLikeType && right.getDataType() 
instanceof DateLikeType) {
+            return processDateLikeTypeCoercion(cp, left, right);
+        }
+
+        if (left != cp.left() || right != cp.right()) {
+            return cp.withChildren(left, right);
+        } else {
+            return cp;
+        }
+    }
+
+    private Expression processDateLikeTypeCoercion(ComparisonPredicate cp, 
Expression left, Expression right) {
+        if (left instanceof DateLiteral) {
+            cp = cp.commute();
+            Expression temp = left;
+            left = right;
+            right = temp;
+        }
+
+        if (left instanceof Cast && right instanceof DateLiteral) {
+            Cast cast = (Cast) left;
+            if (cast.child().getDataType() instanceof DateTimeType) {
+                if (right instanceof DateTimeV2Literal) {
+                    left = cast.child();
+                    right = migrateToDateTime((DateTimeV2Literal) right);
+                }
+            }
+            // datetime to datev2
+            if (cast.child().getDataType() instanceof DateType || 
cast.child().getDataType() instanceof DateV2Type) {
+                if (right instanceof DateTimeLiteral) {
+                    if (cannotAdjust((DateTimeLiteral) right, cp)) {
+                        return cp;
+                    }
+                    AdjustType type = AdjustType.NONE;
+                    if (cp instanceof GreaterThanEqual || cp instanceof 
LessThan) {
+                        type = AdjustType.UPPER;
+                    } else if (cp instanceof GreaterThan || cp instanceof 
LessThanEqual) {
+                        type = AdjustType.LOWER;
+                    }
+                    right = migrateToDateV2((DateTimeLiteral) right, type);
+                    if (cast.child().getDataType() instanceof DateV2Type) {
+                        left = cast.child();
+                    }
+                }
+            }
+
+            // datev2 to date
+            if (cast.child().getDataType() instanceof DateType) {
+                if (right instanceof DateV2Literal) {
+                    left = cast.child();
+                    right = migrateToDate((DateV2Literal) right);
+                }
+            }
+        }
+
+        if (left != cp.left() || right != cp.right()) {
+            return cp.withChildren(left, right);
+        } else {
+            return cp;
+        }
+    }
+
+    private Expression migrateToDateTime(DateTimeV2Literal l) {
+        return new DateTimeLiteral(l.getYear(), l.getMonth(), l.getDay(), 
l.getHour(), l.getMinute(), l.getSecond());
+    }
+
+    private boolean cannotAdjust(DateTimeLiteral l, ComparisonPredicate cp) {
+        return cp instanceof EqualTo && (l.getHour() != 0 || l.getMinute() != 
0 || l.getSecond() != 0);
+    }
+
+    private Expression migrateToDateV2(DateTimeLiteral l, AdjustType type) {
+        DateV2Literal d = new DateV2Literal(l.getYear(), l.getMonth(), 
l.getDay());
+        if (type == AdjustType.UPPER) {
+            d = d.plusDays(1);
+        }
+        return d;
+    }
+
+    private Expression migrateToDate(DateV2Literal l) {
+        return new DateLiteral(l.getYear(), l.getMonth(), l.getDay());
+    }
+}
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DateLiteral.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DateLiteral.java
index e3093c2a09..9a83db217a 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DateLiteral.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DateLiteral.java
@@ -18,11 +18,12 @@
 package org.apache.doris.nereids.trees.expressions.literal;
 
 import org.apache.doris.analysis.LiteralExpr;
-import org.apache.doris.catalog.ScalarType;
+import org.apache.doris.catalog.Type;
 import org.apache.doris.nereids.exceptions.AnalysisException;
 import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
 import org.apache.doris.nereids.types.DataType;
 import org.apache.doris.nereids.types.DateType;
+import org.apache.doris.nereids.types.coercion.DateLikeType;
 import org.apache.doris.nereids.util.DateUtils;
 
 import org.apache.logging.log4j.LogManager;
@@ -35,14 +36,13 @@ import org.joda.time.format.DateTimeFormatter;
  */
 public class DateLiteral extends Literal {
 
-    private static final Logger LOG = LogManager.getLogger(DateLiteral.class);
+    protected static DateTimeFormatter DATE_FORMATTER = null;
+    protected static DateTimeFormatter DATE_FORMATTER_TWO_DIGIT = null;
+    protected static DateTimeFormatter DATEKEY_FORMATTER = null;
 
+    private static final Logger LOG = LogManager.getLogger(DateLiteral.class);
     private static final int DATEKEY_LENGTH = 8;
 
-    private static DateTimeFormatter DATE_FORMATTER = null;
-    private static DateTimeFormatter DATE_FORMATTER_TWO_DIGIT = null;
-    private static DateTimeFormatter DATEKEY_FORMATTER = null;
-
     protected long year;
     protected long month;
     protected long day;
@@ -59,7 +59,11 @@ public class DateLiteral extends Literal {
     }
 
     public DateLiteral(String s) throws AnalysisException {
-        super(DataType.fromCatalogType(ScalarType.createDateType()));
+        this(DateType.INSTANCE, s);
+    }
+
+    protected DateLiteral(DateLikeType dataType, String s) throws 
AnalysisException {
+        super(dataType);
         init(s);
     }
 
@@ -71,7 +75,14 @@ public class DateLiteral extends Literal {
      * C'tor for date type.
      */
     public DateLiteral(long year, long month, long day) {
-        super(DateType.INSTANCE);
+        this(DateType.INSTANCE, year, month, day);
+    }
+
+    /**
+     * C'tor for date type.
+     */
+    public DateLiteral(DateLikeType dataType, long year, long month, long day) 
{
+        super(dataType);
         this.year = year;
         this.month = month;
         this.day = day;
@@ -87,7 +98,7 @@ public class DateLiteral extends Literal {
         this.day = other.day;
     }
 
-    private void init(String s) throws AnalysisException {
+    protected void init(String s) throws AnalysisException {
         try {
             LocalDateTime dateTime;
             if (s.split("-")[0].length() == 2) {
@@ -106,13 +117,13 @@ public class DateLiteral extends Literal {
     }
 
     @Override
-    public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
-        return visitor.visitDateLiteral(this, context);
+    public Long getValue() {
+        return (year * 10000 + month * 100 + day) * 1000000L;
     }
 
     @Override
-    public Long getValue() {
-        return (year * 10000 + month * 100 + day) * 1000000L;
+    public String getStringValue() {
+        return String.format("%04d-%02d-%02d", year, month, day);
     }
 
     @Override
@@ -121,18 +132,18 @@ public class DateLiteral extends Literal {
     }
 
     @Override
-    public String toString() {
-        return String.format("%04d-%02d-%02d", year, month, day);
+    public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
+        return visitor.visitDateLiteral(this, context);
     }
 
     @Override
-    public String getStringValue() {
+    public String toString() {
         return String.format("%04d-%02d-%02d", year, month, day);
     }
 
     @Override
     public LiteralExpr toLegacyLiteral() {
-        return new org.apache.doris.analysis.DateLiteral(year, month, day);
+        return new org.apache.doris.analysis.DateLiteral(year, month, day, 
Type.DATE);
     }
 
     public long getYear() {
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DateTimeLiteral.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DateTimeLiteral.java
index 5b62296057..a2211d5c8f 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DateTimeLiteral.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DateTimeLiteral.java
@@ -18,9 +18,11 @@
 package org.apache.doris.nereids.trees.expressions.literal;
 
 import org.apache.doris.analysis.LiteralExpr;
+import org.apache.doris.catalog.Type;
 import org.apache.doris.nereids.exceptions.AnalysisException;
 import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
 import org.apache.doris.nereids.types.DateTimeType;
+import org.apache.doris.nereids.types.coercion.DateLikeType;
 import org.apache.doris.nereids.util.DateUtils;
 
 import org.apache.logging.log4j.LogManager;
@@ -34,20 +36,21 @@ import java.util.Objects;
  * date time literal.
  */
 public class DateTimeLiteral extends DateLiteral {
-    private static final Logger LOG = 
LogManager.getLogger(DateTimeLiteral.class);
 
-    private static final int DATETIME_TO_MINUTE_STRING_LENGTH = 16;
-    private static final int DATETIME_TO_HOUR_STRING_LENGTH = 13;
-    private static final int DATETIME_DEFAULT_STRING_LENGTH = 10;
-    private static DateTimeFormatter DATE_TIME_DEFAULT_FORMATTER = null;
-    private static DateTimeFormatter DATE_TIME_FORMATTER = null;
-    private static DateTimeFormatter DATE_TIME_FORMATTER_TO_HOUR = null;
-    private static DateTimeFormatter DATE_TIME_FORMATTER_TO_MINUTE = null;
-    private static DateTimeFormatter DATE_TIME_FORMATTER_TWO_DIGIT = null;
+    protected static final int DATETIME_TO_MINUTE_STRING_LENGTH = 16;
+    protected static final int DATETIME_TO_HOUR_STRING_LENGTH = 13;
+    protected static final int DATETIME_DEFAULT_STRING_LENGTH = 10;
+    protected static DateTimeFormatter DATE_TIME_DEFAULT_FORMATTER = null;
+    protected static DateTimeFormatter DATE_TIME_FORMATTER = null;
+    protected static DateTimeFormatter DATE_TIME_FORMATTER_TO_HOUR = null;
+    protected static DateTimeFormatter DATE_TIME_FORMATTER_TO_MINUTE = null;
+    protected static DateTimeFormatter DATE_TIME_FORMATTER_TWO_DIGIT = null;
+
+    private static final Logger LOG = 
LogManager.getLogger(DateTimeLiteral.class);
 
-    private long hour;
-    private long minute;
-    private long second;
+    protected long hour;
+    protected long minute;
+    protected long second;
 
     static {
         try {
@@ -63,7 +66,11 @@ public class DateTimeLiteral extends DateLiteral {
     }
 
     public DateTimeLiteral(String s) {
-        super(DateTimeType.INSTANCE);
+        this(DateTimeType.INSTANCE, s);
+    }
+
+    protected DateTimeLiteral(DateLikeType dataType, String s) {
+        super(dataType);
         init(s);
     }
 
@@ -71,7 +78,15 @@ public class DateTimeLiteral extends DateLiteral {
      * C'tor data time literal.
      */
     public DateTimeLiteral(long year, long month, long day, long hour, long 
minute, long second) {
-        super(DateTimeType.INSTANCE);
+        this(DateTimeType.INSTANCE, year, month, day, hour, minute, second);
+    }
+
+    /**
+     * C'tor data time literal.
+     */
+    public DateTimeLiteral(DateLikeType dataType, long year, long month, long 
day,
+            long hour, long minute, long second) {
+        super(dataType);
         this.hour = hour;
         this.minute = minute;
         this.second = second;
@@ -80,7 +95,8 @@ public class DateTimeLiteral extends DateLiteral {
         this.day = day;
     }
 
-    private void init(String s) throws AnalysisException {
+    @Override
+    protected void init(String s) throws AnalysisException {
         try {
             LocalDateTime dateTime;
             if (s.split("-")[0].length() == 2) {
@@ -132,20 +148,25 @@ public class DateTimeLiteral extends DateLiteral {
         return String.format("%04d-%02d-%02d %02d:%02d:%02d", year, month, 
day, hour, minute, second);
     }
 
-    public DateTimeLiteral plusYears(int years) {
-        LocalDateTime d = LocalDateTime.parse(getStringValue(), 
DATE_TIME_FORMATTER).plusYears(years);
+    @Override
+    public LiteralExpr toLegacyLiteral() {
+        return new org.apache.doris.analysis.DateLiteral(year, month, day, 
hour, minute, second, Type.DATETIME);
+    }
+
+    public DateTimeLiteral plusDays(int days) {
+        LocalDateTime d = LocalDateTime.parse(getStringValue(), 
DATE_TIME_FORMATTER).plusDays(days);
         return new DateTimeLiteral(d.getYear(), d.getMonthOfYear(), 
d.getDayOfMonth(),
                 d.getHourOfDay(), d.getMinuteOfHour(), d.getSecondOfMinute());
     }
 
-    public DateTimeLiteral plusMonths(int months) {
-        LocalDateTime d = LocalDateTime.parse(getStringValue(), 
DATE_TIME_FORMATTER).plusMonths(months);
+    public DateTimeLiteral plusYears(int years) {
+        LocalDateTime d = LocalDateTime.parse(getStringValue(), 
DATE_TIME_FORMATTER).plusYears(years);
         return new DateTimeLiteral(d.getYear(), d.getMonthOfYear(), 
d.getDayOfMonth(),
                 d.getHourOfDay(), d.getMinuteOfHour(), d.getSecondOfMinute());
     }
 
-    public DateTimeLiteral plusDays(int days) {
-        LocalDateTime d = LocalDateTime.parse(getStringValue(), 
DATE_TIME_FORMATTER).plusDays(days);
+    public DateTimeLiteral plusMonths(int months) {
+        LocalDateTime d = LocalDateTime.parse(getStringValue(), 
DATE_TIME_FORMATTER).plusMonths(months);
         return new DateTimeLiteral(d.getYear(), d.getMonthOfYear(), 
d.getDayOfMonth(),
                 d.getHourOfDay(), d.getMinuteOfHour(), d.getSecondOfMinute());
     }
@@ -168,11 +189,6 @@ public class DateTimeLiteral extends DateLiteral {
                 d.getHourOfDay(), d.getMinuteOfHour(), d.getSecondOfMinute());
     }
 
-    @Override
-    public LiteralExpr toLegacyLiteral() {
-        return new org.apache.doris.analysis.DateLiteral(year, month, day, 
hour, minute, second);
-    }
-
     public long getHour() {
         return hour;
     }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DateTimeV2Literal.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DateTimeV2Literal.java
new file mode 100644
index 0000000000..4706c87a0e
--- /dev/null
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DateTimeV2Literal.java
@@ -0,0 +1,89 @@
+// 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.literal;
+
+import org.apache.doris.nereids.exceptions.UnboundException;
+import org.apache.doris.nereids.types.DateTimeV2Type;
+
+import org.joda.time.LocalDateTime;
+
+/**
+ * date time v2 literal for nereids
+ */
+public class DateTimeV2Literal extends DateTimeLiteral {
+
+    public DateTimeV2Literal(String s) {
+        super(DateTimeV2Type.INSTANCE, s);
+    }
+
+    public DateTimeV2Literal(long year, long month, long day, long hour, long 
minute, long second) {
+        super(DateTimeV2Type.INSTANCE, year, month, day, hour, minute, second);
+    }
+
+    public DateTimeV2Literal(DateTimeV2Type dataType,
+            long year, long month, long day, long hour, long minute, long 
second) {
+        super(dataType, year, month, day, hour, minute, second);
+    }
+
+    @Override
+    public DateTimeV2Type getDataType() throws UnboundException {
+        return (DateTimeV2Type) super.getDataType();
+    }
+
+    @Override
+    public DateTimeV2Literal plusYears(int years) {
+        LocalDateTime d = LocalDateTime.parse(getStringValue(), 
DATE_TIME_FORMATTER).plusYears(years);
+        return new DateTimeV2Literal(this.getDataType(), d.getYear(), 
d.getMonthOfYear(), d.getDayOfMonth(),
+                d.getHourOfDay(), d.getMinuteOfHour(), d.getSecondOfMinute());
+    }
+
+    @Override
+    public DateTimeV2Literal plusMonths(int months) {
+        LocalDateTime d = LocalDateTime.parse(getStringValue(), 
DATE_TIME_FORMATTER).plusMonths(months);
+        return new DateTimeV2Literal(this.getDataType(), d.getYear(), 
d.getMonthOfYear(), d.getDayOfMonth(),
+                d.getHourOfDay(), d.getMinuteOfHour(), d.getSecondOfMinute());
+    }
+
+    @Override
+    public DateTimeLiteral plusDays(int days) {
+        LocalDateTime d = LocalDateTime.parse(getStringValue(), 
DATE_TIME_FORMATTER).plusDays(days);
+        return new DateTimeV2Literal(this.getDataType(), d.getYear(), 
d.getMonthOfYear(), d.getDayOfMonth(),
+                d.getHourOfDay(), d.getMinuteOfHour(), d.getSecondOfMinute());
+    }
+
+    @Override
+    public DateTimeV2Literal plusHours(int hours) {
+        LocalDateTime d = LocalDateTime.parse(getStringValue(), 
DATE_TIME_FORMATTER).plusHours(hours);
+        return new DateTimeV2Literal(this.getDataType(), d.getYear(), 
d.getMonthOfYear(), d.getDayOfMonth(),
+                d.getHourOfDay(), d.getMinuteOfHour(), d.getSecondOfMinute());
+    }
+
+    @Override
+    public DateTimeV2Literal plusMinutes(int minutes) {
+        LocalDateTime d = LocalDateTime.parse(getStringValue(), 
DATE_TIME_FORMATTER).plusMinutes(minutes);
+        return new DateTimeV2Literal(this.getDataType(), d.getYear(), 
d.getMonthOfYear(), d.getDayOfMonth(),
+                d.getHourOfDay(), d.getMinuteOfHour(), d.getSecondOfMinute());
+    }
+
+    @Override
+    public DateTimeV2Literal plusSeconds(int seconds) {
+        LocalDateTime d = LocalDateTime.parse(getStringValue(), 
DATE_TIME_FORMATTER).plusSeconds(seconds);
+        return new DateTimeV2Literal(this.getDataType(), d.getYear(), 
d.getMonthOfYear(), d.getDayOfMonth(),
+                d.getHourOfDay(), d.getMinuteOfHour(), d.getSecondOfMinute());
+    }
+}
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DateV2Literal.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DateV2Literal.java
new file mode 100644
index 0000000000..18fe8e9ca6
--- /dev/null
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DateV2Literal.java
@@ -0,0 +1,49 @@
+// 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.literal;
+
+import org.apache.doris.analysis.LiteralExpr;
+import org.apache.doris.catalog.Type;
+import org.apache.doris.nereids.exceptions.AnalysisException;
+import org.apache.doris.nereids.types.DateV2Type;
+
+import org.joda.time.LocalDateTime;
+
+/**
+ * date v2 literal for nereids
+ */
+public class DateV2Literal extends DateLiteral {
+
+    public DateV2Literal(String s) throws AnalysisException {
+        super(DateV2Type.INSTANCE, s);
+    }
+
+    public DateV2Literal(long year, long month, long day) {
+        super(DateV2Type.INSTANCE, year, month, day);
+    }
+
+    @Override
+    public LiteralExpr toLegacyLiteral() {
+        return new org.apache.doris.analysis.DateLiteral(year, month, day, 
Type.DATEV2);
+    }
+
+    public DateV2Literal plusDays(int days) {
+        LocalDateTime dateTime = LocalDateTime.parse(getStringValue(), 
DATE_FORMATTER).plusDays(days);
+        return new DateV2Literal(dateTime.getYear(), 
dateTime.getMonthOfYear(), dateTime.getDayOfMonth());
+    }
+}
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/types/DateTimeType.java 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/types/DateTimeType.java
index 48a1b1a59c..b59e47d3eb 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/types/DateTimeType.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/types/DateTimeType.java
@@ -18,12 +18,12 @@
 package org.apache.doris.nereids.types;
 
 import org.apache.doris.catalog.Type;
-import org.apache.doris.nereids.types.coercion.PrimitiveType;
+import org.apache.doris.nereids.types.coercion.DateLikeType;
 
 /**
  * Datetime type in Nereids.
  */
-public class DateTimeType extends PrimitiveType {
+public class DateTimeType extends DateLikeType {
 
     public static final DateTimeType INSTANCE = new DateTimeType();
 
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/types/DateTimeV2Type.java 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/types/DateTimeV2Type.java
index d21649142b..c6737a1618 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/types/DateTimeV2Type.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/types/DateTimeV2Type.java
@@ -19,7 +19,7 @@ package org.apache.doris.nereids.types;
 
 import org.apache.doris.catalog.ScalarType;
 import org.apache.doris.catalog.Type;
-import org.apache.doris.nereids.types.coercion.PrimitiveType;
+import org.apache.doris.nereids.types.coercion.DateLikeType;
 
 import com.google.common.base.Preconditions;
 
@@ -28,7 +28,7 @@ import java.util.Objects;
 /**
  * Datetime type in Nereids.
  */
-public class DateTimeV2Type extends PrimitiveType {
+public class DateTimeV2Type extends DateLikeType {
     public static final int MAX_SCALE = 6;
     public static final DateTimeV2Type INSTANCE = new DateTimeV2Type(0);
 
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/types/DateType.java 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/types/DateType.java
index 04bf92920c..a33fec9d1c 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/types/DateType.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/types/DateType.java
@@ -18,12 +18,12 @@
 package org.apache.doris.nereids.types;
 
 import org.apache.doris.catalog.Type;
-import org.apache.doris.nereids.types.coercion.PrimitiveType;
+import org.apache.doris.nereids.types.coercion.DateLikeType;
 
 /**
  * Date type in Nereids.
  */
-public class DateType extends PrimitiveType {
+public class DateType extends DateLikeType {
 
     public static final DateType INSTANCE = new DateType();
 
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/types/DateV2Type.java 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/types/DateV2Type.java
index 4f5b808b84..9cf5efdbb6 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/types/DateV2Type.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/types/DateV2Type.java
@@ -18,12 +18,12 @@
 package org.apache.doris.nereids.types;
 
 import org.apache.doris.catalog.Type;
-import org.apache.doris.nereids.types.coercion.PrimitiveType;
+import org.apache.doris.nereids.types.coercion.DateLikeType;
 
 /**
  * Date type in Nereids.
  */
-public class DateV2Type extends PrimitiveType {
+public class DateV2Type extends DateLikeType {
 
     public static final DateV2Type INSTANCE = new DateV2Type();
 
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/types/DateType.java 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/types/coercion/DateLikeType.java
similarity index 61%
copy from fe/fe-core/src/main/java/org/apache/doris/nereids/types/DateType.java
copy to 
fe/fe-core/src/main/java/org/apache/doris/nereids/types/coercion/DateLikeType.java
index 04bf92920c..ee491fa18d 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/types/DateType.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/types/coercion/DateLikeType.java
@@ -15,31 +15,10 @@
 // specific language governing permissions and limitations
 // under the License.
 
-package org.apache.doris.nereids.types;
-
-import org.apache.doris.catalog.Type;
-import org.apache.doris.nereids.types.coercion.PrimitiveType;
+package org.apache.doris.nereids.types.coercion;
 
 /**
- * Date type in Nereids.
+ * date like type.
  */
-public class DateType extends PrimitiveType {
-
-    public static final DateType INSTANCE = new DateType();
-
-    private static final int WIDTH = 16;
-
-    private DateType() {
-    }
-
-    @Override
-    public Type toCatalogDataType() {
-        return Type.DATE;
-    }
-
-    @Override
-    public int width() {
-        return WIDTH;
-    }
+public abstract class DateLikeType extends PrimitiveType {
 }
-
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 7c9cc60ee2..d1cc520bbf 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
@@ -26,6 +26,8 @@ import org.apache.doris.nereids.types.BigIntType;
 import org.apache.doris.nereids.types.BooleanType;
 import org.apache.doris.nereids.types.DataType;
 import org.apache.doris.nereids.types.DateTimeType;
+import org.apache.doris.nereids.types.DateTimeV2Type;
+import org.apache.doris.nereids.types.DateV2Type;
 import org.apache.doris.nereids.types.DecimalV2Type;
 import org.apache.doris.nereids.types.DoubleType;
 import org.apache.doris.nereids.types.FloatType;
@@ -37,6 +39,7 @@ import org.apache.doris.nereids.types.StringType;
 import org.apache.doris.nereids.types.TinyIntType;
 import org.apache.doris.nereids.types.coercion.AbstractDataType;
 import org.apache.doris.nereids.types.coercion.CharacterType;
+import org.apache.doris.nereids.types.coercion.DateLikeType;
 import org.apache.doris.nereids.types.coercion.FractionalType;
 import org.apache.doris.nereids.types.coercion.IntegralType;
 import org.apache.doris.nereids.types.coercion.NumericType;
@@ -207,6 +210,22 @@ public class TypeCoercionUtils {
             tightestCommonType = 
DecimalV2Type.widerDecimalV2Type((DecimalV2Type) left, 
DecimalV2Type.forType(right));
         } else if (left instanceof IntegralType && right instanceof 
DecimalV2Type) {
             tightestCommonType = 
DecimalV2Type.widerDecimalV2Type((DecimalV2Type) right, 
DecimalV2Type.forType(left));
+        } else if (left instanceof DateLikeType && right instanceof 
DateLikeType) {
+            if (left instanceof DateTimeV2Type && right instanceof 
DateTimeV2Type) {
+                if (((DateTimeV2Type) left).getScale() > ((DateTimeV2Type) 
right).getScale()) {
+                    tightestCommonType = left;
+                } else {
+                    tightestCommonType = right;
+                }
+            } else if (left instanceof DateTimeV2Type) {
+                tightestCommonType = left;
+            } else if (right instanceof DateTimeV2Type) {
+                tightestCommonType = right;
+            } else if (left instanceof DateTimeType || right instanceof 
DateTimeType) {
+                tightestCommonType = DateTimeType.INSTANCE;
+            } else if (left instanceof DateV2Type || right instanceof 
DateV2Type) {
+                tightestCommonType = DateV2Type.INSTANCE;
+            }
         }
         return Optional.ofNullable(tightestCommonType);
     }
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rewrite/ExpressionRewriteTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rewrite/ExpressionRewriteTest.java
index a77ab645e4..92810237fb 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rewrite/ExpressionRewriteTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rewrite/ExpressionRewriteTest.java
@@ -23,16 +23,26 @@ import 
org.apache.doris.nereids.rules.expression.rewrite.rules.ExtractCommonFact
 import 
org.apache.doris.nereids.rules.expression.rewrite.rules.InPredicateToEqualToRule;
 import 
org.apache.doris.nereids.rules.expression.rewrite.rules.NormalizeBinaryPredicatesRule;
 import 
org.apache.doris.nereids.rules.expression.rewrite.rules.SimplifyCastRule;
+import 
org.apache.doris.nereids.rules.expression.rewrite.rules.SimplifyComparisonPredicate;
 import 
org.apache.doris.nereids.rules.expression.rewrite.rules.SimplifyNotExprRule;
 import org.apache.doris.nereids.trees.expressions.Cast;
+import org.apache.doris.nereids.trees.expressions.EqualTo;
+import org.apache.doris.nereids.trees.expressions.Expression;
+import org.apache.doris.nereids.trees.expressions.GreaterThan;
+import org.apache.doris.nereids.trees.expressions.LessThan;
 import org.apache.doris.nereids.trees.expressions.literal.BigIntLiteral;
 import org.apache.doris.nereids.trees.expressions.literal.CharLiteral;
+import org.apache.doris.nereids.trees.expressions.literal.DateLiteral;
+import org.apache.doris.nereids.trees.expressions.literal.DateTimeLiteral;
+import org.apache.doris.nereids.trees.expressions.literal.DateTimeV2Literal;
+import org.apache.doris.nereids.trees.expressions.literal.DateV2Literal;
 import org.apache.doris.nereids.trees.expressions.literal.DecimalLiteral;
 import org.apache.doris.nereids.trees.expressions.literal.IntegerLiteral;
 import org.apache.doris.nereids.trees.expressions.literal.SmallIntLiteral;
 import org.apache.doris.nereids.trees.expressions.literal.StringLiteral;
 import org.apache.doris.nereids.trees.expressions.literal.TinyIntLiteral;
 import org.apache.doris.nereids.trees.expressions.literal.VarcharLiteral;
+import org.apache.doris.nereids.types.DateTimeV2Type;
 import org.apache.doris.nereids.types.DecimalV2Type;
 import org.apache.doris.nereids.types.StringType;
 import org.apache.doris.nereids.types.VarcharType;
@@ -212,4 +222,70 @@ public class ExpressionRewriteTest extends 
ExpressionRewriteTestHelper {
         assertRewrite(new Cast(new BigIntLiteral(1L), 
DecimalV2Type.createDecimalV2Type(15, 9)),
                 new DecimalLiteral(new BigDecimal(1)));
     }
+
+    @Test
+    public void testSimplifyComparisonPredicateRule() {
+        executor = new 
ExpressionRuleExecutor(ImmutableList.of(SimplifyComparisonPredicate.INSTANCE));
+
+        Expression dtv2 = new DateTimeV2Literal(1, 1, 1, 1, 1, 1);
+        Expression dt = new DateTimeLiteral(1, 1, 1, 1, 1, 1);
+        Expression dv2 = new DateV2Literal(1, 1, 1);
+        Expression dv2PlusOne = new DateV2Literal(1, 1, 2);
+        Expression d = new DateLiteral(1, 1, 1);
+        Expression dPlusOne = new DateLiteral(1, 1, 2);
+
+        // DateTimeV2 -> DateTime
+        assertRewrite(
+                new GreaterThan(new Cast(dt, DateTimeV2Type.INSTANCE), dtv2),
+                new GreaterThan(dt, dt));
+
+        // DateTimeV2 -> DateV2
+        assertRewrite(
+                new GreaterThan(new Cast(dv2, DateTimeV2Type.INSTANCE), dtv2),
+                new GreaterThan(dv2, dv2));
+        assertRewrite(
+                new LessThan(new Cast(dv2, DateTimeV2Type.INSTANCE), dtv2),
+                new LessThan(dv2, dv2PlusOne));
+        assertRewrite(
+                new EqualTo(new Cast(dv2, DateTimeV2Type.INSTANCE), dtv2),
+                new EqualTo(new Cast(dv2, DateTimeV2Type.INSTANCE), dtv2));
+
+        // DateTime -> DateV2
+        assertRewrite(
+                new GreaterThan(new Cast(dv2, DateTimeV2Type.INSTANCE), dt),
+                new GreaterThan(dv2, dv2));
+        assertRewrite(
+                new LessThan(new Cast(dv2, DateTimeV2Type.INSTANCE), dt),
+                new LessThan(dv2, dv2PlusOne));
+        assertRewrite(
+                new EqualTo(new Cast(dv2, DateTimeV2Type.INSTANCE), dt),
+                new EqualTo(new Cast(dv2, DateTimeV2Type.INSTANCE), dt));
+
+        // DateTimeV2 -> Date
+        assertRewrite(
+                new GreaterThan(new Cast(d, DateTimeV2Type.INSTANCE), dtv2),
+                new GreaterThan(d, d));
+        assertRewrite(
+                new LessThan(new Cast(d, DateTimeV2Type.INSTANCE), dtv2),
+                new LessThan(d, dPlusOne));
+        assertRewrite(
+                new EqualTo(new Cast(d, DateTimeV2Type.INSTANCE), dtv2),
+                new EqualTo(new Cast(d, DateTimeV2Type.INSTANCE), dtv2));
+
+        // DateTime -> Date
+        assertRewrite(
+                new GreaterThan(new Cast(d, DateTimeV2Type.INSTANCE), dt),
+                new GreaterThan(d, d));
+        assertRewrite(
+                new LessThan(new Cast(d, DateTimeV2Type.INSTANCE), dt),
+                new LessThan(d, dPlusOne));
+        assertRewrite(
+                new EqualTo(new Cast(d, DateTimeV2Type.INSTANCE), dt),
+                new EqualTo(new Cast(d, DateTimeV2Type.INSTANCE), dt));
+
+        // DateV2 -> Date
+        assertRewrite(
+                new GreaterThan(new Cast(d, DateTimeV2Type.INSTANCE), dv2),
+                new GreaterThan(d, d));
+    }
 }


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


Reply via email to