Search in sources :

Example 1 with PartialAggregationStrategy

use of com.facebook.presto.sql.analyzer.FeaturesConfig.PartialAggregationStrategy in project presto by prestodb.

the class PushPartialAggregationThroughExchange method apply.

@Override
public Result apply(AggregationNode aggregationNode, Captures captures, Context context) {
    ExchangeNode exchangeNode = captures.get(EXCHANGE_NODE);
    boolean decomposable = isDecomposable(aggregationNode, functionAndTypeManager);
    if (aggregationNode.getStep().equals(SINGLE) && aggregationNode.hasEmptyGroupingSet() && aggregationNode.hasNonEmptyGroupingSet() && exchangeNode.getType() == REPARTITION) {
        // single-step aggregation w/ empty grouping sets in a partitioned stage, so we need a partial that will produce
        // the default intermediates for the empty grouping set that will be routed to the appropriate final aggregation.
        // TODO: technically, AddExchanges generates a broken plan that this rule "fixes"
        checkState(decomposable, "Distributed aggregation with empty grouping set requires partial but functions are not decomposable");
        return Result.ofPlanNode(split(aggregationNode, context));
    }
    PartialAggregationStrategy partialAggregationStrategy = getPartialAggregationStrategy(context.getSession());
    if (!decomposable || partialAggregationStrategy == NEVER || partialAggregationStrategy == AUTOMATIC && partialAggregationNotUseful(aggregationNode, exchangeNode, context) && aggregationNode.getGroupingKeys().size() == 1) {
        return Result.empty();
    }
    // the cardinality of the stream (i.e., gather or repartition)
    if ((exchangeNode.getType() != GATHER && exchangeNode.getType() != REPARTITION) || exchangeNode.getPartitioningScheme().isReplicateNullsAndAny()) {
        return Result.empty();
    }
    if (exchangeNode.getType() == REPARTITION) {
        // if partitioning columns are not a subset of grouping keys,
        // we can't push this through
        List<VariableReferenceExpression> partitioningColumns = exchangeNode.getPartitioningScheme().getPartitioning().getArguments().stream().filter(VariableReferenceExpression.class::isInstance).map(VariableReferenceExpression.class::cast).collect(Collectors.toList());
        if (!aggregationNode.getGroupingKeys().containsAll(partitioningColumns)) {
            return Result.empty();
        }
    }
    // currently, we only support plans that don't use pre-computed hash functions
    if (aggregationNode.getHashVariable().isPresent() || exchangeNode.getPartitioningScheme().getHashColumn().isPresent()) {
        return Result.empty();
    }
    switch(aggregationNode.getStep()) {
        case SINGLE:
            // Split it into a FINAL on top of a PARTIAL and
            return Result.ofPlanNode(split(aggregationNode, context));
        case PARTIAL:
            // Push it underneath each branch of the exchange
            return Result.ofPlanNode(pushPartial(aggregationNode, exchangeNode, context));
        default:
            return Result.empty();
    }
}
Also used : ExchangeNode(com.facebook.presto.sql.planner.plan.ExchangeNode) SystemSessionProperties.getPartialAggregationStrategy(com.facebook.presto.SystemSessionProperties.getPartialAggregationStrategy) PartialAggregationStrategy(com.facebook.presto.sql.analyzer.FeaturesConfig.PartialAggregationStrategy) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression)

Aggregations

SystemSessionProperties.getPartialAggregationStrategy (com.facebook.presto.SystemSessionProperties.getPartialAggregationStrategy)1 VariableReferenceExpression (com.facebook.presto.spi.relation.VariableReferenceExpression)1 PartialAggregationStrategy (com.facebook.presto.sql.analyzer.FeaturesConfig.PartialAggregationStrategy)1 ExchangeNode (com.facebook.presto.sql.planner.plan.ExchangeNode)1