Skip to content

Commit ee0201a

Browse files
fix
1 parent 3bb843d commit ee0201a

File tree

3 files changed

+40
-40
lines changed

3 files changed

+40
-40
lines changed

fe/fe-core/src/main/java/org/apache/doris/nereids/properties/FuncDeps.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,6 @@ public boolean isFuncDeps(Set<Slot> dominate, Set<Slot> dependency) {
184184
return items.contains(new FuncDepsItem(dominate, dependency));
185185
}
186186

187-
// 这个也是判断是否为双射的
188187
public boolean isCircleDeps(Set<Slot> dominate, Set<Slot> dependency) {
189188
return items.contains(new FuncDepsItem(dominate, dependency))
190189
&& items.contains(new FuncDepsItem(dependency, dominate));

fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/EliminateGroupByKey.java

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package org.apache.doris.nereids.rules.rewrite;
1919

2020
import org.apache.doris.nereids.annotation.DependsRules;
21+
import org.apache.doris.nereids.properties.DataTrait;
2122
import org.apache.doris.nereids.properties.FuncDeps;
2223
import org.apache.doris.nereids.rules.Rule;
2324
import org.apache.doris.nereids.rules.RuleType;
@@ -78,17 +79,38 @@ public List<Rule> buildRules() {
7879
}
7980

8081
LogicalAggregate<Plan> eliminateGroupByKey(LogicalAggregate<? extends Plan> agg, Set<Slot> requireOutput) {
82+
Set<Expression> removeExpression = findCanBeRemovedExpressions(agg, requireOutput,
83+
agg.child().getLogicalProperties().getTrait());
84+
List<Expression> newGroupExpression = new ArrayList<>();
85+
for (Expression expression : agg.getGroupByExpressions()) {
86+
if (!removeExpression.contains(expression)) {
87+
newGroupExpression.add(expression);
88+
}
89+
}
90+
List<NamedExpression> newOutput = new ArrayList<>();
91+
for (NamedExpression expression : agg.getOutputExpressions()) {
92+
if (!removeExpression.contains(expression)) {
93+
newOutput.add(expression);
94+
}
95+
}
96+
return agg.withGroupByAndOutput(newGroupExpression, newOutput);
97+
}
98+
99+
/**
100+
* return removeExpression
101+
*/
102+
public static Set<Expression> findCanBeRemovedExpressions(LogicalAggregate<? extends Plan> agg,
103+
Set<Slot> requireOutput, DataTrait dataTrait) {
81104
Map<Expression, Set<Slot>> groupBySlots = new HashMap<>();
82105
Set<Slot> validSlots = new HashSet<>();
83106
for (Expression expression : agg.getGroupByExpressions()) {
84107
groupBySlots.put(expression, expression.getInputSlots());
85108
validSlots.addAll(expression.getInputSlots());
86109
}
87110

88-
FuncDeps funcDeps = agg.child().getLogicalProperties()
89-
.getTrait().getAllValidFuncDeps(validSlots);
111+
FuncDeps funcDeps = dataTrait.getAllValidFuncDeps(validSlots);
90112
if (funcDeps.isEmpty()) {
91-
return null;
113+
return new HashSet<>();
92114
}
93115

94116
Set<Set<Slot>> minGroupBySlots = funcDeps.eliminateDeps(new HashSet<>(groupBySlots.values()), requireOutput);
@@ -99,19 +121,6 @@ LogicalAggregate<Plan> eliminateGroupByKey(LogicalAggregate<? extends Plan> agg,
99121
removeExpression.add(entry.getKey());
100122
}
101123
}
102-
103-
List<Expression> newGroupExpression = new ArrayList<>();
104-
for (Expression expression : agg.getGroupByExpressions()) {
105-
if (!removeExpression.contains(expression)) {
106-
newGroupExpression.add(expression);
107-
}
108-
}
109-
List<NamedExpression> newOutput = new ArrayList<>();
110-
for (NamedExpression expression : agg.getOutputExpressions()) {
111-
if (!removeExpression.contains(expression)) {
112-
newOutput.add(expression);
113-
}
114-
}
115-
return agg.withGroupByAndOutput(newGroupExpression, newOutput);
124+
return removeExpression;
116125
}
117126
}

fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/PushDownAggThroughJoinOnPkFk.java

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
package org.apache.doris.nereids.rules.rewrite;
1919

2020
import org.apache.doris.common.Pair;
21-
import org.apache.doris.nereids.properties.DataTrait;
2221
import org.apache.doris.nereids.properties.FuncDeps;
2322
import org.apache.doris.nereids.rules.Rule;
2423
import org.apache.doris.nereids.rules.RuleType;
@@ -125,45 +124,36 @@ public List<Rule> buildRules() {
125124
}
126125

127126
// eliminate the slot of primary plan in agg
127+
// e.g.
128+
// select primary_table_pk, primary_table_other from primary_table join foreign_table on pk = fk
129+
// group by pk, primary_table_other_cols;
128130
private LogicalAggregate<?> eliminatePrimaryOutput(LogicalAggregate<?> agg, Plan child,
129131
Plan primary, Plan foreign) {
130132
Set<Slot> aggInputs = agg.getInputSlots();
131133
if (primary.getOutputSet().stream().noneMatch(aggInputs::contains)) {
132134
return agg;
133135
}
134136
// Firstly, using fd to eliminate group by key.
135-
// group by primary_table_pk, primary_table_other
136-
// -> group by primary_table_pk
137-
Set<Set<Slot>> groupBySlots = new HashSet<>();
138-
Set<Slot> validSlots = new HashSet<>();
139-
for (Expression expression : agg.getGroupByExpressions()) {
140-
groupBySlots.add(expression.getInputSlots());
141-
validSlots.addAll(expression.getInputSlots());
142-
}
143-
DataTrait dataTrait = child.getLogicalProperties().getTrait();
144-
FuncDeps funcDeps = dataTrait.getAllValidFuncDeps(validSlots);
145-
Set<Slot> foreignOutput = Sets.intersection(agg.getOutputSet(), foreign.getOutputSet());
146-
Set<Set<Slot>> minGroupBySlots = funcDeps.eliminateDeps(groupBySlots, foreignOutput);
147-
Set<Expression> removeExpression = new HashSet<>();
148-
for (Set<Slot> slots : groupBySlots) {
149-
if (!minGroupBySlots.contains(slots) && !foreignOutput.containsAll(slots)) {
150-
removeExpression.add(slots.iterator().next());
151-
}
152-
}
137+
// group by pk, primary_table_other_cols;
138+
// -> group by pk;
139+
Set<Expression> removeExpression = EliminateGroupByKey.findCanBeRemovedExpressions(agg,
140+
Sets.intersection(agg.getOutputSet(), foreign.getOutputSet()),
141+
child.getLogicalProperties().getTrait());
153142
List<Expression> minGroupBySlotList = new ArrayList<>();
154143
for (Expression expression : agg.getGroupByExpressions()) {
155144
if (!removeExpression.contains(expression)) {
156145
minGroupBySlotList.add(expression);
157146
}
158147
}
159148

160-
// Secondly, put bijective slot into map: {primary_table_pk : foreign_table_fk}
149+
// Secondly, put bijective slot into map: {pk : fk}
161150
// Bijective slots are mutually interchangeable within GROUP BY keys.
162-
// group by primary_table_pk equals group by foreign_table_fk
151+
// group by pk -> group by fk
163152
Set<Slot> primaryOutputSet = primary.getOutputSet();
164153
Set<Slot> primarySlots = Sets.intersection(aggInputs, primaryOutputSet);
165154
HashMap<Slot, Slot> primaryToForeignDeps = new HashMap<>();
166-
FuncDeps funcDepsForJoin = dataTrait.getAllValidFuncDeps(Sets.union(primaryOutputSet, foreign.getOutputSet()));
155+
FuncDeps funcDepsForJoin = child.getLogicalProperties().getTrait()
156+
.getAllValidFuncDeps(Sets.union(primaryOutputSet, foreign.getOutputSet()));
167157
for (Slot slot : primarySlots) {
168158
Set<Set<Slot>> replacedSlotSets = funcDepsForJoin.findBijectionSlots(ImmutableSet.of(slot));
169159
for (Set<Slot> replacedSlots : replacedSlotSets) {
@@ -176,6 +166,8 @@ private LogicalAggregate<?> eliminatePrimaryOutput(LogicalAggregate<?> agg, Plan
176166
}
177167

178168
// Thirdly, construct new Agg below join.
169+
// For the pk-fk join, the foreign table side will not expand rows.
170+
// As a result, executing agg(group by fk) before join is same with executing agg(group by fk) after join.
179171
Set<Expression> newGroupBySlots = constructNewGroupBy(minGroupBySlotList, primaryOutputSet,
180172
primaryToForeignDeps);
181173
List<NamedExpression> newOutput = constructNewOutput(

0 commit comments

Comments
 (0)