diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/executor/Analyzer.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/executor/Analyzer.java index 70e24c676c..9ad10a30aa 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/executor/Analyzer.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/executor/Analyzer.java @@ -31,6 +31,7 @@ import org.apache.doris.nereids.rules.analysis.CheckAnalysis; import org.apache.doris.nereids.rules.analysis.CheckPolicy; import org.apache.doris.nereids.rules.analysis.CollectJoinConstraint; import org.apache.doris.nereids.rules.analysis.CollectSubQueryAlias; +import org.apache.doris.nereids.rules.analysis.EliminateDistinctConstant; import org.apache.doris.nereids.rules.analysis.EliminateGroupByConstant; import org.apache.doris.nereids.rules.analysis.EliminateLogicalSelectHint; import org.apache.doris.nereids.rules.analysis.FillUpMissingSlots; @@ -144,6 +145,7 @@ public class Analyzer extends AbstractBatchJobExecutor { // so any rule before this, if create a new logicalProject node // should make sure isDistinct property is correctly passed around. // please see rule BindSlotReference or BindFunction for example + new EliminateDistinctConstant(), new ProjectWithDistinctToAggregate(), new ResolveOrdinalInOrderByAndGroupBy(), new ReplaceExpressionByChildOutput(), 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 672f78163c..fc47d10487 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,6 +104,7 @@ public enum RuleType { DISTINCT_AGGREGATE_DISASSEMBLE(RuleTypeClass.REWRITE), LOGICAL_SUB_QUERY_ALIAS_TO_LOGICAL_PROJECT(RuleTypeClass.REWRITE), COLLECT_SUB_QUERY_ALIAS(RuleTypeClass.REWRITE), + ELIMINATE_DISTINCT_CONSTANT(RuleTypeClass.REWRITE), ELIMINATE_GROUP_BY_CONSTANT(RuleTypeClass.REWRITE), ELIMINATE_LOGICAL_SELECT_HINT(RuleTypeClass.REWRITE), diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/EliminateDistinctConstant.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/EliminateDistinctConstant.java new file mode 100644 index 0000000000..0d051ee8c8 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/EliminateDistinctConstant.java @@ -0,0 +1,48 @@ +// 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.analysis; + +import org.apache.doris.nereids.rules.Rule; +import org.apache.doris.nereids.rules.RuleType; +import org.apache.doris.nereids.trees.expressions.Expression; +import org.apache.doris.nereids.trees.plans.LimitPhase; +import org.apache.doris.nereids.trees.plans.logical.LogicalLimit; +import org.apache.doris.nereids.trees.plans.logical.LogicalProject; + +/** + * EliminateDistinctConstant. + *

+ * example sql: + *

+ * select distinct 1,2,3 from tbl
+ *          =>
+ * select 1,2,3 from (select 1, 2, 3 from tbl limit 1) as tmp
+ *  
+ */ +public class EliminateDistinctConstant extends OneAnalysisRuleFactory { + @Override + public Rule build() { + return RuleType.ELIMINATE_DISTINCT_CONSTANT.build( + logicalProject() + .when(LogicalProject::isDistinct) + .when(project -> project.getProjects().stream().allMatch(Expression::isConstant)) + .then(project -> new LogicalProject(project.getProjects(), new LogicalLimit<>(1, 0, + LimitPhase.ORIGIN, project.child()))) + ); + } +} diff --git a/regression-test/data/nereids_rules_p0/eliminate_distinct_constant/eliminate_distinct_constant.out b/regression-test/data/nereids_rules_p0/eliminate_distinct_constant/eliminate_distinct_constant.out new file mode 100644 index 0000000000..f5ed6baa50 --- /dev/null +++ b/regression-test/data/nereids_rules_p0/eliminate_distinct_constant/eliminate_distinct_constant.out @@ -0,0 +1,40 @@ +-- This file is automatically generated. You should know what you did if you want to edit this +-- !basic_1 -- +PhysicalResultSink +--PhysicalLimit[GLOBAL] +----PhysicalLimit[LOCAL] +------PhysicalProject +--------PhysicalOlapScan[t1] + +-- !basic_2 -- +PhysicalResultSink +--PhysicalLimit[GLOBAL] +----PhysicalLimit[LOCAL] +------PhysicalProject +--------PhysicalOlapScan[t2] + +-- !basic_3 -- +PhysicalResultSink +--PhysicalLimit[GLOBAL] +----PhysicalLimit[LOCAL] +------PhysicalProject +--------PhysicalOlapScan[t3] + +-- !basic_4 -- +PhysicalResultSink +--PhysicalLimit[GLOBAL] +----PhysicalLimit[LOCAL] +------PhysicalProject +--------PhysicalOlapScan[t4] + +-- !basic_1 -- +1 2 3 + +-- !basic_2 -- +1 2 3 + +-- !basic_3 -- + +-- !basic_4 -- +1 2 3 + diff --git a/regression-test/suites/nereids_rules_p0/eliminate_distinct_constant/eliminate_distinct_constant.groovy b/regression-test/suites/nereids_rules_p0/eliminate_distinct_constant/eliminate_distinct_constant.groovy new file mode 100644 index 0000000000..342450026e --- /dev/null +++ b/regression-test/suites/nereids_rules_p0/eliminate_distinct_constant/eliminate_distinct_constant.groovy @@ -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. + +suite("eliminate_distinct_constant") { + sql "SET enable_nereids_planner=true" + sql "set runtime_filter_mode=OFF" + sql "SET enable_fallback_to_original_planner=false" + sql "SET ignore_shape_nodes='PhysicalDistribute'" + sql 'DROP DATABASE IF EXISTS test_aggregate_constant' + sql 'CREATE DATABASE IF NOT EXISTS test_aggregate_constant' + sql 'use test_aggregate_constant' + + // create tables + sql """drop table if exists t1;""" + sql """drop table if exists t2;""" + sql """drop table if exists t3;""" + sql """drop table if exists t4;""" + + sql """create table t1 (c1 int, c11 int) distributed by hash(c1) buckets 3 properties('replication_num' = '1');""" + sql """create table t2 (c2 int, c22 int) distributed by hash(c2) buckets 3 properties('replication_num' = '1');""" + sql """create table t3 (c3 int, c33 int) distributed by hash(c3) buckets 3 properties('replication_num' = '1');""" + sql """create table t4 (c4 int, c44 int) distributed by hash(c4) buckets 3 properties('replication_num' = '1');""" + + sql "insert into t1 values (101, 101)" + sql "insert into t2 values (null, null)" + sql "insert into t4 values (102, 102)" + sql "insert into t4 values (103, 103)" + + /* ******** with one row ******** */ + qt_basic_1 """explain shape plan select distinct 1, 2, 3 from t1;""" + + /* ******** with one row "null" ******** */ + qt_basic_2 """explain shape plan select distinct 1, 2, 3 from t2;""" + + /* ******** with empty table ******** */ + qt_basic_3 """explain shape plan select distinct 1, 2, 3 from t3;""" + + /* ******** with different group table ******** */ + qt_basic_4 """explain shape plan select distinct 1, 2, 3 from t4;""" + + + /* ******** Output ******** */ + + /* ******** with one row ******** */ + order_qt_basic_1 """select distinct 1, 2, 3 from t1;""" + + /* ******** with one row "null" ******** */ + order_qt_basic_2 """select distinct 1, 2, 3 from t2;""" + + /* ******** with empty table ******** */ + order_qt_basic_3 """select distinct 1, 2, 3 from t3;""" + + /* ******** with different group table ******** */ + order_qt_basic_4 """select distinct 1, 2, 3 from t4;""" + +} \ No newline at end of file