|
28 | 28 | import java.util.List;
|
29 | 29 | import java.util.Objects;
|
30 | 30 | import java.util.Optional;
|
| 31 | +import java.util.stream.Collectors; |
31 | 32 | import java.util.stream.Stream;
|
32 | 33 |
|
33 | 34 | import static com.facebook.presto.sql.planner.SortExpressionExtractor.extractSortExpression;
|
| 35 | +import static com.facebook.presto.sql.planner.plan.JoinNode.Type.FULL; |
34 | 36 | import static com.facebook.presto.sql.planner.plan.JoinNode.Type.INNER;
|
| 37 | +import static com.facebook.presto.sql.planner.plan.JoinNode.Type.LEFT; |
| 38 | +import static com.facebook.presto.sql.planner.plan.JoinNode.Type.RIGHT; |
35 | 39 | import static com.google.common.base.Preconditions.checkArgument;
|
36 | 40 | import static com.google.common.collect.ImmutableList.toImmutableList;
|
37 | 41 | import static java.util.Objects.requireNonNull;
|
@@ -100,6 +104,58 @@ public JoinNode(@JsonProperty("id") PlanNodeId id,
|
100 | 104 | checkArgument(!(criteria.isEmpty() && rightHashSymbol.isPresent()), "Right hash symbol is only valid in an equijoin");
|
101 | 105 | }
|
102 | 106 |
|
| 107 | + public JoinNode flipChildren() |
| 108 | + { |
| 109 | + return new JoinNode( |
| 110 | + getId(), |
| 111 | + flipType(type), |
| 112 | + right, |
| 113 | + left, |
| 114 | + flipJoinCriteria(criteria), |
| 115 | + flipOutputSymbols(getOutputSymbols(), left, right), |
| 116 | + filter, |
| 117 | + rightHashSymbol, |
| 118 | + leftHashSymbol, |
| 119 | + distributionType); |
| 120 | + } |
| 121 | + |
| 122 | + private static Type flipType(Type type) |
| 123 | + { |
| 124 | + switch (type) { |
| 125 | + case INNER: |
| 126 | + return INNER; |
| 127 | + case FULL: |
| 128 | + return FULL; |
| 129 | + case LEFT: |
| 130 | + return RIGHT; |
| 131 | + case RIGHT: |
| 132 | + return LEFT; |
| 133 | + default: |
| 134 | + throw new IllegalStateException("No inverse defined for join type: " + type); |
| 135 | + } |
| 136 | + } |
| 137 | + |
| 138 | + private static List<EquiJoinClause> flipJoinCriteria(List<EquiJoinClause> joinCriteria) |
| 139 | + { |
| 140 | + return joinCriteria.stream() |
| 141 | + .map(EquiJoinClause::flip) |
| 142 | + .collect(toImmutableList()); |
| 143 | + } |
| 144 | + |
| 145 | + private static List<Symbol> flipOutputSymbols(List<Symbol> outputSymbols, PlanNode left, PlanNode right) |
| 146 | + { |
| 147 | + List<Symbol> leftSymbols = outputSymbols.stream() |
| 148 | + .filter(symbol -> left.getOutputSymbols().contains(symbol)) |
| 149 | + .collect(Collectors.toList()); |
| 150 | + List<Symbol> rightSymbols = outputSymbols.stream() |
| 151 | + .filter(symbol -> right.getOutputSymbols().contains(symbol)) |
| 152 | + .collect(Collectors.toList()); |
| 153 | + return ImmutableList.<Symbol>builder() |
| 154 | + .addAll(rightSymbols) |
| 155 | + .addAll(leftSymbols) |
| 156 | + .build(); |
| 157 | + } |
| 158 | + |
103 | 159 | public enum DistributionType
|
104 | 160 | {
|
105 | 161 | PARTITIONED,
|
@@ -230,6 +286,11 @@ public PlanNode replaceChildren(List<PlanNode> newChildren)
|
230 | 286 | return new JoinNode(getId(), type, newLeft, newRight, criteria, newOutputSymbols, filter, leftHashSymbol, rightHashSymbol, distributionType);
|
231 | 287 | }
|
232 | 288 |
|
| 289 | + public JoinNode withDistributionType(DistributionType distributionType) |
| 290 | + { |
| 291 | + return new JoinNode(getId(), type, left, right, criteria, outputSymbols, filter, leftHashSymbol, rightHashSymbol, Optional.of(distributionType)); |
| 292 | + } |
| 293 | + |
233 | 294 | public boolean isCrossJoin()
|
234 | 295 | {
|
235 | 296 | return criteria.isEmpty() && !filter.isPresent() && type == INNER;
|
@@ -264,6 +325,11 @@ public ComparisonExpression toExpression()
|
264 | 325 | return new ComparisonExpression(ComparisonExpressionType.EQUAL, left.toSymbolReference(), right.toSymbolReference());
|
265 | 326 | }
|
266 | 327 |
|
| 328 | + public EquiJoinClause flip() |
| 329 | + { |
| 330 | + return new EquiJoinClause(right, left); |
| 331 | + } |
| 332 | + |
267 | 333 | @Override
|
268 | 334 | public boolean equals(Object obj)
|
269 | 335 | {
|
|
0 commit comments