This is an automated email from the ASF dual-hosted git repository. jakevin pushed a commit to branch branch-2.0 in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-2.0 by this push: new 00b752d4b2f [feature](Nereids): Convert topn(x, 1) to max(x) (#26004) (#26303) 00b752d4b2f is described below commit 00b752d4b2f242f2bb1f4ac6c53261d494d75b4c Author: jakevin <jakevin...@gmail.com> AuthorDate: Thu Nov 2 17:36:04 2023 +0800 [feature](Nereids): Convert topn(x, 1) to max(x) (#26004) (#26303) (cherry picked from commit d953e5c8f443b2bc58e8eb1174306b0e5ef353aa) --- .../rules/expression/ExpressionOptimization.java | 4 +- .../nereids/rules/expression/rules/TopnToMax.java | 55 ++++++++++++++++++++++ .../rules/expression/rules/TopnToMaxTest.java | 40 ++++++++++++++++ .../data/nereids_p0/expression/topn_to_max.out | 8 ++++ .../nereids_p0/expression/topn_to_max.groovy | 49 +++++++++++++++++++ 5 files changed, 155 insertions(+), 1 deletion(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/ExpressionOptimization.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/ExpressionOptimization.java index 869cd6b99ee..a37e6f4754e 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/ExpressionOptimization.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/ExpressionOptimization.java @@ -26,6 +26,7 @@ import org.apache.doris.nereids.rules.expression.rules.SimplifyComparisonPredica import org.apache.doris.nereids.rules.expression.rules.SimplifyDecimalV3Comparison; import org.apache.doris.nereids.rules.expression.rules.SimplifyInPredicate; import org.apache.doris.nereids.rules.expression.rules.SimplifyRange; +import org.apache.doris.nereids.rules.expression.rules.TopnToMax; import com.google.common.collect.ImmutableList; @@ -44,7 +45,8 @@ public class ExpressionOptimization extends ExpressionRewrite { SimplifyRange.INSTANCE, OrToIn.INSTANCE, ArrayContainToArrayOverlap.INSTANCE, - CaseWhenToIf.INSTANCE + CaseWhenToIf.INSTANCE, + TopnToMax.INSTANCE ); private static final ExpressionRuleExecutor EXECUTOR = new ExpressionRuleExecutor(OPTIMIZE_REWRITE_RULES); diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/TopnToMax.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/TopnToMax.java new file mode 100644 index 00000000000..30e76cfe226 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/TopnToMax.java @@ -0,0 +1,55 @@ +// 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.expression.rules; + +import org.apache.doris.nereids.rules.expression.ExpressionRewriteContext; +import org.apache.doris.nereids.rules.expression.ExpressionRewriteRule; +import org.apache.doris.nereids.trees.expressions.Expression; +import org.apache.doris.nereids.trees.expressions.functions.agg.AggregateFunction; +import org.apache.doris.nereids.trees.expressions.functions.agg.Max; +import org.apache.doris.nereids.trees.expressions.functions.agg.TopN; +import org.apache.doris.nereids.trees.expressions.literal.IntegerLikeLiteral; +import org.apache.doris.nereids.trees.expressions.visitor.DefaultExpressionRewriter; + +/** + * Convert topn(x, 1) to max(x) + */ +public class TopnToMax extends DefaultExpressionRewriter<ExpressionRewriteContext> implements + ExpressionRewriteRule<ExpressionRewriteContext> { + + public static final TopnToMax INSTANCE = new TopnToMax(); + + @Override + public Expression rewrite(Expression expr, ExpressionRewriteContext ctx) { + return expr.accept(this, null); + } + + @Override + public Expression visitAggregateFunction(AggregateFunction aggregateFunction, ExpressionRewriteContext context) { + if (!(aggregateFunction instanceof TopN)) { + return aggregateFunction; + } + TopN topN = (TopN) aggregateFunction; + if (topN.arity() == 2 && topN.child(1) instanceof IntegerLikeLiteral + && ((IntegerLikeLiteral) topN.child(1)).getIntValue() == 1) { + return new Max(topN.child(0)); + } else { + return aggregateFunction; + } + } +} diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rules/TopnToMaxTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rules/TopnToMaxTest.java new file mode 100644 index 00000000000..8f3c682de5b --- /dev/null +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rules/TopnToMaxTest.java @@ -0,0 +1,40 @@ +// 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.expression.rules; + +import org.apache.doris.nereids.rules.expression.ExpressionRewriteTestHelper; +import org.apache.doris.nereids.rules.expression.ExpressionRuleExecutor; +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.Max; +import org.apache.doris.nereids.trees.expressions.functions.agg.TopN; +import org.apache.doris.nereids.trees.expressions.literal.Literal; +import org.apache.doris.nereids.types.StringType; + +import com.google.common.collect.ImmutableList; +import org.junit.jupiter.api.Test; + +class TopnToMaxTest extends ExpressionRewriteTestHelper { + @Test + void testSimplifyComparisonPredicateRule() { + executor = new ExpressionRuleExecutor(ImmutableList.of(TopnToMax.INSTANCE)); + + Slot slot = new SlotReference("a", StringType.INSTANCE); + assertRewrite(new TopN(slot, Literal.of(1)), new Max(slot)); + } +} diff --git a/regression-test/data/nereids_p0/expression/topn_to_max.out b/regression-test/data/nereids_p0/expression/topn_to_max.out new file mode 100644 index 00000000000..6c8d190500a --- /dev/null +++ b/regression-test/data/nereids_p0/expression/topn_to_max.out @@ -0,0 +1,8 @@ +-- This file is automatically generated. You should know what you did if you want to edit this +-- !sql -- +1 1 +2 2 + +-- !sql -- +2 + diff --git a/regression-test/suites/nereids_p0/expression/topn_to_max.groovy b/regression-test/suites/nereids_p0/expression/topn_to_max.groovy new file mode 100644 index 00000000000..ae848b5a244 --- /dev/null +++ b/regression-test/suites/nereids_p0/expression/topn_to_max.groovy @@ -0,0 +1,49 @@ +// 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. + +suite("test_topn_to_max") { + sql 'set enable_nereids_planner=true' + sql 'set enable_fallback_to_original_planner=false' + + sql 'drop table if exists test_topn_to_max;' + + sql '''create table test_topn_to_max (k1 int, k2 string) distributed by hash(k1) buckets 3 properties('replication_num' = '1');''' + sql '''insert into test_topn_to_max values (1, "1"), (2, "2");''' + + + order_qt_sql ''' + select k1, topn(k2, 1) + from test_topn_to_max + group by k1; + ''' + res = sql ''' + explain rewritten plan select k1, max(k2) + from test_topn_to_max + group by k1; + ''' + assertTrue(res.toString().contains("max")) + + order_qt_sql ''' + select topn(k2, 1) + from test_topn_to_max; + ''' + res = sql ''' + explain rewritten plan select max(k2) + from test_topn_to_max; + ''' + assertTrue(res.toString().contains("max")) +} --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org