You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@doris.apache.org by li...@apache.org on 2022/05/16 07:01:21 UTC

[incubator-doris] branch master updated: [Feature](Nereids) Data structure of comparison predicate (#9506)

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

lingmiao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-doris.git


The following commit(s) were added to refs/heads/master by this push:
     new 9f9b666bc1 [Feature](Nereids) Data structure of comparison predicate (#9506)
9f9b666bc1 is described below

commit 9f9b666bc190005dd8b5e5f5f1bc295470ff04bd
Author: EmmyMiao87 <52...@qq.com>
AuthorDate: Mon May 16 15:01:13 2022 +0800

    [Feature](Nereids) Data structure of comparison predicate (#9506)
    
    1. The data structure of the comparison expression
    2. Refactored the inheritance and implementation relationship of tree node
    
    ```
            +-- ---- ---- ---+- ---- ---- ---- ---+- ---- ----- ---- ----TreeNode-----------------+
            |                |                    |                                               |
                                                                                                  |
            |                |                    |                                               |
                                                                                                  v
            v                v                    v                                           Abstract Tree Node
        Leaf Node        Unary Node          Binary Node                              +--------          ---------+
            |                |                    |                                   |        (children)         |
                                                                                      |                           |
            v                v                    v                                   v                           v
    Leaf Expression   Unary Expression      Binary Expression              +------Expression----+           Plan Node
            |                |                    |                        |                    |
                                                                           |                    |
            |                |                    |                        v                    v
            |                |                    +- ---- ---- -----> Comparison Predicate     Named Expr
                                                                                           +----   -------+
            |                |                                                             v              v
            |                +- -- --- --- --- --- --- --- --- --- --- --- --- --- ---> Alias Expr      Slot
                                                                                                          ^
            |                                                                                             |
            |                                                                                             |
            +---- --- ---- ------ ---- ------- ------ ------- --- ------ ------ ----- ---- ----- ----- ---+
    ```
---
 .../antlr4/org/apache/doris/nereids/DorisLexer.g4  |   3 +-
 .../antlr4/org/apache/doris/nereids/DorisParser.g4 |   2 +-
 .../doris/nereids/analyzer/UnboundAlias.java       |   5 +-
 .../apache/doris/nereids/analyzer/UnboundStar.java |   2 +-
 .../{AstBuilder.java => LogicalPlanBuilder.java}   |  34 +++---
 .../org/apache/doris/nereids/parser/SqlParser.java |   4 +-
 .../org/apache/doris/nereids/pattern/Patterns.java |  39 +++----
 .../org/apache/doris/nereids/trees/NodeType.java   |   9 +-
 .../doris/nereids/trees/expressions/Alias.java     |   9 +-
 .../trees/expressions/BinaryExpression.java        |  20 +---
 .../nereids/trees/expressions/BinaryPredicate.java | 122 ---------------------
 ...actExpression.java => ComparisonPredicate.java} |  46 ++++----
 .../expressions/{Expression.java => EqualTo.java}  |  26 ++---
 .../nereids/trees/expressions/Expression.java      |  30 +++--
 .../{BinaryExpression.java => GreaterThan.java}    |  31 +++---
 ...stractExpression.java => GreaterThanEqual.java} |  42 +++----
 .../nereids/trees/expressions/LeafExpression.java  |  11 +-
 .../{BinaryExpression.java => LessThan.java}       |  31 +++---
 .../{BinaryExpression.java => LessThanEqual.java}  |  31 +++---
 .../doris/nereids/trees/expressions/Literal.java   |   4 +-
 .../nereids/trees/expressions/NamedExpression.java |  36 ++----
 .../{Slot.java => NamedExpressionUtil.java}        |  23 ++--
 .../expressions/{Expression.java => Not.java}      |  27 +++--
 ...{AbstractExpression.java => NullSafeEqual.java} |  43 +++-----
 .../doris/nereids/trees/expressions/Slot.java      |   5 +-
 .../nereids/trees/expressions/SlotReference.java   |   2 +-
 .../nereids/trees/expressions/UnaryExpression.java |  11 +-
 ...icateTest.java => ComparisonPredicateTest.java} |   6 +-
 28 files changed, 239 insertions(+), 415 deletions(-)

diff --git a/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisLexer.g4 b/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisLexer.g4
index bd1737b7ac..c07854e0cc 100644
--- a/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisLexer.g4
+++ b/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisLexer.g4
@@ -371,8 +371,7 @@ ZONE: 'ZONE';
 
 EQ  : '=' | '==';
 NSEQ: '<=>';
-NEQ : '<>';
-NEQJ: '!=';
+NEQ : '<>' | '!=';
 LT  : '<';
 LTE : '<=' | '!>';
 GT  : '>';
diff --git a/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4 b/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4
index 602a5ed394..d4c580dfc7 100644
--- a/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4
+++ b/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4
@@ -170,7 +170,7 @@ constant
     ;
 
 comparisonOperator
-    : EQ | NEQ | NEQJ | LT | LTE | GT | GTE | NSEQ
+    : EQ | NEQ | LT | LTE | GT | GTE | NSEQ
     ;
 
 booleanValue
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/analyzer/UnboundAlias.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/analyzer/UnboundAlias.java
index 4b7301734e..23272aaf7e 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/analyzer/UnboundAlias.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/analyzer/UnboundAlias.java
@@ -29,9 +29,8 @@ import java.util.List;
 /**
  * Expression for unbound alias.
  */
-public class UnboundAlias<CHILD_TYPE extends Expression>
-        extends UnaryExpression<UnboundAlias<CHILD_TYPE>, CHILD_TYPE>
-        implements NamedExpression<UnboundAlias<CHILD_TYPE>> {
+public class UnboundAlias<CHILD_TYPE extends Expression> extends NamedExpression<UnboundAlias<CHILD_TYPE>>
+        implements UnaryExpression<UnboundAlias<CHILD_TYPE>, CHILD_TYPE> {
 
     public UnboundAlias(CHILD_TYPE child) {
         super(NodeType.UNBOUND_ALIAS, child);
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/analyzer/UnboundStar.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/analyzer/UnboundStar.java
index d94d1df637..ce4c9c1ca4 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/analyzer/UnboundStar.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/analyzer/UnboundStar.java
@@ -29,7 +29,7 @@ import java.util.List;
 /**
  * Star expression.
  */
-public class UnboundStar extends LeafExpression<UnboundStar> implements NamedExpression<UnboundStar> {
+public class UnboundStar extends NamedExpression<UnboundStar> implements LeafExpression<UnboundStar> {
     private final List<String> target;
 
     public UnboundStar(List<String> target) {
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/AstBuilder.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java
similarity index 94%
rename from fe/fe-core/src/main/java/org/apache/doris/nereids/parser/AstBuilder.java
rename to fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java
index 7a93b88e0d..8dfc6bec91 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/AstBuilder.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java
@@ -50,17 +50,24 @@ import org.apache.doris.nereids.analyzer.UnboundRelation;
 import org.apache.doris.nereids.analyzer.UnboundSlot;
 import org.apache.doris.nereids.analyzer.UnboundStar;
 import org.apache.doris.nereids.trees.expressions.Alias;
-import org.apache.doris.nereids.trees.expressions.BinaryPredicate;
+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;
 import org.apache.doris.nereids.trees.expressions.NamedExpression;
+import org.apache.doris.nereids.trees.expressions.Not;
+import org.apache.doris.nereids.trees.expressions.NullSafeEqual;
 import org.apache.doris.nereids.trees.plans.JoinType;
 import org.apache.doris.nereids.trees.plans.logical.LogicalFilter;
 import org.apache.doris.nereids.trees.plans.logical.LogicalJoin;
 import org.apache.doris.nereids.trees.plans.logical.LogicalPlan;
 import org.apache.doris.nereids.trees.plans.logical.LogicalProject;
 
-import com.clearspring.analytics.util.Lists;
+import com.google.common.collect.Lists;
+
 import org.antlr.v4.runtime.ParserRuleContext;
 import org.antlr.v4.runtime.RuleContext;
 import org.antlr.v4.runtime.tree.ParseTree;
@@ -74,9 +81,9 @@ import java.util.function.Supplier;
 import java.util.stream.Collectors;
 
 /**
- * Build an AST that consisting of logical plans.
+ * Build an logical plan tree with unbounded nodes.
  */
-public class AstBuilder extends DorisParserBaseVisitor<Object> {
+public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> {
 
     /**
      * Create a logical plan using a where clause.
@@ -356,20 +363,19 @@ public class AstBuilder extends DorisParserBaseVisitor<Object> {
         TerminalNode operator = (TerminalNode) ctx.comparisonOperator().getChild(0);
         switch (operator.getSymbol().getType()) {
             case DorisParser.EQ:
-                return new BinaryPredicate(left, right, BinaryPredicate.Operator.EQ);
-            case DorisParser.NSEQ:
-                return new BinaryPredicate(left, right, BinaryPredicate.Operator.NSEQ);
+                return new EqualTo(left, right);
+            case DorisParser.NEQ:
+                return new Not(new EqualTo(left, right));
             case DorisParser.LT:
-                return new BinaryPredicate(left, right, BinaryPredicate.Operator.LT);
+                return new LessThan(left, right);
             case DorisParser.GT:
-                return new BinaryPredicate(left, right, BinaryPredicate.Operator.GT);
+                return new GreaterThan(left, right);
             case DorisParser.LTE:
-                return new BinaryPredicate(left, right, BinaryPredicate.Operator.LE);
+                return new LessThanEqual(left, right);
             case DorisParser.GTE:
-                return new BinaryPredicate(left, right, BinaryPredicate.Operator.GE);
-            case DorisParser.NEQ:
-            case DorisParser.NEQJ:
-                return new BinaryPredicate(left, right, BinaryPredicate.Operator.EQ);
+                return new GreaterThanEqual(left, right);
+            case DorisParser.NSEQ:
+                return new NullSafeEqual(left, right);
             default:
                 return null;
         }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/SqlParser.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/SqlParser.java
index a2a44378a9..9c734e1edc 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/SqlParser.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/SqlParser.java
@@ -63,7 +63,7 @@ public class SqlParser {
             tree = parser.singleStatement();
         }
 
-        AstBuilder astBuilder = new AstBuilder();
-        return (LogicalPlan) astBuilder.visit(tree);
+        LogicalPlanBuilder logicalPlanBuilder = new LogicalPlanBuilder();
+        return (LogicalPlan) logicalPlanBuilder.visit(tree);
     }
 }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/pattern/Patterns.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/pattern/Patterns.java
index c73a45cc3c..3e35bae60b 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/pattern/Patterns.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/pattern/Patterns.java
@@ -25,8 +25,7 @@ import org.apache.doris.nereids.rules.RulePromise;
 import org.apache.doris.nereids.trees.NodeType;
 import org.apache.doris.nereids.trees.TreeNode;
 import org.apache.doris.nereids.trees.expressions.Alias;
-import org.apache.doris.nereids.trees.expressions.BinaryPredicate;
-import org.apache.doris.nereids.trees.expressions.BinaryPredicate.Operator;
+import org.apache.doris.nereids.trees.expressions.EqualTo;
 import org.apache.doris.nereids.trees.expressions.Expression;
 import org.apache.doris.nereids.trees.expressions.Literal;
 import org.apache.doris.nereids.trees.expressions.SlotReference;
@@ -329,38 +328,28 @@ public interface Patterns {
     }
 
     /**
-     * create a binaryPredicate pattern.
+     * TODO create a ComparisonPredicate pattern.
      */
-    default PatternDescriptor<BinaryPredicate<Expression, Expression>, Expression> binaryPredicate() {
-        return new PatternDescriptor<>(
-                new Pattern<>(NodeType.BINARY_PREDICATE),
-                defaultPromise()
-        );
-    }
 
     /**
-     * create a binaryPredicate pattern with operator type.
+     * TODO create a ComparisonPredicate pattern with children patterns.
      */
-    default PatternDescriptor<BinaryPredicate<Expression, Expression>, Expression> binaryPredicate(Operator operator) {
-        return new PatternDescriptor<BinaryPredicate<Expression, Expression>, Expression>(
-                new Pattern<>(NodeType.BINARY_PREDICATE),
-                defaultPromise()
-        ).when(p -> p.getOperator() == operator);
+
+    /**
+     * create a equal to predicate pattern.
+     */
+    default PatternDescriptor<EqualTo<Expression, Expression>, Expression> equalTo() {
+        return new PatternDescriptor<>(new Pattern<>(NodeType.EQUAL_TO), defaultPromise());
     }
 
     /**
-     * create a binaryPredicate pattern with children patterns.
+     * create a equal to predicate pattern with children patterns.
      */
-    default <C1 extends Expression, C2 extends Expression> PatternDescriptor<BinaryPredicate<C1, C2>, Expression>
-            binaryPredicate(PatternDescriptor<C1, Expression> leftChildPattern,
-                PatternDescriptor<C2, Expression> rightChildPattern) {
+    default <C1 extends Expression, C2 extends Expression> PatternDescriptor<EqualTo<C1, C2>, Expression> equalTo(
+            PatternDescriptor<C1, Expression> leftChildPattern, PatternDescriptor<C2, Expression> rightChildPattern) {
         return new PatternDescriptor<>(
-                new Pattern<>(NodeType.BINARY_PREDICATE,
-                        leftChildPattern.pattern,
-                        rightChildPattern.pattern
-                ),
-                defaultPromise()
-        );
+                new Pattern<>(NodeType.EQUAL_TO, leftChildPattern.pattern, rightChildPattern.pattern),
+                defaultPromise());
     }
 
     /**
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/NodeType.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/NodeType.java
index 71a9830415..bf048208a3 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/NodeType.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/NodeType.java
@@ -43,7 +43,14 @@ public enum NodeType {
     UNBOUND_STAR,
     LITERAL,
     SLOT_REFERENCE,
-    BINARY_PREDICATE,
+    COMPARISON_PREDICATE,
+    EQUAL_TO,
+    LESS_THAN,
+    GREATER_THAN,
+    LESS_THAN_EQUAL,
+    GREATER_THAN_EQUAL,
+    NULL_SAFE_EQUAL,
+    NOT,
     ALIAS,
 
     // pattern
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Alias.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Alias.java
index c688df8915..a9b46ae80c 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Alias.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Alias.java
@@ -20,16 +20,15 @@ package org.apache.doris.nereids.trees.expressions;
 import org.apache.doris.nereids.exceptions.UnboundException;
 import org.apache.doris.nereids.trees.NodeType;
 
-import com.clearspring.analytics.util.Lists;
+import com.google.common.collect.Lists;
 
 import java.util.List;
 
 /**
  * Expression for alias, such as col1 as c1.
  */
-public class Alias<CHILD_TYPE extends Expression>
-        extends UnaryExpression<Alias<CHILD_TYPE>, CHILD_TYPE>
-        implements NamedExpression<Alias<CHILD_TYPE>> {
+public class Alias<CHILD_TYPE extends Expression> extends NamedExpression<Alias<CHILD_TYPE>>
+        implements UnaryExpression<Alias<CHILD_TYPE>, CHILD_TYPE> {
 
     private final ExprId exprId;
     private final String name;
@@ -43,7 +42,7 @@ public class Alias<CHILD_TYPE extends Expression>
      */
     public Alias(CHILD_TYPE child, String name) {
         super(NodeType.ALIAS, child);
-        exprId = NamedExpressionUtils.newExprId();
+        exprId = NamedExpressionUtil.newExprId();
         this.name = name;
         qualifier = Lists.newArrayList();
     }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/BinaryExpression.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/BinaryExpression.java
index 7cac178f55..988985c196 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/BinaryExpression.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/BinaryExpression.java
@@ -21,26 +21,12 @@ import org.apache.doris.nereids.trees.BinaryNode;
 import org.apache.doris.nereids.trees.NodeType;
 
 /**
- * Abstract class for all expression that have two children.
+ * Interface for all expression that have two children.
  */
-public abstract class BinaryExpression<
+public interface BinaryExpression<
             EXPR_TYPE extends BinaryExpression<EXPR_TYPE, LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE>,
             LEFT_CHILD_TYPE extends Expression,
             RIGHT_CHILD_TYPE extends Expression>
-        extends AbstractExpression<EXPR_TYPE>
-        implements BinaryNode<EXPR_TYPE, LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE> {
+        extends BinaryNode<EXPR_TYPE, LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE> {
 
-    public BinaryExpression(NodeType type, LEFT_CHILD_TYPE left, RIGHT_CHILD_TYPE right) {
-        super(type, left, right);
-    }
-
-    @Override
-    public LEFT_CHILD_TYPE left() {
-        return BinaryNode.super.left();
-    }
-
-    @Override
-    public RIGHT_CHILD_TYPE right() {
-        return BinaryNode.super.right();
-    }
 }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/BinaryPredicate.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/BinaryPredicate.java
deleted file mode 100644
index f962732627..0000000000
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/BinaryPredicate.java
+++ /dev/null
@@ -1,122 +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.common.AnalysisException;
-import org.apache.doris.nereids.exceptions.UnboundException;
-import org.apache.doris.nereids.trees.NodeType;
-import org.apache.doris.nereids.types.BooleanType;
-import org.apache.doris.nereids.types.DataType;
-
-/**
- * Binary predicate expression.
- */
-public class BinaryPredicate<
-            LEFT_CHILD_TYPE extends Expression,
-            RIGHT_CHILD_TYPE extends Expression>
-        extends BinaryExpression<BinaryPredicate<LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE>,
-            LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE> {
-
-    private final Operator operator;
-
-    /**
-     * Operator for binary predicate.
-     */
-    public enum Operator {
-        EQ("="),
-        NSEQ("<=>"),
-        LT("<"),
-        GT(">"),
-        LE("<="),
-        GE(">="),
-        ;
-
-        private final String operand;
-
-        Operator(String operand) {
-            this.operand = operand;
-        }
-
-        /**
-         * Translate expression op in Nereids to legacy one in Doris.
-         *
-         * @param operator expression operator in Nereids
-         * @return legacy expression operator in Doris
-         * @throws AnalysisException throw exception when operator cannot be recognized
-         */
-        public static org.apache.doris.analysis.BinaryPredicate.Operator toExprOp(Operator operator)
-                throws AnalysisException {
-            switch (operator) {
-                case EQ:
-                    return org.apache.doris.analysis.BinaryPredicate.Operator.EQ;
-                case GE:
-                    return org.apache.doris.analysis.BinaryPredicate.Operator.GE;
-                case GT:
-                    return org.apache.doris.analysis.BinaryPredicate.Operator.GT;
-                case LE:
-                    return org.apache.doris.analysis.BinaryPredicate.Operator.LE;
-                case LT:
-                    return org.apache.doris.analysis.BinaryPredicate.Operator.LT;
-                case NSEQ:
-                    return org.apache.doris.analysis.BinaryPredicate.Operator.EQ_FOR_NULL;
-                default:
-                    throw new AnalysisException("Not support operator: " + operator.name());
-            }
-        }
-    }
-
-    /**
-     * Constructor of BinaryPredicate.
-     *
-     * @param left left child of binary predicate
-     * @param right right child of binary predicate
-     * @param operator operator of binary predicate
-     */
-    public BinaryPredicate(LEFT_CHILD_TYPE left, RIGHT_CHILD_TYPE right, Operator operator) {
-        super(NodeType.BINARY_PREDICATE, left, right);
-        this.operator = operator;
-    }
-
-    public Operator getOperator() {
-        return operator;
-    }
-
-    @Override
-    public boolean nullable() throws UnboundException {
-        if (operator == Operator.NSEQ) {
-            return false;
-        } else {
-            return left().nullable() || right().nullable();
-        }
-    }
-
-    @Override
-    public DataType getDataType() throws UnboundException {
-        return BooleanType.INSTANCE;
-    }
-
-    @Override
-    public String sql() {
-        return null;
-    }
-
-    @Override
-    public String toString() {
-        return "(" + left() + " " + operator.operand + " " + right() + ")";
-    }
-}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/AbstractExpression.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/ComparisonPredicate.java
similarity index 55%
copy from fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/AbstractExpression.java
copy to fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/ComparisonPredicate.java
index 6996a66cc2..4f3307d9ab 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/AbstractExpression.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/ComparisonPredicate.java
@@ -18,42 +18,36 @@
 package org.apache.doris.nereids.trees.expressions;
 
 import org.apache.doris.nereids.exceptions.UnboundException;
-import org.apache.doris.nereids.trees.AbstractTreeNode;
 import org.apache.doris.nereids.trees.NodeType;
+import org.apache.doris.nereids.types.BooleanType;
 import org.apache.doris.nereids.types.DataType;
 
-import java.util.List;
-
 /**
- * Abstract class for all Expression in Nereids.
+ * Comparison predicate expression.
+ * Such as: "=", "<", "<=", ">", ">=", "<=>"
  */
-public abstract class AbstractExpression<EXPR_TYPE extends AbstractExpression<EXPR_TYPE>>
-        extends AbstractTreeNode<EXPR_TYPE>
-        implements Expression<EXPR_TYPE> {
-
-    public AbstractExpression(NodeType type, Expression... children) {
-        super(type, children);
-    }
-
-    public DataType getDataType() throws UnboundException {
-        throw new UnboundException("dataType");
-    }
-
-    public String sql() throws UnboundException {
-        throw new UnboundException("sql");
-    }
-
-    public boolean nullable() throws UnboundException {
-        throw new UnboundException("nullable");
+public class ComparisonPredicate<LEFT_CHILD_TYPE extends Expression, RIGHT_CHILD_TYPE extends Expression>
+        extends Expression<ComparisonPredicate<LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE>> implements
+        BinaryExpression<ComparisonPredicate<LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE>, LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE> {
+
+    /**
+     * Constructor of ComparisonPredicate.
+     *
+     * @param nodeType node type of expression
+     * @param left     left child of comparison predicate
+     * @param right    right child of comparison predicate
+     */
+    public ComparisonPredicate(NodeType nodeType, LEFT_CHILD_TYPE left, RIGHT_CHILD_TYPE right) {
+        super(nodeType, left, right);
     }
 
     @Override
-    public List<Expression> children() {
-        return (List) children;
+    public DataType getDataType() throws UnboundException {
+        return BooleanType.INSTANCE;
     }
 
     @Override
-    public Expression child(int index) {
-        return (Expression) children.get(index);
+    public String sql() {
+        return toString();
     }
 }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Expression.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/EqualTo.java
similarity index 62%
copy from fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Expression.java
copy to fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/EqualTo.java
index 6783102fa7..20517d7523 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Expression.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/EqualTo.java
@@ -18,25 +18,25 @@
 package org.apache.doris.nereids.trees.expressions;
 
 import org.apache.doris.nereids.exceptions.UnboundException;
-import org.apache.doris.nereids.trees.TreeNode;
-import org.apache.doris.nereids.types.DataType;
-
-import java.util.List;
+import org.apache.doris.nereids.trees.NodeType;
 
 /**
- * Abstract class for all Expression in Nereids.
+ * Equal to expression: a = b.
  */
-public interface Expression<EXPR_TYPE extends Expression<EXPR_TYPE>> extends TreeNode<EXPR_TYPE> {
-
-    DataType getDataType() throws UnboundException;
-
-    String sql() throws UnboundException;
+public class EqualTo<LEFT_CHILD_TYPE extends Expression, RIGHT_CHILD_TYPE extends Expression>
+        extends ComparisonPredicate<LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE> {
 
-    boolean nullable() throws UnboundException;
+    public EqualTo(LEFT_CHILD_TYPE left, RIGHT_CHILD_TYPE right) {
+        super(NodeType.EQUAL_TO, left, right);
+    }
 
     @Override
-    List<Expression> children();
+    public boolean nullable() throws UnboundException {
+        return left().nullable() || right().nullable();
+    }
 
     @Override
-    Expression child(int index);
+    public String toString() {
+        return "(" + left() + " = " + right() + ")";
+    }
 }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Expression.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Expression.java
index 6783102fa7..c490627e38 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Expression.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Expression.java
@@ -18,7 +18,8 @@
 package org.apache.doris.nereids.trees.expressions;
 
 import org.apache.doris.nereids.exceptions.UnboundException;
-import org.apache.doris.nereids.trees.TreeNode;
+import org.apache.doris.nereids.trees.AbstractTreeNode;
+import org.apache.doris.nereids.trees.NodeType;
 import org.apache.doris.nereids.types.DataType;
 
 import java.util.List;
@@ -26,17 +27,32 @@ import java.util.List;
 /**
  * Abstract class for all Expression in Nereids.
  */
-public interface Expression<EXPR_TYPE extends Expression<EXPR_TYPE>> extends TreeNode<EXPR_TYPE> {
+public abstract class Expression<EXPR_TYPE extends Expression<EXPR_TYPE>>
+        extends AbstractTreeNode<EXPR_TYPE> {
 
-    DataType getDataType() throws UnboundException;
+    public Expression(NodeType type, Expression... children) {
+        super(type, children);
+    }
 
-    String sql() throws UnboundException;
+    public DataType getDataType() throws UnboundException {
+        throw new UnboundException("dataType");
+    }
 
-    boolean nullable() throws UnboundException;
+    public String sql() throws UnboundException {
+        throw new UnboundException("sql");
+    }
+
+    public boolean nullable() throws UnboundException {
+        throw new UnboundException("nullable");
+    }
 
     @Override
-    List<Expression> children();
+    public List<Expression> children() {
+        return (List) children;
+    }
 
     @Override
-    Expression child(int index);
+    public Expression child(int index) {
+        return (Expression) children.get(index);
+    }
 }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/BinaryExpression.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/GreaterThan.java
similarity index 55%
copy from fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/BinaryExpression.java
copy to fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/GreaterThan.java
index 7cac178f55..99ce4cb7b9 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/BinaryExpression.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/GreaterThan.java
@@ -17,30 +17,31 @@
 
 package org.apache.doris.nereids.trees.expressions;
 
-import org.apache.doris.nereids.trees.BinaryNode;
+import org.apache.doris.nereids.exceptions.UnboundException;
 import org.apache.doris.nereids.trees.NodeType;
 
 /**
- * Abstract class for all expression that have two children.
+ * Greater than expression: a > b.
  */
-public abstract class BinaryExpression<
-            EXPR_TYPE extends BinaryExpression<EXPR_TYPE, LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE>,
-            LEFT_CHILD_TYPE extends Expression,
-            RIGHT_CHILD_TYPE extends Expression>
-        extends AbstractExpression<EXPR_TYPE>
-        implements BinaryNode<EXPR_TYPE, LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE> {
-
-    public BinaryExpression(NodeType type, LEFT_CHILD_TYPE left, RIGHT_CHILD_TYPE right) {
-        super(type, left, right);
+public class GreaterThan<LEFT_CHILD_TYPE extends Expression, RIGHT_CHILD_TYPE extends Expression>
+        extends ComparisonPredicate<LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE> {
+    /**
+     * Constructor of Greater Than ComparisonPredicate.
+     *
+     * @param left  left child of greater than
+     * @param right right child of greater than
+     */
+    public GreaterThan(LEFT_CHILD_TYPE left, RIGHT_CHILD_TYPE right) {
+        super(NodeType.GREATER_THAN, left, right);
     }
 
     @Override
-    public LEFT_CHILD_TYPE left() {
-        return BinaryNode.super.left();
+    public boolean nullable() throws UnboundException {
+        return left().nullable() || right().nullable();
     }
 
     @Override
-    public RIGHT_CHILD_TYPE right() {
-        return BinaryNode.super.right();
+    public String toString() {
+        return "(" + left() + " > " + right() + ")";
     }
 }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/AbstractExpression.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/GreaterThanEqual.java
similarity index 54%
copy from fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/AbstractExpression.java
copy to fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/GreaterThanEqual.java
index 6996a66cc2..4e7a2f92dc 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/AbstractExpression.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/GreaterThanEqual.java
@@ -18,42 +18,30 @@
 package org.apache.doris.nereids.trees.expressions;
 
 import org.apache.doris.nereids.exceptions.UnboundException;
-import org.apache.doris.nereids.trees.AbstractTreeNode;
 import org.apache.doris.nereids.trees.NodeType;
-import org.apache.doris.nereids.types.DataType;
-
-import java.util.List;
 
 /**
- * Abstract class for all Expression in Nereids.
+ * Greater than and equal expression: a >= b.
  */
-public abstract class AbstractExpression<EXPR_TYPE extends AbstractExpression<EXPR_TYPE>>
-        extends AbstractTreeNode<EXPR_TYPE>
-        implements Expression<EXPR_TYPE> {
-
-    public AbstractExpression(NodeType type, Expression... children) {
-        super(type, children);
-    }
-
-    public DataType getDataType() throws UnboundException {
-        throw new UnboundException("dataType");
-    }
-
-    public String sql() throws UnboundException {
-        throw new UnboundException("sql");
-    }
-
-    public boolean nullable() throws UnboundException {
-        throw new UnboundException("nullable");
+public class GreaterThanEqual<LEFT_CHILD_TYPE extends Expression, RIGHT_CHILD_TYPE extends Expression>
+        extends ComparisonPredicate<LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE> {
+    /**
+     * Constructor of Greater Than And Equal.
+     *
+     * @param left  left child of Greater Than And Equal
+     * @param right right child of Greater Than And Equal
+     */
+    public GreaterThanEqual(LEFT_CHILD_TYPE left, RIGHT_CHILD_TYPE right) {
+        super(NodeType.GREATER_THAN_EQUAL, left, right);
     }
 
     @Override
-    public List<Expression> children() {
-        return (List) children;
+    public boolean nullable() throws UnboundException {
+        return left().nullable() || right().nullable();
     }
 
     @Override
-    public Expression child(int index) {
-        return (Expression) children.get(index);
+    public String toString() {
+        return "(" + left() + " >= " + right() + ")";
     }
 }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/LeafExpression.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/LeafExpression.java
index 7fc5f1d6de..2c8aeb55c4 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/LeafExpression.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/LeafExpression.java
@@ -18,16 +18,9 @@
 package org.apache.doris.nereids.trees.expressions;
 
 import org.apache.doris.nereids.trees.LeafNode;
-import org.apache.doris.nereids.trees.NodeType;
 
 /**
- * Abstract class for all expression that have no child.
+ * Interface for all expression that have no child.
  */
-public abstract class LeafExpression<EXPR_TYPE extends LeafExpression<EXPR_TYPE>>
-        extends AbstractExpression<EXPR_TYPE>
-        implements LeafNode<EXPR_TYPE> {
-
-    public LeafExpression(NodeType type) {
-        super(type);
-    }
+public interface LeafExpression<EXPR_TYPE extends LeafExpression<EXPR_TYPE>> extends LeafNode<EXPR_TYPE> {
 }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/BinaryExpression.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/LessThan.java
similarity index 56%
copy from fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/BinaryExpression.java
copy to fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/LessThan.java
index 7cac178f55..cfea4676de 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/BinaryExpression.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/LessThan.java
@@ -17,30 +17,31 @@
 
 package org.apache.doris.nereids.trees.expressions;
 
-import org.apache.doris.nereids.trees.BinaryNode;
+import org.apache.doris.nereids.exceptions.UnboundException;
 import org.apache.doris.nereids.trees.NodeType;
 
 /**
- * Abstract class for all expression that have two children.
+ * Less than expression: a < b.
  */
-public abstract class BinaryExpression<
-            EXPR_TYPE extends BinaryExpression<EXPR_TYPE, LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE>,
-            LEFT_CHILD_TYPE extends Expression,
-            RIGHT_CHILD_TYPE extends Expression>
-        extends AbstractExpression<EXPR_TYPE>
-        implements BinaryNode<EXPR_TYPE, LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE> {
-
-    public BinaryExpression(NodeType type, LEFT_CHILD_TYPE left, RIGHT_CHILD_TYPE right) {
-        super(type, left, right);
+public class LessThan<LEFT_CHILD_TYPE extends Expression, RIGHT_CHILD_TYPE extends Expression>
+        extends ComparisonPredicate<LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE> {
+    /**
+     * Constructor of Less Than Comparison Predicate.
+     *
+     * @param left  left child of Less Than
+     * @param right right child of Less Than
+     */
+    public LessThan(LEFT_CHILD_TYPE left, RIGHT_CHILD_TYPE right) {
+        super(NodeType.LESS_THAN, left, right);
     }
 
     @Override
-    public LEFT_CHILD_TYPE left() {
-        return BinaryNode.super.left();
+    public boolean nullable() throws UnboundException {
+        return left().nullable() || right().nullable();
     }
 
     @Override
-    public RIGHT_CHILD_TYPE right() {
-        return BinaryNode.super.right();
+    public String toString() {
+        return "(" + left() + " < " + right() + ")";
     }
 }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/BinaryExpression.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/LessThanEqual.java
similarity index 55%
copy from fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/BinaryExpression.java
copy to fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/LessThanEqual.java
index 7cac178f55..5ba2c1a5bb 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/BinaryExpression.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/LessThanEqual.java
@@ -17,30 +17,31 @@
 
 package org.apache.doris.nereids.trees.expressions;
 
-import org.apache.doris.nereids.trees.BinaryNode;
+import org.apache.doris.nereids.exceptions.UnboundException;
 import org.apache.doris.nereids.trees.NodeType;
 
 /**
- * Abstract class for all expression that have two children.
+ * Less than and equal expression: a <= b.
  */
-public abstract class BinaryExpression<
-            EXPR_TYPE extends BinaryExpression<EXPR_TYPE, LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE>,
-            LEFT_CHILD_TYPE extends Expression,
-            RIGHT_CHILD_TYPE extends Expression>
-        extends AbstractExpression<EXPR_TYPE>
-        implements BinaryNode<EXPR_TYPE, LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE> {
-
-    public BinaryExpression(NodeType type, LEFT_CHILD_TYPE left, RIGHT_CHILD_TYPE right) {
-        super(type, left, right);
+public class LessThanEqual<LEFT_CHILD_TYPE extends Expression, RIGHT_CHILD_TYPE extends Expression>
+        extends ComparisonPredicate<LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE> {
+    /**
+     * Constructor of Less Than And Equal.
+     *
+     * @param left  left child of Less Than And Equal
+     * @param right right child of Less Than And Equal
+     */
+    public LessThanEqual(LEFT_CHILD_TYPE left, RIGHT_CHILD_TYPE right) {
+        super(NodeType.LESS_THAN_EQUAL, left, right);
     }
 
     @Override
-    public LEFT_CHILD_TYPE left() {
-        return BinaryNode.super.left();
+    public boolean nullable() throws UnboundException {
+        return left().nullable() || right().nullable();
     }
 
     @Override
-    public RIGHT_CHILD_TYPE right() {
-        return BinaryNode.super.right();
+    public String toString() {
+        return "(" + left() + " <= " + right() + ")";
     }
 }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Literal.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Literal.java
index 21fce728f7..79e830d91d 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Literal.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Literal.java
@@ -30,14 +30,14 @@ import org.apache.doris.nereids.types.StringType;
 /**
  * All data type literal expression in Nereids.
  */
-public class Literal extends LeafExpression<Literal> {
+public class Literal extends Expression<Literal> implements LeafExpression<Literal> {
     private final DataType dataType;
     private final Object value;
 
     /**
      * Constructor for Literal.
      *
-     * @param value real value stored in java object
+     * @param value    real value stored in java object
      * @param dataType logical data type in Nereids
      */
     public Literal(Object value, DataType dataType) {
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/NamedExpression.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/NamedExpression.java
index 1001ba7205..ae7f4d27f1 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/NamedExpression.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/NamedExpression.java
@@ -18,38 +18,34 @@
 package org.apache.doris.nereids.trees.expressions;
 
 import org.apache.doris.nereids.exceptions.UnboundException;
+import org.apache.doris.nereids.trees.NodeType;
 
 import org.apache.commons.collections.CollectionUtils;
 
 import java.util.List;
-import java.util.UUID;
-import java.util.concurrent.atomic.AtomicLong;
 
 /**
  * Expression in Nereids that having name.
  */
-public interface NamedExpression<EXPR_TYPE extends NamedExpression<EXPR_TYPE>>
-        extends Expression<EXPR_TYPE> {
+public abstract class NamedExpression<EXPR_TYPE extends NamedExpression<EXPR_TYPE>> extends Expression<EXPR_TYPE> {
 
-    @Override
-    Expression child(int index);
-
-    @Override
-    List<Expression> children();
+    public NamedExpression(NodeType type, Expression... children) {
+        super(type, children);
+    }
 
-    default Slot toSlot() throws UnboundException {
+    public Slot toSlot() throws UnboundException {
         throw new UnboundException("toSlot");
     }
 
-    default String getName() throws UnboundException {
+    public String getName() throws UnboundException {
         throw new UnboundException("name");
     }
 
-    default ExprId getExprId() throws UnboundException {
+    public ExprId getExprId() throws UnboundException {
         throw new UnboundException("exprId");
     }
 
-    default List<String> getQualifier() throws UnboundException {
+    public List<String> getQualifier() throws UnboundException {
         throw new UnboundException("qualifier");
     }
 
@@ -59,23 +55,11 @@ public interface NamedExpression<EXPR_TYPE extends NamedExpression<EXPR_TYPE>>
      * @return qualified name
      * @throws UnboundException throw this exception if this expression is unbound
      */
-    default String getQualifiedName() throws UnboundException {
+    public String getQualifiedName() throws UnboundException {
         String qualifiedName = "";
         if (CollectionUtils.isNotEmpty(getQualifier())) {
             qualifiedName = String.join(".", getQualifier()) + ".";
         }
         return qualifiedName + getName();
     }
-
-    /**
-     * Tool class for generate next ExprId.
-     */
-    class NamedExpressionUtils {
-        static final UUID JVM_ID = UUID.randomUUID();
-        private static final AtomicLong CURRENT_ID = new AtomicLong();
-
-        static ExprId newExprId() {
-            return new ExprId(CURRENT_ID.getAndIncrement(), JVM_ID);
-        }
-    }
 }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Slot.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/NamedExpressionUtil.java
similarity index 67%
copy from fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Slot.java
copy to fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/NamedExpressionUtil.java
index 62f18e994c..610a695475 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Slot.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/NamedExpressionUtil.java
@@ -17,21 +17,20 @@
 
 package org.apache.doris.nereids.trees.expressions;
 
-import org.apache.doris.nereids.trees.NodeType;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicLong;
 
 /**
- * Abstract class for all slot in expression.
+ * The util of named expression.
  */
-public abstract class Slot<EXPR_TYPE extends Slot<EXPR_TYPE>>
-        extends LeafExpression<EXPR_TYPE>
-        implements NamedExpression<EXPR_TYPE> {
+public class NamedExpressionUtil {
+    /**
+     * Tool class for generate next ExprId.
+     */
+    private static final UUID JVM_ID = UUID.randomUUID();
+    private static final AtomicLong CURRENT_ID = new AtomicLong();
 
-    public Slot(NodeType type) {
-        super(type);
-    }
-
-    @Override
-    public Slot toSlot() {
-        return this;
+    public static ExprId newExprId() {
+        return new ExprId(CURRENT_ID.getAndIncrement(), JVM_ID);
     }
 }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Expression.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Not.java
similarity index 66%
copy from fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Expression.java
copy to fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Not.java
index 6783102fa7..15ddcf54b5 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Expression.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Not.java
@@ -18,25 +18,24 @@
 package org.apache.doris.nereids.trees.expressions;
 
 import org.apache.doris.nereids.exceptions.UnboundException;
-import org.apache.doris.nereids.trees.TreeNode;
-import org.apache.doris.nereids.types.DataType;
-
-import java.util.List;
+import org.apache.doris.nereids.trees.NodeType;
 
 /**
- * Abstract class for all Expression in Nereids.
+ * Not expression: not a.
  */
-public interface Expression<EXPR_TYPE extends Expression<EXPR_TYPE>> extends TreeNode<EXPR_TYPE> {
-
-    DataType getDataType() throws UnboundException;
-
-    String sql() throws UnboundException;
-
-    boolean nullable() throws UnboundException;
+public class Not<CHILD_TYPE extends Expression> extends Expression<Not<CHILD_TYPE>>
+        implements UnaryExpression<Not<CHILD_TYPE>, CHILD_TYPE> {
+    public Not(CHILD_TYPE child) {
+        super(NodeType.NOT, child);
+    }
 
     @Override
-    List<Expression> children();
+    public boolean nullable() throws UnboundException {
+        return child().nullable();
+    }
 
     @Override
-    Expression child(int index);
+    public String toString() {
+        return "( not " + child() + ")";
+    }
 }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/AbstractExpression.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/NullSafeEqual.java
similarity index 54%
rename from fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/AbstractExpression.java
rename to fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/NullSafeEqual.java
index 6996a66cc2..61488318b9 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/AbstractExpression.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/NullSafeEqual.java
@@ -18,42 +18,31 @@
 package org.apache.doris.nereids.trees.expressions;
 
 import org.apache.doris.nereids.exceptions.UnboundException;
-import org.apache.doris.nereids.trees.AbstractTreeNode;
 import org.apache.doris.nereids.trees.NodeType;
-import org.apache.doris.nereids.types.DataType;
-
-import java.util.List;
 
 /**
- * Abstract class for all Expression in Nereids.
+ * Null safe equal expression: a <=> b.
+ * Unlike normal equal to expression, null <=> null is true.
  */
-public abstract class AbstractExpression<EXPR_TYPE extends AbstractExpression<EXPR_TYPE>>
-        extends AbstractTreeNode<EXPR_TYPE>
-        implements Expression<EXPR_TYPE> {
-
-    public AbstractExpression(NodeType type, Expression... children) {
-        super(type, children);
-    }
-
-    public DataType getDataType() throws UnboundException {
-        throw new UnboundException("dataType");
-    }
-
-    public String sql() throws UnboundException {
-        throw new UnboundException("sql");
-    }
-
-    public boolean nullable() throws UnboundException {
-        throw new UnboundException("nullable");
+public class NullSafeEqual<LEFT_CHILD_TYPE extends Expression, RIGHT_CHILD_TYPE extends Expression>
+        extends ComparisonPredicate<LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE> {
+    /**
+     * Constructor of Null Safe Equal ComparisonPredicate.
+     *
+     * @param left  left child of Null Safe Equal
+     * @param right right child of Null Safe Equal
+     */
+    public NullSafeEqual(LEFT_CHILD_TYPE left, RIGHT_CHILD_TYPE right) {
+        super(NodeType.NULL_SAFE_EQUAL, left, right);
     }
 
     @Override
-    public List<Expression> children() {
-        return (List) children;
+    public boolean nullable() throws UnboundException {
+        return false;
     }
 
     @Override
-    public Expression child(int index) {
-        return (Expression) children.get(index);
+    public String toString() {
+        return "(" + left() + " <=> " + right() + ")";
     }
 }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Slot.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Slot.java
index 62f18e994c..16d23ffd98 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Slot.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Slot.java
@@ -22,9 +22,8 @@ import org.apache.doris.nereids.trees.NodeType;
 /**
  * Abstract class for all slot in expression.
  */
-public abstract class Slot<EXPR_TYPE extends Slot<EXPR_TYPE>>
-        extends LeafExpression<EXPR_TYPE>
-        implements NamedExpression<EXPR_TYPE> {
+public abstract class Slot<EXPR_TYPE extends Slot<EXPR_TYPE>> extends NamedExpression<EXPR_TYPE>
+        implements LeafExpression<EXPR_TYPE> {
 
     public Slot(NodeType type) {
         super(type);
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/SlotReference.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/SlotReference.java
index b4d76ac136..f779b9eaba 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/SlotReference.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/SlotReference.java
@@ -38,7 +38,7 @@ public class SlotReference extends Slot<SlotReference> {
     private final boolean nullable;
 
     public SlotReference(String name, DataType dataType, boolean nullable, List<String> qualifier) {
-        this(NamedExpressionUtils.newExprId(), name, dataType, nullable, qualifier);
+        this(NamedExpressionUtil.newExprId(), name, dataType, nullable, qualifier);
     }
 
     /**
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/UnaryExpression.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/UnaryExpression.java
index 7729720d42..991edda91c 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/UnaryExpression.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/UnaryExpression.java
@@ -17,19 +17,12 @@
 
 package org.apache.doris.nereids.trees.expressions;
 
-import org.apache.doris.nereids.trees.NodeType;
 import org.apache.doris.nereids.trees.UnaryNode;
 
 /**
  * Abstract class for all expression that have one child.
  */
-public abstract class UnaryExpression<
-            EXPR_TYPE extends UnaryExpression<EXPR_TYPE, CHILD_TYPE>,
-            CHILD_TYPE extends Expression>
-        extends AbstractExpression<EXPR_TYPE>
-        implements UnaryNode<EXPR_TYPE, CHILD_TYPE> {
+public interface UnaryExpression<EXPR_TYPE extends UnaryExpression<EXPR_TYPE, CHILD_TYPE>,
+        CHILD_TYPE extends Expression> extends UnaryNode<EXPR_TYPE, CHILD_TYPE> {
 
-    public UnaryExpression(NodeType type, CHILD_TYPE child) {
-        super(type, child);
-    }
 }
diff --git a/fe/fe-core/src/test/java/org/apache/doris/analysis/BinaryPredicateTest.java b/fe/fe-core/src/test/java/org/apache/doris/analysis/ComparisonPredicateTest.java
similarity index 98%
rename from fe/fe-core/src/test/java/org/apache/doris/analysis/BinaryPredicateTest.java
rename to fe/fe-core/src/test/java/org/apache/doris/analysis/ComparisonPredicateTest.java
index e1c7d3ec99..d050c94d90 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/analysis/BinaryPredicateTest.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/analysis/ComparisonPredicateTest.java
@@ -31,7 +31,11 @@ import mockit.Mocked;
 import org.junit.Assert;
 import org.junit.Test;
 
-public class BinaryPredicateTest {
+
+/**
+ * Comparison Predicate unit test.
+ */
+public class ComparisonPredicateTest {
 
     @Mocked
     Analyzer analyzer;


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