public boolean hasSingleNodeExecutionPreference(FunctionRegistry functionRegistry) { // There are two kinds of aggregations the have single node execution preference: // // 1. aggregations with only empty grouping sets like // // SELECT count(*) FROM lineitem; // // there is no need for distributed aggregation. Single node FINAL aggregation will suffice, // since all input have to be aggregated into one line output. // // 2. aggregations that must produce default output and are not decomposable, we can not distribute them. return (hasEmptyGroupingSet() && !hasNonEmptyGroupingSet()) || (hasDefaultOutput() && !isDecomposable(functionRegistry)); }
public boolean hasSingleNodeExecutionPreference(FunctionRegistry functionRegistry) { // There are two kinds of aggregations the have single node execution preference: // // 1. aggregations with only empty grouping sets like // // SELECT count(*) FROM lineitem; // // there is no need for distributed aggregation. Single node FINAL aggregation will suffice, // since all input have to be aggregated into one line output. // // 2. aggregations that must produce default output and are not decomposable, we can not distribute them. return (hasEmptyGroupingSet() && !hasNonEmptyGroupingSet()) || (hasDefaultOutput() && !isDecomposable(functionRegistry)); }
@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 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(); } }
if (node.hasDefaultOutput()) { checkState(node.isDecomposable(metadata.getFunctionRegistry()));
if (node.hasDefaultOutput()) { checkState(node.isDecomposable(metadata.getFunctionRegistry()));