@Override public PlanNode visitDistinctLimit(DistinctLimitNode node, RewriteContext<Set<Symbol>> context) { Set<Symbol> expectedInputs; if (node.getHashSymbol().isPresent()) { expectedInputs = ImmutableSet.copyOf(concat(node.getDistinctSymbols(), ImmutableList.of(node.getHashSymbol().get()))); } else { expectedInputs = ImmutableSet.copyOf(node.getDistinctSymbols()); } PlanNode source = context.rewrite(node.getSource(), expectedInputs); return new DistinctLimitNode(node.getId(), source, node.getLimit(), node.isPartial(), node.getDistinctSymbols(), node.getHashSymbol()); }
@Override public Void visitDistinctLimit(DistinctLimitNode node, Integer indent) { print(indent, "- DistinctLimit%s[%s]%s => [%s]", node.isPartial() ? "Partial" : "", node.getLimit(), formatHash(node.getHashSymbol()), formatOutputs(node.getOutputSymbols())); printPlanNodesStatsAndCost(indent + 2, node); printStats(indent + 2, node.getId()); return processChildren(node, indent + 1); }
@Override public PlanNode replaceChildren(List<PlanNode> newChildren) { return new DistinctLimitNode(getId(), Iterables.getOnlyElement(newChildren), limit, partial, distinctSymbols, hashSymbol); } }
@Override public PlanNode visitDistinctLimit(DistinctLimitNode node, List<PlanNode> newChildren) { return new DistinctLimitNode(node.getId(), Iterables.getOnlyElement(newChildren), node.getLimit(), node.getHashSymbol()); }
@Override public PhysicalOperation visitDistinctLimit(DistinctLimitNode node, LocalExecutionPlanContext context) { PhysicalOperation source = node.getSource().accept(this, context); Optional<Integer> hashChannel = node.getHashSymbol().map(channelGetter(source)); List<Integer> distinctChannels = getChannelsForSymbols(node.getDistinctSymbols(), source.getLayout()); OperatorFactory operatorFactory = new DistinctLimitOperatorFactory( context.getNextOperatorId(), node.getId(), source.getTypes(), distinctChannels, node.getLimit(), hashChannel, joinCompiler); return new PhysicalOperation(operatorFactory, makeLayout(node), context, source); }
@Override public PlanWithProperties visitDistinctLimit(DistinctLimitNode node, PreferredProperties preferredProperties) { PlanWithProperties child = planChild(node, PreferredProperties.any()); if (!child.getProperties().isSingleNode()) { child = withDerivedProperties( gatheringExchange( idAllocator.getNextId(), REMOTE, new DistinctLimitNode(idAllocator.getNextId(), child.getNode(), node.getLimit(), true, node.getDistinctSymbols(), node.getHashSymbol())), child.getProperties()); } return rebaseAndDeriveProperties(node, child); }
@Override public PlanNode visitDistinctLimit(DistinctLimitNode node, RewriteContext<Void> context) { PlanNode rewrittenSource = context.rewrite(node.getSource(), null); Symbol hashSymbol = symbolAllocator.newHashSymbol(); PlanNode hashProjectNode = getHashProjectNode(idAllocator, rewrittenSource, hashSymbol, node.getOutputSymbols()); return new DistinctLimitNode(idAllocator.getNextId(), hashProjectNode, node.getLimit(), Optional.of(hashSymbol)); }
@Override public PlanWithProperties visitDistinctLimit(DistinctLimitNode node, Context context) { PlanWithProperties child = planChild(node, context.withPreferredProperties(PreferredProperties.any())); if (!child.getProperties().isSingleNode()) { child = withDerivedProperties( gatheringExchange( idAllocator.getNextId(), new DistinctLimitNode(idAllocator.getNextId(), child.getNode(), node.getLimit(), node.getHashSymbol())), child.getProperties()); } return rebaseAndDeriveProperties(node, child); }
@Override public Void visitDistinctLimit(DistinctLimitNode node, Set<Symbol> boundSymbols) { PlanNode source = node.getSource(); source.accept(this, boundSymbols); // visit child checkDependencies(source.getOutputSymbols(), node.getOutputSymbols(), "Invalid node. Output column dependencies (%s) not in source plan output (%s)", node.getOutputSymbols(), source.getOutputSymbols()); return null; }
@Override public Map<PlanNodeId, SplitSource> visitDistinctLimit(DistinctLimitNode node, Void context) { return node.getSource().accept(this, context); }
@Override public Void visitDistinctLimit(DistinctLimitNode node, Integer indent) { print(indent, "- DistinctLimit[%s] => [%s]", node.getLimit(), formatOutputs(node.getOutputSymbols())); return processChildren(node, indent + 1); }
@Override @Deprecated public PlanNode visitAggregation(AggregationNode node, RewriteContext<LimitContext> context) { LimitContext limit = context.get(); if (limit != null && node.getAggregations().isEmpty() && node.getOutputSymbols().size() == node.getGroupingKeys().size() && node.getOutputSymbols().containsAll(node.getGroupingKeys())) { PlanNode rewrittenSource = context.rewrite(node.getSource()); return new DistinctLimitNode(idAllocator.getNextId(), rewrittenSource, limit.getCount(), false, rewrittenSource.getOutputSymbols(), Optional.empty()); } PlanNode rewrittenNode = context.defaultRewrite(node); if (limit != null) { // Drop in a LimitNode b/c limits cannot be pushed through aggregations rewrittenNode = new LimitNode(idAllocator.getNextId(), rewrittenNode, limit.getCount(), limit.isPartial()); } return rewrittenNode; }
@Override public ActualProperties visitDistinctLimit(DistinctLimitNode node, List<ActualProperties> inputProperties) { ActualProperties properties = Iterables.getOnlyElement(inputProperties); return ActualProperties.builderFrom(properties) .local(LocalProperties.grouped(node.getDistinctSymbols())) .build(); }
public List<Symbol> getDistinctSymbols() { if (hashSymbol.isPresent()) { return ImmutableList.copyOf(Iterables.filter(getOutputSymbols(), not(hashSymbol.get()::equals))); } return getOutputSymbols(); }
@Override public PlanWithProperties visitDistinctLimit(DistinctLimitNode node, StreamPreferredProperties parentPreferences) { // final limit requires that all data be in one stream StreamPreferredProperties requiredProperties; StreamPreferredProperties preferredProperties; if (node.isPartial()) { requiredProperties = parentPreferences.withoutPreference().withDefaultParallelism(session); preferredProperties = parentPreferences.withDefaultParallelism(session); } else { // a final changes the input organization completely, so we do not pass through parent preferences requiredProperties = singleStream(); preferredProperties = defaultParallelism(session); } return planAndEnforceChildren(node, requiredProperties, preferredProperties); }
@Override public PlanNode visitDistinctLimit(DistinctLimitNode node, RewriteContext<Set<Symbol>> context) { Set<Symbol> expectedInputs; if (node.getHashSymbol().isPresent()) { expectedInputs = ImmutableSet.copyOf(concat(node.getOutputSymbols(), ImmutableList.of(node.getHashSymbol().get()))); } else { expectedInputs = ImmutableSet.copyOf(node.getOutputSymbols()); } PlanNode source = context.rewrite(node.getSource(), expectedInputs); return new DistinctLimitNode(node.getId(), source, node.getLimit(), node.getHashSymbol()); }
@Override public PhysicalOperation visitDistinctLimit(DistinctLimitNode node, LocalExecutionPlanContext context) { PhysicalOperation source = node.getSource().accept(this, context); Optional<Integer> hashChannel = node.getHashSymbol().map(channelGetter(source)); List<Integer> distinctChannels = getChannelsForSymbols(node.getDistinctSymbols(), source.getLayout()); OperatorFactory operatorFactory = new DistinctLimitOperatorFactory( context.getNextOperatorId(), node.getId(), source.getTypes(), distinctChannels, node.getLimit(), hashChannel); return new PhysicalOperation(operatorFactory, source.getLayout(), source); }
@Override public Expression visitDistinctLimit(DistinctLimitNode node, Void context) { return node.getSource().accept(this, context); }