Skip to content

Commit f4f5719

Browse files
committed
support count pushdown. tpcds 14/ tpch13
ds14 增加了agg push,执行时间 4.7 -> 4.8 h13 增加了 agg push,应该让p6 恢复到 p4 的成绩,提高一些 当任一 group key的ndv 接近 行数(0.9 倍)时,不下推agg DORIS-24367 case-when 不能下推join 补null的一侧 pick unnest-subquery-cte ut-tmp adjust rt update-shape fix eager_agg.groovy, runtime_filter_mode=OFF; fmt 14/67 因为rebase后增加了 repeat 拆分, 形状变化 支持 min(if), max(if), 增加了context.isValid检查,避免无效下推 doris-24240: rewriteRoot 检查nullable失败则不做eagerAgg column pruning 不产生不合法 的setOp 24207-2: orExpansion union 字段没对齐 DORIS-24239 context.groupKeys 不能为空 DORIS-24206: fix EliminateGroupByKeyByUniform bug:没有替换alias的exprId DORIS-24205 1. union 的孩子不能部分改写 2. agg 输入字段和 group key 有交集,则不下推 LogicalProject 构造projectMap时不能有unbound DORIS-23842 没有aggFunc时 下推包含所有group key 的分支,而不是大分支. ds37/38/82/87 受到影响。select distinct A from T1 join T2 on ... group by A` aliasMap 使用HashMap,不用IdentityMap DORIS-24149 DORIS-24151 doris-24150 rt case 1. exprId 的等值判断, 2.update rt. DORIS-24150 update shape remove unused code 1. sum-if 不考虑穿过bigJoin, 2. 支持union q5 两个sum(0)错误去重了 sum-if 基本款 (还没有支持union), 43 有提升 simple sum-if no union 检查context的字段 是project的输出.拒绝 sum(A) 下推 proj(x, x+y as A) 且x 不是group key derive deep false throw exception for eager agg when FeDebug 1. remove finalGroupKeys, 2. project 下推后改写projects push agg on join group key only slotreference do not support avg/count mode=1 时 即使没有经过big join 也要 强制 下推 shape with/without pkfk based on tpc_preview
1 parent 4d616aa commit f4f5719

File tree

283 files changed

+25378
-12624
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

283 files changed

+25378
-12624
lines changed

fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/executor/Rewriter.java

Lines changed: 128 additions & 124 deletions
Large diffs are not rendered by default.

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

Lines changed: 6 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717

1818
package org.apache.doris.nereids.rules.rewrite;
1919

20-
import org.apache.doris.common.util.DebugUtil;
21-
import org.apache.doris.nereids.exceptions.AnalysisException;
2220
import org.apache.doris.nereids.jobs.JobContext;
2321
import org.apache.doris.nereids.properties.OrderKey;
2422
import org.apache.doris.nereids.trees.expressions.Alias;
@@ -52,15 +50,14 @@
5250
import org.apache.doris.nereids.trees.plans.visitor.DefaultPlanRewriter;
5351
import org.apache.doris.nereids.util.ExpressionUtils;
5452
import org.apache.doris.qe.ConnectContext;
53+
import org.apache.doris.qe.SessionVariable;
5554

5655
import com.google.common.collect.ImmutableList;
5756
import com.google.common.collect.ImmutableSet;
5857
import com.google.common.collect.LinkedHashMultimap;
5958
import com.google.common.collect.Lists;
6059
import com.google.common.collect.Maps;
6160
import com.google.common.collect.Multimap;
62-
import org.apache.logging.log4j.LogManager;
63-
import org.apache.logging.log4j.Logger;
6461

6562
import java.util.LinkedHashMap;
6663
import java.util.List;
@@ -74,25 +71,10 @@
7471
* So, we need add a rule to adjust all expression's nullable attribute after rewrite.
7572
*/
7673
public class AdjustNullable extends DefaultPlanRewriter<Map<ExprId, Slot>> implements CustomRewriter {
77-
78-
private static final Logger LOG = LogManager.getLogger(AdjustNullable.class);
79-
8074
private final boolean isAnalyzedPhase;
8175

82-
/**
83-
* When check is true, if we find a slot that is non-nullable in the plan,
84-
* but we infer it should be nullable from the plan's subtree, and fe_debug is true,
85-
* then throw an exception.
86-
*/
87-
private final boolean check;
88-
89-
public AdjustNullable(boolean isAnalyzedPhase, boolean check) {
90-
this.isAnalyzedPhase = isAnalyzedPhase;
91-
this.check = check;
92-
}
93-
9476
public AdjustNullable(boolean isAnalyzedPhase) {
95-
this(isAnalyzedPhase, !isAnalyzedPhase);
77+
this.isAnalyzedPhase = isAnalyzedPhase;
9678
}
9779

9880
@Override
@@ -460,7 +442,7 @@ private <T extends Expression> Optional<T> updateExpression(Optional<T> input,
460442
private <T extends Expression> Optional<T> updateExpression(T input,
461443
Map<ExprId, Slot> replaceMap, boolean debugCheck) {
462444
AtomicBoolean changed = new AtomicBoolean(false);
463-
Expression replaced = doUpdateExpression(changed, input, replaceMap, check && debugCheck);
445+
Expression replaced = doUpdateExpression(changed, input, replaceMap, !isAnalyzedPhase && debugCheck);
464446
return changed.get() ? Optional.of((T) replaced) : Optional.empty();
465447
}
466448

@@ -497,14 +479,9 @@ private static Expression doUpdateExpression(AtomicBoolean changed, Expression i
497479
// repeat may check fail.
498480
if (!slotReference.nullable() && newSlotReference.nullable()
499481
&& check && ConnectContext.get() != null) {
500-
if (ConnectContext.get().getSessionVariable().feDebug) {
501-
throw new AnalysisException("AdjustNullable convert slot " + slotReference
502-
+ " from not-nullable to nullable. You can disable check by set fe_debug = false.");
503-
} else {
504-
LOG.warn("adjust nullable convert slot '" + slotReference
505-
+ "' from not-nullable to nullable for query "
506-
+ DebugUtil.printId(ConnectContext.get().queryId()));
507-
}
482+
SessionVariable.throwAnalysisExceptionWhenFeDebug("AdjustNullable convert slot "
483+
+ slotReference
484+
+ " from not-nullable to nullable. You can disable check by set fe_debug = false.");
508485
}
509486
return newSlotReference;
510487
} else {

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

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@
5959
import org.apache.doris.qe.ConnectContext;
6060

6161
import com.google.common.collect.ImmutableList;
62-
import com.google.common.collect.ImmutableList.Builder;
6362
import com.google.common.collect.Lists;
6463
import com.google.common.collect.Sets;
6564
import org.roaringbitmap.RoaringBitmap;
@@ -69,7 +68,6 @@
6968
import java.util.Optional;
7069
import java.util.Set;
7170
import java.util.function.Function;
72-
import java.util.stream.IntStream;
7371

7472
/**
7573
* ColumnPruning.
@@ -221,28 +219,21 @@ public Plan visitLogicalUnion(LogicalUnion union, PruneContext context) {
221219
}
222220
LogicalUnion prunedOutputUnion = pruneUnionOutput(union, context);
223221
// start prune children of union
224-
List<Slot> originOutput = union.getOutput();
225-
Set<Slot> prunedOutput = prunedOutputUnion.getOutputSet();
226-
List<Integer> prunedOutputIndexes = IntStream.range(0, originOutput.size())
227-
.filter(index -> prunedOutput.contains(originOutput.get(index)))
228-
.boxed()
229-
.collect(ImmutableList.toImmutableList());
230-
231222
ImmutableList.Builder<Plan> prunedChildren = ImmutableList.builder();
232223
ImmutableList.Builder<List<SlotReference>> prunedChildrenOutputs = ImmutableList.builder();
233224
for (int i = 0; i < prunedOutputUnion.arity(); i++) {
234225
List<SlotReference> regularChildOutputs = prunedOutputUnion.getRegularChildOutput(i);
235226

236227
RoaringBitmap prunedChildOutputExprIds = new RoaringBitmap();
237-
Builder<SlotReference> prunedChildOutputBuilder
238-
= ImmutableList.builderWithExpectedSize(regularChildOutputs.size());
239-
for (Integer index : prunedOutputIndexes) {
240-
SlotReference slot = regularChildOutputs.get(index);
241-
prunedChildOutputBuilder.add(slot);
242-
prunedChildOutputExprIds.add(slot.getExprId().asInt());
243-
}
244-
245-
List<SlotReference> prunedChildOutput = prunedChildOutputBuilder.build();
228+
//Builder<SlotReference> prunedChildOutputBuilder
229+
// = ImmutableList.builderWithExpectedSize(regularChildOutputs.size());
230+
//for (Integer index : prunedOutputIndexes) {
231+
// SlotReference slot = regularChildOutputs.get(index);
232+
// prunedChildOutputBuilder.add(slot);
233+
// prunedChildOutputExprIds.add(slot.getExprId().asInt());
234+
//}
235+
regularChildOutputs.forEach(col -> prunedChildOutputExprIds.add(col.getExprId().asInt()));
236+
List<SlotReference> prunedChildOutput = regularChildOutputs; //prunedChildOutputBuilder.build();
246237
Plan prunedChild = doPruneChild(
247238
prunedOutputUnion, prunedOutputUnion.child(i), prunedChildOutputExprIds,
248239
prunedChildOutput, true
@@ -420,15 +411,15 @@ private LogicalUnion pruneUnionOutput(LogicalUnion union, PruneContext context)
420411
extractColumnIndex.add(i);
421412
}
422413
}
423-
424414
ImmutableList.Builder<List<NamedExpression>> prunedConstantExprsList
425415
= ImmutableList.builderWithExpectedSize(constantExprsList.size());
416+
List<List<SlotReference>> prunedRegularChildrenOutputs =
417+
Lists.newArrayListWithCapacity(regularChildrenOutputs.size());
426418
if (prunedOutputs.isEmpty()) {
427419
// process prune all columns
428420
NamedExpression originSlot = originOutput.get(0);
429421
prunedOutputs = ImmutableList.of(new SlotReference(originSlot.getExprId(), originSlot.getName(),
430422
TinyIntType.INSTANCE, false, originSlot.getQualifier()));
431-
regularChildrenOutputs = Lists.newArrayListWithCapacity(regularChildrenOutputs.size());
432423
children = Lists.newArrayListWithCapacity(children.size());
433424
for (int i = 0; i < union.getArity(); i++) {
434425
Plan child = union.child(i);
@@ -442,28 +433,36 @@ private LogicalUnion pruneUnionOutput(LogicalUnion union, PruneContext context)
442433
} else {
443434
project = new LogicalProject<>(newProjectOutput, child);
444435
}
445-
regularChildrenOutputs.add((List) project.getOutput());
436+
prunedRegularChildrenOutputs.add((List) project.getOutput());
446437
children.add(project);
447438
}
448439
for (int i = 0; i < constantExprsList.size(); i++) {
449440
prunedConstantExprsList.add(ImmutableList.of(new Alias(new TinyIntLiteral((byte) 1))));
450441
}
451442
} else {
452-
int len = extractColumnIndex.size();
443+
int prunedOutputSize = extractColumnIndex.size();
453444
for (List<NamedExpression> row : constantExprsList) {
454-
ImmutableList.Builder<NamedExpression> newRow = ImmutableList.builderWithExpectedSize(len);
445+
ImmutableList.Builder<NamedExpression> newRow = ImmutableList.builderWithExpectedSize(prunedOutputSize);
455446
for (int idx : extractColumnIndex) {
456447
newRow.add(row.get(idx));
457448
}
458449
prunedConstantExprsList.add(newRow.build());
459450
}
451+
452+
for (int childIdx = 0; childIdx < union.getRegularChildrenOutputs().size(); childIdx++) {
453+
List<SlotReference> regular = Lists.newArrayListWithExpectedSize(prunedOutputSize);
454+
for (int colIdx : extractColumnIndex) {
455+
regular.add(regularChildrenOutputs.get(childIdx).get(colIdx));
456+
}
457+
prunedRegularChildrenOutputs.add(regular);
458+
}
460459
}
461460

462461
if (prunedOutputs.equals(originOutput) && !context.requiredSlotsIds.isEmpty()) {
463462
return union;
464463
} else {
465464
return union.withNewOutputsChildrenAndConstExprsList(prunedOutputs, children,
466-
regularChildrenOutputs, prunedConstantExprsList.build());
465+
prunedRegularChildrenOutputs, prunedConstantExprsList.build());
467466
}
468467
}
469468

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

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,10 +176,13 @@ public Plan visitLogicalJoin(LogicalJoin<? extends Plan, ? extends Plan> join, O
176176
}
177177
//4. union all joins and put producers to context
178178
List<List<SlotReference>> childrenOutputs = joins.stream()
179-
.map(j -> j.getOutput().stream()
179+
.map(j -> j.getOutput().stream() //.map(j -> j.getOutput().stream().distinct()
180180
.map(SlotReference.class::cast)
181181
.collect(ImmutableList.toImmutableList()))
182182
.collect(ImmutableList.toImmutableList());
183+
//LogicalUnion union = new LogicalUnion(Qualifier.ALL,
184+
// new ArrayList<>(join.getOutput().stream().distinct().collect(Collectors.toList())),
185+
// childrenOutputs, ImmutableList.of(), false, joins);
183186
LogicalUnion union = new LogicalUnion(Qualifier.ALL, new ArrayList<>(join.getOutput()),
184187
childrenOutputs, ImmutableList.of(), false, joins);
185188
ctx.cteProducerList.add(leftProducer);
@@ -319,8 +322,26 @@ private List<Plan> expandInnerJoin(CascadesContext ctx, Pair<List<Expression>,
319322

320323
LogicalCTEConsumer left = new LogicalCTEConsumer(ctx.getStatementContext().getNextRelationId(),
321324
leftProducer.getCteId(), "", leftProducer);
325+
List<NamedExpression> leftOutput = new ArrayList<>();
326+
for (Slot producerOutputSlot : leftProducer.getOutput()) {
327+
for (Slot consumerSlot : left.getProducerToConsumerOutputMap().get(producerOutputSlot)) {
328+
if (!leftOutput.contains(consumerSlot)) {
329+
leftOutput.add(consumerSlot);
330+
break;
331+
}
332+
}
333+
}
322334
LogicalCTEConsumer right = new LogicalCTEConsumer(ctx.getStatementContext().getNextRelationId(),
323335
rightProducer.getCteId(), "", rightProducer);
336+
List<NamedExpression> rightOutput = new ArrayList<>();
337+
for (Slot producerOutputSlot : rightProducer.getOutput()) {
338+
for (Slot consumerSlot : right.getProducerToConsumerOutputMap().get(producerOutputSlot)) {
339+
if (!rightOutput.contains(consumerSlot)) {
340+
rightOutput.add(consumerSlot);
341+
break;
342+
}
343+
}
344+
}
324345
ctx.putCTEIdToConsumer(left);
325346
ctx.putCTEIdToConsumer(right);
326347

@@ -335,7 +356,10 @@ private List<Plan> expandInnerJoin(CascadesContext ctx, Pair<List<Expression>,
335356

336357
LogicalJoin<? extends Plan, ? extends Plan> newJoin = new LogicalJoin<>(
337358
JoinType.INNER_JOIN, hashCond, otherCond, join.getDistributeHint(),
338-
join.getMarkJoinSlotReference(), left, right, null);
359+
join.getMarkJoinSlotReference(),
360+
new LogicalProject<>(leftOutput, left),
361+
new LogicalProject<>(rightOutput, right),
362+
null);
339363
if (newJoin.getHashJoinConjuncts().stream()
340364
.anyMatch(equalTo -> equalTo.children().stream().anyMatch(e -> !(e instanceof Slot)))) {
341365
Plan plan = PushDownExpressionsInHashCondition.pushDownHashExpression(newJoin);

0 commit comments

Comments
 (0)