@Override public Map<PlanNodeId, SplitSource> visitAggregation(AggregationNode node, Void context) { return node.getSource().accept(this, context); }
@Override public Map<PlanNodeId, SplitSource> visitAggregation(AggregationNode node, Void context) { return node.getSource().accept(this, context); }
@Override public Map<Symbol, Symbol> visitAggregation(AggregationNode node, Set<Symbol> lookupSymbols) { Set<Symbol> groupByLookupSymbols = lookupSymbols.stream() .filter(node.getGroupingKeys()::contains) .collect(toImmutableSet()); checkState(!groupByLookupSymbols.isEmpty(), "No lookup symbols were able to pass through the aggregation group by"); return node.getSource().accept(this, groupByLookupSymbols); }
@Override public Map<Symbol, Symbol> visitAggregation(AggregationNode node, Set<Symbol> lookupSymbols) { Set<Symbol> groupByLookupSymbols = lookupSymbols.stream() .filter(node.getGroupingKeys()::contains) .collect(toImmutableSet()); checkState(!groupByLookupSymbols.isEmpty(), "No lookup symbols were able to pass through the aggregation group by"); return node.getSource().accept(this, groupByLookupSymbols); }
@Override public PlanNode visitAggregation(AggregationNode node, RewriteContext<Void> context) { PlanNode source = context.rewrite(node.getSource()); //TODO: use mapper in other methods SymbolMapper mapper = new SymbolMapper(mapping); return mapper.map(node, source); }
@Override public Void visitAggregation(AggregationNode node, Void context) { if (node.getPreGroupedSymbols().isEmpty()) { return null; } StreamProperties properties = derivePropertiesRecursively(node.getSource(), metadata, sesstion, types, sqlParser); List<LocalProperty<Symbol>> desiredProperties = ImmutableList.of(new GroupingProperty<>(node.getPreGroupedSymbols())); Iterator<Optional<LocalProperty<Symbol>>> matchIterator = LocalProperties.match(properties.getLocalProperties(), desiredProperties).iterator(); Optional<LocalProperty<Symbol>> unsatisfiedRequirement = Iterators.getOnlyElement(matchIterator); checkArgument(!unsatisfiedRequirement.isPresent(), "Streaming aggregation with input not grouped on the grouping keys"); return null; } }
@Override public Void visitAggregation(AggregationNode node, Void context) { if (node.getPreGroupedSymbols().isEmpty()) { return null; } StreamProperties properties = derivePropertiesRecursively(node.getSource(), metadata, sesstion, types, sqlParser); List<LocalProperty<Symbol>> desiredProperties = ImmutableList.of(new GroupingProperty<>(node.getPreGroupedSymbols())); Iterator<Optional<LocalProperty<Symbol>>> matchIterator = LocalProperties.match(properties.getLocalProperties(), desiredProperties).iterator(); Optional<LocalProperty<Symbol>> unsatisfiedRequirement = Iterators.getOnlyElement(matchIterator); checkArgument(!unsatisfiedRequirement.isPresent(), "Streaming aggregation with input not grouped on the grouping keys"); return null; } }
@Override public PlanNode visitAggregation(AggregationNode node, RewriteContext<Void> context) { PlanNode source = context.rewrite(node.getSource()); //TODO: use mapper in other methods SymbolMapper mapper = new SymbolMapper(mapping); return mapper.map(node, source); }
@Override protected Optional<PlanNodeStatsEstimate> doCalculate(AggregationNode node, StatsProvider statsProvider, Lookup lookup, Session session, TypeProvider types) { if (node.getGroupingSetCount() != 1) { return Optional.empty(); } if (node.getStep() != SINGLE) { return Optional.empty(); } return Optional.of(groupBy( statsProvider.getStats(node.getSource()), node.getGroupingKeys(), node.getAggregations())); }
@Override public Expression visitAggregation(AggregationNode node, Void context) { // GROUP BY () always produces a group, regardless of whether there's any // input (unlike the case where there are group by keys, which produce // no output if there's no input). // Therefore, we can't say anything about the effective predicate of the // output of such an aggregation. if (node.getGroupingKeys().isEmpty()) { return TRUE_LITERAL; } Expression underlyingPredicate = node.getSource().accept(this, context); return pullExpressionThroughSymbols(underlyingPredicate, node.getGroupingKeys()); }
@Override public Expression visitAggregation(AggregationNode node, Void context) { // GROUP BY () always produces a group, regardless of whether there's any // input (unlike the case where there are group by keys, which produce // no output if there's no input). // Therefore, we can't say anything about the effective predicate of the // output of such an aggregation. if (node.getGroupingKeys().isEmpty()) { return TRUE_LITERAL; } Expression underlyingPredicate = node.getSource().accept(this, context); return pullExpressionThroughSymbols(underlyingPredicate, node.getGroupingKeys()); }
@Override protected Optional<PlanNodeStatsEstimate> doCalculate(AggregationNode node, StatsProvider statsProvider, Lookup lookup, Session session, TypeProvider types) { if (node.getGroupingSetCount() != 1) { return Optional.empty(); } if (node.getStep() != SINGLE) { return Optional.empty(); } return Optional.of(groupBy( statsProvider.getStats(node.getSource()), node.getGroupingKeys(), node.getAggregations())); }
@Override public PlanNodeCostEstimate visitAggregation(AggregationNode node, Void context) { if (node.getStep() != FINAL && node.getStep() != SINGLE) { return PlanNodeCostEstimate.unknown(); } PlanNodeStatsEstimate aggregationStats = getStats(node); PlanNodeStatsEstimate sourceStats = getStats(node.getSource()); double cpuCost = sourceStats.getOutputSizeInBytes(node.getSource().getOutputSymbols(), types); double memoryCost = aggregationStats.getOutputSizeInBytes(node.getOutputSymbols(), types); return new PlanNodeCostEstimate(cpuCost, memoryCost, 0); }
@Override public PlanNodeCostEstimate visitAggregation(AggregationNode node, Void context) { if (node.getStep() != FINAL && node.getStep() != SINGLE) { return PlanNodeCostEstimate.unknown(); } PlanNodeStatsEstimate aggregationStats = getStats(node); PlanNodeStatsEstimate sourceStats = getStats(node.getSource()); double cpuCost = sourceStats.getOutputSizeInBytes(node.getSource().getOutputSymbols(), types); double memoryCost = aggregationStats.getOutputSizeInBytes(node.getOutputSymbols(), types); return new PlanNodeCostEstimate(cpuCost, memoryCost, 0); }
@Override public PhysicalOperation visitAggregation(AggregationNode node, LocalExecutionPlanContext context) { PhysicalOperation source = node.getSource().accept(this, context); if (node.getGroupingKeys().isEmpty()) { return planGlobalAggregation(node, source, context); } boolean spillEnabled = isSpillEnabled(context.getSession()); DataSize unspillMemoryLimit = getAggregationOperatorUnspillMemoryLimit(context.getSession()); return planGroupByAggregation(node, source, spillEnabled, unspillMemoryLimit, context); }
@Override public PhysicalOperation visitAggregation(AggregationNode node, LocalExecutionPlanContext context) { PhysicalOperation source = node.getSource().accept(this, context); if (node.getGroupingKeys().isEmpty()) { return planGlobalAggregation(node, source, context); } boolean spillEnabled = isSpillEnabled(context.getSession()); DataSize unspillMemoryLimit = getAggregationOperatorUnspillMemoryLimit(context.getSession()); return planGroupByAggregation(node, source, spillEnabled, unspillMemoryLimit, context); }
@Override public PlanNodeCostEstimate visitAggregation(AggregationNode node, Void context) { PlanNode source = node.getSource(); double inputSizeInBytes = getStats(source).getOutputSizeInBytes(source.getOutputSymbols(), types); PlanNodeCostEstimate remoteRepartitionCost = calculateRemoteRepartitionCost(inputSizeInBytes); PlanNodeCostEstimate localRepartitionCost = calculateLocalRepartitionCost(inputSizeInBytes); // TODO consider cost of aggregation itself, not only exchanges, based on aggregation's properties return remoteRepartitionCost.add(localRepartitionCost); }
@Override public PlanNodeCostEstimate visitAggregation(AggregationNode node, Void context) { PlanNode source = node.getSource(); double inputSizeInBytes = getStats(source).getOutputSizeInBytes(source.getOutputSymbols(), types); PlanNodeCostEstimate remoteRepartitionCost = calculateRemoteRepartitionCost(inputSizeInBytes); PlanNodeCostEstimate localRepartitionCost = calculateLocalRepartitionCost(inputSizeInBytes); // TODO consider cost of aggregation itself, not only exchanges, based on aggregation's properties return remoteRepartitionCost.add(localRepartitionCost); }
@Override public Result apply(LimitNode parent, Captures captures, Context context) { AggregationNode child = captures.get(CHILD); return Result.ofPlanNode( new DistinctLimitNode( parent.getId(), child.getSource(), parent.getCount(), false, child.getGroupingKeys(), child.getHashSymbol())); } }
@Override public Result apply(LimitNode parent, Captures captures, Context context) { AggregationNode child = captures.get(CHILD); return Result.ofPlanNode( new DistinctLimitNode( parent.getId(), child.getSource(), parent.getCount(), false, child.getGroupingKeys(), child.getHashSymbol())); } }