@Override public PlanNode replaceChildren(List<PlanNode> newChildren) { checkArgument(newChildren.size() == 2, "expected newChildren to contain 2 nodes"); return new JoinNode(getId(), type, newChildren.get(0), newChildren.get(1), criteria, outputSymbols, filter, leftHashSymbol, rightHashSymbol, distributionType); }
public JoinNode withDistributionType(DistributionType distributionType) { return new JoinNode(getId(), type, left, right, criteria, outputSymbols, filter, leftHashSymbol, rightHashSymbol, Optional.of(distributionType)); }
private static JoinNode leftOuterJoin(PlanNodeIdAllocator idAllocator, AssignUniqueId probeSide, ProjectNode buildSide, Expression joinExpression) { return new JoinNode( idAllocator.getNextId(), JoinNode.Type.LEFT, probeSide, buildSide, ImmutableList.of(), ImmutableList.<Symbol>builder() .addAll(probeSide.getOutputSymbols()) .addAll(buildSide.getOutputSymbols()) .build(), Optional.of(joinExpression), Optional.empty(), Optional.empty(), Optional.empty()); }
@Override public Result apply(LateralJoinNode lateralJoinNode, Captures captures, Context context) { return Result.ofPlanNode(new JoinNode( context.getIdAllocator().getNextId(), JoinNode.Type.INNER, lateralJoinNode.getInput(), lateralJoinNode.getSubquery(), ImmutableList.of(), ImmutableList.<Symbol>builder() .addAll(lateralJoinNode.getInput().getOutputSymbols()) .addAll(lateralJoinNode.getSubquery().getOutputSymbols()) .build(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty())); } }
public JoinNode join( JoinNode.Type type, PlanNode left, PlanNode right, List<JoinNode.EquiJoinClause> criteria, List<Symbol> outputSymbols, Optional<Expression> filter, Optional<Symbol> leftHashSymbol, Optional<Symbol> rightHashSymbol, Optional<JoinNode.DistributionType> distributionType) { return new JoinNode(idAllocator.getNextId(), type, left, right, criteria, outputSymbols, filter, leftHashSymbol, rightHashSymbol, distributionType); }
.collect(toImmutableList()); return setJoinNodeProperties(new JoinNode( idAllocator.getNextId(), INNER,
new JoinNode( node.getId(), node.getType(),
@Override protected Optional<PlanNode> pushDownProjectOff(PlanNodeIdAllocator idAllocator, JoinNode joinNode, Set<Symbol> referencedOutputs) { Optional<PlanNode> newLeft = restrictOutputs(idAllocator, joinNode.getLeft(), referencedOutputs); Optional<PlanNode> newRight = restrictOutputs(idAllocator, joinNode.getRight(), referencedOutputs); if (!newLeft.isPresent() && !newRight.isPresent()) { return Optional.empty(); } ImmutableList.Builder<Symbol> outputSymbolBuilder = ImmutableList.builder(); outputSymbolBuilder.addAll(newLeft.orElse(joinNode.getLeft()).getOutputSymbols()); outputSymbolBuilder.addAll(newRight.orElse(joinNode.getRight()).getOutputSymbols()); return Optional.of(new JoinNode( idAllocator.getNextId(), joinNode.getType(), newLeft.orElse(joinNode.getLeft()), newRight.orElse(joinNode.getRight()), joinNode.getCriteria(), outputSymbolBuilder.build(), joinNode.getFilter(), joinNode.getLeftHashSymbol(), joinNode.getRightHashSymbol(), joinNode.getDistributionType())); } }
return new JoinNode(node.getId(), node.getType(), left, right, node.getCriteria(), outputSymbols, node.getFilter(), node.getLeftHashSymbol(), node.getRightHashSymbol(), node.getDistributionType());
private PlanNode pushPartialToJoin( AggregationNode aggregation, JoinNode child, PlanNode leftChild, PlanNode rightChild, Context context) { JoinNode joinNode = new JoinNode( child.getId(), child.getType(), leftChild, rightChild, child.getCriteria(), ImmutableList.<Symbol>builder() .addAll(leftChild.getOutputSymbols()) .addAll(rightChild.getOutputSymbols()) .build(), child.getFilter(), child.getLeftHashSymbol(), child.getRightHashSymbol(), child.getDistributionType()); return restrictOutputs(context.getIdAllocator(), joinNode, ImmutableSet.copyOf(aggregation.getOutputSymbols())).orElse(joinNode); } }
public JoinNode flipChildren() { return new JoinNode( getId(), flipType(type), right, left, flipJoinCriteria(criteria), flipOutputSymbols(getOutputSymbols(), left, right), filter, rightHashSymbol, leftHashSymbol, distributionType); }
@Override public Result apply(LateralJoinNode lateralJoinNode, Captures captures, Context context) { PlanNode subquery = lateralJoinNode.getSubquery(); PlanNodeDecorrelator planNodeDecorrelator = new PlanNodeDecorrelator(context.getIdAllocator(), context.getLookup()); Optional<DecorrelatedNode> decorrelatedNodeOptional = planNodeDecorrelator.decorrelateFilters(subquery, lateralJoinNode.getCorrelation()); return decorrelatedNodeOptional.map(decorrelatedNode -> Result.ofPlanNode(new JoinNode( context.getIdAllocator().getNextId(), lateralJoinNode.getType().toJoinNodeType(), lateralJoinNode.getInput(), decorrelatedNode.getNode(), ImmutableList.of(), lateralJoinNode.getOutputSymbols(), decorrelatedNode.getCorrelatedPredicates(), Optional.empty(), Optional.empty(), Optional.empty()))).orElseGet(Result::empty); } }
private JoinNode joinNode(PlanNode left, PlanNode right, String... symbols) { checkArgument(symbols.length % 2 == 0); ImmutableList.Builder<JoinNode.EquiJoinClause> criteria = ImmutableList.builder(); for (int i = 0; i < symbols.length; i += 2) { criteria.add(new JoinNode.EquiJoinClause(new Symbol(symbols[i]), new Symbol(symbols[i + 1]))); } return new JoinNode( idAllocator.getNextId(), JoinNode.Type.INNER, left, right, criteria.build(), ImmutableList.<Symbol>builder() .addAll(left.getOutputSymbols()) .addAll(right.getOutputSymbols()) .build(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty()); }
private PlanWithProperties buildJoin(JoinNode node, PlanWithProperties newLeft, PlanWithProperties newRight, JoinNode.DistributionType newDistributionType) { JoinNode result = new JoinNode(node.getId(), node.getType(), newLeft.getNode(), newRight.getNode(), node.getCriteria(), node.getOutputSymbols(), node.getFilter(), node.getLeftHashSymbol(), node.getRightHashSymbol(), Optional.of(newDistributionType)); return new PlanWithProperties(result, deriveProperties(result, ImmutableList.of(newLeft.getProperties(), newRight.getProperties()))); }
/** * EquiJoinClause is created from symbols in form of: * symbol[0] = symbol[1] AND symbol[2] = symbol[3] AND ... */ private JoinNode join(String planNodeId, PlanNode left, PlanNode right, JoinNode.DistributionType distributionType, String... symbols) { checkArgument(symbols.length % 2 == 0); ImmutableList.Builder<JoinNode.EquiJoinClause> criteria = ImmutableList.builder(); for (int i = 0; i < symbols.length; i += 2) { criteria.add(new JoinNode.EquiJoinClause(new Symbol(symbols[i]), new Symbol(symbols[i + 1]))); } return new JoinNode( new PlanNodeId(planNodeId), JoinNode.Type.INNER, left, right, criteria.build(), ImmutableList.<Symbol>builder() .addAll(left.getOutputSymbols()) .addAll(right.getOutputSymbols()) .build(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.of(distributionType)); }
@Override public PlanNode visitJoin(JoinNode node, RewriteContext<Void> context) { PlanNode left = context.rewrite(node.getLeft()); PlanNode right = context.rewrite(node.getRight()); List<JoinNode.EquiJoinClause> canonicalCriteria = canonicalizeJoinCriteria(node.getCriteria()); Optional<Expression> canonicalFilter = node.getFilter().map(this::canonicalize); Optional<Symbol> canonicalLeftHashSymbol = canonicalize(node.getLeftHashSymbol()); Optional<Symbol> canonicalRightHashSymbol = canonicalize(node.getRightHashSymbol()); if (node.getType().equals(INNER)) { canonicalCriteria.stream() .filter(clause -> types.get(clause.getLeft()).equals(types.get(clause.getRight()))) .filter(clause -> node.getOutputSymbols().contains(clause.getLeft())) .forEach(clause -> map(clause.getRight(), clause.getLeft())); } return new JoinNode(node.getId(), node.getType(), left, right, canonicalCriteria, canonicalizeAndDistinct(node.getOutputSymbols()), canonicalFilter, canonicalLeftHashSymbol, canonicalRightHashSymbol, node.getDistributionType()); }
@Override protected Optional<PlanNode> pushDownProjectOff(PlanNodeIdAllocator idAllocator, JoinNode joinNode, Set<Symbol> referencedOutputs) { return Optional.of( new JoinNode( joinNode.getId(), joinNode.getType(), joinNode.getLeft(), joinNode.getRight(), joinNode.getCriteria(), filteredCopy(joinNode.getOutputSymbols(), referencedOutputs::contains), joinNode.getFilter(), joinNode.getLeftHashSymbol(), joinNode.getRightHashSymbol(), joinNode.getDistributionType())); } }
@Override public Result apply(JoinNode joinNode, Captures captures, Context context) { Optional<Expression> filter = joinNode.getFilter().map(x -> rewriter.rewrite(x, context)); if (!joinNode.getFilter().equals(filter)) { return Result.ofPlanNode(new JoinNode( joinNode.getId(), joinNode.getType(), joinNode.getLeft(), joinNode.getRight(), joinNode.getCriteria(), joinNode.getOutputSymbols(), filter, joinNode.getLeftHashSymbol(), joinNode.getRightHashSymbol(), joinNode.getDistributionType())); } return Result.empty(); } }
PlanFragment testFragment = new PlanFragment( new PlanFragmentId("plan_id"), new JoinNode(new PlanNodeId("join_id"), INNER, tableScan,
private JoinNode tryNormalizeToOuterToInnerJoin(JoinNode node, Expression inheritedPredicate) { checkArgument(EnumSet.of(INNER, RIGHT, LEFT, FULL).contains(node.getType()), "Unsupported join type: %s", node.getType()); if (node.getType() == JoinNode.Type.INNER) { return node; } if (node.getType() == JoinNode.Type.FULL) { boolean canConvertToLeftJoin = canConvertOuterToInner(node.getLeft().getOutputSymbols(), inheritedPredicate); boolean canConvertToRightJoin = canConvertOuterToInner(node.getRight().getOutputSymbols(), inheritedPredicate); if (!canConvertToLeftJoin && !canConvertToRightJoin) { return node; } if (canConvertToLeftJoin && canConvertToRightJoin) { return new JoinNode(node.getId(), INNER, node.getLeft(), node.getRight(), node.getCriteria(), node.getOutputSymbols(), node.getFilter(), node.getLeftHashSymbol(), node.getRightHashSymbol(), node.getDistributionType()); } else { return new JoinNode(node.getId(), canConvertToLeftJoin ? LEFT : RIGHT, node.getLeft(), node.getRight(), node.getCriteria(), node.getOutputSymbols(), node.getFilter(), node.getLeftHashSymbol(), node.getRightHashSymbol(), node.getDistributionType()); } } if (node.getType() == JoinNode.Type.LEFT && !canConvertOuterToInner(node.getRight().getOutputSymbols(), inheritedPredicate) || node.getType() == JoinNode.Type.RIGHT && !canConvertOuterToInner(node.getLeft().getOutputSymbols(), inheritedPredicate)) { return node; } return new JoinNode(node.getId(), JoinNode.Type.INNER, node.getLeft(), node.getRight(), node.getCriteria(), node.getOutputSymbols(), node.getFilter(), node.getLeftHashSymbol(), node.getRightHashSymbol(), node.getDistributionType()); }