Search in sources :

Example 16 with PlanNode

use of io.trino.sql.planner.plan.PlanNode in project trino by trinodb.

the class PruneWindowColumns method pushDownProjectOff.

@Override
protected Optional<PlanNode> pushDownProjectOff(Context context, WindowNode windowNode, Set<Symbol> referencedOutputs) {
    Map<Symbol, WindowNode.Function> referencedFunctions = Maps.filterKeys(windowNode.getWindowFunctions(), referencedOutputs::contains);
    if (referencedFunctions.isEmpty()) {
        return Optional.of(windowNode.getSource());
    }
    ImmutableSet.Builder<Symbol> referencedInputs = ImmutableSet.<Symbol>builder().addAll(windowNode.getSource().getOutputSymbols().stream().filter(referencedOutputs::contains).iterator()).addAll(windowNode.getPartitionBy());
    windowNode.getOrderingScheme().ifPresent(orderingScheme -> orderingScheme.getOrderBy().forEach(referencedInputs::add));
    windowNode.getHashSymbol().ifPresent(referencedInputs::add);
    for (WindowNode.Function windowFunction : referencedFunctions.values()) {
        referencedInputs.addAll(SymbolsExtractor.extractUnique(windowFunction));
    }
    PlanNode prunedWindowNode = new WindowNode(windowNode.getId(), restrictOutputs(context.getIdAllocator(), windowNode.getSource(), referencedInputs.build()).orElse(windowNode.getSource()), windowNode.getSpecification(), referencedFunctions, windowNode.getHashSymbol(), windowNode.getPrePartitionedInputs(), windowNode.getPreSortedOrderPrefix());
    if (prunedWindowNode.getOutputSymbols().size() == windowNode.getOutputSymbols().size()) {
        // Neither function pruning nor input pruning was successful.
        return Optional.empty();
    }
    return Optional.of(prunedWindowNode);
}
Also used : WindowNode(io.trino.sql.planner.plan.WindowNode) PlanNode(io.trino.sql.planner.plan.PlanNode) ImmutableSet(com.google.common.collect.ImmutableSet) Symbol(io.trino.sql.planner.Symbol)

Example 17 with PlanNode

use of io.trino.sql.planner.plan.PlanNode in project trino by trinodb.

the class PushAggregationThroughOuterJoin method getInnerTable.

private static PlanNode getInnerTable(JoinNode join) {
    checkState(join.getType() == JoinNode.Type.LEFT || join.getType() == JoinNode.Type.RIGHT, "expected LEFT or RIGHT JOIN");
    PlanNode innerNode;
    if (join.getType() == JoinNode.Type.LEFT) {
        innerNode = join.getRight();
    } else {
        innerNode = join.getLeft();
    }
    return innerNode;
}
Also used : PlanNode(io.trino.sql.planner.plan.PlanNode)

Example 18 with PlanNode

use of io.trino.sql.planner.plan.PlanNode in project trino by trinodb.

the class PushDownDereferenceThroughFilter method apply.

@Override
public Result apply(ProjectNode node, Captures captures, Rule.Context context) {
    FilterNode filterNode = captures.get(CHILD);
    // Pushdown superset of dereference expressions from projections and filtering predicate
    List<Expression> expressions = ImmutableList.<Expression>builder().addAll(node.getAssignments().getExpressions()).add(filterNode.getPredicate()).build();
    // Extract dereferences from project node assignments for pushdown
    Set<SubscriptExpression> dereferences = extractRowSubscripts(expressions, false, context.getSession(), typeAnalyzer, context.getSymbolAllocator().getTypes());
    if (dereferences.isEmpty()) {
        return Result.empty();
    }
    // Create new symbols for dereference expressions
    Assignments dereferenceAssignments = Assignments.of(dereferences, context.getSession(), context.getSymbolAllocator(), typeAnalyzer);
    // Rewrite project node assignments using new symbols for dereference expressions
    Map<Expression, SymbolReference> mappings = HashBiMap.create(dereferenceAssignments.getMap()).inverse().entrySet().stream().collect(toImmutableMap(Map.Entry::getKey, entry -> entry.getValue().toSymbolReference()));
    Assignments assignments = node.getAssignments().rewrite(expression -> replaceExpression(expression, mappings));
    PlanNode source = filterNode.getSource();
    return Result.ofPlanNode(new ProjectNode(context.getIdAllocator().getNextId(), new FilterNode(context.getIdAllocator().getNextId(), new ProjectNode(context.getIdAllocator().getNextId(), source, Assignments.builder().putIdentities(source.getOutputSymbols()).putAll(dereferenceAssignments).build()), replaceExpression(filterNode.getPredicate(), mappings)), assignments));
}
Also used : Patterns.filter(io.trino.sql.planner.plan.Patterns.filter) Capture.newCapture(io.trino.matching.Capture.newCapture) FilterNode(io.trino.sql.planner.plan.FilterNode) PlanNode(io.trino.sql.planner.plan.PlanNode) SubscriptExpression(io.trino.sql.tree.SubscriptExpression) ImmutableList(com.google.common.collect.ImmutableList) Map(java.util.Map) Objects.requireNonNull(java.util.Objects.requireNonNull) Rule(io.trino.sql.planner.iterative.Rule) ProjectNode(io.trino.sql.planner.plan.ProjectNode) Assignments(io.trino.sql.planner.plan.Assignments) Set(java.util.Set) Capture(io.trino.matching.Capture) DereferencePushdown.extractRowSubscripts(io.trino.sql.planner.iterative.rule.DereferencePushdown.extractRowSubscripts) HashBiMap(com.google.common.collect.HashBiMap) List(java.util.List) ImmutableMap.toImmutableMap(com.google.common.collect.ImmutableMap.toImmutableMap) Pattern(io.trino.matching.Pattern) TypeAnalyzer(io.trino.sql.planner.TypeAnalyzer) Patterns.source(io.trino.sql.planner.plan.Patterns.source) SymbolReference(io.trino.sql.tree.SymbolReference) Captures(io.trino.matching.Captures) ExpressionNodeInliner.replaceExpression(io.trino.sql.planner.ExpressionNodeInliner.replaceExpression) Expression(io.trino.sql.tree.Expression) Patterns.project(io.trino.sql.planner.plan.Patterns.project) PlanNode(io.trino.sql.planner.plan.PlanNode) SubscriptExpression(io.trino.sql.tree.SubscriptExpression) ExpressionNodeInliner.replaceExpression(io.trino.sql.planner.ExpressionNodeInliner.replaceExpression) Expression(io.trino.sql.tree.Expression) SymbolReference(io.trino.sql.tree.SymbolReference) FilterNode(io.trino.sql.planner.plan.FilterNode) Assignments(io.trino.sql.planner.plan.Assignments) SubscriptExpression(io.trino.sql.tree.SubscriptExpression) ProjectNode(io.trino.sql.planner.plan.ProjectNode) Map(java.util.Map) HashBiMap(com.google.common.collect.HashBiMap) ImmutableMap.toImmutableMap(com.google.common.collect.ImmutableMap.toImmutableMap)

Example 19 with PlanNode

use of io.trino.sql.planner.plan.PlanNode in project trino by trinodb.

the class TransformCorrelatedDistinctAggregationWithProjection method apply.

@Override
public Result apply(CorrelatedJoinNode correlatedJoinNode, Captures captures, Context context) {
    // decorrelate nested plan
    PlanNodeDecorrelator decorrelator = new PlanNodeDecorrelator(plannerContext, context.getSymbolAllocator(), context.getLookup());
    Optional<PlanNodeDecorrelator.DecorrelatedNode> decorrelatedSource = decorrelator.decorrelateFilters(captures.get(AGGREGATION).getSource(), correlatedJoinNode.getCorrelation());
    if (decorrelatedSource.isEmpty()) {
        return Result.empty();
    }
    PlanNode source = decorrelatedSource.get().getNode();
    // assign unique id on correlated join's input. It will be used to distinguish between original input rows after join
    PlanNode inputWithUniqueId = new AssignUniqueId(context.getIdAllocator().getNextId(), correlatedJoinNode.getInput(), context.getSymbolAllocator().newSymbol("unique", BIGINT));
    JoinNode join = new JoinNode(context.getIdAllocator().getNextId(), JoinNode.Type.LEFT, inputWithUniqueId, source, ImmutableList.of(), inputWithUniqueId.getOutputSymbols(), source.getOutputSymbols(), false, decorrelatedSource.get().getCorrelatedPredicates(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), ImmutableMap.of(), Optional.empty());
    // restore aggregation
    AggregationNode aggregation = captures.get(AGGREGATION);
    aggregation = new AggregationNode(aggregation.getId(), join, aggregation.getAggregations(), singleGroupingSet(ImmutableList.<Symbol>builder().addAll(join.getLeftOutputSymbols()).addAll(aggregation.getGroupingKeys()).build()), ImmutableList.of(), aggregation.getStep(), Optional.empty(), Optional.empty());
    // restrict outputs and apply projection
    Set<Symbol> outputSymbols = new HashSet<>(correlatedJoinNode.getOutputSymbols());
    List<Symbol> expectedAggregationOutputs = aggregation.getOutputSymbols().stream().filter(outputSymbols::contains).collect(toImmutableList());
    Assignments assignments = Assignments.builder().putIdentities(expectedAggregationOutputs).putAll(captures.get(PROJECTION).getAssignments()).build();
    return Result.ofPlanNode(new ProjectNode(context.getIdAllocator().getNextId(), aggregation, assignments));
}
Also used : CorrelatedJoinNode(io.trino.sql.planner.plan.CorrelatedJoinNode) JoinNode(io.trino.sql.planner.plan.JoinNode) Symbol(io.trino.sql.planner.Symbol) Assignments(io.trino.sql.planner.plan.Assignments) AggregationNode(io.trino.sql.planner.plan.AggregationNode) PlanNodeDecorrelator(io.trino.sql.planner.optimizations.PlanNodeDecorrelator) PlanNode(io.trino.sql.planner.plan.PlanNode) AssignUniqueId(io.trino.sql.planner.plan.AssignUniqueId) ProjectNode(io.trino.sql.planner.plan.ProjectNode) HashSet(java.util.HashSet)

Example 20 with PlanNode

use of io.trino.sql.planner.plan.PlanNode in project trino by trinodb.

the class TransformCorrelatedDistinctAggregationWithoutProjection method apply.

@Override
public Result apply(CorrelatedJoinNode correlatedJoinNode, Captures captures, Context context) {
    // decorrelate nested plan
    PlanNodeDecorrelator decorrelator = new PlanNodeDecorrelator(plannerContext, context.getSymbolAllocator(), context.getLookup());
    Optional<PlanNodeDecorrelator.DecorrelatedNode> decorrelatedSource = decorrelator.decorrelateFilters(captures.get(AGGREGATION).getSource(), correlatedJoinNode.getCorrelation());
    if (decorrelatedSource.isEmpty()) {
        return Result.empty();
    }
    PlanNode source = decorrelatedSource.get().getNode();
    // assign unique id on correlated join's input. It will be used to distinguish between original input rows after join
    PlanNode inputWithUniqueId = new AssignUniqueId(context.getIdAllocator().getNextId(), correlatedJoinNode.getInput(), context.getSymbolAllocator().newSymbol("unique", BIGINT));
    JoinNode join = new JoinNode(context.getIdAllocator().getNextId(), JoinNode.Type.LEFT, inputWithUniqueId, source, ImmutableList.of(), inputWithUniqueId.getOutputSymbols(), source.getOutputSymbols(), false, decorrelatedSource.get().getCorrelatedPredicates(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), ImmutableMap.of(), Optional.empty());
    // restore aggregation
    AggregationNode aggregation = captures.get(AGGREGATION);
    aggregation = new AggregationNode(aggregation.getId(), join, aggregation.getAggregations(), singleGroupingSet(ImmutableList.<Symbol>builder().addAll(join.getLeftOutputSymbols()).addAll(aggregation.getGroupingKeys()).build()), ImmutableList.of(), aggregation.getStep(), Optional.empty(), Optional.empty());
    // restrict outputs
    Optional<PlanNode> project = restrictOutputs(context.getIdAllocator(), aggregation, ImmutableSet.copyOf(correlatedJoinNode.getOutputSymbols()));
    return Result.ofPlanNode(project.orElse(aggregation));
}
Also used : PlanNodeDecorrelator(io.trino.sql.planner.optimizations.PlanNodeDecorrelator) PlanNode(io.trino.sql.planner.plan.PlanNode) AssignUniqueId(io.trino.sql.planner.plan.AssignUniqueId) CorrelatedJoinNode(io.trino.sql.planner.plan.CorrelatedJoinNode) JoinNode(io.trino.sql.planner.plan.JoinNode) Symbol(io.trino.sql.planner.Symbol) AggregationNode(io.trino.sql.planner.plan.AggregationNode)

Aggregations

PlanNode (io.trino.sql.planner.plan.PlanNode)235 Test (org.testng.annotations.Test)90 Symbol (io.trino.sql.planner.Symbol)83 Expression (io.trino.sql.tree.Expression)62 ImmutableList (com.google.common.collect.ImmutableList)52 JoinNode (io.trino.sql.planner.plan.JoinNode)52 ProjectNode (io.trino.sql.planner.plan.ProjectNode)51 List (java.util.List)43 Session (io.trino.Session)41 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)39 Map (java.util.Map)37 Optional (java.util.Optional)37 AggregationNode (io.trino.sql.planner.plan.AggregationNode)35 BasePlanTest (io.trino.sql.planner.assertions.BasePlanTest)34 Assignments (io.trino.sql.planner.plan.Assignments)33 ComparisonExpression (io.trino.sql.tree.ComparisonExpression)32 Objects.requireNonNull (java.util.Objects.requireNonNull)31 ImmutableMap (com.google.common.collect.ImmutableMap)29 ImmutableSet (com.google.common.collect.ImmutableSet)29 Set (java.util.Set)29