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/07/05 10:23:07 UTC

[doris] branch master updated: [enhancement](nereids) make filter node and join node work in Nereids (#10605)

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/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new 589ab06b5c [enhancement](nereids) make filter node and join node work in Nereids (#10605)
589ab06b5c is described below

commit 589ab06b5c33abe580868a17ccfdf16e2826b3a1
Author: morrySnow <10...@users.noreply.github.com>
AuthorDate: Tue Jul 5 18:23:00 2022 +0800

    [enhancement](nereids) make filter node and join node work in Nereids (#10605)
    
    enhancement
    - add functions `finalizeForNereids` and `finalizeImplForNereids` in stale expression to generate some attributes using in BE.
    - remove unnecessary parameter `Analyzer` in function `getBuiltinFunction`
    - swap join condition if its left hand expression related to right table
    - change join physical implementation to broadcast hash join
    - add push predicate rule into planner
    
    fix
    - swap join children visit order to ensure the last fragment is root
    - avoid visit join left child twice
    
    known issues
    - expression compute will generate a wrong answer when expression include arithmetic with two literal children.
---
 .../org/apache/doris/analysis/ArithmeticExpr.java  |  24 +++--
 .../apache/doris/analysis/BetweenPredicate.java    |   5 +
 .../org/apache/doris/analysis/BinaryPredicate.java |  13 ++-
 .../apache/doris/analysis/CompoundPredicate.java   |   5 +
 .../apache/doris/analysis/DefaultValueExpr.java    |   5 +
 .../main/java/org/apache/doris/analysis/Expr.java  |  21 +++-
 .../apache/doris/analysis/FunctionCallExpr.java    |  22 ++--
 .../doris/analysis/GroupingFunctionCallExpr.java   |   3 +-
 .../org/apache/doris/analysis/InPredicate.java     |  27 ++++-
 .../org/apache/doris/analysis/IsNullPredicate.java |  17 ++-
 .../org/apache/doris/analysis/LikePredicate.java   |  10 +-
 .../org/apache/doris/analysis/LiteralExpr.java     |   5 +
 .../java/org/apache/doris/analysis/Predicate.java  |   5 +
 .../java/org/apache/doris/analysis/SlotRef.java    |   5 +
 .../doris/analysis/TimestampArithmeticExpr.java    |   4 +-
 .../doris/analysis/TupleIsNullPredicate.java       |   5 +
 .../org/apache/doris/nereids/NereidsPlanner.java   |  41 ++++++--
 .../glue/translator/ExpressionTranslator.java      |  24 ++++-
 .../glue/translator/PhysicalPlanTranslator.java    | 114 +++++++++++----------
 .../jobs/PredicatePushDownRulesJob.java}           |  35 +++----
 .../java/org/apache/doris/nereids/util/Utils.java  |  15 ---
 21 files changed, 270 insertions(+), 135 deletions(-)

diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/ArithmeticExpr.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/ArithmeticExpr.java
index 8629d771ba..4eb3b84879 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/ArithmeticExpr.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/ArithmeticExpr.java
@@ -321,8 +321,7 @@ public class ArithmeticExpr extends Expr {
                 } else {
                     type = t;
                 }
-                fn = getBuiltinFunction(
-                        analyzer, op.getName(), collectChildReturnTypes(), Function.CompareMode.IS_SUPERTYPE_OF);
+                fn = getBuiltinFunction(op.getName(), collectChildReturnTypes(), Function.CompareMode.IS_SUPERTYPE_OF);
                 if (fn == null) {
                     Preconditions.checkState(false, String.format("No match for op with operand types", toSql()));
                 }
@@ -406,8 +405,7 @@ public class ArithmeticExpr extends Expr {
                             "Unknown arithmetic operation " + op.toString() + " in: " + this.toSql());
                     break;
             }
-            fn = getBuiltinFunction(analyzer, op.name, collectChildReturnTypes(),
-                    Function.CompareMode.IS_IDENTICAL);
+            fn = getBuiltinFunction(op.name, collectChildReturnTypes(), Function.CompareMode.IS_IDENTICAL);
             if (fn == null) {
                 Preconditions.checkState(false, String.format(
                         "No match for vec function '%s' with operand types %s and %s", toSql(), t1, t2));
@@ -420,8 +418,7 @@ public class ArithmeticExpr extends Expr {
                 if (getChild(0).getType().getPrimitiveType() != PrimitiveType.BIGINT) {
                     castChild(type, 0);
                 }
-                fn = getBuiltinFunction(
-                        analyzer, op.getName(), collectChildReturnTypes(), Function.CompareMode.IS_SUPERTYPE_OF);
+                fn = getBuiltinFunction(op.getName(), collectChildReturnTypes(), Function.CompareMode.IS_SUPERTYPE_OF);
                 if (fn == null) {
                     Preconditions.checkState(false, String.format("No match for op with operand types", toSql()));
                 }
@@ -467,8 +464,7 @@ public class ArithmeticExpr extends Expr {
                     break;
             }
             type = castBinaryOp(commonType);
-            fn = getBuiltinFunction(analyzer, fnName, collectChildReturnTypes(),
-                    Function.CompareMode.IS_IDENTICAL);
+            fn = getBuiltinFunction(fnName, collectChildReturnTypes(), Function.CompareMode.IS_IDENTICAL);
             if (fn == null) {
                 Preconditions.checkState(false, String.format(
                         "No match for '%s' with operand types %s and %s", toSql(), t1, t2));
@@ -506,4 +502,16 @@ public class ArithmeticExpr extends Expr {
         return 31 * super.hashCode() + Objects.hashCode(op);
     }
 
+    @Override
+    public void finalizeImplForNereids() throws AnalysisException {
+        if (op == Operator.BITNOT) {
+            fn = getBuiltinFunction(op.getName(), collectChildReturnTypes(), Function.CompareMode.IS_SUPERTYPE_OF);
+        } else {
+            fn = getBuiltinFunction(op.name, collectChildReturnTypes(), Function.CompareMode.IS_IDENTICAL);
+        }
+        if (fn == null) {
+            Preconditions.checkState(false, String.format("No match for op with operand types. %s", toSql()));
+        }
+        type = fn.getReturnType();
+    }
 }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/BetweenPredicate.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/BetweenPredicate.java
index 84fe311237..b3cca47ad1 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/BetweenPredicate.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/BetweenPredicate.java
@@ -124,4 +124,9 @@ public class BetweenPredicate extends Predicate {
     public int hashCode() {
         return 31 * super.hashCode() + Boolean.hashCode(isNotBetween);
     }
+
+    @Override
+    public void finalizeImplForNereids() throws AnalysisException {
+        throw new AnalysisException("analyze between predicate for Nereids do not implementation.");
+    }
 }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/BinaryPredicate.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/BinaryPredicate.java
index 7da7356b36..d43143e3db 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/BinaryPredicate.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/BinaryPredicate.java
@@ -278,8 +278,8 @@ public class BinaryPredicate extends Predicate implements Writable {
         //OpcodeRegistry.BuiltinFunction match = OpcodeRegistry.instance().getFunctionInfo(
         //        op.toFilterFunctionOp(), true, true, cmpType, cmpType);
         try {
-            match = getBuiltinFunction(analyzer, op.name, collectChildReturnTypes(),
-                Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF);
+            match = getBuiltinFunction(op.name, collectChildReturnTypes(),
+                    Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF);
         } catch (AnalysisException e) {
             Preconditions.checkState(false);
         }
@@ -408,8 +408,7 @@ public class BinaryPredicate extends Predicate implements Writable {
 
         this.opcode = op.getOpcode();
         String opName = op.getName();
-        fn = getBuiltinFunction(analyzer, opName, collectChildReturnTypes(),
-                Function.CompareMode.IS_SUPERTYPE_OF);
+        fn = getBuiltinFunction(opName, collectChildReturnTypes(), Function.CompareMode.IS_SUPERTYPE_OF);
         if (fn == null) {
             Preconditions.checkState(false, String.format(
                     "No match for '%s' with operand types %s and %s", toSql()));
@@ -697,4 +696,10 @@ public class BinaryPredicate extends Predicate implements Writable {
         }
         return hasNullableChild();
     }
+
+    @Override
+    public void finalizeImplForNereids() throws AnalysisException {
+        super.finalizeImplForNereids();
+        fn = getBuiltinFunction(op.name, collectChildReturnTypes(), Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF);
+    }
 }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/CompoundPredicate.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/CompoundPredicate.java
index 2672d5564c..7ce22bb732 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/CompoundPredicate.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/CompoundPredicate.java
@@ -256,4 +256,9 @@ public class CompoundPredicate extends Predicate {
     public boolean isNullable() {
         return hasNullableChild();
     }
+
+    @Override
+    public void finalizeImplForNereids() throws AnalysisException {
+
+    }
 }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/DefaultValueExpr.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/DefaultValueExpr.java
index 4552e6f84f..01ed882a2c 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/DefaultValueExpr.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/DefaultValueExpr.java
@@ -40,4 +40,9 @@ public class DefaultValueExpr extends Expr {
     public Expr clone() {
         return null;
     }
+
+    @Override
+    public void finalizeImplForNereids() throws AnalysisException {
+
+    }
 }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/Expr.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/Expr.java
index cb6c5d7f0e..383a75ba31 100755
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/Expr.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/Expr.java
@@ -1617,8 +1617,7 @@ public abstract class Expr extends TreeNode<Expr> implements ParseNode, Cloneabl
      * Looks up in the catalog the builtin for 'name' and 'argTypes'.
      * Returns null if the function is not found.
      */
-    protected Function getBuiltinFunction(
-            Analyzer analyzer, String name, Type[] argTypes, Function.CompareMode mode)
+    protected Function getBuiltinFunction(String name, Type[] argTypes, Function.CompareMode mode)
             throws AnalysisException {
         FunctionName fnName = new FunctionName(name);
         Function searchDesc = new Function(fnName, Arrays.asList(argTypes), Type.INVALID, false,
@@ -1633,8 +1632,7 @@ public abstract class Expr extends TreeNode<Expr> implements ParseNode, Cloneabl
         return f;
     }
 
-    protected Function getTableFunction(String name, Type[] argTypes,
-                                        Function.CompareMode mode) {
+    protected Function getTableFunction(String name, Type[] argTypes, Function.CompareMode mode) {
         FunctionName fnName = new FunctionName(name);
         Function searchDesc = new Function(fnName, Arrays.asList(argTypes), Type.INVALID, false,
                 VectorizedUtil.isVectorized());
@@ -1975,4 +1973,19 @@ public abstract class Expr extends TreeNode<Expr> implements ParseNode, Cloneabl
         }
         return true;
     }
+
+    public final void finalizeForNereids() throws AnalysisException {
+        if (isAnalyzed()) {
+            return;
+        }
+        for (Expr child : children) {
+            child.finalizeForNereids();
+        }
+        finalizeImplForNereids();
+        analysisDone();
+    }
+
+    public void finalizeImplForNereids() throws AnalysisException {
+        throw new AnalysisException("analyze for Nereids do not implementation.");
+    }
 }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java
index 5f7af9643f..637bf6c158 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java
@@ -793,15 +793,13 @@ public class FunctionCallExpr extends Expr {
      * @throws AnalysisException
      */
     public void analyzeImplForDefaultValue() throws AnalysisException {
-        fn = getBuiltinFunction(null, fnName.getFunction(), new Type[0],
-                Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF);
+        fn = getBuiltinFunction(fnName.getFunction(), new Type[0], Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF);
         type = fn.getReturnType();
         for (int i = 0; i < children.size(); ++i) {
             if (getChild(i).getType().isNull()) {
                 uncheckedCastChild(Type.BOOLEAN, i);
             }
         }
-        return;
     }
 
     @Override
@@ -825,8 +823,7 @@ public class FunctionCallExpr extends Expr {
             // There is no version of COUNT() that takes more than 1 argument but after
             // the equal, we only need count(*).
             // TODO: fix how we equal count distinct.
-            fn = getBuiltinFunction(analyzer, fnName.getFunction(), new Type[0],
-                    Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF);
+            fn = getBuiltinFunction(fnName.getFunction(), new Type[0], Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF);
             type = fn.getReturnType();
 
             // Make sure BE doesn't see any TYPE_NULL exprs
@@ -854,7 +851,7 @@ public class FunctionCallExpr extends Expr {
             if (!VectorizedUtil.isVectorized()) {
                 type = getChild(0).type.getMaxResolutionType();
             }
-            fn = getBuiltinFunction(analyzer, fnName.getFunction(), new Type[]{type},
+            fn = getBuiltinFunction(fnName.getFunction(), new Type[]{type},
                     Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF);
         } else if (fnName.getFunction().equalsIgnoreCase("count_distinct")) {
             Type compatibleType = this.children.get(0).getType();
@@ -867,7 +864,7 @@ public class FunctionCallExpr extends Expr {
                 }
             }
 
-            fn = getBuiltinFunction(analyzer, fnName.getFunction(), new Type[]{compatibleType},
+            fn = getBuiltinFunction(fnName.getFunction(), new Type[]{compatibleType},
                     Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF);
         } else if (fnName.getFunction().equalsIgnoreCase(FunctionSet.WINDOW_FUNNEL)) {
             if (fnParams.exprs() == null || fnParams.exprs().size() < 4) {
@@ -895,14 +892,14 @@ public class FunctionCallExpr extends Expr {
                 }
                 childTypes[i] = children.get(i).type;
             }
-            fn = getBuiltinFunction(analyzer, fnName.getFunction(), childTypes,
+            fn = getBuiltinFunction(fnName.getFunction(), childTypes,
                     Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF);
         } else if (fnName.getFunction().equalsIgnoreCase("if")) {
             Type[] childTypes = collectChildReturnTypes();
             Type assignmentCompatibleType = ScalarType.getAssignmentCompatibleType(childTypes[1], childTypes[2], true);
             childTypes[1] = assignmentCompatibleType;
             childTypes[2] = assignmentCompatibleType;
-            fn = getBuiltinFunction(analyzer, fnName.getFunction(), childTypes,
+            fn = getBuiltinFunction(fnName.getFunction(), childTypes,
                     Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF);
         } else {
             // now first find table function in table function sets
@@ -917,7 +914,7 @@ public class FunctionCallExpr extends Expr {
                 // now first find function in built-in functions
                 if (Strings.isNullOrEmpty(fnName.getDb())) {
                     Type[] childTypes = collectChildReturnTypes();
-                    fn = getBuiltinFunction(analyzer, fnName.getFunction(), childTypes,
+                    fn = getBuiltinFunction(fnName.getFunction(), childTypes,
                             Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF);
                 }
 
@@ -1257,4 +1254,9 @@ public class FunctionCallExpr extends Expr {
         }
         return result.toString();
     }
+
+    @Override
+    public void finalizeImplForNereids() throws AnalysisException {
+        super.finalizeImplForNereids();
+    }
 }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/GroupingFunctionCallExpr.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/GroupingFunctionCallExpr.java
index c2057506a3..47ea283962 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/GroupingFunctionCallExpr.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/GroupingFunctionCallExpr.java
@@ -73,8 +73,7 @@ public class GroupingFunctionCallExpr extends FunctionCallExpr {
         }
         Type[] childTypes = new Type[1];
         childTypes[0] = Type.BIGINT;
-        fn = getBuiltinFunction(analyzer, getFnName().getFunction(), childTypes,
-                Function.CompareMode.IS_IDENTICAL);
+        fn = getBuiltinFunction(getFnName().getFunction(), childTypes, Function.CompareMode.IS_IDENTICAL);
         this.type = fn.getReturnType();
     }
 
diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/InPredicate.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/InPredicate.java
index 32f9bd5ffb..5d01e08a9c 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/InPredicate.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/InPredicate.java
@@ -199,7 +199,7 @@ public class InPredicate extends Predicate {
             // argTypes, Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF);
             opcode = isNotIn ? TExprOpcode.FILTER_NOT_IN : TExprOpcode.FILTER_IN;
         } else {
-            fn = getBuiltinFunction(analyzer, isNotIn ? NOT_IN_ITERATE : IN_ITERATE,
+            fn = getBuiltinFunction(isNotIn ? NOT_IN_ITERATE : IN_ITERATE,
                     argTypes, Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF);
             opcode = isNotIn ? TExprOpcode.FILTER_NEW_NOT_IN : TExprOpcode.FILTER_NEW_IN;
         }
@@ -319,4 +319,29 @@ public class InPredicate extends Predicate {
     public boolean isNullable() {
         return hasNullableChild();
     }
+
+    @Override
+    public void finalizeImplForNereids() throws AnalysisException {
+        super.finalizeImplForNereids();
+        boolean allConstant = true;
+        for (int i = 1; i < children.size(); ++i) {
+            if (!children.get(i).isConstant()) {
+                allConstant = false;
+                break;
+            }
+        }
+        // Only lookup fn_ if all subqueries have been rewritten. If the second child is a
+        // subquery, it will have type ArrayType, which cannot be resolved to a builtin
+        // function and will fail analysis.
+        Type[] argTypes = {getChild(0).type, getChild(1).type};
+        if (allConstant) {
+            // fn = getBuiltinFunction(analyzer, isNotIn ? NOT_IN_SET_LOOKUP : IN_SET_LOOKUP,
+            // argTypes, Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF);
+            opcode = isNotIn ? TExprOpcode.FILTER_NOT_IN : TExprOpcode.FILTER_IN;
+        } else {
+            fn = getBuiltinFunction(isNotIn ? NOT_IN_ITERATE : IN_ITERATE,
+                    argTypes, Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF);
+            opcode = isNotIn ? TExprOpcode.FILTER_NEW_NOT_IN : TExprOpcode.FILTER_NEW_IN;
+        }
+    }
 }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/IsNullPredicate.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/IsNullPredicate.java
index 8c17ff9af7..3263551c8a 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/IsNullPredicate.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/IsNullPredicate.java
@@ -113,11 +113,9 @@ public class IsNullPredicate extends Predicate {
     public void analyzeImpl(Analyzer analyzer) throws AnalysisException {
         super.analyzeImpl(analyzer);
         if (isNotNull) {
-            fn = getBuiltinFunction(
-                    analyzer, IS_NOT_NULL, collectChildReturnTypes(), Function.CompareMode.IS_INDISTINGUISHABLE);
+            fn = getBuiltinFunction(IS_NOT_NULL, collectChildReturnTypes(), Function.CompareMode.IS_INDISTINGUISHABLE);
         } else {
-            fn = getBuiltinFunction(
-                    analyzer, IS_NULL, collectChildReturnTypes(), Function.CompareMode.IS_INDISTINGUISHABLE);
+            fn = getBuiltinFunction(IS_NULL, collectChildReturnTypes(), Function.CompareMode.IS_INDISTINGUISHABLE);
         }
         Preconditions.checkState(fn != null, "tupleisNull fn == NULL");
 
@@ -156,4 +154,15 @@ public class IsNullPredicate extends Predicate {
         }
         return childValue instanceof NullLiteral ? new BoolLiteral(!isNotNull) : new BoolLiteral(isNotNull);
     }
+
+    @Override
+    public void finalizeImplForNereids() throws AnalysisException {
+        super.finalizeImplForNereids();
+        if (isNotNull) {
+            fn = getBuiltinFunction(IS_NOT_NULL, collectChildReturnTypes(), Function.CompareMode.IS_INDISTINGUISHABLE);
+        } else {
+            fn = getBuiltinFunction(IS_NULL, collectChildReturnTypes(), Function.CompareMode.IS_INDISTINGUISHABLE);
+        }
+        Preconditions.checkState(fn != null, "tupleisNull fn == NULL");
+    }
 }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/LikePredicate.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/LikePredicate.java
index 05cee02937..3edf3ff11b 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/LikePredicate.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/LikePredicate.java
@@ -134,8 +134,8 @@ public class LikePredicate extends Predicate {
             uncheckedCastChild(Type.VARCHAR, 0);
         }
 
-        fn = getBuiltinFunction(analyzer, op.toString(),
-                collectChildReturnTypes(), Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF);
+        fn = getBuiltinFunction(op.toString(), collectChildReturnTypes(),
+                Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF);
 
         if (!getChild(1).getType().isNull() && getChild(1).isLiteral() && (op == Operator.REGEXP)) {
             // let's make sure the pattern works
@@ -154,4 +154,10 @@ public class LikePredicate extends Predicate {
         return 31 * super.hashCode() + Objects.hashCode(op);
     }
 
+    @Override
+    public void finalizeImplForNereids() throws AnalysisException {
+        super.finalizeImplForNereids();
+        fn = getBuiltinFunction(op.toString(), collectChildReturnTypes(),
+                Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF);
+    }
 }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/LiteralExpr.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/LiteralExpr.java
index 3d3574dd35..0c41bf3a15 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/LiteralExpr.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/LiteralExpr.java
@@ -247,4 +247,9 @@ public abstract class LiteralExpr extends Expr implements Comparable<LiteralExpr
     public boolean isNullable() {
         return this instanceof NullLiteral;
     }
+
+    @Override
+    public void finalizeImplForNereids() throws AnalysisException {
+
+    }
 }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/Predicate.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/Predicate.java
index 1c2f87b4f5..b2fb78cc4c 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/Predicate.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/Predicate.java
@@ -156,4 +156,9 @@ public abstract class Predicate extends Expr {
     public Pair<SlotId, SlotId> getEqSlots() {
         return null;
     }
+
+    @Override
+    public void finalizeImplForNereids() throws AnalysisException {
+        type = Type.BOOLEAN;
+    }
 }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/SlotRef.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/SlotRef.java
index 6bb77fd379..6a0976404b 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/SlotRef.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/SlotRef.java
@@ -441,4 +441,9 @@ public class SlotRef extends Expr {
         Preconditions.checkNotNull(desc);
         return desc.getIsNullable();
     }
+
+    @Override
+    public void finalizeImplForNereids() throws AnalysisException {
+
+    }
 }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/TimestampArithmeticExpr.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/TimestampArithmeticExpr.java
index 1517bfff89..3f8a143f73 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/TimestampArithmeticExpr.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/TimestampArithmeticExpr.java
@@ -213,8 +213,8 @@ public class TimestampArithmeticExpr extends Expr {
                     (op == ArithmeticExpr.Operator.ADD) ? "ADD" : "SUB");
         }
 
-        fn = getBuiltinFunction(analyzer, funcOpName.toLowerCase(),
-                collectChildReturnTypes(), Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF);
+        fn = getBuiltinFunction(funcOpName.toLowerCase(), collectChildReturnTypes(),
+                Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF);
         LOG.debug("fn is {} name is {}", fn, funcOpName);
     }
 
diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/TupleIsNullPredicate.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/TupleIsNullPredicate.java
index 7e9e422d4e..8132e2d730 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/TupleIsNullPredicate.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/TupleIsNullPredicate.java
@@ -198,4 +198,9 @@ public class TupleIsNullPredicate extends Predicate {
     public boolean isNullable() {
         return false;
     }
+
+    @Override
+    public void finalizeImplForNereids() throws AnalysisException {
+        super.finalizeImplForNereids();
+    }
 }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/NereidsPlanner.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/NereidsPlanner.java
index 96a4a26f04..f30c333502 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/NereidsPlanner.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/NereidsPlanner.java
@@ -18,19 +18,27 @@
 package org.apache.doris.nereids;
 
 import org.apache.doris.analysis.DescriptorTable;
+import org.apache.doris.analysis.Expr;
+import org.apache.doris.analysis.SlotDescriptor;
+import org.apache.doris.analysis.SlotRef;
 import org.apache.doris.analysis.StatementBase;
+import org.apache.doris.analysis.TupleDescriptor;
+import org.apache.doris.analysis.TupleId;
 import org.apache.doris.common.AnalysisException;
+import org.apache.doris.common.Id;
 import org.apache.doris.common.UserException;
 import org.apache.doris.nereids.glue.LogicalPlanAdapter;
 import org.apache.doris.nereids.glue.translator.PhysicalPlanTranslator;
 import org.apache.doris.nereids.glue.translator.PlanTranslatorContext;
 import org.apache.doris.nereids.jobs.AnalyzeRulesJob;
 import org.apache.doris.nereids.jobs.OptimizeRulesJob;
+import org.apache.doris.nereids.jobs.PredicatePushDownRulesJob;
 import org.apache.doris.nereids.memo.Group;
 import org.apache.doris.nereids.memo.GroupExpression;
 import org.apache.doris.nereids.memo.Memo;
 import org.apache.doris.nereids.properties.PhysicalProperties;
 import org.apache.doris.nereids.trees.expressions.NamedExpression;
+import org.apache.doris.nereids.trees.expressions.Slot;
 import org.apache.doris.nereids.trees.plans.Plan;
 import org.apache.doris.nereids.trees.plans.logical.LogicalPlan;
 import org.apache.doris.nereids.trees.plans.physical.PhysicalPlan;
@@ -40,10 +48,12 @@ import org.apache.doris.planner.ScanNode;
 import org.apache.doris.qe.ConnectContext;
 
 import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
 
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 import java.util.stream.Collectors;
 
 /**
@@ -66,26 +76,42 @@ public class NereidsPlanner extends Planner {
         if (!(queryStmt instanceof LogicalPlanAdapter)) {
             throw new RuntimeException("Wrong type of queryStmt, expected: <? extends LogicalPlanAdapter>");
         }
+
         LogicalPlanAdapter logicalPlanAdapter = (LogicalPlanAdapter) queryStmt;
         PhysicalPlan physicalPlan = plan(logicalPlanAdapter.getLogicalPlan(), new PhysicalProperties(), ctx);
+
         PhysicalPlanTranslator physicalPlanTranslator = new PhysicalPlanTranslator();
         PlanTranslatorContext planTranslatorContext = new PlanTranslatorContext();
         physicalPlanTranslator.translatePlan(physicalPlan, planTranslatorContext);
+
+        scanNodeList = planTranslatorContext.getScanNodeList();
         descTable = planTranslatorContext.getDescTable();
         fragments = new ArrayList<>(planTranslatorContext.getPlanFragmentList());
-        PlanFragment root = fragments.get(fragments.size() - 1);
         for (PlanFragment fragment : fragments) {
             fragment.finalize(queryStmt);
         }
-        root.resetOutputExprs(descTable.getTupleDesc(root.getPlanRoot().getTupleIds().get(0)));
+        Collections.reverse(fragments);
+        PlanFragment root = fragments.get(0);
+
+        // compute output exprs
+        Map<Integer, Expr> outputCandidates = Maps.newHashMap();
+        List<Expr> outputExprs = Lists.newArrayList();
+        for (TupleId tupleId : root.getPlanRoot().getTupleIds()) {
+            TupleDescriptor tupleDescriptor = descTable.getTupleDesc(tupleId);
+            for (SlotDescriptor slotDescriptor : tupleDescriptor.getSlots()) {
+                SlotRef slotRef = new SlotRef(slotDescriptor);
+                outputCandidates.put(slotDescriptor.getId().asInt(), slotRef);
+            }
+        }
+        physicalPlan.getOutput().stream().map(Slot::getExprId)
+                .map(Id::asInt).forEach(i -> outputExprs.add(outputCandidates.get(i)));
+        root.setOutputExprs(outputExprs);
         root.getPlanRoot().convertToVectoriezd();
-        scanNodeList = planTranslatorContext.getScanNodeList();
-        logicalPlanAdapter.setResultExprs(root.getOutputExprs());
+
+        logicalPlanAdapter.setResultExprs(outputExprs);
         ArrayList<String> columnLabelList = physicalPlan.getOutput().stream()
                 .map(NamedExpression::getName).collect(Collectors.toCollection(ArrayList::new));
         logicalPlanAdapter.setColLabels(columnLabelList);
-
-        Collections.reverse(fragments);
     }
 
     /**
@@ -118,6 +144,9 @@ public class NereidsPlanner extends Planner {
         AnalyzeRulesJob analyzeRulesJob = new AnalyzeRulesJob(plannerContext);
         analyzeRulesJob.execute();
 
+        PredicatePushDownRulesJob predicatePushDownRulesJob = new PredicatePushDownRulesJob(plannerContext);
+        predicatePushDownRulesJob.execute();
+
         OptimizeRulesJob optimizeRulesJob = new OptimizeRulesJob(plannerContext);
         optimizeRulesJob.execute();
 
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/ExpressionTranslator.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/ExpressionTranslator.java
index 85dd9625ed..69e8ac5bb4 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/ExpressionTranslator.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/ExpressionTranslator.java
@@ -28,6 +28,7 @@ import org.apache.doris.analysis.IntLiteral;
 import org.apache.doris.analysis.NullLiteral;
 import org.apache.doris.analysis.StringLiteral;
 import org.apache.doris.catalog.Type;
+import org.apache.doris.nereids.exceptions.AnalysisException;
 import org.apache.doris.nereids.trees.NodeType;
 import org.apache.doris.nereids.trees.expressions.Arithmetic;
 import org.apache.doris.nereids.trees.expressions.Between;
@@ -62,8 +63,23 @@ public class ExpressionTranslator extends DefaultExpressionVisitor<Expr, PlanTra
 
     public static ExpressionTranslator INSTANCE = new ExpressionTranslator();
 
-    public static Expr translate(Expression expression, PlanTranslatorContext planContext) {
-        return expression.accept(INSTANCE, planContext);
+    /**
+     * The entry function of ExpressionTranslator, call {@link Expr#finalizeForNereids()} to generate
+     * some attributes using in BE.
+     *
+     * @param expression nereids expression
+     * @param context translator context
+     * @return stale planner's expr
+     */
+    public static Expr translate(Expression expression, PlanTranslatorContext context) {
+        Expr staleExpr =  expression.accept(INSTANCE, context);
+        try {
+            staleExpr.finalizeForNereids();
+        } catch (org.apache.doris.common.AnalysisException e) {
+            throw new AnalysisException(
+                    "Translate Nereids expression to stale expression failed. " + e.getMessage(), e);
+        }
+        return staleExpr;
     }
 
     @Override
@@ -159,7 +175,7 @@ public class ExpressionTranslator extends DefaultExpressionVisitor<Expr, PlanTra
     @Override
     public Expr visitCompoundPredicate(CompoundPredicate compoundPredicate, PlanTranslatorContext context) {
         NodeType nodeType = compoundPredicate.getType();
-        org.apache.doris.analysis.CompoundPredicate.Operator staleOp = null;
+        org.apache.doris.analysis.CompoundPredicate.Operator staleOp;
         switch (nodeType) {
             case OR:
                 staleOp = org.apache.doris.analysis.CompoundPredicate.Operator.OR;
@@ -171,7 +187,7 @@ public class ExpressionTranslator extends DefaultExpressionVisitor<Expr, PlanTra
                 staleOp = org.apache.doris.analysis.CompoundPredicate.Operator.NOT;
                 break;
             default:
-                throw new RuntimeException(String.format("Unknown node type: %s", nodeType.name()));
+                throw new AnalysisException(String.format("Unknown node type: %s", nodeType.name()));
         }
         return new org.apache.doris.analysis.CompoundPredicate(staleOp,
                 compoundPredicate.child(0).accept(this, context),
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java
index 04abd987cb..da69c993fa 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java
@@ -21,13 +21,11 @@ import org.apache.doris.analysis.AggregateInfo;
 import org.apache.doris.analysis.BaseTableRef;
 import org.apache.doris.analysis.Expr;
 import org.apache.doris.analysis.FunctionCallExpr;
-import org.apache.doris.analysis.SlotDescriptor;
 import org.apache.doris.analysis.SlotRef;
 import org.apache.doris.analysis.SortInfo;
 import org.apache.doris.analysis.TableName;
 import org.apache.doris.analysis.TableRef;
 import org.apache.doris.analysis.TupleDescriptor;
-import org.apache.doris.analysis.TupleId;
 import org.apache.doris.catalog.OlapTable;
 import org.apache.doris.catalog.Table;
 import org.apache.doris.nereids.exceptions.AnalysisException;
@@ -40,23 +38,27 @@ import org.apache.doris.nereids.operators.plans.physical.PhysicalOlapScan;
 import org.apache.doris.nereids.operators.plans.physical.PhysicalOperator;
 import org.apache.doris.nereids.operators.plans.physical.PhysicalProject;
 import org.apache.doris.nereids.properties.OrderKey;
+import org.apache.doris.nereids.trees.expressions.EqualTo;
+import org.apache.doris.nereids.trees.expressions.ExprId;
 import org.apache.doris.nereids.trees.expressions.Expression;
 import org.apache.doris.nereids.trees.expressions.NamedExpression;
 import org.apache.doris.nereids.trees.expressions.Slot;
 import org.apache.doris.nereids.trees.expressions.SlotReference;
 import org.apache.doris.nereids.trees.expressions.functions.AggregateFunction;
+import org.apache.doris.nereids.trees.expressions.visitor.SlotExtractor;
 import org.apache.doris.nereids.trees.plans.Plan;
 import org.apache.doris.nereids.trees.plans.PlanOperatorVisitor;
 import org.apache.doris.nereids.trees.plans.physical.PhysicalBinaryPlan;
 import org.apache.doris.nereids.trees.plans.physical.PhysicalLeafPlan;
 import org.apache.doris.nereids.trees.plans.physical.PhysicalPlan;
 import org.apache.doris.nereids.trees.plans.physical.PhysicalUnaryPlan;
-import org.apache.doris.nereids.util.Utils;
+import org.apache.doris.nereids.util.ExpressionUtils;
 import org.apache.doris.planner.AggregationNode;
 import org.apache.doris.planner.CrossJoinNode;
 import org.apache.doris.planner.DataPartition;
 import org.apache.doris.planner.ExchangeNode;
 import org.apache.doris.planner.HashJoinNode;
+import org.apache.doris.planner.HashJoinNode.DistributionMode;
 import org.apache.doris.planner.OlapScanNode;
 import org.apache.doris.planner.PlanFragment;
 import org.apache.doris.planner.PlanNode;
@@ -64,8 +66,6 @@ import org.apache.doris.planner.SortNode;
 
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
 
 import java.util.ArrayList;
 import java.util.HashSet;
@@ -82,7 +82,23 @@ import java.util.stream.Collectors;
  * </STRONG>
  */
 public class PhysicalPlanTranslator extends PlanOperatorVisitor<PlanFragment, PlanTranslatorContext> {
-    private static final Logger LOG = LogManager.getLogger(PhysicalPlanTranslator.class);
+    /**
+     * The left and right child of origin predicates need to be swap sometimes.
+     * Case A:
+     * select * from t1 join t2 on t2.id=t1.id
+     * The left plan node is t1 and the right plan node is t2.
+     * The left child of origin predicate is t2.id and the right child of origin predicate is t1.id.
+     * In this situation, the children of predicate need to be swap => t1.id=t2.id.
+     */
+    private static Expression swapEqualToForChildrenOrder(EqualTo<?, ?> equalTo, List<Slot> leftOutput) {
+        Set<ExprId> leftSlots = SlotExtractor.extractSlot(equalTo.left()).stream()
+                .map(NamedExpression::getExprId).collect(Collectors.toSet());
+        if (leftOutput.stream().map(NamedExpression::getExprId).collect(Collectors.toSet()).containsAll(leftSlots)) {
+            return equalTo;
+        } else {
+            return new EqualTo<>(equalTo.right(), equalTo.left());
+        }
+    }
 
     public void translatePlan(PhysicalPlan physicalPlan, PlanTranslatorContext context) {
         visit(physicalPlan, context);
@@ -103,7 +119,7 @@ public class PhysicalPlanTranslator extends PlanOperatorVisitor<PlanFragment, Pl
 
         PlanFragment inputPlanFragment = visit(agg.child(0), context);
 
-        AggregationNode aggregationNode = null;
+        AggregationNode aggregationNode;
         List<Slot> slotList = new ArrayList<>();
         PhysicalAggregation physicalAggregation = agg.getOperator();
         AggregateInfo.AggPhase phase = physicalAggregation.getAggPhase().toExec();
@@ -129,7 +145,7 @@ public class PhysicalPlanTranslator extends PlanOperatorVisitor<PlanFragment, Pl
         List<Expr> execPartitionExpressions = partitionExpressionList.stream()
                 .map(e -> (FunctionCallExpr) ExpressionTranslator.translate(e, context)).collect(Collectors.toList());
         // todo: support DISTINCT
-        AggregateInfo aggInfo = null;
+        AggregateInfo aggInfo;
         switch (phase) {
             case FIRST:
                 aggInfo = AggregateInfo.create(execGroupingExpressions, execAggExpressions, outputTupleDesc,
@@ -240,15 +256,15 @@ public class PhysicalPlanTranslator extends PlanOperatorVisitor<PlanFragment, Pl
         return mergeFragment;
     }
 
-    // TODO: 1. support broadcast join / co-locate / bucket shuffle join later
+    // TODO: 1. support shuffle join / co-locate / bucket shuffle join later
     //       2. For ssb, there are only binary equal predicate, we shall support more in the future.
     @Override
     public PlanFragment visitPhysicalHashJoin(
             PhysicalBinaryPlan<PhysicalHashJoin, Plan, Plan> hashJoin, PlanTranslatorContext context) {
+        // NOTICE: We must visit from right to left, to ensure the last fragment is root fragment
+        PlanFragment rightFragment = visit(hashJoin.child(1), context);
         PlanFragment leftFragment = visit(hashJoin.child(0), context);
-        PlanFragment rightFragment = visit(hashJoin.child(0), context);
         PhysicalHashJoin physicalHashJoin = hashJoin.getOperator();
-        Expression predicateExpr = physicalHashJoin.getCondition().get();
 
         //        Expression predicateExpr = physicalHashJoin.getCondition().get();
         //        List<Expression> eqExprList = Utils.getEqConjuncts(hashJoin.child(0).getOutput(),
@@ -259,14 +275,11 @@ public class PhysicalPlanTranslator extends PlanOperatorVisitor<PlanFragment, Pl
         PlanNode rightFragmentPlanRoot = rightFragment.getPlanRoot();
 
         if (joinType.equals(JoinType.CROSS_JOIN)
-                || physicalHashJoin.getJoinType().equals(JoinType.INNER_JOIN) && false /* eqExprList.isEmpty() */) {
+                || physicalHashJoin.getJoinType().equals(JoinType.INNER_JOIN)
+                && !physicalHashJoin.getCondition().isPresent()) {
             CrossJoinNode crossJoinNode = new CrossJoinNode(context.nextNodeId(), leftFragment.getPlanRoot(),
                     rightFragment.getPlanRoot(), null);
             crossJoinNode.setLimit(physicalHashJoin.getLimit());
-            List<Expr> conjuncts = Utils.extractConjuncts(predicateExpr).stream()
-                    .map(e -> ExpressionTranslator.translate(e, context))
-                    .collect(Collectors.toCollection(ArrayList::new));
-            crossJoinNode.addConjuncts(conjuncts);
             ExchangeNode exchangeNode = new ExchangeNode(context.nextNodeId(), rightFragment.getPlanRoot(), false);
             exchangeNode.setNumInstances(rightFragmentPlanRoot.getNumInstances());
             exchangeNode.setFragment(leftFragment);
@@ -277,24 +290,22 @@ public class PhysicalPlanTranslator extends PlanOperatorVisitor<PlanFragment, Pl
             context.addPlanFragment(leftFragment);
             return leftFragment;
         }
-        List<Expr> execEqConjunctList = Lists.newArrayList(ExpressionTranslator.translate(predicateExpr, context));
+
+        Expression eqJoinExpression = physicalHashJoin.getCondition().get();
+        List<Expr> execEqConjunctList = ExpressionUtils.extractConjunct(eqJoinExpression).stream()
+                .map(EqualTo.class::cast)
+                .map(e -> swapEqualToForChildrenOrder(e, hashJoin.left().getOutput()))
+                .map(e -> ExpressionTranslator.translate(e, context))
+                .collect(Collectors.toList());
 
         HashJoinNode hashJoinNode = new HashJoinNode(context.nextNodeId(), leftFragmentPlanRoot, rightFragmentPlanRoot,
                 JoinType.toJoinOperator(physicalHashJoin.getJoinType()), execEqConjunctList, Lists.newArrayList());
 
-        ExchangeNode leftExch = new ExchangeNode(context.nextNodeId(), leftFragmentPlanRoot, false);
-        leftExch.setNumInstances(leftFragmentPlanRoot.getNumInstances());
-        ExchangeNode rightExch = new ExchangeNode(context.nextNodeId(), leftFragmentPlanRoot, false);
-        rightExch.setNumInstances(rightFragmentPlanRoot.getNumInstances());
+        hashJoinNode.setDistributionMode(DistributionMode.BROADCAST);
         hashJoinNode.setChild(0, leftFragmentPlanRoot);
-        hashJoinNode.setChild(1, leftFragmentPlanRoot);
-        hashJoinNode.setDistributionMode(HashJoinNode.DistributionMode.PARTITIONED);
-        hashJoinNode.setLimit(physicalHashJoin.getLimit());
-        leftFragment.setDestination((ExchangeNode) rightFragment.getPlanRoot());
-        rightFragment.setDestination((ExchangeNode) leftFragmentPlanRoot);
-        PlanFragment result = new PlanFragment(context.nextFragmentId(), hashJoinNode, leftFragment.getDataPartition());
-        context.addPlanFragment(result);
-        return result;
+        connectChildFragment(hashJoinNode, 1, leftFragment, rightFragment, context);
+        leftFragment.setPlanRoot(hashJoinNode);
+        return leftFragment;
     }
 
     // TODO: generate expression mapping when be project could do in ExecNode
@@ -318,28 +329,9 @@ public class PhysicalPlanTranslator extends PlanOperatorVisitor<PlanFragment, Pl
                 requiredSlotIdList.add(((SlotRef) expr).getDesc().getId().asInt());
             }
         }
-        for (TupleId tupleId : inputPlanNode.getTupleIds()) {
-            TupleDescriptor tupleDescriptor = context.getTupleDesc(tupleId);
-            Preconditions.checkNotNull(tupleDescriptor);
-            List<SlotDescriptor> slotDescList = tupleDescriptor.getSlots();
-            slotDescList.removeIf(slotDescriptor -> !requiredSlotIdList.contains(slotDescriptor.getId().asInt()));
-            for (int i = 0; i < slotDescList.size(); i++) {
-                slotDescList.get(i).setSlotOffset(i);
-            }
-        }
         return inputFragment;
     }
 
-    private void extractExecSlot(Expr root, Set<Integer>  slotRefList) {
-        if (root instanceof SlotRef) {
-            slotRefList.add(((SlotRef) root).getDesc().getId().asInt());
-            return;
-        }
-        for (Expr child : root.getChildren()) {
-            extractExecSlot(child, slotRefList);
-        }
-    }
-
     @Override
     public PlanFragment visitPhysicalFilter(
             PhysicalUnaryPlan<PhysicalFilter, Plan> filterPlan, PlanTranslatorContext context) {
@@ -347,13 +339,21 @@ public class PhysicalPlanTranslator extends PlanOperatorVisitor<PlanFragment, Pl
         PlanNode planNode = inputFragment.getPlanRoot();
         PhysicalFilter filter = filterPlan.getOperator();
         Expression expression = filter.getPredicates();
-        List<Expression> expressionList = Utils.extractConjuncts(expression);
-        expressionList.stream().map(e -> {
-            return ExpressionTranslator.translate(e, context);
-        }).forEach(planNode::addConjunct);
+        List<Expression> expressionList = ExpressionUtils.extractConjunct(expression);
+        expressionList.stream().map(e -> ExpressionTranslator.translate(e, context)).forEach(planNode::addConjunct);
         return inputFragment;
     }
 
+    private void extractExecSlot(Expr root, Set<Integer>  slotRefList) {
+        if (root instanceof SlotRef) {
+            slotRefList.add(((SlotRef) root).getDesc().getId().asInt());
+            return;
+        }
+        for (Expr child : root.getChildren()) {
+            extractExecSlot(child, slotRefList);
+        }
+    }
+
     private TupleDescriptor generateTupleDesc(List<Slot> slotList, PlanTranslatorContext context, Table table) {
         TupleDescriptor tupleDescriptor = context.generateTupleDesc();
         tupleDescriptor.setTable(table);
@@ -373,6 +373,16 @@ public class PhysicalPlanTranslator extends PlanOperatorVisitor<PlanFragment, Pl
         return parentFragment;
     }
 
+    private void connectChildFragment(PlanNode node, int childIdx,
+            PlanFragment parentFragment, PlanFragment childFragment,
+            PlanTranslatorContext context) {
+        ExchangeNode exchangeNode = new ExchangeNode(context.nextNodeId(), childFragment.getPlanRoot(), false);
+        exchangeNode.setNumInstances(childFragment.getPlanRoot().getNumInstances());
+        exchangeNode.setFragment(parentFragment);
+        node.setChild(childIdx, exchangeNode);
+        childFragment.setDestination(exchangeNode);
+    }
+
     /**
      * Helper function to eliminate unnecessary checked exception caught requirement from the main logic of translator.
      *
diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/DefaultValueExpr.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/PredicatePushDownRulesJob.java
similarity index 57%
copy from fe/fe-core/src/main/java/org/apache/doris/analysis/DefaultValueExpr.java
copy to fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/PredicatePushDownRulesJob.java
index 4552e6f84f..84d00132e4 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/DefaultValueExpr.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/PredicatePushDownRulesJob.java
@@ -15,29 +15,22 @@
 // specific language governing permissions and limitations
 // under the License.
 
-package org.apache.doris.analysis;
+package org.apache.doris.nereids.jobs;
 
-import org.apache.doris.common.AnalysisException;
-import org.apache.doris.thrift.TExprNode;
+import org.apache.doris.nereids.PlannerContext;
+import org.apache.doris.nereids.rules.rewrite.logical.PushPredicateThroughJoin;
 
-//
-public class DefaultValueExpr extends Expr {
-    @Override
-    protected void analyzeImpl(Analyzer analyzer) throws AnalysisException {
-    }
-
-    @Override
-    protected String toSqlImpl() {
-        return null;
-    }
-
-    @Override
-    protected void toThrift(TExprNode msg) {
-
-    }
+import com.google.common.collect.ImmutableList;
 
-    @Override
-    public Expr clone() {
-        return null;
+/**
+ * execute predicate push down job.
+ */
+public class PredicatePushDownRulesJob extends BatchRulesJob {
+    public PredicatePushDownRulesJob(PlannerContext plannerContext) {
+        super(plannerContext);
+        rulesJob.addAll(ImmutableList.of(
+                topDownBatch(ImmutableList.of(
+                        new PushPredicateThroughJoin())
+                )));
     }
 }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/Utils.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/Utils.java
index ff66e62191..a01a867593 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/Utils.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/Utils.java
@@ -17,11 +17,6 @@
 
 package org.apache.doris.nereids.util;
 
-import org.apache.doris.nereids.trees.expressions.Expression;
-import org.apache.doris.nereids.trees.expressions.Slot;
-
-import java.util.List;
-
 /**
  * Utils for Nereids.
  */
@@ -39,14 +34,4 @@ public class Utils {
             return part.replace("`", "``");
         }
     }
-
-    // TODO: implement later
-    public static List<Expression> getEqConjuncts(List<Slot> left, List<Slot> right, Expression eqExpr) {
-        return null;
-    }
-
-    // TODO: implement later
-    public static List<Expression> extractConjuncts(Expression expr) {
-        return null;
-    }
 }


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