use of com.facebook.presto.spi.plan.AggregationNode in project presto by prestodb.
the class PushPartialAggregationThroughExchange method pushPartial.
private PlanNode pushPartial(AggregationNode aggregation, ExchangeNode exchange, Context context) {
List<PlanNode> partials = new ArrayList<>();
for (int i = 0; i < exchange.getSources().size(); i++) {
PlanNode source = exchange.getSources().get(i);
SymbolMapper.Builder mappingsBuilder = SymbolMapper.builder();
for (int outputIndex = 0; outputIndex < exchange.getOutputVariables().size(); outputIndex++) {
VariableReferenceExpression output = exchange.getOutputVariables().get(outputIndex);
VariableReferenceExpression input = exchange.getInputs().get(i).get(outputIndex);
if (!output.equals(input)) {
mappingsBuilder.put(output, input);
}
}
SymbolMapper symbolMapper = mappingsBuilder.build();
AggregationNode mappedPartial = symbolMapper.map(aggregation, source, context.getIdAllocator());
Assignments.Builder assignments = Assignments.builder();
for (VariableReferenceExpression output : aggregation.getOutputVariables()) {
VariableReferenceExpression input = symbolMapper.map(output);
assignments.put(output, input);
}
partials.add(new ProjectNode(exchange.getSourceLocation(), context.getIdAllocator().getNextId(), mappedPartial, assignments.build(), LOCAL));
}
for (PlanNode node : partials) {
verify(aggregation.getOutputVariables().equals(node.getOutputVariables()));
}
// Since this exchange source is now guaranteed to have the same symbols as the inputs to the the partial
// aggregation, we don't need to rewrite symbols in the partitioning function
List<VariableReferenceExpression> aggregationOutputs = aggregation.getOutputVariables();
PartitioningScheme partitioning = new PartitioningScheme(exchange.getPartitioningScheme().getPartitioning(), aggregationOutputs, exchange.getPartitioningScheme().getHashColumn(), exchange.getPartitioningScheme().isReplicateNullsAndAny(), exchange.getPartitioningScheme().getBucketToPartition());
return new ExchangeNode(aggregation.getSourceLocation(), context.getIdAllocator().getNextId(), exchange.getType(), exchange.getScope(), partitioning, partials, ImmutableList.copyOf(Collections.nCopies(partials.size(), aggregationOutputs)), exchange.isEnsureSourceOrdering(), Optional.empty());
}
use of com.facebook.presto.spi.plan.AggregationNode in project presto by prestodb.
the class SingleDistinctAggregationToGroupBy method apply.
@Override
public Result apply(AggregationNode aggregation, Captures captures, Context context) {
List<Set<RowExpression>> argumentSets = extractArgumentSets(aggregation).collect(Collectors.toList());
Set<VariableReferenceExpression> variables = Iterables.getOnlyElement(argumentSets).stream().map(OriginalExpressionUtils::castToExpression).map(context.getVariableAllocator()::toVariableReference).collect(Collectors.toSet());
return Result.ofPlanNode(new AggregationNode(aggregation.getSourceLocation(), aggregation.getId(), new AggregationNode(aggregation.getSourceLocation(), context.getIdAllocator().getNextId(), aggregation.getSource(), ImmutableMap.of(), singleGroupingSet(ImmutableList.<VariableReferenceExpression>builder().addAll(aggregation.getGroupingKeys()).addAll(variables).build()), ImmutableList.of(), SINGLE, Optional.empty(), Optional.empty()), // remove DISTINCT flag from function calls
aggregation.getAggregations().entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> removeDistinct(e.getValue()))), aggregation.getGroupingSets(), emptyList(), aggregation.getStep(), aggregation.getHashVariable(), aggregation.getGroupIdVariable()));
}
use of com.facebook.presto.spi.plan.AggregationNode in project presto by prestodb.
the class TransformExistsApplyToLateralNode method rewriteToDefaultAggregation.
private PlanNode rewriteToDefaultAggregation(ApplyNode parent, Context context) {
VariableReferenceExpression count = context.getVariableAllocator().newVariable("count", BIGINT);
VariableReferenceExpression exists = getOnlyElement(parent.getSubqueryAssignments().getVariables());
return new LateralJoinNode(parent.getSourceLocation(), parent.getId(), parent.getInput(), new ProjectNode(context.getIdAllocator().getNextId(), new AggregationNode(parent.getSourceLocation(), context.getIdAllocator().getNextId(), parent.getSubquery(), ImmutableMap.of(count, new Aggregation(new CallExpression(exists.getSourceLocation(), "count", functionResolution.countFunction(), BIGINT, ImmutableList.of()), Optional.empty(), Optional.empty(), false, Optional.empty())), globalAggregation(), ImmutableList.of(), AggregationNode.Step.SINGLE, Optional.empty(), Optional.empty()), Assignments.of(exists, castToRowExpression(new ComparisonExpression(GREATER_THAN, asSymbolReference(count), new Cast(new LongLiteral("0"), BIGINT.toString()))))), parent.getCorrelation(), INNER, parent.getOriginSubqueryError());
}
use of com.facebook.presto.spi.plan.AggregationNode in project presto by prestodb.
the class TransformCorrelatedInPredicateToJoin method buildInPredicateEquivalent.
private PlanNode buildInPredicateEquivalent(ApplyNode apply, InPredicate inPredicate, VariableReferenceExpression inPredicateOutputVariable, Decorrelated decorrelated, PlanNodeIdAllocator idAllocator, PlanVariableAllocator variableAllocator) {
Expression correlationCondition = and(decorrelated.getCorrelatedPredicates());
PlanNode decorrelatedBuildSource = decorrelated.getDecorrelatedNode();
AssignUniqueId probeSide = new AssignUniqueId(apply.getSourceLocation(), idAllocator.getNextId(), apply.getInput(), variableAllocator.newVariable("unique", BIGINT));
VariableReferenceExpression buildSideKnownNonNull = variableAllocator.newVariable(inPredicateOutputVariable.getSourceLocation(), "buildSideKnownNonNull", BIGINT);
ProjectNode buildSide = new ProjectNode(idAllocator.getNextId(), decorrelatedBuildSource, Assignments.builder().putAll(identitiesAsSymbolReferences(decorrelatedBuildSource.getOutputVariables())).put(buildSideKnownNonNull, castToRowExpression(bigint(0))).build());
checkArgument(inPredicate.getValue() instanceof SymbolReference, "Unexpected expression: %s", inPredicate.getValue());
SymbolReference probeSideSymbolReference = (SymbolReference) inPredicate.getValue();
checkArgument(inPredicate.getValueList() instanceof SymbolReference, "Unexpected expression: %s", inPredicate.getValueList());
SymbolReference buildSideSymbolReference = (SymbolReference) inPredicate.getValueList();
Expression joinExpression = and(or(new IsNullPredicate(probeSideSymbolReference), new ComparisonExpression(ComparisonExpression.Operator.EQUAL, probeSideSymbolReference, buildSideSymbolReference), new IsNullPredicate(buildSideSymbolReference)), correlationCondition);
JoinNode leftOuterJoin = leftOuterJoin(idAllocator, probeSide, buildSide, joinExpression);
VariableReferenceExpression countMatchesVariable = variableAllocator.newVariable(getSourceLocation(buildSideSymbolReference.getLocation()), "countMatches", BIGINT);
VariableReferenceExpression countNullMatchesVariable = variableAllocator.newVariable(getSourceLocation(buildSideSymbolReference.getLocation()), "countNullMatches", BIGINT);
Expression matchCondition = and(new IsNotNullPredicate(probeSideSymbolReference), new IsNotNullPredicate(buildSideSymbolReference));
Expression nullMatchCondition = and(new IsNotNullPredicate(createSymbolReference(buildSideKnownNonNull)), new NotExpression(matchCondition));
AggregationNode aggregation = new AggregationNode(apply.getSourceLocation(), idAllocator.getNextId(), leftOuterJoin, ImmutableMap.<VariableReferenceExpression, AggregationNode.Aggregation>builder().put(countMatchesVariable, countWithFilter(matchCondition)).put(countNullMatchesVariable, countWithFilter(nullMatchCondition)).build(), singleGroupingSet(probeSide.getOutputVariables()), ImmutableList.of(), AggregationNode.Step.SINGLE, Optional.empty(), Optional.empty());
// TODO since we care only about "some count > 0", we could have specialized node instead of leftOuterJoin that does the job without materializing join results
SearchedCaseExpression inPredicateEquivalent = new SearchedCaseExpression(ImmutableList.of(new WhenClause(isGreaterThan(countMatchesVariable, 0), booleanConstant(true)), new WhenClause(isGreaterThan(countNullMatchesVariable, 0), booleanConstant(null))), Optional.of(booleanConstant(false)));
return new ProjectNode(idAllocator.getNextId(), aggregation, Assignments.builder().putAll(identitiesAsSymbolReferences(apply.getInput().getOutputVariables())).put(inPredicateOutputVariable, castToRowExpression(inPredicateEquivalent)).build());
}
use of com.facebook.presto.spi.plan.AggregationNode in project presto by prestodb.
the class TransformCorrelatedScalarAggregationToJoin method apply.
@Override
public Result apply(LateralJoinNode lateralJoinNode, Captures captures, Context context) {
PlanNode subquery = lateralJoinNode.getSubquery();
if (!isScalar(subquery, context.getLookup())) {
return Result.empty();
}
Optional<AggregationNode> aggregation = findAggregation(subquery, context.getLookup());
if (!(aggregation.isPresent() && aggregation.get().getGroupingKeys().isEmpty())) {
return Result.empty();
}
ScalarAggregationToJoinRewriter rewriter = new ScalarAggregationToJoinRewriter(functionAndTypeManager, context.getVariableAllocator(), context.getIdAllocator(), context.getLookup());
PlanNode rewrittenNode = rewriter.rewriteScalarAggregation(lateralJoinNode, aggregation.get());
if (rewrittenNode instanceof LateralJoinNode) {
return Result.empty();
}
return Result.ofPlanNode(rewrittenNode);
}
Aggregations