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 169f556225..049680ee3f 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 @@ -80,6 +80,7 @@ import org.apache.doris.nereids.rules.rewrite.logical.PushdownFilterThroughJoin; import org.apache.doris.nereids.rules.rewrite.logical.PushdownFilterThroughProject; import org.apache.doris.nereids.rules.rewrite.logical.PushdownFilterThroughRepeat; import org.apache.doris.nereids.rules.rewrite.logical.PushdownFilterThroughSetOperation; +import org.apache.doris.nereids.rules.rewrite.logical.PushdownFilterThroughSort; import org.apache.doris.nereids.rules.rewrite.logical.PushdownFilterThroughWindow; import org.apache.doris.nereids.rules.rewrite.logical.PushdownJoinOtherCondition; import org.apache.doris.nereids.rules.rewrite.logical.PushdownProjectThroughLimit; @@ -113,6 +114,7 @@ public class RuleSet { public static final List PUSH_DOWN_FILTERS = ImmutableList.of( new PushdownFilterThroughProject(), + new PushdownFilterThroughSort(), new PushdownJoinOtherCondition(), new PushdownFilterThroughJoin(), new PushdownExpressionsInHashCondition(), 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 3db4863e07..b3006f799f 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 @@ -138,6 +138,7 @@ public enum RuleType { PUSHDOWN_PROJECT_THROUGH_LIMIT(RuleTypeClass.REWRITE), PUSHDOWN_ALIAS_THROUGH_JOIN(RuleTypeClass.REWRITE), PUSHDOWN_FILTER_THROUGH_SET_OPERATION(RuleTypeClass.REWRITE), + PUSHDOWN_FILTER_THROUGH_SORT(RuleTypeClass.REWRITE), PUSHDOWN_FILTER_THROUGH_CTE_ANCHOR(RuleTypeClass.REWRITE), diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/logical/PushdownFilterThroughSort.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/logical/PushdownFilterThroughSort.java new file mode 100644 index 0000000000..c3bccfde5f --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/logical/PushdownFilterThroughSort.java @@ -0,0 +1,43 @@ +// 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.rules.Rule; +import org.apache.doris.nereids.rules.RuleType; +import org.apache.doris.nereids.rules.rewrite.OneRewriteRuleFactory; +import org.apache.doris.nereids.trees.plans.Plan; +import org.apache.doris.nereids.trees.plans.logical.LogicalFilter; +import org.apache.doris.nereids.trees.plans.logical.LogicalSort; + +/** + * Push down filter through sort. + * input: + * filter -> sort + * output: + * sort -> filter + * The filter can be directly push down to the sort. + */ +public class PushdownFilterThroughSort extends OneRewriteRuleFactory { + @Override + public Rule build() { + return logicalFilter(logicalSort()).then(filter -> { + LogicalSort sort = filter.child(); + return sort.withChildren(new LogicalFilter<>(filter.getConjuncts(), sort.child())); + }).toRule(RuleType.PUSHDOWN_FILTER_THROUGH_SORT); + } +} diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/logical/PushdownFilterThroughSortTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/logical/PushdownFilterThroughSortTest.java new file mode 100644 index 0000000000..0ce850262e --- /dev/null +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/logical/PushdownFilterThroughSortTest.java @@ -0,0 +1,64 @@ +// 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.properties.OrderKey; +import org.apache.doris.nereids.trees.expressions.Expression; +import org.apache.doris.nereids.trees.expressions.GreaterThan; +import org.apache.doris.nereids.trees.expressions.Slot; +import org.apache.doris.nereids.trees.expressions.literal.Literal; +import org.apache.doris.nereids.trees.plans.logical.LogicalOlapScan; +import org.apache.doris.nereids.trees.plans.logical.LogicalPlan; +import org.apache.doris.nereids.util.LogicalPlanBuilder; +import org.apache.doris.nereids.util.MemoPatternMatchSupported; +import org.apache.doris.nereids.util.MemoTestUtils; +import org.apache.doris.nereids.util.PlanChecker; +import org.apache.doris.nereids.util.PlanConstructor; +import org.apache.doris.nereids.util.RelationUtil; + +import com.google.common.collect.ImmutableList; +import org.junit.jupiter.api.Test; + +import java.util.stream.Collectors; + +public class PushdownFilterThroughSortTest implements MemoPatternMatchSupported { + private final LogicalOlapScan scan = new LogicalOlapScan(RelationUtil.newRelationId(), PlanConstructor.student, + ImmutableList.of("")); + + @Test + void testPushdownFilterThroughSortTest() { + Slot gender = scan.getOutput().get(1); + + Expression filterPredicate = new GreaterThan(gender, Literal.of(1)); + + LogicalPlan plan = new LogicalPlanBuilder(scan) + .sort(scan.getOutput().stream().map(c -> new OrderKey(c, true, true)).collect(Collectors.toList())) + .filter(filterPredicate) + .build(); + + PlanChecker.from(MemoTestUtils.createConnectContext(), plan) + .applyTopDown(new PushdownFilterThroughSort()) + .matches( + logicalSort( + logicalFilter( + logicalOlapScan() + ) + ) + ); + } +}