You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@doris.apache.org by mo...@apache.org on 2022/12/08 07:34:47 UTC
[doris] branch master updated: [feature](Nereids) support push down no group agg to olap scan (#14683)
This is an automated email from the ASF dual-hosted git repository.
morrysnow pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new 1887881a61 [feature](Nereids) support push down no group agg to olap scan (#14683)
1887881a61 is described below
commit 1887881a61e71ad4e2ea47df730240b33e705fa6
Author: morrySnow <10...@users.noreply.github.com>
AuthorDate: Thu Dec 8 15:34:39 2022 +0800
[feature](Nereids) support push down no group agg to olap scan (#14683)
use zonemap to do aggregate without group by exprs.
valid aggregate function:
- count
- min
- max
implementation in legacy planner: #12881
---
.../glue/translator/PhysicalPlanTranslator.java | 1 +
.../jobs/batch/NereidsRewriteJobExecutor.java | 2 +
.../org/apache/doris/nereids/rules/RuleType.java | 4 +-
.../LogicalOlapScanToPhysicalOlapScan.java | 3 +-
.../rewrite/logical/PushAggregateToOlapScan.java | 197 +++++++++++++++++++++
.../logical/PushdownProjectThroughLimit.java | 2 +-
.../nereids/trees/plans/PushDownAggOperator.java | 70 ++++++++
.../trees/plans/logical/LogicalOlapScan.java | 67 ++++---
.../trees/plans/physical/PhysicalOlapScan.java | 27 ++-
.../translator/PhysicalPlanTranslatorTest.java | 3 +-
.../postprocess/MergeProjectPostProcessTest.java | 6 +-
.../rewrite/logical/PruneOlapScanTabletTest.java | 4 +-
.../logical/PushAggregateToOlapScanTest.java | 154 ++++++++++++++++
.../doris/nereids/trees/plans/PlanEqualsTest.java | 6 +-
.../nereids/trees/plans/PlanToStringTest.java | 2 +-
.../apache/doris/nereids/util/PlanConstructor.java | 2 +-
16 files changed, 506 insertions(+), 44 deletions(-)
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 75ab8bd8a9..0a8875989f 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
@@ -378,6 +378,7 @@ public class PhysicalPlanTranslator extends DefaultPlanVisitor<PlanFragment, Pla
tupleDescriptor.setRef(tableRef);
olapScanNode.setSelectedPartitionIds(olapScan.getSelectedPartitionIds());
olapScanNode.setSampleTabletIds(olapScan.getSelectedTabletIds());
+ olapScanNode.setPushDownAggNoGrouping(olapScan.getPushDownAggOperator().toThrift());
switch (olapScan.getTable().getKeysType()) {
case AGG_KEYS:
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/batch/NereidsRewriteJobExecutor.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/batch/NereidsRewriteJobExecutor.java
index cfd777ad2a..a64b9385ed 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/batch/NereidsRewriteJobExecutor.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/batch/NereidsRewriteJobExecutor.java
@@ -39,6 +39,7 @@ import org.apache.doris.nereids.rules.rewrite.logical.MergeProjects;
import org.apache.doris.nereids.rules.rewrite.logical.NormalizeAggregate;
import org.apache.doris.nereids.rules.rewrite.logical.PruneOlapScanPartition;
import org.apache.doris.nereids.rules.rewrite.logical.PruneOlapScanTablet;
+import org.apache.doris.nereids.rules.rewrite.logical.PushAggregateToOlapScan;
import org.apache.doris.nereids.rules.rewrite.logical.PushFilterInsideJoin;
import org.apache.doris.nereids.rules.rewrite.logical.ReorderJoin;
@@ -94,6 +95,7 @@ public class NereidsRewriteJobExecutor extends BatchRulesJob {
// to avoid two consecutive same project appear when we do optimization.
.add(topDownBatch(ImmutableList.of(new EliminateGroupByConstant())))
.add(topDownBatch(ImmutableList.of(new EliminateUnnecessaryProject())))
+ .add(topDownBatch(ImmutableList.of(new PushAggregateToOlapScan())))
// this rule batch must keep at the end of rewrite to do some plan check
.add(bottomUpBatch(ImmutableList.of(new CheckAfterRewrite())))
.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 36891c6629..4c4d5f43b1 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
@@ -104,7 +104,7 @@ public enum RuleType {
PUSHDOWN_FILTER_THROUGH_LEFT_SEMI_JOIN(RuleTypeClass.REWRITE),
PUSH_FILTER_INSIDE_JOIN(RuleTypeClass.REWRITE),
PUSHDOWN_FILTER_THROUGH_PROJECT(RuleTypeClass.REWRITE),
- PUSHDOWN_PROJECT_THROUGHT_LIMIT(RuleTypeClass.REWRITE),
+ PUSHDOWN_PROJECT_THROUGH_LIMIT(RuleTypeClass.REWRITE),
// column prune rules,
COLUMN_PRUNE_AGGREGATION_CHILD(RuleTypeClass.REWRITE),
COLUMN_PRUNE_FILTER_CHILD(RuleTypeClass.REWRITE),
@@ -139,8 +139,8 @@ public enum RuleType {
MATERIALIZED_INDEX_FILTER_PROJECT_SCAN(RuleTypeClass.REWRITE),
OLAP_SCAN_PARTITION_PRUNE(RuleTypeClass.REWRITE),
OLAP_SCAN_TABLET_PRUNE(RuleTypeClass.REWRITE),
+ PUSH_AGGREGATE_TO_OLAP_SCAN(RuleTypeClass.REWRITE),
EXTRACT_SINGLE_TABLE_EXPRESSION_FROM_DISJUNCTION(RuleTypeClass.REWRITE),
- REWRITE_SENTINEL(RuleTypeClass.REWRITE),
// limit push down
PUSH_LIMIT_THROUGH_JOIN(RuleTypeClass.REWRITE),
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalOlapScanToPhysicalOlapScan.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalOlapScanToPhysicalOlapScan.java
index 8a348bb3b5..582027cef2 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalOlapScanToPhysicalOlapScan.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalOlapScanToPhysicalOlapScan.java
@@ -49,10 +49,11 @@ public class LogicalOlapScanToPhysicalOlapScan extends OneImplementationRuleFact
olapScan.getTable(),
olapScan.getQualifier(),
olapScan.getSelectedIndexId(),
- olapScan.getSelectedTabletId(),
+ olapScan.getSelectedTabletIds(),
olapScan.getSelectedPartitionIds(),
convertDistribution(olapScan),
olapScan.getPreAggStatus(),
+ olapScan.getPushDownAggOperator(),
Optional.empty(),
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/rewrite/logical/PushAggregateToOlapScan.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/logical/PushAggregateToOlapScan.java
new file mode 100644
index 0000000000..f301c456c9
--- /dev/null
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/logical/PushAggregateToOlapScan.java
@@ -0,0 +1,197 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.rules.rewrite.logical;
+
+import org.apache.doris.catalog.KeysType;
+import org.apache.doris.nereids.rules.Rule;
+import org.apache.doris.nereids.rules.RuleType;
+import org.apache.doris.nereids.rules.rewrite.RewriteRuleFactory;
+import org.apache.doris.nereids.trees.expressions.Alias;
+import org.apache.doris.nereids.trees.expressions.Cast;
+import org.apache.doris.nereids.trees.expressions.Expression;
+import org.apache.doris.nereids.trees.expressions.Slot;
+import org.apache.doris.nereids.trees.expressions.SlotReference;
+import org.apache.doris.nereids.trees.expressions.functions.agg.AggregateFunction;
+import org.apache.doris.nereids.trees.expressions.functions.agg.Count;
+import org.apache.doris.nereids.trees.expressions.functions.agg.Max;
+import org.apache.doris.nereids.trees.expressions.functions.agg.Min;
+import org.apache.doris.nereids.trees.plans.Plan;
+import org.apache.doris.nereids.trees.plans.PushDownAggOperator;
+import org.apache.doris.nereids.trees.plans.logical.LogicalAggregate;
+import org.apache.doris.nereids.trees.plans.logical.LogicalOlapScan;
+import org.apache.doris.nereids.trees.plans.logical.LogicalProject;
+import org.apache.doris.nereids.types.ArrayType;
+import org.apache.doris.nereids.types.BitmapType;
+import org.apache.doris.nereids.types.DataType;
+import org.apache.doris.nereids.types.HllType;
+import org.apache.doris.nereids.types.StringType;
+import org.apache.doris.nereids.types.coercion.CharacterType;
+import org.apache.doris.nereids.types.coercion.NumericType;
+import org.apache.doris.qe.ConnectContext;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Maps;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * push aggregate without group by exprs to olap scan.
+ */
+public class PushAggregateToOlapScan implements RewriteRuleFactory {
+ @Override
+ public List<Rule> buildRules() {
+ return ImmutableList.of(
+ logicalAggregate(logicalOlapScan())
+ .when(aggregate -> check(aggregate, aggregate.child()))
+ .then(aggregate -> {
+ LogicalOlapScan olapScan = aggregate.child();
+ Map<Slot, Slot> projections = Maps.newHashMap();
+ olapScan.getOutput().forEach(s -> projections.put(s, s));
+ LogicalOlapScan pushed = pushAggregateToOlapScan(aggregate, olapScan, projections);
+ if (pushed == olapScan) {
+ return aggregate;
+ } else {
+ return aggregate.withChildren(pushed);
+ }
+ })
+ .toRule(RuleType.PUSH_AGGREGATE_TO_OLAP_SCAN),
+ logicalAggregate(logicalProject(logicalOlapScan()))
+ .when(aggregate -> check(aggregate, aggregate.child().child()))
+ .then(aggregate -> {
+ LogicalProject<LogicalOlapScan> project = aggregate.child();
+ LogicalOlapScan olapScan = project.child();
+ Map<Slot, Slot> projections = Maps.newHashMap();
+ olapScan.getOutput().forEach(s -> projections.put(s, s));
+ project.getProjects().stream()
+ .filter(Alias.class::isInstance)
+ .map(Alias.class::cast)
+ .filter(alias -> alias.child() instanceof Slot)
+ .forEach(alias -> projections.put(alias.toSlot(), (Slot) alias.child()));
+ LogicalOlapScan pushed = pushAggregateToOlapScan(aggregate, olapScan, projections);
+ if (pushed == olapScan) {
+ return aggregate;
+ } else {
+ return aggregate.withChildren(project.withChildren(pushed));
+ }
+ })
+ .toRule(RuleType.PUSH_AGGREGATE_TO_OLAP_SCAN)
+ );
+ }
+
+ private boolean check(LogicalAggregate<? extends Plan> aggregate, LogicalOlapScan olapScan) {
+ // session variables
+ if (ConnectContext.get() != null && !ConnectContext.get().getSessionVariable().enablePushDownNoGroupAgg()) {
+ return false;
+ }
+
+ // olap scan
+ if (olapScan.isAggPushed()) {
+ return false;
+ }
+ KeysType keysType = olapScan.getTable().getKeysType();
+ if (keysType == KeysType.UNIQUE_KEYS || keysType == KeysType.PRIMARY_KEYS) {
+ return false;
+ }
+
+ // aggregate
+ if (!aggregate.getGroupByExpressions().isEmpty()) {
+ return false;
+ }
+ List<AggregateFunction> aggregateFunctions = aggregate.getOutputExpressions().stream()
+ .<Set<AggregateFunction>>map(e -> e.collect(AggregateFunction.class::isInstance))
+ .flatMap(Set::stream).collect(Collectors.toList());
+ if (aggregateFunctions.stream().anyMatch(af -> af.arity() > 1)) {
+ return false;
+ }
+ if (!aggregateFunctions.stream()
+ .allMatch(af -> af instanceof Count || af instanceof Min || af instanceof Max)) {
+ return false;
+ }
+
+ // both
+ if (aggregateFunctions.stream().anyMatch(Count.class::isInstance) && keysType != KeysType.DUP_KEYS) {
+ return false;
+ }
+
+ return true;
+
+ }
+
+ private LogicalOlapScan pushAggregateToOlapScan(
+ LogicalAggregate<? extends Plan> aggregate,
+ LogicalOlapScan olapScan,
+ Map<Slot, Slot> projections) {
+ List<AggregateFunction> aggregateFunctions = aggregate.getOutputExpressions().stream()
+ .<Set<AggregateFunction>>map(e -> e.collect(AggregateFunction.class::isInstance))
+ .flatMap(Set::stream).collect(Collectors.toList());
+
+ PushDownAggOperator pushDownAggOperator = olapScan.getPushDownAggOperator();
+ for (AggregateFunction aggregateFunction : aggregateFunctions) {
+ pushDownAggOperator = pushDownAggOperator.merge(aggregateFunction.getName());
+ if (aggregateFunction.arity() == 0) {
+ continue;
+ }
+ Expression child = aggregateFunction.child(0);
+ Slot slot;
+ if (child instanceof Slot) {
+ slot = (Slot) child;
+ } else if (child instanceof Cast && child.child(0) instanceof SlotReference) {
+ if (child.getDataType() instanceof NumericType
+ && child.child(0).getDataType() instanceof NumericType) {
+ slot = (Slot) child.child(0);
+ } else {
+ return olapScan;
+ }
+ } else {
+ return olapScan;
+ }
+
+ // replace by SlotReference in olap table. check no complex project on this SlotReference.
+ if (!projections.containsKey(slot)) {
+ return olapScan;
+ }
+ slot = projections.get(slot);
+
+ DataType dataType = slot.getDataType();
+ if (pushDownAggOperator.containsMinMax()) {
+
+ if (dataType instanceof ArrayType
+ || dataType instanceof HllType
+ || dataType instanceof BitmapType
+ || dataType instanceof StringType) {
+ return olapScan;
+ }
+ }
+
+ // The zone map max length of CharFamily is 512, do not
+ // over the length: https://github.com/apache/doris/pull/6293
+ if (dataType instanceof CharacterType
+ && (((CharacterType) dataType).getLen() > 512 || ((CharacterType) dataType).getLen() < 0)) {
+ return olapScan;
+ }
+
+ if (pushDownAggOperator.containsCount() && slot.nullable()) {
+ return olapScan;
+ }
+ }
+ return olapScan.withPushDownAggregateOperator(pushDownAggOperator);
+ }
+}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/logical/PushdownProjectThroughLimit.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/logical/PushdownProjectThroughLimit.java
index bd56224d26..4faed0a5cf 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/logical/PushdownProjectThroughLimit.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/logical/PushdownProjectThroughLimit.java
@@ -54,6 +54,6 @@ public class PushdownProjectThroughLimit extends OneRewriteRuleFactory {
return new LogicalLimit<LogicalProject<GroupPlan>>(logicalLimit.getLimit(),
logicalLimit.getOffset(), new LogicalProject<>(logicalProject.getProjects(),
logicalLimit.child()));
- }).toRule(RuleType.PUSHDOWN_PROJECT_THROUGHT_LIMIT);
+ }).toRule(RuleType.PUSHDOWN_PROJECT_THROUGH_LIMIT);
}
}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PushDownAggOperator.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PushDownAggOperator.java
new file mode 100644
index 0000000000..a73839c8ef
--- /dev/null
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PushDownAggOperator.java
@@ -0,0 +1,70 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.trees.plans;
+
+import org.apache.doris.thrift.TPushAggOp;
+
+/**
+ * use for push down agg without group by exprs to olap scan.
+ */
+public class PushDownAggOperator {
+ public static PushDownAggOperator NONE = new PushDownAggOperator(TPushAggOp.NONE);
+ public static PushDownAggOperator MIN_MAX = new PushDownAggOperator(TPushAggOp.MINMAX);
+ public static PushDownAggOperator COUNT = new PushDownAggOperator(TPushAggOp.COUNT);
+ public static PushDownAggOperator MIX = new PushDownAggOperator(TPushAggOp.MIX);
+
+ private final TPushAggOp thriftOperator;
+
+ private PushDownAggOperator(TPushAggOp thriftOperator) {
+ this.thriftOperator = thriftOperator;
+ }
+
+ /**
+ * merge operator.
+ */
+ public PushDownAggOperator merge(String functionName) {
+ PushDownAggOperator newOne;
+ if ("COUNT".equalsIgnoreCase(functionName)) {
+ newOne = COUNT;
+ } else {
+ newOne = MIN_MAX;
+ }
+ if (this == NONE || this == newOne) {
+ return newOne;
+ } else {
+ return MIX;
+ }
+ }
+
+ public TPushAggOp toThrift() {
+ return thriftOperator;
+ }
+
+ public boolean containsMinMax() {
+ return this == MIN_MAX || this == MIX;
+ }
+
+ public boolean containsCount() {
+ return this == COUNT || this == MIX;
+ }
+
+ @Override
+ public String toString() {
+ return thriftOperator.toString();
+ }
+}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalOlapScan.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalOlapScan.java
index dcf4aeeb93..a6bb23029c 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalOlapScan.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalOlapScan.java
@@ -27,6 +27,7 @@ import org.apache.doris.nereids.properties.LogicalProperties;
import org.apache.doris.nereids.trees.plans.Plan;
import org.apache.doris.nereids.trees.plans.PlanType;
import org.apache.doris.nereids.trees.plans.PreAggStatus;
+import org.apache.doris.nereids.trees.plans.PushDownAggOperator;
import org.apache.doris.nereids.trees.plans.RelationId;
import org.apache.doris.nereids.trees.plans.algebra.CatalogRelation;
import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor;
@@ -47,15 +48,18 @@ import java.util.Optional;
public class LogicalOlapScan extends LogicalRelation implements CatalogRelation {
private final long selectedIndexId;
- private final ImmutableList<Long> selectedTabletId;
+ private final List<Long> selectedTabletIds;
private final boolean partitionPruned;
private final boolean tabletPruned;
- private final ImmutableList<Long> candidateIndexIds;
+ private final List<Long> candidateIndexIds;
private final boolean indexSelected;
private final PreAggStatus preAggStatus;
+ private final boolean aggPushed;
+ private final PushDownAggOperator pushDownAggOperator;
+
public LogicalOlapScan(RelationId id, OlapTable table) {
this(id, table, ImmutableList.of());
}
@@ -63,13 +67,13 @@ public class LogicalOlapScan extends LogicalRelation implements CatalogRelation
public LogicalOlapScan(RelationId id, OlapTable table, List<String> qualifier) {
this(id, table, qualifier, Optional.empty(), Optional.empty(),
table.getPartitionIds(), false, ImmutableList.of(), false,
- ImmutableList.of(), false, PreAggStatus.on());
+ ImmutableList.of(), false, PreAggStatus.on(), false, PushDownAggOperator.NONE);
}
public LogicalOlapScan(RelationId id, Table table, List<String> qualifier) {
this(id, table, qualifier, Optional.empty(), Optional.empty(),
((OlapTable) table).getPartitionIds(), false, ImmutableList.of(), false,
- ImmutableList.of(), false, PreAggStatus.on());
+ ImmutableList.of(), false, PreAggStatus.on(), false, PushDownAggOperator.NONE);
}
/**
@@ -78,20 +82,23 @@ public class LogicalOlapScan extends LogicalRelation implements CatalogRelation
public LogicalOlapScan(RelationId id, Table table, List<String> qualifier,
Optional<GroupExpression> groupExpression, Optional<LogicalProperties> logicalProperties,
List<Long> selectedPartitionIds, boolean partitionPruned,
- ImmutableList<Long> selectedTabletIds, boolean tabletPruned,
- List<Long> candidateIndexIds, boolean indexSelected, PreAggStatus preAggStatus) {
+ List<Long> selectedTabletIds, boolean tabletPruned,
+ List<Long> candidateIndexIds, boolean indexSelected, PreAggStatus preAggStatus,
+ boolean aggPushed, PushDownAggOperator pushDownAggOperator) {
super(id, PlanType.LOGICAL_OLAP_SCAN, table, qualifier,
groupExpression, logicalProperties, selectedPartitionIds);
// TODO: use CBO manner to select best index id, according to index's statistics info,
// revisit this after rollup and materialized view selection are fully supported.
this.selectedIndexId = CollectionUtils.isEmpty(candidateIndexIds)
? getTable().getBaseIndexId() : candidateIndexIds.get(0);
- this.selectedTabletId = selectedTabletIds;
+ this.selectedTabletIds = ImmutableList.copyOf(selectedTabletIds);
this.partitionPruned = partitionPruned;
this.tabletPruned = tabletPruned;
this.candidateIndexIds = ImmutableList.copyOf(candidateIndexIds);
this.indexSelected = indexSelected;
this.preAggStatus = preAggStatus;
+ this.aggPushed = aggPushed;
+ this.pushDownAggOperator = pushDownAggOperator;
}
@Override
@@ -114,7 +121,8 @@ public class LogicalOlapScan extends LogicalRelation implements CatalogRelation
"output", getOutput(),
"candidateIndexIds", candidateIndexIds,
"selectedIndexId", selectedIndexId,
- "preAgg", preAggStatus
+ "preAgg", preAggStatus,
+ "pushAgg", pushDownAggOperator
);
}
@@ -128,44 +136,51 @@ public class LogicalOlapScan extends LogicalRelation implements CatalogRelation
}
return Objects.equals(selectedPartitionIds, ((LogicalOlapScan) o).selectedPartitionIds)
&& Objects.equals(candidateIndexIds, ((LogicalOlapScan) o).candidateIndexIds)
- && Objects.equals(selectedTabletId, ((LogicalOlapScan) o).selectedTabletId);
+ && Objects.equals(selectedTabletIds, ((LogicalOlapScan) o).selectedTabletIds)
+ && Objects.equals(pushDownAggOperator, ((LogicalOlapScan) o).pushDownAggOperator);
}
@Override
public int hashCode() {
- return Objects.hash(id, selectedPartitionIds, candidateIndexIds, selectedTabletId);
+ return Objects.hash(id, selectedPartitionIds, candidateIndexIds, selectedTabletIds, pushDownAggOperator);
}
@Override
public Plan withGroupExpression(Optional<GroupExpression> groupExpression) {
return new LogicalOlapScan(id, table, qualifier, groupExpression, Optional.of(getLogicalProperties()),
- selectedPartitionIds, partitionPruned, selectedTabletId, tabletPruned,
- candidateIndexIds, indexSelected, preAggStatus);
+ selectedPartitionIds, partitionPruned, selectedTabletIds, tabletPruned,
+ candidateIndexIds, indexSelected, preAggStatus, aggPushed, pushDownAggOperator);
}
@Override
public LogicalOlapScan withLogicalProperties(Optional<LogicalProperties> logicalProperties) {
return new LogicalOlapScan(id, table, qualifier, Optional.empty(), logicalProperties,
- selectedPartitionIds, partitionPruned, selectedTabletId, tabletPruned,
- candidateIndexIds, indexSelected, preAggStatus);
+ selectedPartitionIds, partitionPruned, selectedTabletIds, tabletPruned,
+ candidateIndexIds, indexSelected, preAggStatus, aggPushed, pushDownAggOperator);
}
public LogicalOlapScan withSelectedPartitionIds(List<Long> selectedPartitionIds) {
return new LogicalOlapScan(id, table, qualifier, Optional.empty(), Optional.of(getLogicalProperties()),
- selectedPartitionIds, true, selectedTabletId, tabletPruned,
- candidateIndexIds, indexSelected, preAggStatus);
+ selectedPartitionIds, true, selectedTabletIds, tabletPruned,
+ candidateIndexIds, indexSelected, preAggStatus, aggPushed, pushDownAggOperator);
}
public LogicalOlapScan withMaterializedIndexSelected(PreAggStatus preAgg, List<Long> candidateIndexIds) {
return new LogicalOlapScan(id, table, qualifier, Optional.empty(), Optional.of(getLogicalProperties()),
- selectedPartitionIds, partitionPruned, selectedTabletId, tabletPruned,
- candidateIndexIds, true, preAgg);
+ selectedPartitionIds, partitionPruned, selectedTabletIds, tabletPruned,
+ candidateIndexIds, true, preAgg, aggPushed, pushDownAggOperator);
+ }
+
+ public LogicalOlapScan withSelectedTabletIds(List<Long> selectedTabletIds) {
+ return new LogicalOlapScan(id, table, qualifier, Optional.empty(), Optional.of(getLogicalProperties()),
+ selectedPartitionIds, partitionPruned, selectedTabletIds, true,
+ candidateIndexIds, indexSelected, preAggStatus, aggPushed, pushDownAggOperator);
}
- public LogicalOlapScan withSelectedTabletIds(ImmutableList<Long> selectedTabletIds) {
+ public LogicalOlapScan withPushDownAggregateOperator(PushDownAggOperator pushDownAggOperator) {
return new LogicalOlapScan(id, table, qualifier, Optional.empty(), Optional.of(getLogicalProperties()),
selectedPartitionIds, partitionPruned, selectedTabletIds, true,
- candidateIndexIds, indexSelected, preAggStatus);
+ candidateIndexIds, indexSelected, preAggStatus, true, pushDownAggOperator);
}
@Override
@@ -181,8 +196,8 @@ public class LogicalOlapScan extends LogicalRelation implements CatalogRelation
return tabletPruned;
}
- public List<Long> getSelectedTabletId() {
- return selectedTabletId;
+ public List<Long> getSelectedTabletIds() {
+ return selectedTabletIds;
}
public long getSelectedIndexId() {
@@ -197,6 +212,14 @@ public class LogicalOlapScan extends LogicalRelation implements CatalogRelation
return preAggStatus;
}
+ public boolean isAggPushed() {
+ return aggPushed;
+ }
+
+ public PushDownAggOperator getPushDownAggOperator() {
+ return pushDownAggOperator;
+ }
+
@VisibleForTesting
public Optional<String> getSelectedMaterializedIndexName() {
return indexSelected ? Optional.ofNullable(((OlapTable) table).getIndexNameById(selectedIndexId))
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalOlapScan.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalOlapScan.java
index 32323da0a1..c4228b91b4 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalOlapScan.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalOlapScan.java
@@ -24,6 +24,7 @@ import org.apache.doris.nereids.properties.LogicalProperties;
import org.apache.doris.nereids.properties.PhysicalProperties;
import org.apache.doris.nereids.trees.plans.PlanType;
import org.apache.doris.nereids.trees.plans.PreAggStatus;
+import org.apache.doris.nereids.trees.plans.PushDownAggOperator;
import org.apache.doris.nereids.trees.plans.RelationId;
import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor;
import org.apache.doris.nereids.util.Utils;
@@ -45,13 +46,15 @@ public class PhysicalOlapScan extends PhysicalRelation {
private final ImmutableList<Long> selectedTabletIds;
private final ImmutableList<Long> selectedPartitionIds;
private final PreAggStatus preAggStatus;
+ private final PushDownAggOperator pushDownAggOperator;
/**
* Constructor for PhysicalOlapScan.
*/
public PhysicalOlapScan(RelationId id, OlapTable olapTable, List<String> qualifier, long selectedIndexId,
List<Long> selectedTabletIds, List<Long> selectedPartitionIds, DistributionSpec distributionSpec,
- PreAggStatus preAggStatus, Optional<GroupExpression> groupExpression, LogicalProperties logicalProperties) {
+ PreAggStatus preAggStatus, PushDownAggOperator pushDownAggOperator,
+ Optional<GroupExpression> groupExpression, LogicalProperties logicalProperties) {
super(id, PlanType.PHYSICAL_OLAP_SCAN, qualifier, groupExpression, logicalProperties);
this.olapTable = olapTable;
this.selectedIndexId = selectedIndexId;
@@ -59,6 +62,7 @@ public class PhysicalOlapScan extends PhysicalRelation {
this.selectedPartitionIds = ImmutableList.copyOf(selectedPartitionIds);
this.distributionSpec = distributionSpec;
this.preAggStatus = preAggStatus;
+ this.pushDownAggOperator = pushDownAggOperator;
}
/**
@@ -66,7 +70,8 @@ public class PhysicalOlapScan extends PhysicalRelation {
*/
public PhysicalOlapScan(RelationId id, OlapTable olapTable, List<String> qualifier, long selectedIndexId,
List<Long> selectedTabletIds, List<Long> selectedPartitionIds, DistributionSpec distributionSpec,
- PreAggStatus preAggStatus, Optional<GroupExpression> groupExpression, LogicalProperties logicalProperties,
+ PreAggStatus preAggStatus, PushDownAggOperator pushDownAggOperator,
+ Optional<GroupExpression> groupExpression, LogicalProperties logicalProperties,
PhysicalProperties physicalProperties, StatsDeriveResult statsDeriveResult) {
super(id, PlanType.PHYSICAL_OLAP_SCAN, qualifier, groupExpression, logicalProperties, physicalProperties,
statsDeriveResult);
@@ -76,6 +81,7 @@ public class PhysicalOlapScan extends PhysicalRelation {
this.selectedPartitionIds = ImmutableList.copyOf(selectedPartitionIds);
this.distributionSpec = distributionSpec;
this.preAggStatus = preAggStatus;
+ this.pushDownAggOperator = pushDownAggOperator;
}
public long getSelectedIndexId() {
@@ -103,6 +109,10 @@ public class PhysicalOlapScan extends PhysicalRelation {
return preAggStatus;
}
+ public PushDownAggOperator getPushDownAggOperator() {
+ return pushDownAggOperator;
+ }
+
@Override
public String toString() {
return Utils.toSqlString("PhysicalOlapScan",
@@ -140,20 +150,23 @@ public class PhysicalOlapScan extends PhysicalRelation {
@Override
public PhysicalOlapScan withGroupExpression(Optional<GroupExpression> groupExpression) {
return new PhysicalOlapScan(id, olapTable, qualifier, selectedIndexId, selectedTabletIds,
- selectedPartitionIds, distributionSpec, preAggStatus, groupExpression, getLogicalProperties());
+ selectedPartitionIds, distributionSpec, preAggStatus, pushDownAggOperator,
+ groupExpression, getLogicalProperties());
}
@Override
public PhysicalOlapScan withLogicalProperties(Optional<LogicalProperties> logicalProperties) {
return new PhysicalOlapScan(id, olapTable, qualifier, selectedIndexId, selectedTabletIds,
- selectedPartitionIds, distributionSpec, preAggStatus, Optional.empty(), logicalProperties.get());
+ selectedPartitionIds, distributionSpec, preAggStatus, pushDownAggOperator,
+ Optional.empty(), logicalProperties.get());
}
@Override
- public PhysicalOlapScan withPhysicalPropertiesAndStats(PhysicalProperties physicalProperties,
- StatsDeriveResult statsDeriveResult) {
+ public PhysicalOlapScan withPhysicalPropertiesAndStats(
+ PhysicalProperties physicalProperties, StatsDeriveResult statsDeriveResult) {
return new PhysicalOlapScan(id, olapTable, qualifier, selectedIndexId, selectedTabletIds,
- selectedPartitionIds, distributionSpec, preAggStatus, Optional.empty(), getLogicalProperties(),
+ selectedPartitionIds, distributionSpec, preAggStatus, pushDownAggOperator,
+ Optional.empty(), getLogicalProperties(),
physicalProperties, statsDeriveResult);
}
}
diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslatorTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslatorTest.java
index cc540dce8c..ab1f8250a3 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslatorTest.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslatorTest.java
@@ -28,6 +28,7 @@ import org.apache.doris.nereids.trees.expressions.SlotReference;
import org.apache.doris.nereids.trees.expressions.literal.IntegerLiteral;
import org.apache.doris.nereids.trees.expressions.literal.Literal;
import org.apache.doris.nereids.trees.plans.PreAggStatus;
+import org.apache.doris.nereids.trees.plans.PushDownAggOperator;
import org.apache.doris.nereids.trees.plans.RelationId;
import org.apache.doris.nereids.trees.plans.physical.PhysicalFilter;
import org.apache.doris.nereids.trees.plans.physical.PhysicalOlapScan;
@@ -63,7 +64,7 @@ public class PhysicalPlanTranslatorTest {
t1Output.add(col3);
LogicalProperties t1Properties = new LogicalProperties(() -> t1Output);
PhysicalOlapScan scan = new PhysicalOlapScan(RelationId.createGenerator().getNextId(), t1, qualifier, 0L,
- Collections.emptyList(), Collections.emptyList(), null, PreAggStatus.on(),
+ Collections.emptyList(), Collections.emptyList(), null, PreAggStatus.on(), PushDownAggOperator.NONE,
Optional.empty(),
t1Properties);
Literal t1FilterRight = new IntegerLiteral(1);
diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/postprocess/MergeProjectPostProcessTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/postprocess/MergeProjectPostProcessTest.java
index caa075379d..9cd75c66ee 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/nereids/postprocess/MergeProjectPostProcessTest.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/postprocess/MergeProjectPostProcessTest.java
@@ -27,6 +27,7 @@ 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.PreAggStatus;
+import org.apache.doris.nereids.trees.plans.PushDownAggOperator;
import org.apache.doris.nereids.trees.plans.RelationId;
import org.apache.doris.nereids.trees.plans.physical.PhysicalOlapScan;
import org.apache.doris.nereids.trees.plans.physical.PhysicalPlan;
@@ -75,9 +76,8 @@ public class MergeProjectPostProcessTest {
t1Output.add(c);
LogicalProperties t1Properties = new LogicalProperties(() -> t1Output);
PhysicalOlapScan scan = new PhysicalOlapScan(RelationId.createGenerator().getNextId(), t1, qualifier, 0L,
- Collections.emptyList(), Collections.emptyList(), null, PreAggStatus.on(),
- Optional.empty(),
- t1Properties);
+ Collections.emptyList(), Collections.emptyList(), null, PreAggStatus.on(), PushDownAggOperator.NONE,
+ Optional.empty(), t1Properties);
Alias x = new Alias(a, "x");
List<NamedExpression> projList3 = Lists.newArrayList(x, b, c);
PhysicalProject proj3 = new PhysicalProject(projList3, placeHolder, scan);
diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/logical/PruneOlapScanTabletTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/logical/PruneOlapScanTabletTest.java
index e5745658be..15cec48f21 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/logical/PruneOlapScanTabletTest.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/logical/PruneOlapScanTabletTest.java
@@ -152,13 +152,13 @@ public class PruneOlapScanTabletTest {
LogicalFilter<LogicalOlapScan> filter = new LogicalFilter<>(expr,
new LogicalOlapScan(RelationId.createGenerator().getNextId(), olapTable));
- Assertions.assertEquals(0, filter.child().getSelectedTabletId().size());
+ Assertions.assertEquals(0, filter.child().getSelectedTabletIds().size());
CascadesContext context = MemoTestUtils.createCascadesContext(filter);
context.topDownRewrite(ImmutableList.of(new PruneOlapScanTablet().build()));
LogicalFilter<LogicalOlapScan> filter1 = ((LogicalFilter<LogicalOlapScan>) context.getMemo().copyOut());
LogicalOlapScan olapScan = filter1.child();
- Assertions.assertEquals(19, olapScan.getSelectedTabletId().size());
+ Assertions.assertEquals(19, olapScan.getSelectedTabletIds().size());
}
}
diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/logical/PushAggregateToOlapScanTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/logical/PushAggregateToOlapScanTest.java
new file mode 100644
index 0000000000..0f275e465e
--- /dev/null
+++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/logical/PushAggregateToOlapScanTest.java
@@ -0,0 +1,154 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.rules.rewrite.logical;
+
+import org.apache.doris.nereids.CascadesContext;
+import org.apache.doris.nereids.trees.expressions.Alias;
+import org.apache.doris.nereids.trees.expressions.functions.agg.Count;
+import org.apache.doris.nereids.trees.expressions.functions.agg.Max;
+import org.apache.doris.nereids.trees.expressions.functions.agg.Min;
+import org.apache.doris.nereids.trees.expressions.functions.scalar.Ln;
+import org.apache.doris.nereids.trees.plans.PushDownAggOperator;
+import org.apache.doris.nereids.trees.plans.logical.LogicalAggregate;
+import org.apache.doris.nereids.trees.plans.logical.LogicalOlapScan;
+import org.apache.doris.nereids.trees.plans.logical.LogicalProject;
+import org.apache.doris.nereids.util.MemoTestUtils;
+import org.apache.doris.nereids.util.PlanConstructor;
+
+import com.google.common.collect.ImmutableList;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.Collections;
+
+public class PushAggregateToOlapScanTest {
+
+ @Test
+ public void testWithoutProject() {
+ LogicalOlapScan olapScan = PlanConstructor.newLogicalOlapScan(1, "tbl", 0);
+ LogicalAggregate<LogicalOlapScan> aggregate;
+ CascadesContext context;
+ LogicalOlapScan pushedOlapScan;
+
+ // min max
+ aggregate = new LogicalAggregate<>(
+ Collections.emptyList(),
+ ImmutableList.of(new Alias(new Min(olapScan.getOutput().get(0)), "min")),
+ olapScan);
+ context = MemoTestUtils.createCascadesContext(aggregate);
+
+ context.topDownRewrite(new PushAggregateToOlapScan());
+ pushedOlapScan = (LogicalOlapScan) (context.getMemo().copyOut().child(0));
+ Assertions.assertTrue(pushedOlapScan.isAggPushed());
+ Assertions.assertEquals(PushDownAggOperator.MIN_MAX, pushedOlapScan.getPushDownAggOperator());
+
+ // count
+ aggregate = new LogicalAggregate<>(
+ Collections.emptyList(),
+ ImmutableList.of(new Alias(new Count(olapScan.getOutput().get(0)), "count")),
+ olapScan);
+ context = MemoTestUtils.createCascadesContext(aggregate);
+
+ context.topDownRewrite(new PushAggregateToOlapScan());
+ pushedOlapScan = (LogicalOlapScan) (context.getMemo().copyOut().child(0));
+ Assertions.assertTrue(pushedOlapScan.isAggPushed());
+ Assertions.assertEquals(PushDownAggOperator.COUNT, pushedOlapScan.getPushDownAggOperator());
+
+ // mix
+ aggregate = new LogicalAggregate<>(
+ Collections.emptyList(),
+ ImmutableList.of(new Alias(new Count(olapScan.getOutput().get(0)), "count"),
+ new Alias(new Max(olapScan.getOutput().get(0)), "max")),
+ olapScan);
+ context = MemoTestUtils.createCascadesContext(aggregate);
+
+ context.topDownRewrite(new PushAggregateToOlapScan());
+ pushedOlapScan = (LogicalOlapScan) (context.getMemo().copyOut().child(0));
+ Assertions.assertTrue(pushedOlapScan.isAggPushed());
+ Assertions.assertEquals(PushDownAggOperator.MIX, pushedOlapScan.getPushDownAggOperator());
+ }
+
+ @Test
+ public void testWithProject() {
+ LogicalOlapScan olapScan = PlanConstructor.newLogicalOlapScan(1, "tbl", 0);
+ LogicalProject<LogicalOlapScan> project = new LogicalProject<>(
+ ImmutableList.of(olapScan.getOutput().get(0)), olapScan);
+ LogicalAggregate<LogicalProject<LogicalOlapScan>> aggregate;
+ CascadesContext context;
+ LogicalOlapScan pushedOlapScan;
+
+ // min max
+ aggregate = new LogicalAggregate<>(
+ Collections.emptyList(),
+ ImmutableList.of(new Alias(new Min(project.getOutput().get(0)), "min")),
+ project);
+ context = MemoTestUtils.createCascadesContext(aggregate);
+
+ context.topDownRewrite(new PushAggregateToOlapScan());
+ pushedOlapScan = (LogicalOlapScan) (context.getMemo().copyOut().child(0).child(0));
+ Assertions.assertTrue(pushedOlapScan.isAggPushed());
+ Assertions.assertEquals(PushDownAggOperator.MIN_MAX, pushedOlapScan.getPushDownAggOperator());
+
+ // count
+ aggregate = new LogicalAggregate<>(
+ Collections.emptyList(),
+ ImmutableList.of(new Alias(new Count(project.getOutput().get(0)), "count")),
+ project);
+ context = MemoTestUtils.createCascadesContext(aggregate);
+
+ context.topDownRewrite(new PushAggregateToOlapScan());
+ pushedOlapScan = (LogicalOlapScan) (context.getMemo().copyOut().child(0).child(0));
+ Assertions.assertTrue(pushedOlapScan.isAggPushed());
+ Assertions.assertEquals(PushDownAggOperator.COUNT, pushedOlapScan.getPushDownAggOperator());
+
+ // mix
+ aggregate = new LogicalAggregate<>(
+ Collections.emptyList(),
+ ImmutableList.of(new Alias(new Count(project.getOutput().get(0)), "count"),
+ new Alias(new Max(olapScan.getOutput().get(0)), "max")),
+ project);
+ context = MemoTestUtils.createCascadesContext(aggregate);
+
+ context.topDownRewrite(new PushAggregateToOlapScan());
+ pushedOlapScan = (LogicalOlapScan) (context.getMemo().copyOut().child(0).child(0));
+ Assertions.assertTrue(pushedOlapScan.isAggPushed());
+ Assertions.assertEquals(PushDownAggOperator.MIX, pushedOlapScan.getPushDownAggOperator());
+ }
+
+ @Test
+ void testProjectionCheck() {
+ LogicalOlapScan olapScan = PlanConstructor.newLogicalOlapScan(1, "tbl", 0);
+ LogicalProject<LogicalOlapScan> project = new LogicalProject<>(
+ ImmutableList.of(new Alias(new Ln(olapScan.getOutput().get(0)), "alias")), olapScan);
+ LogicalAggregate<LogicalProject<LogicalOlapScan>> aggregate;
+ CascadesContext context;
+ LogicalOlapScan pushedOlapScan;
+
+ // min max
+ aggregate = new LogicalAggregate<>(
+ Collections.emptyList(),
+ ImmutableList.of(new Alias(new Min(project.getOutput().get(0)), "min")),
+ project);
+ context = MemoTestUtils.createCascadesContext(aggregate);
+
+ context.topDownRewrite(new PushAggregateToOlapScan());
+ pushedOlapScan = (LogicalOlapScan) (context.getMemo().copyOut().child(0).child(0));
+ Assertions.assertFalse(pushedOlapScan.isAggPushed());
+ Assertions.assertEquals(PushDownAggOperator.NONE, pushedOlapScan.getPushDownAggOperator());
+ }
+}
diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/PlanEqualsTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/PlanEqualsTest.java
index a750e32368..cb4b0acde3 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/PlanEqualsTest.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/PlanEqualsTest.java
@@ -251,16 +251,16 @@ public class PlanEqualsTest {
PhysicalOlapScan actual = new PhysicalOlapScan(id, olapTable, Lists.newArrayList("a"),
olapTable.getBaseIndexId(), selectedTabletId, olapTable.getPartitionIds(), distributionSpecHash,
- PreAggStatus.on(), Optional.empty(), logicalProperties);
+ PreAggStatus.on(), PushDownAggOperator.NONE, Optional.empty(), logicalProperties);
PhysicalOlapScan expected = new PhysicalOlapScan(id, olapTable, Lists.newArrayList("a"),
olapTable.getBaseIndexId(), selectedTabletId, olapTable.getPartitionIds(), distributionSpecHash,
- PreAggStatus.on(), Optional.empty(), logicalProperties);
+ PreAggStatus.on(), PushDownAggOperator.NONE, Optional.empty(), logicalProperties);
Assertions.assertEquals(expected, actual);
PhysicalOlapScan unexpected = new PhysicalOlapScan(id, olapTable, Lists.newArrayList("b"),
olapTable.getBaseIndexId(), selectedTabletId, olapTable.getPartitionIds(), distributionSpecHash,
- PreAggStatus.on(), Optional.empty(), logicalProperties);
+ PreAggStatus.on(), PushDownAggOperator.NONE, Optional.empty(), logicalProperties);
Assertions.assertNotEquals(unexpected, actual);
}
diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/PlanToStringTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/PlanToStringTest.java
index 9f350abb1d..1dc0a8047a 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/PlanToStringTest.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/PlanToStringTest.java
@@ -81,7 +81,7 @@ public class PlanToStringTest {
LogicalOlapScan plan = PlanConstructor.newLogicalOlapScan(0, "table", 0);
Assertions.assertTrue(
plan.toString().matches("LogicalOlapScan \\( qualified=db\\.table, "
- + "output=\\[id#\\d+, name#\\d+], candidateIndexIds=\\[], selectedIndexId=-1, preAgg=ON \\)"));
+ + "output=\\[id#\\d+, name#\\d+], candidateIndexIds=\\[], selectedIndexId=-1, preAgg=ON, pushAgg=NONE \\)"));
}
@Test
diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/util/PlanConstructor.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/util/PlanConstructor.java
index c03d24445b..9549524cc4 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/nereids/util/PlanConstructor.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/util/PlanConstructor.java
@@ -77,7 +77,7 @@ public class PlanConstructor {
}
public static OlapTable newOlapTable(long tableId, String tableName, int hashColumn) {
- return newOlapTable(tableId, tableName, hashColumn, KeysType.PRIMARY_KEYS);
+ return newOlapTable(tableId, tableName, hashColumn, KeysType.DUP_KEYS);
}
public static OlapTable newOlapTable(long tableId, String tableName, int hashColumn, KeysType keysType) {
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org