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 f5936aa7ce [enhancement](Nereids): add more implmentation rules. (#10335) f5936aa7ce is described below commit f5936aa7ce0b0b00fefa599c841cacc018b5e171 Author: jakevin <30525741+jackwe...@users.noreply.github.com> AuthorDate: Tue Jun 28 17:08:33 2022 +0800 [enhancement](Nereids): add more implmentation rules. (#10335) Add more implmentation rules. Current some `logical` and `physical` operator is different. I change some code to make them match. Implementation - Sort:only heap sort - Agg - OlapScan --- .../org/apache/doris/nereids/OperatorVisitor.java | 4 +- .../doris/nereids/operators/AbstractOperator.java | 16 +- .../plans/logical/LogicalAggregation.java | 74 ++++---- .../plans/logical/LogicalOlapScan.java} | 39 ++-- .../operators/plans/logical/LogicalRelation.java | 2 +- .../operators/plans/logical/LogicalSort.java | 84 +++------ .../plans/physical/PhysicalAggregation.java | 33 ++-- .../{PhysicalSort.java => PhysicalHeapSort.java} | 37 ++-- .../plans/physical/PhysicalUnaryOperator.java | 4 + .../doris/nereids/parser/LogicalPlanBuilder.java | 86 ++++----- .../apache/doris/nereids/properties/OrderKey.java | 1 + .../org/apache/doris/nereids/rules/RuleSet.java | 4 +- .../org/apache/doris/nereids/rules/RuleType.java | 8 +- .../doris/nereids/rules/analysis/BindRelation.java | 11 +- ...ction.java => LogicalAggToPhysicalHashAgg.java} | 22 ++- .../LogicalFilterToPhysicalFilter.java | 2 +- ...java => LogicalOlapScanToPhysicalOlapScan.java} | 17 +- ...n.java => LogicalProjectToPhysicalProject.java} | 14 +- ...ter.java => LogicalSortToPhysicalHeapSort.java} | 15 +- .../trees/plans/PhysicalPlanTranslator.java | 29 +-- .../nereids/trees/plans/PlanOperatorVisitor.java | 4 +- .../java/org/apache/doris/planner/SortNode.java | 196 ++++++++++----------- .../doris/nereids/jobs/RewriteTopDownJobTest.java | 4 +- .../apache/doris/nereids/plan/TestPlanOutput.java | 5 +- ...va => LogicalProjectToPhysicalProjectTest.java} | 4 +- 25 files changed, 324 insertions(+), 391 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/OperatorVisitor.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/OperatorVisitor.java index 7b168355ca..d2a7c4ef6e 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/OperatorVisitor.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/OperatorVisitor.java @@ -21,9 +21,9 @@ import org.apache.doris.nereids.operators.Operator; import org.apache.doris.nereids.operators.plans.physical.PhysicalAggregation; import org.apache.doris.nereids.operators.plans.physical.PhysicalFilter; import org.apache.doris.nereids.operators.plans.physical.PhysicalHashJoin; +import org.apache.doris.nereids.operators.plans.physical.PhysicalHeapSort; import org.apache.doris.nereids.operators.plans.physical.PhysicalOlapScan; import org.apache.doris.nereids.operators.plans.physical.PhysicalProject; -import org.apache.doris.nereids.operators.plans.physical.PhysicalSort; /** * Base class for the processing of logical and physical operator. @@ -44,7 +44,7 @@ public abstract class OperatorVisitor<R, C> { return null; } - public R visitPhysicalSort(PhysicalSort physicalSort, C context) { + public R visitPhysicalHeapSort(PhysicalHeapSort physicalHeapSort, C context) { return null; } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/operators/AbstractOperator.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/operators/AbstractOperator.java index d3b7a25e92..6dbe1d85c7 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/operators/AbstractOperator.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/operators/AbstractOperator.java @@ -28,16 +28,16 @@ import java.util.Objects; */ public abstract class AbstractOperator implements Operator { protected final OperatorType type; - protected final long limited; + protected final long limit; public AbstractOperator(OperatorType type) { this.type = Objects.requireNonNull(type, "type can not be null"); - this.limited = -1; + this.limit = -1; } - public AbstractOperator(OperatorType type, long limited) { + public AbstractOperator(OperatorType type, long limit) { this.type = type; - this.limited = limited; + this.limit = limit; } @Override @@ -45,6 +45,10 @@ public abstract class AbstractOperator implements Operator { return type; } + public long getLimit() { + return limit; + } + /** * Child operator should overwrite this method. * for example: @@ -65,8 +69,4 @@ public abstract class AbstractOperator implements Operator { return null; } - public long getLimited() { - return limited; - } - } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/operators/plans/logical/LogicalAggregation.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/operators/plans/logical/LogicalAggregation.java index eb6172420a..00088bf1f1 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/operators/plans/logical/LogicalAggregation.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/operators/plans/logical/LogicalAggregation.java @@ -19,6 +19,7 @@ package org.apache.doris.nereids.operators.plans.logical; import org.apache.doris.nereids.exceptions.UnboundException; import org.apache.doris.nereids.operators.OperatorType; +import org.apache.doris.nereids.operators.plans.AggPhase; import org.apache.doris.nereids.trees.expressions.Expression; import org.apache.doris.nereids.trees.expressions.NamedExpression; import org.apache.doris.nereids.trees.expressions.Slot; @@ -31,68 +32,71 @@ import java.util.List; /** * Logical Aggregation plan operator. - * - *eg:select a, sum(b), c from table group by a, c; + * <p> + * eg:select a, sum(b), c from table group by a, c; * groupByExpressions: Column field after group by. eg: a, c; * outputExpressions: Column field after select. eg: a, sum(b), c; - * + * partitionExprList: Column field after partition by. + * <p> * Each agg node only contains the select statement field of the same layer, * and other agg nodes in the subquery contain. */ public class LogicalAggregation extends LogicalUnaryOperator { - private final List<Expression> groupByExpressions; - private final List<? extends NamedExpression> outputExpressions; + private final List<Expression> groupByExprList; + private final List<NamedExpression> outputExpressionList; + private List<Expression> partitionExprList; + + private AggPhase aggPhase; /** * Desc: Constructor for LogicalAggregation. */ - public LogicalAggregation(List<Expression> groupByExpressions, - List<? extends NamedExpression> outputExpressions) { + public LogicalAggregation(List<Expression> groupByExprList, List<NamedExpression> outputExpressionList) { super(OperatorType.LOGICAL_AGGREGATION); - this.groupByExpressions = groupByExpressions; - this.outputExpressions = outputExpressions; + this.groupByExprList = groupByExprList; + this.outputExpressionList = outputExpressionList; } - /** - * Get GroupByAggregation list. - * - * @return all group by of this node. - */ - public List<Expression> getGroupByExpressions() { - return groupByExpressions; + public List<Expression> getPartitionExprList() { + return partitionExprList == null ? groupByExprList : partitionExprList; } - /** - * Get outputExpressions list. - * - * @return all agg expressions. - */ - public List<? extends NamedExpression> getoutputExpressions() { - return outputExpressions; + public void setPartitionExprList(List<Expression> partitionExprList) { + this.partitionExprList = partitionExprList; + } + + public List<Expression> getGroupByExprList() { + return groupByExprList; + } + + public List<NamedExpression> getOutputExpressionList() { + return outputExpressionList; + } + + public AggPhase getAggPhase() { + return aggPhase; } @Override public String toString() { - return "Aggregation (" + "outputExpressions: " + StringUtils.join(outputExpressions, ", ") - + ", groupByExpressions: " + StringUtils.join(groupByExpressions, ", ") + ")"; + return "Aggregation (" + "outputExpressionList: " + StringUtils.join(outputExpressionList, ", ") + + ", groupByExprList: " + StringUtils.join(groupByExprList, ", ") + ")"; } @Override public List<Slot> computeOutput(Plan input) { - return outputExpressions.stream() - .map(namedExpr -> { - try { - return namedExpr.toSlot(); - } catch (UnboundException e) { - throw new IllegalStateException(e); - } - }) - .collect(ImmutableList.toImmutableList()); + return outputExpressionList.stream().map(namedExpr -> { + try { + return namedExpr.toSlot(); + } catch (UnboundException e) { + throw new IllegalStateException(e); + } + }).collect(ImmutableList.toImmutableList()); } @Override public List<Expression> getExpressions() { - return new ImmutableList.Builder<Expression>().addAll(groupByExpressions).addAll(outputExpressions).build(); + return new ImmutableList.Builder<Expression>().addAll(groupByExprList).addAll(outputExpressionList).build(); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/properties/OrderKey.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/operators/plans/logical/LogicalOlapScan.java similarity index 53% copy from fe/fe-core/src/main/java/org/apache/doris/nereids/properties/OrderKey.java copy to fe/fe-core/src/main/java/org/apache/doris/nereids/operators/plans/logical/LogicalOlapScan.java index b01862dff6..b9e61b29ea 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/properties/OrderKey.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/operators/plans/logical/LogicalOlapScan.java @@ -15,41 +15,24 @@ // specific language governing permissions and limitations // under the License. -package org.apache.doris.nereids.properties; +package org.apache.doris.nereids.operators.plans.logical; -import org.apache.doris.nereids.trees.expressions.Expression; +import org.apache.doris.catalog.Table; + +import java.util.List; /** - * Represents the order key of a statement. + * Logical OlapScan operator. */ -public class OrderKey { - - private Expression expr; - - private boolean isAsc; - - private boolean nullFirst; +public class LogicalOlapScan extends LogicalRelation { /** - * Constructor of OrderKey. + * Constructor for LogicalOlapScan. * - * @param nullFirst True if "NULLS FIRST", false if "NULLS LAST", null if not specified. + * @param table Doris table + * @param qualifier qualified relation name */ - public OrderKey(Expression expr, boolean isAsc, boolean nullFirst) { - this.expr = expr; - this.isAsc = isAsc; - this.nullFirst = nullFirst; - } - - public Expression getExpr() { - return expr; - } - - public boolean isAsc() { - return isAsc; - } - - public boolean isNullFirst() { - return nullFirst; + public LogicalOlapScan(Table table, List<String> qualifier) { + super(table, qualifier); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/operators/plans/logical/LogicalRelation.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/operators/plans/logical/LogicalRelation.java index 0a2563766d..6f7ce83e14 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/operators/plans/logical/LogicalRelation.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/operators/plans/logical/LogicalRelation.java @@ -32,7 +32,7 @@ import java.util.Objects; /** * Logical relation plan operator. */ -public class LogicalRelation extends LogicalLeafOperator { +public abstract class LogicalRelation extends LogicalLeafOperator { private final Table table; private final List<String> qualifier; diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/operators/plans/logical/LogicalSort.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/operators/plans/logical/LogicalSort.java index b1984051f7..6c63f8a09e 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/operators/plans/logical/LogicalSort.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/operators/plans/logical/LogicalSort.java @@ -18,6 +18,7 @@ package org.apache.doris.nereids.operators.plans.logical; import org.apache.doris.nereids.operators.OperatorType; +import org.apache.doris.nereids.properties.OrderKey; import org.apache.doris.nereids.trees.expressions.Expression; import org.apache.doris.nereids.trees.expressions.Slot; import org.apache.doris.nereids.trees.plans.Plan; @@ -31,26 +32,24 @@ import java.util.stream.Collectors; /** * Logical Sort plan operator. - * + * <p> * eg: select * from table order by a, b desc; - * sortItems: list of column information after order by. eg:[a, asc],[b, desc]. - * SortItems: Contains order expression information and sorting method. Default is ascending. + * orderKeys: list of column information after order by. eg:[a, asc],[b, desc]. + * OrderKey: Contains order expression information and sorting method. Default is ascending. */ public class LogicalSort extends LogicalUnaryOperator { - private List<SortItems> sortItems; + // Default offset is 0. + private int offset = 0; + + private final List<OrderKey> orderKeys; /** - * Constructor for SortItems. + * Constructor for LogicalSort. */ - public LogicalSort(List<SortItems> sortItems) { + public LogicalSort(List<OrderKey> orderKeys) { super(OperatorType.LOGICAL_SORT); - this.sortItems = Objects.requireNonNull(sortItems, "sorItems can not be null"); - } - - @Override - public String toString() { - return "Sort (" + StringUtils.join(sortItems, ", ") + ")"; + this.orderKeys = Objects.requireNonNull(orderKeys, "orderKeys can not be null"); } @Override @@ -58,57 +57,26 @@ public class LogicalSort extends LogicalUnaryOperator { return input.getOutput(); } - /** - * Get SortItems. - * - * @return List of SortItems. - */ - public List<SortItems> getSortItems() { - return sortItems; + public List<OrderKey> getOrderKeys() { + return orderKeys; } - @Override - public List<Expression> getExpressions() { - return new ImmutableList.Builder<Expression>().addAll( - sortItems.stream().map(expr -> expr.getSort()).collect(Collectors.toList())) - .build(); + public int getOffset() { + return offset; } - /** - * SortItem. Show sort expressions and their order types. - */ - public static class SortItems { - /** - * enum of OrderDirection. - */ - public enum OrderDirection { - ASC, - DESC - } - - private final Expression sort; - private final OrderDirection orderDirection; - - public SortItems(Expression sort, OrderDirection orderDirection) { - this.sort = sort; - this.orderDirection = orderDirection; - } - - public Expression getSort() { - return sort; - } + public void setOffset(int offset) { + this.offset = offset; + } - /** - * Get OrderDirection. - * - * @return boolean. - */ - public OrderDirection getOrderDirection() { - return orderDirection; - } + @Override + public String toString() { + return "Sort (" + StringUtils.join(orderKeys, ", ") + ")"; + } - public String toString() { - return "Expression: " + sort.sql() + " OrderDirection: " + orderDirection.toString(); - } + @Override + public List<Expression> getExpressions() { + return new ImmutableList.Builder<Expression>().addAll( + orderKeys.stream().map(OrderKey::getExpr).collect(Collectors.toList())).build(); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/operators/plans/physical/PhysicalAggregation.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/operators/plans/physical/PhysicalAggregation.java index 55462751d7..f42072abc2 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/operators/plans/physical/PhysicalAggregation.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/operators/plans/physical/PhysicalAggregation.java @@ -20,6 +20,7 @@ package org.apache.doris.nereids.operators.plans.physical; import org.apache.doris.nereids.operators.OperatorType; import org.apache.doris.nereids.operators.plans.AggPhase; import org.apache.doris.nereids.trees.expressions.Expression; +import org.apache.doris.nereids.trees.expressions.NamedExpression; import org.apache.doris.nereids.trees.plans.Plan; import org.apache.doris.nereids.trees.plans.PlanOperatorVisitor; import org.apache.doris.nereids.trees.plans.physical.PhysicalUnaryPlan; @@ -35,7 +36,7 @@ public class PhysicalAggregation extends PhysicalUnaryOperator { private final List<Expression> groupByExprList; - private final List<Expression> aggExprList; + private final List<NamedExpression> outputExpressionList; private final List<Expression> partitionExprList; @@ -47,30 +48,30 @@ public class PhysicalAggregation extends PhysicalUnaryOperator { * Constructor of PhysicalAggNode. * * @param groupByExprList group by expr list. - * @param aggExprList agg expr list. - * @param partitionExprList partition expr list, used for analytic agg. + * @param outputExpressionList agg expr list. + * @param partitionExprList partition expr list, used for analytic agg. * @param usingStream whether it's stream agg. */ - public PhysicalAggregation(List<Expression> groupByExprList, List<Expression> aggExprList, + public PhysicalAggregation(List<Expression> groupByExprList, List<NamedExpression> outputExpressionList, List<Expression> partitionExprList, AggPhase aggPhase, boolean usingStream) { super(OperatorType.PHYSICAL_AGGREGATION); this.groupByExprList = groupByExprList; - this.aggExprList = aggExprList; - this.partitionExprList = partitionExprList; + this.outputExpressionList = outputExpressionList; this.aggPhase = aggPhase; + this.partitionExprList = partitionExprList; this.usingStream = usingStream; } - public List<Expression> getGroupByExprList() { - return groupByExprList; + public AggPhase getAggPhase() { + return aggPhase; } - public List<Expression> getAggExprList() { - return aggExprList; + public List<Expression> getGroupByExprList() { + return groupByExprList; } - public AggPhase getAggPhase() { - return aggPhase; + public List<NamedExpression> getOutputExpressionList() { + return outputExpressionList; } public boolean isUsingStream() { @@ -88,10 +89,8 @@ public class PhysicalAggregation extends PhysicalUnaryOperator { @Override public List<Expression> getExpressions() { - return new ImmutableList.Builder<Expression>() - .addAll(groupByExprList) - .addAll(aggExprList) - .addAll(partitionExprList) - .build(); + // TODO: partitionExprList maybe null. + return new ImmutableList.Builder<Expression>().addAll(groupByExprList).addAll(outputExpressionList) + .addAll(partitionExprList).build(); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/operators/plans/physical/PhysicalSort.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/operators/plans/physical/PhysicalHeapSort.java similarity index 71% rename from fe/fe-core/src/main/java/org/apache/doris/nereids/operators/plans/physical/PhysicalSort.java rename to fe/fe-core/src/main/java/org/apache/doris/nereids/operators/plans/physical/PhysicalHeapSort.java index bf1c831b8f..4637098e55 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/operators/plans/physical/PhysicalSort.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/operators/plans/physical/PhysicalHeapSort.java @@ -32,41 +32,27 @@ import java.util.stream.Collectors; /** * Physical sort plan operator. */ -public class PhysicalSort extends PhysicalUnaryOperator { - +public class PhysicalHeapSort extends PhysicalUnaryOperator { + // Default offset is 0. private final int offset; - private final int limit; - - private final List<OrderKey> orderList; - - private final boolean useTopN; + private final List<OrderKey> orderKeys; /** * Constructor of PhysicalHashJoinNode. */ - public PhysicalSort(int offset, int limit, List<OrderKey> orderList, boolean useTopN) { - super(OperatorType.PHYSICAL_SORT); + public PhysicalHeapSort(List<OrderKey> orderKeys, long limit, int offset) { + super(OperatorType.PHYSICAL_SORT, limit); this.offset = offset; - this.limit = limit; - this.orderList = orderList; - this.useTopN = useTopN; + this.orderKeys = orderKeys; } public int getOffset() { return offset; } - public int getLimit() { - return limit; - } - - public List<OrderKey> getOrderList() { - return orderList; - } - - public boolean isUseTopN() { - return useTopN; + public List<OrderKey> getOrderKeys() { + return orderKeys; } public boolean hasLimit() { @@ -75,15 +61,12 @@ public class PhysicalSort extends PhysicalUnaryOperator { @Override public <R, C> R accept(PlanOperatorVisitor<R, C> visitor, Plan plan, C context) { - return visitor.visitPhysicalSort((PhysicalUnaryPlan<PhysicalSort, Plan>) plan, context); + return visitor.visitPhysicalSort((PhysicalUnaryPlan<PhysicalHeapSort, Plan>) plan, context); } @Override public List<Expression> getExpressions() { return ImmutableList.<Expression>builder() - .addAll(orderList.stream() - .map(o -> o.getExpr()) - .collect(Collectors.toList()) - ).build(); + .addAll(orderKeys.stream().map(o -> o.getExpr()).collect(Collectors.toList())).build(); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/operators/plans/physical/PhysicalUnaryOperator.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/operators/plans/physical/PhysicalUnaryOperator.java index fb2f0812cc..345de2e1ea 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/operators/plans/physical/PhysicalUnaryOperator.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/operators/plans/physical/PhysicalUnaryOperator.java @@ -37,6 +37,10 @@ public abstract class PhysicalUnaryOperator extends AbstractOperator super(type); } + public PhysicalUnaryOperator(OperatorType type, long limit) { + super(type, limit); + } + @Override public PhysicalUnaryPlan toTreeNode(GroupExpression groupExpression) { LogicalProperties logicalProperties = groupExpression.getParent().getLogicalProperties(); diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java index 6b83a63f73..8cac723572 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java @@ -68,8 +68,7 @@ import org.apache.doris.nereids.operators.plans.logical.LogicalFilter; import org.apache.doris.nereids.operators.plans.logical.LogicalJoin; import org.apache.doris.nereids.operators.plans.logical.LogicalProject; import org.apache.doris.nereids.operators.plans.logical.LogicalSort; -import org.apache.doris.nereids.operators.plans.logical.LogicalSort.SortItems; -import org.apache.doris.nereids.operators.plans.logical.LogicalSort.SortItems.OrderDirection; +import org.apache.doris.nereids.properties.OrderKey; import org.apache.doris.nereids.trees.analysis.FunctionParams; import org.apache.doris.nereids.trees.expressions.Add; import org.apache.doris.nereids.trees.expressions.Alias; @@ -121,9 +120,9 @@ public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> { /** * Create a logical plan using a where clause. */ - private final BiFunction<WhereClauseContext, LogicalPlan, LogicalPlan> withWhereClause = - (WhereClauseContext ctx, LogicalPlan plan) - -> new LogicalUnaryPlan(new LogicalFilter(expression((ctx.booleanExpression()))), plan); + private final BiFunction<WhereClauseContext, LogicalPlan, LogicalPlan> withWhereClause + = (WhereClauseContext ctx, LogicalPlan plan) -> new LogicalUnaryPlan( + new LogicalFilter(expression((ctx.booleanExpression()))), plan); protected <T> T typedVisit(ParseTree ctx) { return (T) ctx.accept(this); @@ -180,8 +179,8 @@ public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> { } private LogicalPlan withQueryOrganization(QueryOrganizationContext ctx, LogicalPlan children) { - List<SortItems> sortItems = visitQueryOrganization(ctx); - return sortItems == null ? children : new LogicalUnaryPlan(new LogicalSort(sortItems), children); + List<OrderKey> orderKeys = visitQueryOrganization(ctx); + return orderKeys == null ? children : new LogicalUnaryPlan(new LogicalSort(orderKeys), children); } @Override @@ -189,12 +188,7 @@ public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> { Supplier<LogicalPlan> f = () -> { // TODO: support on row relation LogicalPlan from = visitFromClause(ctx.fromClause()); - return withSelectQuerySpecification( - ctx, - ctx.selectClause(), - ctx.whereClause(), - from, - ctx.aggClause()); + return withSelectQuerySpecification(ctx, ctx.selectClause(), ctx.whereClause(), from, ctx.aggClause()); }; return ParserUtils.withOrigin(ctx, f); } @@ -232,11 +226,8 @@ public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> { AggClauseContext aggClause) { Supplier<LogicalPlan> f = () -> { // Filter(expression(ctx.booleanExpression), plan); - LogicalPlan plan = visitCommonSelectQueryClausePlan( - relation, - visitNamedExpressionSeq(selectClause.namedExpressionSeq()), - whereClause, - aggClause); + LogicalPlan plan = visitCommonSelectQueryClausePlan(relation, + visitNamedExpressionSeq(selectClause.namedExpressionSeq()), whereClause, aggClause); // TODO: process hint return plan; }; @@ -287,8 +278,7 @@ public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> { if (left == null) { left = right; } else { - left = new LogicalBinaryPlan( - new LogicalJoin(JoinType.INNER_JOIN, Optional.empty()), left, right); + left = new LogicalBinaryPlan(new LogicalJoin(JoinType.INNER_JOIN, Optional.empty()), left, right); } left = withJoinRelations(left, relation); } @@ -328,16 +318,14 @@ public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> { condition = expression(joinCriteria.booleanExpression()); } - last = new LogicalBinaryPlan( - new LogicalJoin(joinType, Optional.ofNullable(condition)), - last, plan(join.relationPrimary()) - ); + last = new LogicalBinaryPlan(new LogicalJoin(joinType, Optional.ofNullable(condition)), last, + plan(join.relationPrimary())); } return last; } - private LogicalPlan withAggClause(List<NamedExpression> aggExpressions, - GroupByItemContext ctx, LogicalPlan aggClause) { + private LogicalPlan withAggClause(List<NamedExpression> aggExpressions, GroupByItemContext ctx, + LogicalPlan aggClause) { List<Expression> tmpExpressions = new ArrayList<>(); for (ExpressionContext expressionCtx : ctx.expression()) { tmpExpressions.add(typedVisit(expressionCtx)); @@ -346,35 +334,32 @@ public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> { } /** - * Generate sortItems. + * Generate OrderKey. * * @param ctx SortItemContext - * @return SortItems + * @return OrderKey */ - public SortItems genSortItems(SortItemContext ctx) { - OrderDirection orderDirection; - if (ctx.DESC() != null) { - orderDirection = OrderDirection.DESC; - } else { - orderDirection = OrderDirection.ASC; - } + public OrderKey genOrderKeys(SortItemContext ctx) { + boolean isAsc = ctx.DESC() == null; + // TODO(wj): isNullFirst + boolean isNullFirst = true; Expression expression = typedVisit(ctx.expression()); - return new SortItems(expression, orderDirection); + return new OrderKey(expression, isAsc, isNullFirst); } /** - * Create SortItems list. + * Create OrderKey list. * * @param ctx QueryOrganizationContext - * @return List of SortItems + * @return List of OrderKey */ - public List<SortItems> visitQueryOrganization(QueryOrganizationContext ctx) { - List<SortItems> sortItems = new ArrayList<>(); + public List<OrderKey> visitQueryOrganization(QueryOrganizationContext ctx) { + List<OrderKey> orderKeys = new ArrayList<>(); if (ctx.sortClause().ORDER() != null) { for (SortItemContext sortItemContext : ctx.sortClause().sortItem()) { - sortItems.add(genSortItems(sortItemContext)); + orderKeys.add(genOrderKeys(sortItemContext)); } - return new ArrayList<>(sortItems); + return new ArrayList<>(orderKeys); } else { return null; } @@ -438,8 +423,8 @@ public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> { final QualifiedNameContext qualifiedNameContext = ctx.qualifiedName(); List<String> target; if (qualifiedNameContext != null) { - target = qualifiedNameContext.identifier().stream() - .map(RuleContext::getText).collect(Collectors.toList()); + target = qualifiedNameContext.identifier().stream().map(RuleContext::getText) + .collect(Collectors.toList()); } else { target = Lists.newArrayList(); } @@ -530,7 +515,7 @@ public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> { * Create a predicated expression. A predicated expression is a normal expression with a * predicate attached to it, for example: * {{{ - * a + 1 IS NULL + * a + 1 IS NULL * }}} */ @Override @@ -568,11 +553,7 @@ public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> { */ public Expression withBetween(PredicateContext ctx, Expression e) { boolean isNotBetween = ctx.NOT() != null ? true : false; - BetweenPredicate betweenPredicate = new BetweenPredicate( - e, - expression(ctx.lower), - expression(ctx.upper) - ); + BetweenPredicate betweenPredicate = new BetweenPredicate(e, expression(ctx.lower), expression(ctx.upper)); return isNotBetween ? new Not(betweenPredicate) : betweenPredicate; } @@ -597,7 +578,7 @@ public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> { return genArithmetic(ctx.operator, left, right); } - private Arithmetic genArithmetic(Token token, Expression left, Expression right) { + private Arithmetic genArithmetic(Token token, Expression left, Expression right) { switch (token.getType()) { case DorisParser.ASTERISK: return new Multiply(left, right); @@ -626,8 +607,7 @@ public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> { } return new FunctionCall(functionName, - new FunctionParams(ctx.aggFunction().DISTINCT() != null, - expression(ctx.aggFunction().expression()))); + new FunctionParams(ctx.aggFunction().DISTINCT() != null, expression(ctx.aggFunction().expression()))); } @Override diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/properties/OrderKey.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/properties/OrderKey.java index b01862dff6..9cbf800d6e 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/properties/OrderKey.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/properties/OrderKey.java @@ -26,6 +26,7 @@ public class OrderKey { private Expression expr; + // Order is ascending. private boolean isAsc; private boolean nullFirst; diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleSet.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleSet.java index 657ab82c76..fda9440e36 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleSet.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleSet.java @@ -22,7 +22,7 @@ import org.apache.doris.nereids.rules.exploration.join.JoinCommutative; import org.apache.doris.nereids.rules.exploration.join.JoinLeftAssociative; import org.apache.doris.nereids.rules.implementation.LogicalFilterToPhysicalFilter; import org.apache.doris.nereids.rules.implementation.LogicalJoinToHashJoin; -import org.apache.doris.nereids.rules.implementation.LogicalProjectionToPhysicalProjection; +import org.apache.doris.nereids.rules.implementation.LogicalProjectToPhysicalProject; import org.apache.doris.nereids.trees.TreeNode; import org.apache.doris.nereids.trees.plans.Plan; @@ -46,7 +46,7 @@ public class RuleSet { public static final List<Rule<Plan>> IMPLEMENTATION_RULES = planRuleFactories() .add(new LogicalJoinToHashJoin()) - .add(new LogicalProjectionToPhysicalProjection()) + .add(new LogicalProjectToPhysicalProject()) .add(new LogicalFilterToPhysicalFilter()) .build(); diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleType.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleType.java index 93f9e846df..a2caa236c2 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleType.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleType.java @@ -42,12 +42,12 @@ public enum RuleType { LOGICAL_JOIN_EXCHANGE(RuleTypeClass.EXPLORATION), // implementation rules + LOGICAL_AGG_TO_PHYSICAL_HASH_AGG_RULE(RuleTypeClass.IMPLEMENTATION), LOGICAL_JOIN_TO_HASH_JOIN_RULE(RuleTypeClass.IMPLEMENTATION), - LOGICAL_PROJECTION_TO_PHYSICAL_PROJECTION_RULE(RuleTypeClass.IMPLEMENTATION), + LOGICAL_PROJECT_TO_PHYSICAL_PROJECT_RULE(RuleTypeClass.IMPLEMENTATION), LOGICAL_FILTER_TO_PHYSICAL_FILTER_RULE(RuleTypeClass.IMPLEMENTATION), - LOGICAL_LIMIT_TO_PHYSICAL_LIMIT_RULE(RuleTypeClass.IMPLEMENTATION), - LOGICAL_JOIN_TO_HASH_AGG_RULE(RuleTypeClass.IMPLEMENTATION), - LOGICAL_JOIN_TO_OLAP_SCAN_RULE(RuleTypeClass.IMPLEMENTATION), + LOGICAL_SORT_TO_PHYSICAL_HEAP_SORT_RULE(RuleTypeClass.IMPLEMENTATION), + LOGICAL_OLAP_SCAN_TO_PHYSICAL_OLAP_SCAN_RULE(RuleTypeClass.IMPLEMENTATION), IMPLEMENTATION_SENTINEL(RuleTypeClass.IMPLEMENTATION), // sentinel, use to count rules diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindRelation.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindRelation.java index 88a4b38f02..d51791ca86 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindRelation.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindRelation.java @@ -20,7 +20,7 @@ package org.apache.doris.nereids.rules.analysis; import org.apache.doris.catalog.Catalog; import org.apache.doris.catalog.Database; import org.apache.doris.catalog.Table; -import org.apache.doris.nereids.operators.plans.logical.LogicalRelation; +import org.apache.doris.nereids.operators.plans.logical.LogicalOlapScan; import org.apache.doris.nereids.rules.Rule; import org.apache.doris.nereids.rules.RuleType; import org.apache.doris.nereids.trees.plans.Plan; @@ -45,13 +45,14 @@ public class BindRelation extends OneAnalysisRuleFactory { case 1: { List<String> qualifier = Lists.newArrayList(connectContext.getDatabase(), nameParts.get(0)); Table table = getTable(qualifier, connectContext.getCatalog()); - LogicalRelation relation = new LogicalRelation(table, qualifier); - return new LogicalLeafPlan<>(relation); + // TODO: should generate different Scan sub class according to table's type + LogicalOlapScan olapScan = new LogicalOlapScan(table, qualifier); + return new LogicalLeafPlan<>(olapScan); } case 2: { Table table = getTable(nameParts, connectContext.getCatalog()); - LogicalRelation relation = new LogicalRelation(table, nameParts); - return new LogicalLeafPlan<>(relation); + LogicalOlapScan olapScan = new LogicalOlapScan(table, nameParts); + return new LogicalLeafPlan<>(olapScan); } default: throw new IllegalStateException("Table name [" diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalProjectionToPhysicalProjection.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalAggToPhysicalHashAgg.java similarity index 60% copy from fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalProjectionToPhysicalProjection.java copy to fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalAggToPhysicalHashAgg.java index 66a2b8ad73..5ea7138473 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalProjectionToPhysicalProjection.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalAggToPhysicalHashAgg.java @@ -17,21 +17,27 @@ package org.apache.doris.nereids.rules.implementation; -import org.apache.doris.nereids.operators.plans.physical.PhysicalProject; +import org.apache.doris.nereids.operators.plans.physical.PhysicalAggregation; import org.apache.doris.nereids.rules.Rule; import org.apache.doris.nereids.rules.RuleType; import org.apache.doris.nereids.trees.plans.Plan; /** - * Implementation rule that convert logical join to physical hash join. + * Implementation rule that convert logical aggregation to physical hash aggregation. */ -public class LogicalProjectionToPhysicalProjection extends OneImplementationRuleFactory { +public class LogicalAggToPhysicalHashAgg extends OneImplementationRuleFactory { @Override public Rule<Plan> build() { - return logicalProject().then(projection -> plan( - new PhysicalProject(projection.getOperator().getProjects()), - projection.getLogicalProperties(), - projection.child() - )).toRule(RuleType.LOGICAL_PROJECTION_TO_PHYSICAL_PROJECTION_RULE); + return logicalAggregation().then(agg -> plan( + new PhysicalAggregation( + // TODO: for use a function to judge whether use stream + agg.getOperator().getGroupByExprList(), + agg.getOperator().getOutputExpressionList(), + agg.getOperator().getPartitionExprList(), + agg.getOperator().getAggPhase(), + false), + agg.getLogicalProperties(), + agg.child() + )).toRule(RuleType.LOGICAL_AGG_TO_PHYSICAL_HASH_AGG_RULE); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalFilterToPhysicalFilter.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalFilterToPhysicalFilter.java index db6e95cc98..1d6afa2f08 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalFilterToPhysicalFilter.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalFilterToPhysicalFilter.java @@ -23,7 +23,7 @@ import org.apache.doris.nereids.rules.RuleType; import org.apache.doris.nereids.trees.plans.Plan; /** - * Implementation rule that convert logical join to physical hash join. + * Implementation rule that convert logical filter to physical filter. */ public class LogicalFilterToPhysicalFilter extends OneImplementationRuleFactory { @Override diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalProjectionToPhysicalProjection.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalOlapScanToPhysicalOlapScan.java similarity index 64% copy from fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalProjectionToPhysicalProjection.java copy to fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalOlapScanToPhysicalOlapScan.java index 66a2b8ad73..dc9e8fff7a 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalProjectionToPhysicalProjection.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalOlapScanToPhysicalOlapScan.java @@ -17,21 +17,22 @@ package org.apache.doris.nereids.rules.implementation; -import org.apache.doris.nereids.operators.plans.physical.PhysicalProject; +import org.apache.doris.catalog.OlapTable; +import org.apache.doris.nereids.operators.plans.physical.PhysicalOlapScan; import org.apache.doris.nereids.rules.Rule; import org.apache.doris.nereids.rules.RuleType; import org.apache.doris.nereids.trees.plans.Plan; /** - * Implementation rule that convert logical join to physical hash join. + * Implementation rule that convert logical OlapScan to physical OlapScan. */ -public class LogicalProjectionToPhysicalProjection extends OneImplementationRuleFactory { +public class LogicalOlapScanToPhysicalOlapScan extends OneImplementationRuleFactory { @Override public Rule<Plan> build() { - return logicalProject().then(projection -> plan( - new PhysicalProject(projection.getOperator().getProjects()), - projection.getLogicalProperties(), - projection.child() - )).toRule(RuleType.LOGICAL_PROJECTION_TO_PHYSICAL_PROJECTION_RULE); + return logicalOlapScan().then(olapScan -> plan( + // TODO: olapScan should get (OlapTable); + new PhysicalOlapScan((OlapTable) olapScan.getOperator().getTable(), + olapScan.getOperator().getQualifier()), olapScan.getLogicalProperties())) + .toRule(RuleType.LOGICAL_OLAP_SCAN_TO_PHYSICAL_OLAP_SCAN_RULE); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalProjectionToPhysicalProjection.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalProjectToPhysicalProject.java similarity index 71% rename from fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalProjectionToPhysicalProjection.java rename to fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalProjectToPhysicalProject.java index 66a2b8ad73..67b665195e 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalProjectionToPhysicalProjection.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalProjectToPhysicalProject.java @@ -23,15 +23,15 @@ import org.apache.doris.nereids.rules.RuleType; import org.apache.doris.nereids.trees.plans.Plan; /** - * Implementation rule that convert logical join to physical hash join. + * Implementation rule that convert logical project to physical project. */ -public class LogicalProjectionToPhysicalProjection extends OneImplementationRuleFactory { +public class LogicalProjectToPhysicalProject extends OneImplementationRuleFactory { @Override public Rule<Plan> build() { - return logicalProject().then(projection -> plan( - new PhysicalProject(projection.getOperator().getProjects()), - projection.getLogicalProperties(), - projection.child() - )).toRule(RuleType.LOGICAL_PROJECTION_TO_PHYSICAL_PROJECTION_RULE); + return logicalProject().then(project -> plan( + new PhysicalProject(project.getOperator().getProjects()), + project.getLogicalProperties(), + project.child() + )).toRule(RuleType.LOGICAL_PROJECT_TO_PHYSICAL_PROJECT_RULE); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalFilterToPhysicalFilter.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalSortToPhysicalHeapSort.java similarity index 70% copy from fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalFilterToPhysicalFilter.java copy to fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalSortToPhysicalHeapSort.java index db6e95cc98..e15ab360f4 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalFilterToPhysicalFilter.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalSortToPhysicalHeapSort.java @@ -17,21 +17,20 @@ package org.apache.doris.nereids.rules.implementation; -import org.apache.doris.nereids.operators.plans.physical.PhysicalFilter; +import org.apache.doris.nereids.operators.plans.physical.PhysicalHeapSort; import org.apache.doris.nereids.rules.Rule; import org.apache.doris.nereids.rules.RuleType; import org.apache.doris.nereids.trees.plans.Plan; /** - * Implementation rule that convert logical join to physical hash join. + * Implementation rule that convert logical sort to physical sort. */ -public class LogicalFilterToPhysicalFilter extends OneImplementationRuleFactory { +public class LogicalSortToPhysicalHeapSort extends OneImplementationRuleFactory { @Override public Rule<Plan> build() { - return logicalFilter().then(filter -> plan( - new PhysicalFilter(filter.getOperator().getPredicates()), - filter.getLogicalProperties(), - filter.child() - )).toRule(RuleType.LOGICAL_FILTER_TO_PHYSICAL_FILTER_RULE); + return logicalSort().then(sort -> plan( + new PhysicalHeapSort(sort.getOperator().getOrderKeys(), sort.getOperator().getLimit(), + sort.getOperator().getOffset()), sort.getLogicalProperties(), sort.child())) + .toRule(RuleType.LOGICAL_SORT_TO_PHYSICAL_HEAP_SORT_RULE); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PhysicalPlanTranslator.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PhysicalPlanTranslator.java index 016b206915..23859d43b5 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PhysicalPlanTranslator.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PhysicalPlanTranslator.java @@ -30,13 +30,14 @@ import org.apache.doris.nereids.operators.plans.JoinType; import org.apache.doris.nereids.operators.plans.physical.PhysicalAggregation; import org.apache.doris.nereids.operators.plans.physical.PhysicalFilter; import org.apache.doris.nereids.operators.plans.physical.PhysicalHashJoin; +import org.apache.doris.nereids.operators.plans.physical.PhysicalHeapSort; 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.operators.plans.physical.PhysicalSort; import org.apache.doris.nereids.properties.OrderKey; import org.apache.doris.nereids.trees.expressions.Expression; import org.apache.doris.nereids.trees.expressions.ExpressionConverter; +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.plans.physical.PhysicalBinaryPlan; @@ -95,9 +96,9 @@ public class PhysicalPlanTranslator extends PlanOperatorVisitor<PlanFragment, Pl ArrayList<Expr> execGroupingExpressions = groupByExpressionList.stream() .map(e -> ExpressionConverter.convert(e, context)).collect(Collectors.toCollection(ArrayList::new)); - List<Expression> aggExpressionList = physicalAggregation.getAggExprList(); + List<NamedExpression> outputExpressionList = physicalAggregation.getOutputExpressionList(); // TODO: agg function could be other expr type either - ArrayList<FunctionCallExpr> execAggExpressions = aggExpressionList.stream() + ArrayList<FunctionCallExpr> execAggExpressions = outputExpressionList.stream() .map(e -> (FunctionCallExpr) ExpressionConverter.convert(e, context)) .collect(Collectors.toCollection(ArrayList::new)); @@ -147,20 +148,21 @@ public class PhysicalPlanTranslator extends PlanOperatorVisitor<PlanFragment, Pl } @Override - public PlanFragment visitPhysicalSort(PhysicalUnaryPlan<PhysicalSort, Plan> sort, + public PlanFragment visitPhysicalSort(PhysicalUnaryPlan<PhysicalHeapSort, Plan> sort, PlanTranslatorContext context) { PlanFragment childFragment = visit(sort.child(0), context); - PhysicalSort physicalSort = sort.getOperator(); + // TODO: Why doesn't the sort node translate if the childfragment is a single instance? + PhysicalHeapSort physicalHeapSort = sort.getOperator(); if (!childFragment.isPartitioned()) { return childFragment; } - long limit = physicalSort.getLimit(); + long limit = physicalHeapSort.getLimit(); List<Expr> execOrderingExprList = Lists.newArrayList(); List<Boolean> ascOrderList = Lists.newArrayList(); List<Boolean> nullsFirstParamList = Lists.newArrayList(); - List<OrderKey> orderKeyList = physicalSort.getOrderList(); + List<OrderKey> orderKeyList = physicalHeapSort.getOrderKeys(); orderKeyList.forEach(k -> { execOrderingExprList.add(ExpressionConverter.convert(k.getExpr(), context)); ascOrderList.add(k.isAsc()); @@ -172,16 +174,17 @@ public class PhysicalPlanTranslator extends PlanOperatorVisitor<PlanFragment, Pl SortInfo sortInfo = new SortInfo(execOrderingExprList, ascOrderList, nullsFirstParamList, tupleDesc); PlanNode childNode = childFragment.getPlanRoot(); - SortNode sortNode = new SortNode(context.nextNodeId(), childNode, sortInfo, physicalSort.isUseTopN(), - physicalSort.hasLimit(), physicalSort.getOffset()); + // TODO: notice topN + SortNode sortNode = new SortNode(context.nextNodeId(), childNode, sortInfo, true, + physicalHeapSort.hasLimit(), physicalHeapSort.getOffset()); PlanFragment mergeFragment = createParentFragment(childFragment, DataPartition.UNPARTITIONED, context); ExchangeNode exchNode = (ExchangeNode) mergeFragment.getPlanRoot(); exchNode.unsetLimit(); - if (physicalSort.hasLimit()) { + if (physicalHeapSort.hasLimit()) { exchNode.setLimit(limit); } - long offset = physicalSort.getOffset(); + long offset = physicalHeapSort.getOffset(); exchNode.setMergeInfo(sortNode.getSortInfo(), offset); // Child nodes should not process the offset. If there is a limit, @@ -216,7 +219,7 @@ public class PhysicalPlanTranslator extends PlanOperatorVisitor<PlanFragment, Pl || physicalHashJoin.getJoinType().equals(JoinType.INNER_JOIN) && eqExprList.isEmpty()) { CrossJoinNode crossJoinNode = new CrossJoinNode(context.nextNodeId(), leftFragment.getPlanRoot(), rightFragment.getPlanRoot(), null); - crossJoinNode.setLimit(physicalHashJoin.getLimited()); + crossJoinNode.setLimit(physicalHashJoin.getLimit()); List<Expr> conjuncts = Utils.extractConjuncts(predicateExpr).stream() .map(e -> ExpressionConverter.convert(e, context)) .collect(Collectors.toCollection(ArrayList::new)); @@ -249,7 +252,7 @@ public class PhysicalPlanTranslator extends PlanOperatorVisitor<PlanFragment, Pl hashJoinNode.setChild(0, leftFragmentPlanRoot); hashJoinNode.setChild(1, leftFragmentPlanRoot); hashJoinNode.setDistributionMode(HashJoinNode.DistributionMode.PARTITIONED); - hashJoinNode.setLimit(physicalHashJoin.getLimited()); + hashJoinNode.setLimit(physicalHashJoin.getLimit()); leftFragment.setDestination((ExchangeNode) rightFragment.getPlanRoot()); rightFragment.setDestination((ExchangeNode) leftFragmentPlanRoot); PlanFragment result = new PlanFragment(context.nextFragmentId(), hashJoinNode, leftFragment.getDataPartition()); diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PlanOperatorVisitor.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PlanOperatorVisitor.java index 52f17f8bce..61a398c219 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PlanOperatorVisitor.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PlanOperatorVisitor.java @@ -23,9 +23,9 @@ import org.apache.doris.nereids.operators.plans.logical.LogicalRelation; import org.apache.doris.nereids.operators.plans.physical.PhysicalAggregation; import org.apache.doris.nereids.operators.plans.physical.PhysicalFilter; import org.apache.doris.nereids.operators.plans.physical.PhysicalHashJoin; +import org.apache.doris.nereids.operators.plans.physical.PhysicalHeapSort; import org.apache.doris.nereids.operators.plans.physical.PhysicalOlapScan; import org.apache.doris.nereids.operators.plans.physical.PhysicalProject; -import org.apache.doris.nereids.operators.plans.physical.PhysicalSort; import org.apache.doris.nereids.trees.plans.logical.LogicalBinaryPlan; import org.apache.doris.nereids.trees.plans.logical.LogicalLeafPlan; import org.apache.doris.nereids.trees.plans.logical.LogicalUnaryPlan; @@ -75,7 +75,7 @@ public abstract class PlanOperatorVisitor<R, C> { return visit(olapScan, context); } - public R visitPhysicalSort(PhysicalUnaryPlan<PhysicalSort, Plan> sort, C context) { + public R visitPhysicalSort(PhysicalUnaryPlan<PhysicalHeapSort, Plan> sort, C context) { return visit(sort, context); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/planner/SortNode.java b/fe/fe-core/src/main/java/org/apache/doris/planner/SortNode.java index 2a7d3e7b29..134891a1b6 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/planner/SortNode.java +++ b/fe/fe-core/src/main/java/org/apache/doris/planner/SortNode.java @@ -54,35 +54,19 @@ import java.util.Set; */ public class SortNode extends PlanNode { private static final Logger LOG = LogManager.getLogger(SortNode.class); + // info_.sortTupleSlotExprs_ substituted with the outputSmap_ for materialized slots in init(). + List<Expr> resolvedTupleExprs; private final SortInfo info; private final boolean useTopN; private final boolean isDefaultLimit; - private long offset; // if true, the output of this node feeds an AnalyticNode private boolean isAnalyticSort; - - // info_.sortTupleSlotExprs_ substituted with the outputSmap_ for materialized slots in init(). - List<Expr> resolvedTupleExprs; - - public void setIsAnalyticSort(boolean v) { - isAnalyticSort = v; - } - - public boolean isAnalyticSort() { - return isAnalyticSort; - } - private DataPartition inputPartition; - public void setInputPartition(DataPartition inputPartition) { - this.inputPartition = inputPartition; - } - - public DataPartition getInputPartition() { - return inputPartition; - } - + /** + * Constructor. + */ public SortNode(PlanNodeId id, PlanNode input, SortInfo info, boolean useTopN, boolean isDefaultLimit, long offset) { super(id, useTopN ? "TOP-N" : "SORT", StatisticalType.SORT_NODE); @@ -98,7 +82,7 @@ public class SortNode extends PlanNode { } /** - * Clone 'inputSortNode' for distributed Top-N + * Clone 'inputSortNode' for distributed Top-N. */ public SortNode(PlanNodeId id, SortNode inputSortNode, PlanNode child) { super(id, inputSortNode, inputSortNode.useTopN ? "TOP-N" : "SORT", StatisticalType.SORT_NODE); @@ -109,6 +93,22 @@ public class SortNode extends PlanNode { this.offset = inputSortNode.offset; } + public void setIsAnalyticSort(boolean v) { + isAnalyticSort = v; + } + + public boolean isAnalyticSort() { + return isAnalyticSort; + } + + public DataPartition getInputPartition() { + return inputPartition; + } + + public void setInputPartition(DataPartition inputPartition) { + this.inputPartition = inputPartition; + } + public long getOffset() { return offset; } @@ -122,14 +122,33 @@ public class SortNode extends PlanNode { } @Override - public void getMaterializedIds(Analyzer analyzer, List<SlotId> ids) { - super.getMaterializedIds(analyzer, ids); - Expr.getIds(info.getOrderingExprs(), null, ids); + public void setCompactData(boolean on) { + this.compactData = on; } @Override - public void setCompactData(boolean on) { - this.compactData = on; + public String getNodeExplainString(String detailPrefix, TExplainLevel detailLevel) { + if (detailLevel == TExplainLevel.BRIEF) { + return ""; + } + + StringBuilder output = new StringBuilder(); + output.append(detailPrefix + "order by: "); + Iterator<Expr> expr = info.getOrderingExprs().iterator(); + Iterator<Boolean> isAsc = info.getIsAscOrder().iterator(); + boolean start = true; + while (expr.hasNext()) { + if (start) { + start = false; + } else { + output.append(", "); + } + output.append(expr.next().toSql() + " "); + output.append(isAsc.next() ? "ASC" : "DESC"); + } + output.append("\n"); + output.append(detailPrefix + "offset: " + offset + "\n"); + return output.toString(); } @Override @@ -160,77 +179,6 @@ public class SortNode extends PlanNode { LOG.debug("stats Sort: cardinality=" + Long.toString(cardinality)); } - @Override - public Set<SlotId> computeInputSlotIds() throws NotImplementedException { - List<SlotId> result = Lists.newArrayList(); - Expr.getIds(resolvedTupleExprs, null, result); - return new HashSet<>(result); - } - - @Override - protected String debugString() { - List<String> strings = Lists.newArrayList(); - for (Boolean isAsc : info.getIsAscOrder()) { - strings.add(isAsc ? "a" : "d"); - } - return MoreObjects.toStringHelper(this).add("ordering_exprs", - Expr.debugString(info.getOrderingExprs())).add("is_asc", - "[" + Joiner.on(" ").join(strings) + "]").addValue(super.debugString()).toString(); - } - - @Override - protected void toThrift(TPlanNode msg) { - msg.node_type = TPlanNodeType.SORT_NODE; - TSortInfo sortInfo = new TSortInfo( - Expr.treesToThrift(info.getOrderingExprs()), - info.getIsAscOrder(), - info.getNullsFirst()); - Preconditions.checkState(tupleIds.size() == 1, "Incorrect size for tupleIds in SortNode"); - sortInfo.setSortTupleSlotExprs(Expr.treesToThrift(resolvedTupleExprs)); - TSortNode sortNode = new TSortNode(sortInfo, useTopN); - - msg.sort_node = sortNode; - msg.sort_node.setOffset(offset); - - // TODO(lingbin): remove blew codes, because it is duplicate with TSortInfo - msg.sort_node.setOrderingExprs(Expr.treesToThrift(info.getOrderingExprs())); - msg.sort_node.setIsAscOrder(info.getIsAscOrder()); - msg.sort_node.setNullsFirst(info.getNullsFirst()); - if (info.getSortTupleSlotExprs() != null) { - msg.sort_node.setSortTupleSlotExprs(Expr.treesToThrift(info.getSortTupleSlotExprs())); - } - } - - @Override - public String getNodeExplainString(String detailPrefix, TExplainLevel detailLevel) { - if (detailLevel == TExplainLevel.BRIEF) { - return ""; - } - - StringBuilder output = new StringBuilder(); - output.append(detailPrefix + "order by: "); - Iterator<Expr> expr = info.getOrderingExprs().iterator(); - Iterator<Boolean> isAsc = info.getIsAscOrder().iterator(); - boolean start = true; - while (expr.hasNext()) { - if (start) { - start = false; - } else { - output.append(", "); - } - output.append(expr.next().toSql() + " "); - output.append(isAsc.next() ? "ASC" : "DESC"); - } - output.append("\n"); - output.append(detailPrefix + "offset: " + offset + "\n"); - return output.toString(); - } - - @Override - public int getNumInstances() { - return children.get(0).getNumInstances(); - } - public void init(Analyzer analyzer) throws UserException { // Compute the memory layout for the generated tuple. computeStats(analyzer); @@ -272,4 +220,56 @@ public class SortNode extends PlanNode { LOG.debug("sort input exprs: " + Expr.debugString(resolvedTupleExprs)); } } + + @Override + public void getMaterializedIds(Analyzer analyzer, List<SlotId> ids) { + super.getMaterializedIds(analyzer, ids); + Expr.getIds(info.getOrderingExprs(), null, ids); + } + + @Override + protected void toThrift(TPlanNode msg) { + msg.node_type = TPlanNodeType.SORT_NODE; + TSortInfo sortInfo = new TSortInfo( + Expr.treesToThrift(info.getOrderingExprs()), + info.getIsAscOrder(), + info.getNullsFirst()); + Preconditions.checkState(tupleIds.size() == 1, "Incorrect size for tupleIds in SortNode"); + sortInfo.setSortTupleSlotExprs(Expr.treesToThrift(resolvedTupleExprs)); + TSortNode sortNode = new TSortNode(sortInfo, useTopN); + + msg.sort_node = sortNode; + msg.sort_node.setOffset(offset); + + // TODO(lingbin): remove blew codes, because it is duplicate with TSortInfo + msg.sort_node.setOrderingExprs(Expr.treesToThrift(info.getOrderingExprs())); + msg.sort_node.setIsAscOrder(info.getIsAscOrder()); + msg.sort_node.setNullsFirst(info.getNullsFirst()); + if (info.getSortTupleSlotExprs() != null) { + msg.sort_node.setSortTupleSlotExprs(Expr.treesToThrift(info.getSortTupleSlotExprs())); + } + } + + @Override + protected String debugString() { + List<String> strings = Lists.newArrayList(); + for (Boolean isAsc : info.getIsAscOrder()) { + strings.add(isAsc ? "a" : "d"); + } + return MoreObjects.toStringHelper(this).add("ordering_exprs", + Expr.debugString(info.getOrderingExprs())).add("is_asc", + "[" + Joiner.on(" ").join(strings) + "]").addValue(super.debugString()).toString(); + } + + @Override + public int getNumInstances() { + return children.get(0).getNumInstances(); + } + + @Override + public Set<SlotId> computeInputSlotIds() throws NotImplementedException { + List<SlotId> result = Lists.newArrayList(); + Expr.getIds(resolvedTupleExprs, null, result); + return new HashSet<>(result); + } } diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/jobs/RewriteTopDownJobTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/jobs/RewriteTopDownJobTest.java index 152d827fc7..4c620c8764 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/nereids/jobs/RewriteTopDownJobTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/jobs/RewriteTopDownJobTest.java @@ -28,8 +28,8 @@ 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.operators.OperatorType; +import org.apache.doris.nereids.operators.plans.logical.LogicalOlapScan; import org.apache.doris.nereids.operators.plans.logical.LogicalProject; -import org.apache.doris.nereids.operators.plans.logical.LogicalRelation; import org.apache.doris.nereids.properties.PhysicalProperties; import org.apache.doris.nereids.rules.Rule; import org.apache.doris.nereids.rules.RuleType; @@ -53,7 +53,7 @@ public class RewriteTopDownJobTest implements Plans { @Override public Rule<Plan> build() { return unboundRelation().then(unboundRelation -> plan( - new LogicalRelation(new Table(0, "test", Table.TableType.OLAP, ImmutableList.of( + new LogicalOlapScan(new Table(0, "test", Table.TableType.OLAP, ImmutableList.of( new Column("id", Type.INT), new Column("name", Type.STRING) )), Lists.newArrayList("test")) diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/plan/TestPlanOutput.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/plan/TestPlanOutput.java index ec0df43660..cfea47f716 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/nereids/plan/TestPlanOutput.java +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/plan/TestPlanOutput.java @@ -24,6 +24,7 @@ import org.apache.doris.catalog.Type; import org.apache.doris.nereids.analyzer.UnboundRelation; import org.apache.doris.nereids.exceptions.UnboundException; import org.apache.doris.nereids.operators.OperatorType; +import org.apache.doris.nereids.operators.plans.logical.LogicalOlapScan; import org.apache.doris.nereids.operators.plans.logical.LogicalRelation; import org.apache.doris.nereids.operators.plans.physical.PhysicalScan; import org.apache.doris.nereids.trees.expressions.Expression; @@ -47,7 +48,7 @@ public class TestPlanOutput implements Plans { new Column("name", Type.STRING, true, AggregateType.NONE, "", "") )); LogicalLeafPlan<LogicalRelation> relationPlan = plan( - new LogicalRelation(table, ImmutableList.of("a")) + new LogicalOlapScan(table, ImmutableList.of("a")) ); List<Slot> output = relationPlan.getOutput(); Assertions.assertEquals(2, output.size()); @@ -83,7 +84,7 @@ public class TestPlanOutput implements Plans { new Column("name", Type.STRING, true, AggregateType.NONE, "", "") )); LogicalLeafPlan<LogicalRelation> relationPlan = plan( - new LogicalRelation(table, ImmutableList.of("a")) + new LogicalOlapScan(table, ImmutableList.of("a")) ); List<Slot> output = relationPlan.getOutput(); diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/implementation/LogicalProjectionToPhysicalProjectionTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/implementation/LogicalProjectToPhysicalProjectTest.java similarity index 93% rename from fe/fe-core/src/test/java/org/apache/doris/nereids/rules/implementation/LogicalProjectionToPhysicalProjectionTest.java rename to fe/fe-core/src/test/java/org/apache/doris/nereids/rules/implementation/LogicalProjectToPhysicalProjectTest.java index 84df7938dd..fbff548b8d 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/implementation/LogicalProjectionToPhysicalProjectionTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/implementation/LogicalProjectToPhysicalProjectTest.java @@ -37,13 +37,13 @@ import org.junit.Test; import java.util.List; -public class LogicalProjectionToPhysicalProjectionTest implements Plans { +public class LogicalProjectToPhysicalProjectTest implements Plans { @Test public void projectionImplTest(@Mocked Group group) { LogicalProject logicalProject = new LogicalProject(Lists.newArrayList()); Plan plan = plan(logicalProject, new GroupPlan(group)); - Rule<Plan> rule = new LogicalProjectionToPhysicalProjection().build(); + Rule<Plan> rule = new LogicalProjectToPhysicalProject().build(); PlannerContext plannerContext = new PlannerContext(new OptimizerContext(new Memo()), new ConnectContext(), new PhysicalProperties()); --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org