Search in sources :

Example 1 with Lookup

use of com.facebook.presto.sql.planner.iterative.Lookup in project presto by prestodb.

the class SingleMarkDistinctToGroupBy method apply.

@Override
public Optional<PlanNode> apply(PlanNode node, Lookup lookup, PlanNodeIdAllocator idAllocator, SymbolAllocator symbolAllocator) {
    if (!(node instanceof AggregationNode)) {
        return Optional.empty();
    }
    AggregationNode parent = (AggregationNode) node;
    PlanNode source = lookup.resolve(parent.getSource());
    if (!(source instanceof MarkDistinctNode)) {
        return Optional.empty();
    }
    MarkDistinctNode child = (MarkDistinctNode) source;
    boolean hasFilters = parent.getAggregations().values().stream().map(FunctionCall::getFilter).anyMatch(Optional::isPresent);
    if (hasFilters) {
        return Optional.empty();
    }
    // optimize if and only if
    // all aggregation functions have a single common distinct mask symbol
    // AND all aggregation functions have mask
    Set<Symbol> masks = ImmutableSet.copyOf(parent.getMasks().values());
    if (masks.size() != 1 || parent.getMasks().size() != parent.getAggregations().size()) {
        return Optional.empty();
    }
    Symbol mask = Iterables.getOnlyElement(masks);
    if (!child.getMarkerSymbol().equals(mask)) {
        return Optional.empty();
    }
    return Optional.of(new AggregationNode(idAllocator.getNextId(), new AggregationNode(idAllocator.getNextId(), child.getSource(), Collections.emptyMap(), ImmutableList.of(child.getDistinctSymbols()), SINGLE, child.getHashSymbol(), Optional.empty()), // remove DISTINCT flag from function calls
    parent.getAssignments().entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> removeDistinct(e.getValue()))), parent.getGroupingSets(), parent.getStep(), parent.getHashSymbol(), parent.getGroupIdSymbol()));
}
Also used : PlanNodeIdAllocator(com.facebook.presto.sql.planner.PlanNodeIdAllocator) Iterables(com.google.common.collect.Iterables) ImmutableSet(com.google.common.collect.ImmutableSet) Rule(com.facebook.presto.sql.planner.iterative.Rule) Set(java.util.Set) Collectors(java.util.stream.Collectors) Lookup(com.facebook.presto.sql.planner.iterative.Lookup) SINGLE(com.facebook.presto.sql.planner.plan.AggregationNode.Step.SINGLE) MarkDistinctNode(com.facebook.presto.sql.planner.plan.MarkDistinctNode) ImmutableList(com.google.common.collect.ImmutableList) Symbol(com.facebook.presto.sql.planner.Symbol) PlanNode(com.facebook.presto.sql.planner.plan.PlanNode) Map(java.util.Map) Optional(java.util.Optional) SymbolAllocator(com.facebook.presto.sql.planner.SymbolAllocator) AggregationNode(com.facebook.presto.sql.planner.plan.AggregationNode) Collections(java.util.Collections) FunctionCall(com.facebook.presto.sql.tree.FunctionCall) PlanNode(com.facebook.presto.sql.planner.plan.PlanNode) MarkDistinctNode(com.facebook.presto.sql.planner.plan.MarkDistinctNode) Optional(java.util.Optional) Symbol(com.facebook.presto.sql.planner.Symbol) AggregationNode(com.facebook.presto.sql.planner.plan.AggregationNode) Map(java.util.Map)

Example 2 with Lookup

use of com.facebook.presto.sql.planner.iterative.Lookup in project presto by prestodb.

the class RuleAssert method applyRule.

private RuleApplication applyRule() {
    PlanVariableAllocator variableAllocator = new PlanVariableAllocator(types.allVariables());
    Memo memo = new Memo(idAllocator, plan);
    Lookup lookup = Lookup.from(planNode -> Stream.of(memo.resolve(planNode)));
    PlanNode memoRoot = memo.getNode(memo.getRootGroup());
    return inTransaction(session -> applyRule(rule, memoRoot, ruleContext(statsCalculator, costCalculator, variableAllocator, memo, lookup, session)));
}
Also used : PlanNode(com.facebook.presto.spi.plan.PlanNode) Lookup(com.facebook.presto.sql.planner.iterative.Lookup) PlanVariableAllocator(com.facebook.presto.sql.planner.PlanVariableAllocator) Memo(com.facebook.presto.sql.planner.iterative.Memo)

Example 3 with Lookup

use of com.facebook.presto.sql.planner.iterative.Lookup in project presto by prestodb.

the class PushAggregationThroughOuterJoin method createAggregationOverNull.

private Optional<MappedAggregationInfo> createAggregationOverNull(AggregationNode referenceAggregation, PlanVariableAllocator variableAllocator, PlanNodeIdAllocator idAllocator, Lookup lookup) {
    // Create a values node that consists of a single row of nulls.
    // Map the output symbols from the referenceAggregation's source
    // to symbol references for the new values node.
    ImmutableList.Builder<VariableReferenceExpression> nullVariables = ImmutableList.builder();
    ImmutableList.Builder<RowExpression> nullLiterals = ImmutableList.builder();
    ImmutableMap.Builder<VariableReferenceExpression, VariableReferenceExpression> sourcesVariableMappingBuilder = ImmutableMap.builder();
    for (VariableReferenceExpression sourceVariable : referenceAggregation.getSource().getOutputVariables()) {
        RowExpression nullLiteral = constantNull(sourceVariable.getSourceLocation(), sourceVariable.getType());
        nullLiterals.add(nullLiteral);
        VariableReferenceExpression nullVariable = variableAllocator.newVariable(nullLiteral);
        nullVariables.add(nullVariable);
        // TODO The type should be from sourceVariable.getType
        sourcesVariableMappingBuilder.put(sourceVariable, nullVariable);
    }
    ValuesNode nullRow = new ValuesNode(referenceAggregation.getSourceLocation(), idAllocator.getNextId(), nullVariables.build(), ImmutableList.of(nullLiterals.build()));
    Map<VariableReferenceExpression, VariableReferenceExpression> sourcesVariableMapping = sourcesVariableMappingBuilder.build();
    // For each aggregation function in the reference node, create a corresponding aggregation function
    // that points to the nullRow. Map the symbols from the aggregations in referenceAggregation to the
    // symbols in these new aggregations.
    ImmutableMap.Builder<VariableReferenceExpression, VariableReferenceExpression> aggregationsVariableMappingBuilder = ImmutableMap.builder();
    ImmutableMap.Builder<VariableReferenceExpression, AggregationNode.Aggregation> aggregationsOverNullBuilder = ImmutableMap.builder();
    for (Map.Entry<VariableReferenceExpression, AggregationNode.Aggregation> entry : referenceAggregation.getAggregations().entrySet()) {
        VariableReferenceExpression aggregationVariable = entry.getKey();
        AggregationNode.Aggregation aggregation = entry.getValue();
        if (!isUsingVariables(aggregation, sourcesVariableMapping.keySet())) {
            return Optional.empty();
        }
        AggregationNode.Aggregation overNullAggregation = new AggregationNode.Aggregation(new CallExpression(aggregation.getCall().getSourceLocation(), aggregation.getCall().getDisplayName(), aggregation.getCall().getFunctionHandle(), aggregation.getCall().getType(), aggregation.getArguments().stream().map(argument -> inlineVariables(sourcesVariableMapping, argument)).collect(toImmutableList())), aggregation.getFilter().map(filter -> inlineVariables(sourcesVariableMapping, filter)), aggregation.getOrderBy().map(orderBy -> inlineOrderByVariables(sourcesVariableMapping, orderBy)), aggregation.isDistinct(), aggregation.getMask().map(x -> new VariableReferenceExpression(sourcesVariableMapping.get(x).getSourceLocation(), sourcesVariableMapping.get(x).getName(), x.getType())));
        QualifiedObjectName functionName = functionAndTypeManager.getFunctionMetadata(overNullAggregation.getFunctionHandle()).getName();
        VariableReferenceExpression overNull = variableAllocator.newVariable(aggregation.getCall().getSourceLocation(), functionName.getObjectName(), aggregationVariable.getType());
        aggregationsOverNullBuilder.put(overNull, overNullAggregation);
        aggregationsVariableMappingBuilder.put(aggregationVariable, overNull);
    }
    Map<VariableReferenceExpression, VariableReferenceExpression> aggregationsSymbolMapping = aggregationsVariableMappingBuilder.build();
    // create an aggregation node whose source is the null row.
    AggregationNode aggregationOverNullRow = new AggregationNode(referenceAggregation.getSourceLocation(), idAllocator.getNextId(), nullRow, aggregationsOverNullBuilder.build(), globalAggregation(), ImmutableList.of(), AggregationNode.Step.SINGLE, Optional.empty(), Optional.empty());
    return Optional.of(new MappedAggregationInfo(aggregationOverNullRow, aggregationsSymbolMapping));
}
Also used : FunctionAndTypeManager(com.facebook.presto.metadata.FunctionAndTypeManager) AggregationNode(com.facebook.presto.spi.plan.AggregationNode) Captures(com.facebook.presto.matching.Captures) Assignments(com.facebook.presto.spi.plan.Assignments) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) Patterns.join(com.facebook.presto.sql.planner.plan.Patterns.join) Pattern(com.facebook.presto.matching.Pattern) ValuesNode(com.facebook.presto.spi.plan.ValuesNode) HashSet(java.util.HashSet) Capture(com.facebook.presto.matching.Capture) ImmutableList(com.google.common.collect.ImmutableList) DistinctOutputQueryUtil.isDistinct(com.facebook.presto.sql.planner.optimizations.DistinctOutputQueryUtil.isDistinct) Map(java.util.Map) Objects.requireNonNull(java.util.Objects.requireNonNull) QualifiedObjectName(com.facebook.presto.common.QualifiedObjectName) AggregationNode.singleGroupingSet(com.facebook.presto.spi.plan.AggregationNode.singleGroupingSet) CallExpression(com.facebook.presto.spi.relation.CallExpression) OrderingScheme(com.facebook.presto.spi.plan.OrderingScheme) SpecialFormExpression(com.facebook.presto.spi.relation.SpecialFormExpression) RowExpression(com.facebook.presto.spi.relation.RowExpression) JoinNode(com.facebook.presto.sql.planner.plan.JoinNode) Patterns.aggregation(com.facebook.presto.sql.planner.plan.Patterns.aggregation) PlanNodeIdAllocator(com.facebook.presto.spi.plan.PlanNodeIdAllocator) AggregationNode.globalAggregation(com.facebook.presto.spi.plan.AggregationNode.globalAggregation) SortOrder(com.facebook.presto.common.block.SortOrder) ImmutableMap(com.google.common.collect.ImmutableMap) Session(com.facebook.presto.Session) Ordering(com.facebook.presto.spi.plan.Ordering) Rule(com.facebook.presto.sql.planner.iterative.Rule) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) Set(java.util.Set) RowExpressionVariableInliner.inlineVariables(com.facebook.presto.sql.planner.RowExpressionVariableInliner.inlineVariables) Expressions.constantNull(com.facebook.presto.sql.relational.Expressions.constantNull) Lookup(com.facebook.presto.sql.planner.iterative.Lookup) Preconditions.checkState(com.google.common.base.Preconditions.checkState) Patterns.source(com.facebook.presto.sql.planner.plan.Patterns.source) PlanNode(com.facebook.presto.spi.plan.PlanNode) List(java.util.List) SystemSessionProperties.shouldPushAggregationThroughJoin(com.facebook.presto.SystemSessionProperties.shouldPushAggregationThroughJoin) ProjectNode(com.facebook.presto.spi.plan.ProjectNode) Capture.newCapture(com.facebook.presto.matching.Capture.newCapture) PlanVariableAllocator(com.facebook.presto.sql.planner.PlanVariableAllocator) Optional(java.util.Optional) ValuesNode(com.facebook.presto.spi.plan.ValuesNode) ImmutableList(com.google.common.collect.ImmutableList) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) RowExpression(com.facebook.presto.spi.relation.RowExpression) AggregationNode(com.facebook.presto.spi.plan.AggregationNode) ImmutableMap(com.google.common.collect.ImmutableMap) QualifiedObjectName(com.facebook.presto.common.QualifiedObjectName) AggregationNode.globalAggregation(com.facebook.presto.spi.plan.AggregationNode.globalAggregation) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) CallExpression(com.facebook.presto.spi.relation.CallExpression)

Example 4 with Lookup

use of com.facebook.presto.sql.planner.iterative.Lookup 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)));
}
Also used : Aggregation(com.facebook.presto.spi.plan.AggregationNode.Aggregation) PlanNode(com.facebook.presto.spi.plan.PlanNode) PlanNodeIdAllocator(com.facebook.presto.spi.plan.PlanNodeIdAllocator) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) TypeProvider(com.facebook.presto.sql.planner.TypeProvider) Lookup(com.facebook.presto.sql.planner.iterative.Lookup) AggregationNode(com.facebook.presto.spi.plan.AggregationNode) Session(com.facebook.presto.Session)

Aggregations

Lookup (com.facebook.presto.sql.planner.iterative.Lookup)4 PlanNode (com.facebook.presto.spi.plan.PlanNode)3 Session (com.facebook.presto.Session)2 AggregationNode (com.facebook.presto.spi.plan.AggregationNode)2 PlanNodeIdAllocator (com.facebook.presto.spi.plan.PlanNodeIdAllocator)2 VariableReferenceExpression (com.facebook.presto.spi.relation.VariableReferenceExpression)2 PlanVariableAllocator (com.facebook.presto.sql.planner.PlanVariableAllocator)2 Rule (com.facebook.presto.sql.planner.iterative.Rule)2 ImmutableList (com.google.common.collect.ImmutableList)2 SystemSessionProperties.shouldPushAggregationThroughJoin (com.facebook.presto.SystemSessionProperties.shouldPushAggregationThroughJoin)1 QualifiedObjectName (com.facebook.presto.common.QualifiedObjectName)1 SortOrder (com.facebook.presto.common.block.SortOrder)1 Capture (com.facebook.presto.matching.Capture)1 Capture.newCapture (com.facebook.presto.matching.Capture.newCapture)1 Captures (com.facebook.presto.matching.Captures)1 Pattern (com.facebook.presto.matching.Pattern)1 FunctionAndTypeManager (com.facebook.presto.metadata.FunctionAndTypeManager)1 Aggregation (com.facebook.presto.spi.plan.AggregationNode.Aggregation)1 AggregationNode.globalAggregation (com.facebook.presto.spi.plan.AggregationNode.globalAggregation)1 AggregationNode.singleGroupingSet (com.facebook.presto.spi.plan.AggregationNode.singleGroupingSet)1