use of com.facebook.presto.spi.plan.AggregationNode.Aggregation in project presto by prestodb.
the class PruneOrderByInAggregation method apply.
@Override
public Result apply(AggregationNode node, Captures captures, Context context) {
if (!node.hasOrderings()) {
return Result.empty();
}
boolean anyRewritten = false;
ImmutableMap.Builder<VariableReferenceExpression, Aggregation> aggregations = ImmutableMap.builder();
for (Map.Entry<VariableReferenceExpression, Aggregation> entry : node.getAggregations().entrySet()) {
Aggregation aggregation = entry.getValue();
if (!aggregation.getOrderBy().isPresent()) {
aggregations.put(entry);
} else // getAggregateFunctionImplementation can be expensive, so check it last.
if (functionAndTypeManager.getAggregateFunctionImplementation(aggregation.getFunctionHandle()).isOrderSensitive()) {
aggregations.put(entry);
} else {
anyRewritten = true;
aggregations.put(entry.getKey(), new Aggregation(aggregation.getCall(), aggregation.getFilter(), Optional.empty(), aggregation.isDistinct(), aggregation.getMask()));
}
}
if (!anyRewritten) {
return Result.empty();
}
return Result.ofPlanNode(new AggregationNode(node.getSourceLocation(), node.getId(), node.getSource(), aggregations.build(), node.getGroupingSets(), node.getPreGroupedVariables(), node.getStep(), node.getHashVariable(), node.getGroupIdVariable()));
}
use of com.facebook.presto.spi.plan.AggregationNode.Aggregation in project presto by prestodb.
the class AggregationFunctionMatcher method getAssignedVariable.
@Override
public Optional<VariableReferenceExpression> getAssignedVariable(PlanNode node, Session session, Metadata metadata, SymbolAliases symbolAliases) {
Optional<VariableReferenceExpression> result = Optional.empty();
if (!(node instanceof AggregationNode)) {
return result;
}
AggregationNode aggregationNode = (AggregationNode) node;
FunctionCall expectedCall = callMaker.getExpectedValue(symbolAliases);
for (Map.Entry<VariableReferenceExpression, Aggregation> assignment : aggregationNode.getAggregations().entrySet()) {
if (verifyAggregation(metadata.getFunctionAndTypeManager(), assignment.getValue(), expectedCall)) {
checkState(!result.isPresent(), "Ambiguous function calls in %s", aggregationNode);
result = Optional.of(assignment.getKey());
}
}
return result;
}
use of com.facebook.presto.spi.plan.AggregationNode.Aggregation in project presto by prestodb.
the class TestTypeValidator method testInvalidAggregationFunctionSignature.
@Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "type of variable 'sum(_[0-9]+)?' is expected to be double, but the actual type is bigint")
public void testInvalidAggregationFunctionSignature() {
VariableReferenceExpression aggregationVariable = variableAllocator.newVariable("sum", DOUBLE);
PlanNode node = new AggregationNode(Optional.empty(), newId(), baseTableScan, ImmutableMap.of(aggregationVariable, new Aggregation(new CallExpression("sum", // should be DOUBLE
FUNCTION_MANAGER.lookupFunction("sum", fromTypes(BIGINT)), DOUBLE, ImmutableList.of(variableC)), Optional.empty(), Optional.empty(), false, Optional.empty())), singleGroupingSet(ImmutableList.of(variableA, variableB)), ImmutableList.of(), SINGLE, Optional.empty(), Optional.empty());
assertTypesValid(node);
}
use of com.facebook.presto.spi.plan.AggregationNode.Aggregation in project presto by prestodb.
the class AddIntermediateAggregations method apply.
@Override
public Result apply(AggregationNode aggregation, Captures captures, Context context) {
Lookup lookup = context.getLookup();
PlanNodeIdAllocator idAllocator = context.getIdAllocator();
Session session = context.getSession();
TypeProvider types = context.getVariableAllocator().getTypes();
Optional<PlanNode> rewrittenSource = recurseToPartial(lookup.resolve(aggregation.getSource()), lookup, idAllocator, types);
if (!rewrittenSource.isPresent()) {
return Result.empty();
}
PlanNode source = rewrittenSource.get();
if (getTaskConcurrency(session) > 1) {
Map<VariableReferenceExpression, Aggregation> variableToAggregations = inputsAsOutputs(aggregation.getAggregations(), types);
if (variableToAggregations.isEmpty()) {
return Result.empty();
}
source = roundRobinExchange(idAllocator.getNextId(), LOCAL, source);
source = new AggregationNode(aggregation.getSourceLocation(), idAllocator.getNextId(), source, variableToAggregations, aggregation.getGroupingSets(), aggregation.getPreGroupedVariables(), INTERMEDIATE, aggregation.getHashVariable(), aggregation.getGroupIdVariable());
source = gatheringExchange(idAllocator.getNextId(), LOCAL, source);
}
return Result.ofPlanNode(aggregation.replaceChildren(ImmutableList.of(source)));
}
use of com.facebook.presto.spi.plan.AggregationNode.Aggregation in project presto by prestodb.
the class AddIntermediateAggregations method inputsAsOutputs.
/**
* Rewrite assignments so that outputs are in terms of the input symbols.
* This operation only reliably applies to aggregation steps that take partial inputs (e.g. INTERMEDIATE and split FINALs),
* which are guaranteed to have exactly one input and one output.
* <p>
* Example:
* 'a' := sum('b') => 'b' := sum('b')
*/
private static Map<VariableReferenceExpression, Aggregation> inputsAsOutputs(Map<VariableReferenceExpression, Aggregation> assignments, TypeProvider types) {
ImmutableMap.Builder<VariableReferenceExpression, Aggregation> builder = ImmutableMap.builder();
for (Map.Entry<VariableReferenceExpression, Aggregation> entry : assignments.entrySet()) {
// Should only have one input symbol
Aggregation aggregation = entry.getValue();
if (!(aggregation.getArguments().size() == 1 && !aggregation.getOrderBy().isPresent() && !aggregation.getFilter().isPresent())) {
return ImmutableMap.of();
}
VariableReferenceExpression input = getOnlyElement(extractAggregationUniqueVariables(entry.getValue(), types));
builder.put(input, entry.getValue());
}
return builder.build();
}
Aggregations