/** * Whether this node corresponds to a DISTINCT operation in SQL */ private static boolean isDistinct(AggregationNode node) { return node.getAggregations().isEmpty() && node.getOutputSymbols().size() == node.getGroupingKeys().size() && node.getOutputSymbols().containsAll(node.getGroupingKeys()); }
/** * Whether this node corresponds to a DISTINCT operation in SQL */ private static boolean isDistinct(AggregationNode node) { return node.getAggregations().isEmpty() && node.getOutputSymbols().size() == node.getGroupingKeys().size() && node.getOutputSymbols().containsAll(node.getGroupingKeys()); }
private static List<Symbol> getTruncatedAggregationSymbols(LateralJoinNode lateralJoinNode, AggregationNode aggregationNode) { Set<Symbol> applySymbols = new HashSet<>(lateralJoinNode.getOutputSymbols()); return aggregationNode.getOutputSymbols().stream() .filter(applySymbols::contains) .collect(toImmutableList()); }
private static List<Symbol> getTruncatedAggregationSymbols(LateralJoinNode lateralJoinNode, AggregationNode aggregationNode) { Set<Symbol> applySymbols = new HashSet<>(lateralJoinNode.getOutputSymbols()); return aggregationNode.getOutputSymbols().stream() .filter(applySymbols::contains) .collect(toImmutableList()); }
@Override public Void visitAggregation(AggregationNode node, Integer indent) { String type = ""; if (node.getStep() != AggregationNode.Step.SINGLE) { type = format("(%s)", node.getStep().toString()); } if (node.isStreamable()) { type = format("%s(STREAMING)", type); } String key = ""; if (!node.getGroupingKeys().isEmpty()) { key = node.getGroupingKeys().toString(); } print(indent, "- Aggregate%s%s%s => [%s]", type, key, formatHash(node.getHashSymbol()), formatOutputs(node.getOutputSymbols())); printPlanNodesStatsAndCost(indent + 2, node); printStats(indent + 2, node.getId()); for (Map.Entry<Symbol, Aggregation> entry : node.getAggregations().entrySet()) { if (entry.getValue().getMask().isPresent()) { print(indent + 2, "%s := %s (mask = %s)", entry.getKey(), entry.getValue().getCall(), entry.getValue().getMask().get()); } else { print(indent + 2, "%s := %s", entry.getKey(), entry.getValue().getCall()); } } return processChildren(node, indent + 1); }
@Override public Result apply(AggregationNode parent, Captures captures, Context context) { if (!parent.hasDefaultOutput() || parent.getOutputSymbols().size() != 1) { return Result.empty(); } Map<Symbol, AggregationNode.Aggregation> assignments = parent.getAggregations(); for (Map.Entry<Symbol, AggregationNode.Aggregation> entry : assignments.entrySet()) { AggregationNode.Aggregation aggregation = entry.getValue(); requireNonNull(aggregation, "aggregation is null"); Signature signature = aggregation.getSignature(); FunctionCall functionCall = aggregation.getCall(); if (!"count".equals(signature.getName()) || !functionCall.getArguments().isEmpty()) { return Result.empty(); } } if (!assignments.isEmpty() && isScalar(parent.getSource(), context.getLookup())) { return Result.ofPlanNode(new ValuesNode(parent.getId(), parent.getOutputSymbols(), ImmutableList.of(ImmutableList.of(new LongLiteral("1"))))); } return Result.empty(); } }
@Override public Void visitAggregation(AggregationNode node, Integer indent) { String type = ""; if (node.getStep() != AggregationNode.Step.SINGLE) { type = format("(%s)", node.getStep().toString()); } if (node.isStreamable()) { type = format("%s(STREAMING)", type); } String key = ""; if (!node.getGroupingKeys().isEmpty()) { key = node.getGroupingKeys().toString(); } print(indent, "- Aggregate%s%s%s => [%s]", type, key, formatHash(node.getHashSymbol()), formatOutputs(node.getOutputSymbols())); printPlanNodesStatsAndCost(indent + 2, node); printStats(indent + 2, node.getId()); for (Map.Entry<Symbol, Aggregation> entry : node.getAggregations().entrySet()) { if (entry.getValue().getMask().isPresent()) { print(indent + 2, "%s := %s (mask = %s)", entry.getKey(), entry.getValue().getCall(), entry.getValue().getMask().get()); } else { print(indent + 2, "%s := %s", entry.getKey(), entry.getValue().getCall()); } } 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 Result apply(AggregationNode parent, Captures captures, Context context) { if (!parent.hasDefaultOutput() || parent.getOutputSymbols().size() != 1) { return Result.empty(); } Map<Symbol, AggregationNode.Aggregation> assignments = parent.getAggregations(); for (Map.Entry<Symbol, AggregationNode.Aggregation> entry : assignments.entrySet()) { AggregationNode.Aggregation aggregation = entry.getValue(); requireNonNull(aggregation, "aggregation is null"); Signature signature = aggregation.getSignature(); FunctionCall functionCall = aggregation.getCall(); if (!"count".equals(signature.getName()) || !functionCall.getArguments().isEmpty()) { return Result.empty(); } } if (!assignments.isEmpty() && isScalar(parent.getSource(), context.getLookup())) { return Result.ofPlanNode(new ValuesNode(parent.getId(), parent.getOutputSymbols(), ImmutableList.of(ImmutableList.of(new LongLiteral("1"))))); } return Result.empty(); } }
@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; }
ImmutableList.<Symbol>builder() .addAll(outerJoin.getOutputSymbols()) .addAll(aggregationOverNull.getOutputSymbols()) .build(), Optional.empty(),
ImmutableList.<Symbol>builder() .addAll(outerJoin.getOutputSymbols()) .addAll(aggregationOverNull.getOutputSymbols()) .build(), Optional.empty(),
private PlanNode pushPartialToJoin( AggregationNode aggregation, JoinNode child, PlanNode leftChild, PlanNode rightChild, Context context) { JoinNode joinNode = new JoinNode( child.getId(), child.getType(), leftChild, rightChild, child.getCriteria(), ImmutableList.<Symbol>builder() .addAll(leftChild.getOutputSymbols()) .addAll(rightChild.getOutputSymbols()) .build(), child.getFilter(), child.getLeftHashSymbol(), child.getRightHashSymbol(), child.getDistributionType()); return restrictOutputs(context.getIdAllocator(), joinNode, ImmutableSet.copyOf(aggregation.getOutputSymbols())).orElse(joinNode); } }
private PlanNode pushPartialToJoin( AggregationNode aggregation, JoinNode child, PlanNode leftChild, PlanNode rightChild, Context context) { JoinNode joinNode = new JoinNode( child.getId(), child.getType(), leftChild, rightChild, child.getCriteria(), ImmutableList.<Symbol>builder() .addAll(leftChild.getOutputSymbols()) .addAll(rightChild.getOutputSymbols()) .build(), child.getFilter(), child.getLeftHashSymbol(), child.getRightHashSymbol(), child.getDistributionType()); return restrictOutputs(context.getIdAllocator(), joinNode, ImmutableSet.copyOf(aggregation.getOutputSymbols())).orElse(joinNode); } }
for (Symbol output : aggregation.getOutputSymbols()) { Symbol input = symbolMapper.map(output); assignments.put(output, input.toSymbolReference()); verify(aggregation.getOutputSymbols().equals(node.getOutputSymbols())); aggregation.getOutputSymbols(), exchange.getPartitioningScheme().getHashColumn(), exchange.getPartitioningScheme().isReplicateNullsAndAny(), partitioning, partials, ImmutableList.copyOf(Collections.nCopies(partials.size(), aggregation.getOutputSymbols())), Optional.empty());
for (Symbol output : aggregation.getOutputSymbols()) { Symbol input = symbolMapper.map(output); assignments.put(output, input.toSymbolReference()); verify(aggregation.getOutputSymbols().equals(node.getOutputSymbols())); aggregation.getOutputSymbols(), exchange.getPartitioningScheme().getHashColumn(), exchange.getPartitioningScheme().isReplicateNullsAndAny(), partitioning, partials, ImmutableList.copyOf(Collections.nCopies(partials.size(), aggregation.getOutputSymbols())), Optional.empty());
@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); }
for (Symbol symbol : source.getOutputSymbols()) { if (distinctSymbol.equals(symbol)) { Symbol newSymbol = symbolAllocator.newSymbol("expr", symbolAllocator.getTypes().get(symbol));
for (Symbol symbol : source.getOutputSymbols()) { if (distinctSymbol.equals(symbol)) { Symbol newSymbol = symbolAllocator.newSymbol("expr", symbolAllocator.getTypes().get(symbol));