@Override public PlanNode visitTopN(TopNNode node, RewriteContext<LimitContext> context) { LimitContext limit = context.get(); PlanNode rewrittenSource = context.rewrite(node.getSource()); if (rewrittenSource == node.getSource() && limit == null) { return node; } long count = node.getCount(); if (limit != null) { count = Math.min(count, limit.getCount()); } return new TopNNode(node.getId(), rewrittenSource, count, node.getOrderingScheme(), node.getStep()); }
@Override public Void visitTopN(TopNNode node, Integer indent) { Iterable<String> keys = Iterables.transform(node.getOrderingScheme().getOrderBy(), input -> input + " " + node.getOrderingScheme().getOrdering(input)); print(indent, "- TopN%s[%s by (%s)] => [%s]", node.getStep() == TopNNode.Step.PARTIAL ? "Partial" : "", node.getCount(), Joiner.on(", ").join(keys), formatOutputs(node.getOutputSymbols())); printPlanNodesStatsAndCost(indent + 2, node); printStats(indent + 2, node.getId()); return processChildren(node, indent + 1); }
@Override public PlanNode visitTopN(TopNNode node, List<PlanNode> newChildren) { return new TopNNode(node.getId(), Iterables.getOnlyElement(newChildren), node.getCount(), node.getOrderBy(), node.getOrderings(), node.isPartial()); }
@Override public Result apply(TopNNode single, Captures captures, Context context) { TopNNode partial = new TopNNode( context.getIdAllocator().getNextId(), single.getSource(), single.getCount(), single.getOrderingScheme(), PARTIAL); return Result.ofPlanNode(new TopNNode( context.getIdAllocator().getNextId(), partial, single.getCount(), single.getOrderingScheme(), FINAL)); } }
public TopNNode map(TopNNode node, PlanNode source, PlanNodeId newNodeId) { ImmutableList.Builder<Symbol> symbols = ImmutableList.builder(); ImmutableMap.Builder<Symbol, SortOrder> orderings = ImmutableMap.builder(); Set<Symbol> seenCanonicals = new HashSet<>(node.getOrderingScheme().getOrderBy().size()); for (Symbol symbol : node.getOrderingScheme().getOrderBy()) { Symbol canonical = map(symbol); if (seenCanonicals.add(canonical)) { seenCanonicals.add(canonical); symbols.add(canonical); orderings.put(canonical, node.getOrderingScheme().getOrdering(symbol)); } } return new TopNNode( newNodeId, source, node.getCount(), new OrderingScheme(symbols.build(), orderings.build()), node.getStep()); }
private PlanBuilder sort(PlanBuilder subPlan, Optional<OrderBy> orderBy, Optional<String> limit, List<Expression> orderByExpressions) { if (!orderBy.isPresent()) { return subPlan; } Iterator<SortItem> sortItems = orderBy.get().getSortItems().iterator(); ImmutableList.Builder<Symbol> orderBySymbols = ImmutableList.builder(); Map<Symbol, SortOrder> orderings = new HashMap<>(); for (Expression fieldOrExpression : orderByExpressions) { Symbol symbol = subPlan.translate(fieldOrExpression); SortItem sortItem = sortItems.next(); if (!orderings.containsKey(symbol)) { orderBySymbols.add(symbol); orderings.put(symbol, toSortOrder(sortItem)); } } PlanNode planNode; OrderingScheme orderingScheme = new OrderingScheme(orderBySymbols.build(), orderings); if (limit.isPresent() && !limit.get().equalsIgnoreCase("all")) { planNode = new TopNNode(idAllocator.getNextId(), subPlan.getRoot(), Long.parseLong(limit.get()), orderingScheme, TopNNode.Step.SINGLE); } else { planNode = new SortNode(idAllocator.getNextId(), subPlan.getRoot(), orderingScheme); } return subPlan.withNewRoot(planNode); }
@Override public PhysicalOperation visitTopN(TopNNode node, LocalExecutionPlanContext context) { PhysicalOperation source = node.getSource().accept(this, context); List<Symbol> orderBySymbols = node.getOrderingScheme().getOrderBy(); List<Integer> sortChannels = new ArrayList<>(); List<SortOrder> sortOrders = new ArrayList<>(); for (Symbol symbol : orderBySymbols) { sortChannels.add(source.getLayout().get(symbol)); sortOrders.add(node.getOrderingScheme().getOrdering(symbol)); } OperatorFactory operator = new TopNOperatorFactory( context.getNextOperatorId(), node.getId(), source.getTypes(), (int) node.getCount(), sortChannels, sortOrders); return new PhysicalOperation(operator, source.getLayout(), context, source); }
@Override public PlanWithProperties visitTopN(TopNNode node, Context context) { PlanWithProperties child = planChild(node, context.withPreferredProperties(PreferredProperties.any())); if (!child.getProperties().isSingleNode()) { child = withDerivedProperties( new TopNNode(idAllocator.getNextId(), child.getNode(), node.getCount(), node.getOrderBy(), node.getOrderings(), true), child.getProperties()); child = withDerivedProperties( gatheringExchange(idAllocator.getNextId(), child.getNode()), child.getProperties()); } return rebaseAndDeriveProperties(node, child); }
@Override public Void visitTopN(final TopNNode node, Void context) { Iterable<String> keys = Iterables.transform(node.getOrderingScheme().getOrderBy(), input -> input + " " + node.getOrderingScheme().getOrdering(input)); printNode(node, format("TopN[%s]", node.getCount()), Joiner.on(", ").join(keys), NODE_COLORS.get(NodeType.TOPN)); return node.getSource().accept(this, context); }
@Override public Void visitTopN(TopNNode node, Set<Symbol> boundSymbols) { PlanNode source = node.getSource(); source.accept(this, boundSymbols); // visit child Set<Symbol> inputs = createInputs(source, boundSymbols); checkDependencies(inputs, node.getOutputSymbols(), "Invalid node. Output symbols (%s) not in source plan output (%s)", node.getOutputSymbols(), node.getSource().getOutputSymbols()); checkDependencies( inputs, node.getOrderingScheme().getOrderBy(), "Invalid node. Order by dependencies (%s) not in source plan output (%s)", node.getOrderingScheme().getOrderBy(), node.getSource().getOutputSymbols()); return null; }
@Override public Void visitTopN(TopNNode node, Integer indent) { Iterable<String> keys = Iterables.transform(node.getOrderBy(), input -> input + " " + node.getOrderings().get(input)); print(indent, "- TopN[%s by (%s)] => [%s]", node.getCount(), Joiner.on(", ").join(keys), formatOutputs(node.getOutputSymbols())); return processChildren(node, indent + 1); }
@Override public Void visitTopN(final TopNNode node, Void context) { Iterable<String> keys = Iterables.transform(node.getOrderBy(), input -> input + " " + node.getOrderings().get(input)); printNode(node, format("TopN[%s]", node.getCount()), Joiner.on(", ").join(keys), NODE_COLORS.get(NodeType.TOPN)); return node.getSource().accept(this, context); }
@Override public MatchResult detailMatches(PlanNode node, StatsProvider stats, Session session, Metadata metadata, SymbolAliases symbolAliases) { checkState(shapeMatches(node), "Plan testing framework error: shapeMatches returned false in detailMatches in %s", this.getClass().getName()); TopNNode topNNode = (TopNNode) node; if (topNNode.getCount() != count) { return NO_MATCH; } if (!orderingSchemeMatches(orderBy, topNNode.getOrderingScheme(), symbolAliases)) { return NO_MATCH; } return match(); }
@Override public Void visitTopN(TopNNode node, Void context) { PlanNode source = node.getSource(); source.accept(this, context); // visit child verifyUniqueId(node); Set<Symbol> inputs = ImmutableSet.copyOf(source.getOutputSymbols()); checkDependencies(inputs, node.getOutputSymbols(), "Invalid node. Output symbols (%s) not in source plan output (%s)", node.getOutputSymbols(), node.getSource().getOutputSymbols()); checkDependencies(inputs, node.getOrderBy(), "Invalid node. Order by dependencies (%s) not in source plan output (%s)", node.getOrderBy(), node.getSource().getOutputSymbols()); return null; }
@Override public Map<PlanNodeId, SplitSource> visitTopN(TopNNode node, Void context) { return node.getSource().accept(this, context); }
@Override public StreamProperties visitTopN(TopNNode node, List<StreamProperties> inputProperties) { // Partial TopN doesn't guarantee that stream is ordered if (node.getStep().equals(TopNNode.Step.PARTIAL)) { return Iterables.getOnlyElement(inputProperties); } return StreamProperties.ordered(); }
@Override public Boolean visitTopN(TopNNode node, Void context) { return node.getCount() <= 1; } }
@Override public ActualProperties visitTopN(TopNNode node, List<ActualProperties> inputProperties) { ActualProperties properties = Iterables.getOnlyElement(inputProperties); List<SortingProperty<Symbol>> localProperties = node.getOrderingScheme().getOrderBy().stream() .map(column -> new SortingProperty<>(column, node.getOrderingScheme().getOrdering(column))) .collect(toImmutableList()); return ActualProperties.builderFrom(properties) .local(localProperties) .build(); }