private PlanNode reportDuplicateId(PlanNode first, PlanNode second) { requireNonNull(first, "first is null"); requireNonNull(second, "second is null"); checkArgument(first.getId().equals(second.getId())); throw new IllegalStateException(format( "Generated plan contains nodes with duplicated id %s: %s and %s", first.getId(), first, second)); } }
@Override public Void visitGroupId(GroupIdNode node, Set<Symbol> boundSymbols) { PlanNode source = node.getSource(); source.accept(this, boundSymbols); // visit child checkDependencies(source.getOutputSymbols(), node.getInputSymbols(), "Invalid node. Grouping symbols (%s) not in source plan output (%s)", node.getInputSymbols(), source.getOutputSymbols()); return null; }
@Override protected Integer visitPlan(PlanNode node, Void context) { int count = 0; for (PlanNode source : node.getSources()) { count += source.accept(this, context); } return count; } }
/** * Transforms a plan like P->C->X to C->P->X */ public static PlanNode transpose(PlanNode parent, PlanNode child) { return child.replaceChildren(ImmutableList.of( parent.replaceChildren( child.getSources()))); }
@Override protected PlanNode visitPlan(PlanNode node, Void context) { List<PlanNode> children = node.getSources().stream() .map(child -> child.accept(this, context)) .collect(Collectors.toList()); return node.replaceChildren(children); }
@Override public List<Symbol> getOutputSymbols() { return source.getOutputSymbols(); }
private Map<PlanNodeId, SplitSource> processSources(List<PlanNode> sources, Void context) { ImmutableMap.Builder<PlanNodeId, SplitSource> result = ImmutableMap.builder(); for (PlanNode child : sources) { result.putAll(child.accept(this, context)); } return result.build(); }
private Set<Integer> getAllReferences(PlanNode node) { return node.getSources().stream() .map(GroupReference.class::cast) .map(GroupReference::getGroupId) .collect(Collectors.toSet()); }
private PlanNode insertChildrenAndRewrite(PlanNode node) { return node.replaceChildren( node.getSources().stream() .map(child -> new GroupReference( idAllocator.getNextId(), insertRecursive(child), child.getOutputSymbols())) .collect(Collectors.toList())); }
private static void findSources(PlanNode node, Set<PlanNodeId> nodeIds, ImmutableSet.Builder<PlanNode> nodes) { if (nodeIds.contains(node.getId())) { nodes.add(node); } for (PlanNode source : node.getSources()) { nodes.addAll(findSources(source, nodeIds)); } }
private String formatPlanNodeStatsAndCost(PlanNode node) { PlanNodeStatsEstimate stats = estimatedStatsAndCosts.getStats().getOrDefault(node.getId(), PlanNodeStatsEstimate.unknown()); PlanNodeCostEstimate cost = estimatedStatsAndCosts.getCosts().getOrDefault(node.getId(), PlanNodeCostEstimate.unknown()); return format("{rows: %s (%s), cpu: %s, memory: %s, network: %s}", formatAsLong(stats.getOutputRowCount()), formatEstimateAsDataSize(stats.getOutputSizeInBytes(node.getOutputSymbols(), types)), formatDouble(cost.getCpuCost()), formatDouble(cost.getMemoryCost()), formatDouble(cost.getNetworkCost())); } }
private PlanWithProperties planAndEnforceChildren(PlanNode node, StreamPreferredProperties requiredProperties, StreamPreferredProperties preferredProperties) { // plan and enforce each child, but strip any requirement not in terms of symbols produced from the child // Note: this assumes the child uses the same symbols as the parent List<PlanWithProperties> children = node.getSources().stream() .map(source -> planAndEnforce( source, requiredProperties.constrainTo(source.getOutputSymbols()), preferredProperties.constrainTo(source.getOutputSymbols()))) .collect(toImmutableList()); return rebaseAndDeriveProperties(node, children); }
private PlanWithProperties rebaseAndDeriveProperties(PlanNode node, List<PlanWithProperties> children) { PlanNode result = node.replaceChildren( children.stream() .map(PlanWithProperties::getNode) .collect(toList())); return new PlanWithProperties(result, deriveProperties(result, children.stream().map(PlanWithProperties::getProperties).collect(toList()))); }
@Override public List<Symbol> getOutputSymbols() { return source.getOutputSymbols(); }
public void processFragment(PlanFragmentId planFragmentId) { PlanFragment planFragment = fragments.get(planFragmentId); checkArgument(planFragment != null, "Fragment not found: %s", planFragmentId); planFragment.getRoot().accept(this, null); schedulerOrder.add(planFragmentId); }
public static Property<PlanNode, PlanNode> source() { return optionalProperty("source", node -> node.getSources().size() == 1 ? Optional.of(node.getSources().get(0)) : Optional.empty()); }
private static void assertMatchesStructure(PlanNode actual, PlanNode expected) { assertEquals(actual.getClass(), expected.getClass()); assertEquals(actual.getId(), expected.getId()); assertEquals(actual.getSources().size(), expected.getSources().size()); for (int i = 0; i < actual.getSources().size(); i++) { assertMatchesStructure(actual.getSources().get(i), expected.getSources().get(i)); } }
@Override public Result apply(PlanNode node, Captures captures, Context context) { return Result.ofPlanNode(node.replaceChildren(node.getSources())); } }
@Override public Void visitMarkDistinct(MarkDistinctNode node, Set<Symbol> boundSymbols) { PlanNode source = node.getSource(); source.accept(this, boundSymbols); // visit child checkDependencies(source.getOutputSymbols(), node.getDistinctSymbols(), "Invalid node. Mark distinct symbols (%s) not in source plan output (%s)", node.getDistinctSymbols(), source.getOutputSymbols()); return null; }
private Void processChildren(PlanNode node, int indent) { for (PlanNode child : node.getSources()) { child.accept(this, indent); } return null; }