[fix](Nereids) reorder join generate plan is not stable (#31539)

This commit is contained in:
morrySnow
2024-02-29 11:10:03 +08:00
committed by yiguolei
parent 000b81f0c7
commit 17359d59a3
2 changed files with 91 additions and 9 deletions

View File

@ -88,7 +88,8 @@ public class ReorderJoin extends OneRewriteRuleFactory {
Map<Plan, JoinDistributeType> planToHintType = Maps.newHashMap();
Plan plan = joinToMultiJoin(filter, planToHintType);
Preconditions.checkState(plan instanceof MultiJoin);
Preconditions.checkState(plan instanceof MultiJoin, "join to multi join should return MultiJoin,"
+ " but return plan is " + plan.getType());
MultiJoin multiJoin = (MultiJoin) plan;
ctx.statementContext.addJoinFilters(multiJoin.getJoinFilter());
ctx.statementContext.setMaxNAryInnerJoin(multiJoin.children().size());
@ -331,14 +332,13 @@ public class ReorderJoin extends OneRewriteRuleFactory {
*/
private LogicalJoin<? extends Plan, ? extends Plan> findInnerJoin(Plan left, List<Plan> candidates,
Set<Expression> joinFilter, Set<Integer> usedPlansIndex, Map<Plan, JoinDistributeType> planToHintType) {
List<Expression> otherJoinConditions = Lists.newArrayList();
List<Expression> firstOtherJoinConditions = ExpressionUtils.EMPTY_CONDITION;
int firstCandidate = -1;
Set<ExprId> leftOutputExprIdSet = left.getOutputExprIdSet();
int candidateIndex = 0;
for (int i = 0; i < candidates.size(); i++) {
if (usedPlansIndex.contains(i)) {
continue;
}
candidateIndex = i;
Plan candidate = candidates.get(i);
Set<ExprId> rightOutputExprIdSet = candidate.getOutputExprIdSet();
@ -356,24 +356,29 @@ public class ReorderJoin extends OneRewriteRuleFactory {
Pair<List<Expression>, List<Expression>> pair = JoinUtils.extractExpressionForHashTable(
left.getOutput(), candidate.getOutput(), currentJoinFilter);
List<Expression> hashJoinConditions = pair.first;
otherJoinConditions = pair.second;
if (!hashJoinConditions.isEmpty()) {
usedPlansIndex.add(i);
return new LogicalJoin<>(JoinType.INNER_JOIN,
hashJoinConditions, otherJoinConditions,
hashJoinConditions, pair.second,
new DistributeHint(DistributeType.fromRightPlanHintType(
planToHintType.getOrDefault(candidate, JoinDistributeType.NONE))),
Optional.empty(),
left, candidate, null);
} else {
if (firstCandidate == -1) {
firstCandidate = i;
firstOtherJoinConditions = pair.second;
}
}
}
// All { left -> one in [candidates] } is CrossJoin
// Generate a CrossJoin
usedPlansIndex.add(candidateIndex);
Plan right = candidates.get(candidateIndex);
// NOTICE: we must traverse for head to tail to ensure result is stable.
usedPlansIndex.add(firstCandidate);
Plan right = candidates.get(firstCandidate);
return new LogicalJoin<>(JoinType.CROSS_JOIN,
ExpressionUtils.EMPTY_CONDITION,
otherJoinConditions,
firstOtherJoinConditions,
new DistributeHint(DistributeType.fromRightPlanHintType(
planToHintType.getOrDefault(right, JoinDistributeType.NONE))),
Optional.empty(),