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 <101034200+morrys...@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-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org