public Collection<Edge> getEdges(PlanNode node) { return ImmutableList.copyOf(edges.get(node.getId())); }
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)); } }
public JoinGraph( List<PlanNode> nodes, Multimap<PlanNodeId, Edge> edges, PlanNodeId rootId, List<Expression> filters, Optional<Map<Symbol, Expression>> assignments) { this.nodes = nodes; this.edges = edges; this.rootId = rootId; this.filters = filters; this.assignments = assignments; }
public StatsAndCosts getForSubplan(PlanNode root) { Iterable<PlanNode> planIterator = Traverser.forTree(PlanNode::getSources) .depthFirstPreOrder(root); ImmutableMap.Builder<PlanNodeId, PlanNodeStatsEstimate> filteredStats = ImmutableMap.builder(); ImmutableMap.Builder<PlanNodeId, PlanNodeCostEstimate> filteredCosts = ImmutableMap.builder(); for (PlanNode node : planIterator) { if (stats.containsKey(node.getId())) { filteredStats.put(node.getId(), stats.get(node.getId())); } if (costs.containsKey(node.getId())) { filteredCosts.put(node.getId(), costs.get(node.getId())); } } return new StatsAndCosts(filteredStats.build(), filteredCosts.build()); }
@Override public void validate(PlanNode planNode, Session session, Metadata metadata, SqlParser sqlParser, TypeProvider types, WarningCollector warningCollector) { Map<PlanNodeId, PlanNode> planNodeIds = new HashMap<>(); searchFrom(planNode) .findAll() .forEach(node -> planNodeIds.merge(node.getId(), node, this::reportDuplicateId)); }
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)); } }
public static StatsAndCosts create(PlanNode root, StatsProvider statsProvider, CostProvider costProvider) { Iterable<PlanNode> planIterator = Traverser.forTree(PlanNode::getSources) .depthFirstPreOrder(root); ImmutableMap.Builder<PlanNodeId, PlanNodeStatsEstimate> stats = ImmutableMap.builder(); ImmutableMap.Builder<PlanNodeId, PlanNodeCostEstimate> costs = ImmutableMap.builder(); for (PlanNode node : planIterator) { stats.put(node.getId(), statsProvider.getStats(node)); costs.put(node.getId(), costProvider.getCumulativeCost(node)); } return new StatsAndCosts(stats.build(), costs.build()); } }
private boolean isPlanNodeStatsAndCostsUnknown(PlanNode node) { PlanNodeStatsEstimate stats = estimatedStatsAndCosts.getStats().getOrDefault(node.getId(), PlanNodeStatsEstimate.unknown()); PlanNodeCostEstimate cost = estimatedStatsAndCosts.getCosts().getOrDefault(node.getId(), PlanNodeCostEstimate.unknown()); return stats.isOutputRowCountUnknown() || cost.equals(PlanNodeCostEstimate.unknown()); }
private StatsCalculator statsCalculator(Map<String, PlanNodeStatsEstimate> stats) { return (node, sourceStats, lookup, session, types) -> requireNonNull(stats.get(node.getId().toString()), "no stats for node"); }
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 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)); } }
private CostAssertionBuilder assertCost( CostCalculator costCalculator, PlanNode node, Map<String, PlanNodeCostEstimate> costs, Map<String, PlanNodeStatsEstimate> stats, Map<String, Type> types) { PlanNodeCostEstimate cumulativeCost = calculateCumulativeCost( costCalculator, node, planNode -> costs.get(planNode.getId().toString()), planNode -> stats.get(planNode.getId().toString()), types); return new CostAssertionBuilder(cumulativeCost); }
public static String graphvizLogicalPlan(PlanNode plan, TypeProvider types) { PlanFragment fragment = new PlanFragment( new PlanFragmentId("graphviz_plan"), plan, types.allTypes(), SINGLE_DISTRIBUTION, ImmutableList.of(plan.getId()), new PartitioningScheme(Partitioning.create(SINGLE_DISTRIBUTION, ImmutableList.of()), plan.getOutputSymbols()), StageExecutionDescriptor.ungroupedExecution(), StatsAndCosts.empty()); return GraphvizPrinter.printLogical(ImmutableList.of(fragment)); }
private static List<OptionalDouble> getEstimatedValuesInternal(List<Metric> metrics, String query, QueryRunner runner, Session session) // TODO inline back this method { Plan queryPlan = runner.createPlan(session, query, WarningCollector.NOOP); OutputNode outputNode = (OutputNode) queryPlan.getRoot(); PlanNodeStatsEstimate outputNodeStats = queryPlan.getStatsAndCosts().getStats().getOrDefault(queryPlan.getRoot().getId(), PlanNodeStatsEstimate.unknown()); StatsContext statsContext = buildStatsContext(queryPlan, outputNode); return getEstimatedValues(metrics, outputNodeStats, statsContext); }
public StatsCalculatorAssertion withSourceStats(PlanNodeId planNodeId, PlanNodeStatsEstimate sourceStats) { PlanNode sourceNode = PlanNodeSearcher.searchFrom(planNode).where(node -> node.getId().equals(planNodeId)).findOnlyElement(); sourcesStats.put(sourceNode, sourceStats); return this; }
private PlanNodeCostEstimate calculateCumulativeCostFragmentedPlan(PlanNode node, StatsCalculator statsCalculator, Map<String, Type> types) { TypeProvider typeProvider = TypeProvider.copyOf(types.entrySet().stream() .collect(ImmutableMap.toImmutableMap(entry -> new Symbol(entry.getKey()), Map.Entry::getValue))); StatsProvider statsProvider = new CachingStatsProvider(statsCalculator, session, typeProvider); CostProvider costProvider = new CachingCostProvider(costCalculatorUsingExchanges, statsProvider, Optional.empty(), session, typeProvider); SubPlan subPlan = fragment(new Plan(node, typeProvider, StatsAndCosts.create(node, statsProvider, costProvider))); return subPlan.getFragment().getStatsAndCosts().getCosts().getOrDefault(node.getId(), PlanNodeCostEstimate.unknown()); }
private CostAssertionBuilder assertCostFragmentedPlan( PlanNode node, Map<String, PlanNodeCostEstimate> costs, Map<String, PlanNodeStatsEstimate> stats, Map<String, Type> types) { TypeProvider typeProvider = TypeProvider.copyOf(types.entrySet().stream() .collect(ImmutableMap.toImmutableMap(entry -> new Symbol(entry.getKey()), Map.Entry::getValue))); StatsProvider statsProvider = new CachingStatsProvider(statsCalculator(stats), session, typeProvider); CostProvider costProvider = new TestingCostProvider(costs, costCalculatorUsingExchanges, statsProvider, session, typeProvider); SubPlan subPlan = fragment(new Plan(node, typeProvider, StatsAndCosts.create(node, statsProvider, costProvider))); return new CostAssertionBuilder(subPlan.getFragment().getStatsAndCosts().getCosts().getOrDefault(node.getId(), PlanNodeCostEstimate.unknown())); }
@Test public void testReplaceSubtree() { PlanNode plan = node(node(node())); Memo memo = new Memo(idAllocator, plan); assertEquals(memo.getGroupCount(), 3); // replace child of root node with subtree PlanNode transformed = node(node()); memo.replace(getChildGroup(memo, memo.getRootGroup()), transformed, "rule"); assertEquals(memo.getGroupCount(), 3); assertMatchesStructure(memo.extract(), node(plan.getId(), transformed)); }