Search in sources :

Example 11 with UnnestNode

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

the class UnnestedSymbolMatcher method getAssignedSymbol.

@Override
public Optional<Symbol> getAssignedSymbol(PlanNode node, Session session, Metadata metadata, SymbolAliases symbolAliases) {
    if (!(node instanceof UnnestNode)) {
        return Optional.empty();
    }
    UnnestNode unnestNode = (UnnestNode) node;
    Symbol unnestSymbol = Symbol.from(symbolAliases.get(symbol));
    List<Mapping> matches = unnestNode.getMappings().stream().filter(mapping -> mapping.getInput().equals(unnestSymbol)).collect(toImmutableList());
    checkState(matches.size() < 2, "alias matching not supported for repeated unnest symbols");
    if (matches.size() == 0) {
        return Optional.empty();
    }
    Mapping mapping = getOnlyElement(matches);
    if (index >= mapping.getOutputs().size()) {
        return Optional.empty();
    }
    return Optional.of(mapping.getOutputs().get(index));
}
Also used : Symbol(io.trino.sql.planner.Symbol) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) Iterables.getOnlyElement(com.google.common.collect.Iterables.getOnlyElement) UnnestNode(io.trino.sql.planner.plan.UnnestNode) PlanNode(io.trino.sql.planner.plan.PlanNode) Preconditions.checkState(com.google.common.base.Preconditions.checkState) List(java.util.List) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) Mapping(io.trino.sql.planner.plan.UnnestNode.Mapping) Objects.requireNonNull(java.util.Objects.requireNonNull) Metadata(io.trino.metadata.Metadata) Optional(java.util.Optional) Session(io.trino.Session) UnnestNode(io.trino.sql.planner.plan.UnnestNode) Symbol(io.trino.sql.planner.Symbol) Mapping(io.trino.sql.planner.plan.UnnestNode.Mapping)

Example 12 with UnnestNode

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

the class PushDownDereferenceThroughUnnest method apply.

@Override
public Result apply(ProjectNode projectNode, Captures captures, Context context) {
    UnnestNode unnestNode = captures.get(CHILD);
    // Extract dereferences from project node's assignments and unnest node's filter
    ImmutableList.Builder<Expression> expressionsBuilder = ImmutableList.builder();
    expressionsBuilder.addAll(projectNode.getAssignments().getExpressions());
    unnestNode.getFilter().ifPresent(expressionsBuilder::add);
    // Extract dereferences for pushdown
    Set<SubscriptExpression> dereferences = extractRowSubscripts(expressionsBuilder.build(), false, context.getSession(), typeAnalyzer, context.getSymbolAllocator().getTypes());
    // Only retain dereferences on replicate symbols
    dereferences = dereferences.stream().filter(expression -> unnestNode.getReplicateSymbols().contains(getBase(expression))).collect(toImmutableSet());
    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 newAssignments = projectNode.getAssignments().rewrite(expression -> replaceExpression(expression, mappings));
    // Create a new ProjectNode (above the original source) adding dereference projections on replicated symbols
    ProjectNode source = new ProjectNode(context.getIdAllocator().getNextId(), unnestNode.getSource(), Assignments.builder().putIdentities(unnestNode.getSource().getOutputSymbols()).putAll(dereferenceAssignments).build());
    // Create projectNode with the new unnest node and assignments with replaced dereferences
    return Result.ofPlanNode(new ProjectNode(context.getIdAllocator().getNextId(), new UnnestNode(context.getIdAllocator().getNextId(), source, ImmutableList.<Symbol>builder().addAll(unnestNode.getReplicateSymbols()).addAll(dereferenceAssignments.getSymbols()).build(), unnestNode.getMappings(), unnestNode.getOrdinalitySymbol(), unnestNode.getJoinType(), unnestNode.getFilter().map(filter -> replaceExpression(filter, mappings))), newAssignments));
}
Also used : Capture.newCapture(io.trino.matching.Capture.newCapture) DereferencePushdown.getBase(io.trino.sql.planner.iterative.rule.DereferencePushdown.getBase) SubscriptExpression(io.trino.sql.tree.SubscriptExpression) ImmutableList(com.google.common.collect.ImmutableList) Patterns.unnest(io.trino.sql.planner.plan.Patterns.unnest) Map(java.util.Map) Objects.requireNonNull(java.util.Objects.requireNonNull) ImmutableSet.toImmutableSet(com.google.common.collect.ImmutableSet.toImmutableSet) Rule(io.trino.sql.planner.iterative.Rule) ProjectNode(io.trino.sql.planner.plan.ProjectNode) Symbol(io.trino.sql.planner.Symbol) Assignments(io.trino.sql.planner.plan.Assignments) Set(java.util.Set) UnnestNode(io.trino.sql.planner.plan.UnnestNode) Capture(io.trino.matching.Capture) DereferencePushdown.extractRowSubscripts(io.trino.sql.planner.iterative.rule.DereferencePushdown.extractRowSubscripts) HashBiMap(com.google.common.collect.HashBiMap) 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) ImmutableList(com.google.common.collect.ImmutableList) SymbolReference(io.trino.sql.tree.SymbolReference) Symbol(io.trino.sql.planner.Symbol) Assignments(io.trino.sql.planner.plan.Assignments) UnnestNode(io.trino.sql.planner.plan.UnnestNode) SubscriptExpression(io.trino.sql.tree.SubscriptExpression) ExpressionNodeInliner.replaceExpression(io.trino.sql.planner.ExpressionNodeInliner.replaceExpression) Expression(io.trino.sql.tree.Expression) 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)

Aggregations

UnnestNode (io.trino.sql.planner.plan.UnnestNode)12 Symbol (io.trino.sql.planner.Symbol)11 PlanNode (io.trino.sql.planner.plan.PlanNode)8 ProjectNode (io.trino.sql.planner.plan.ProjectNode)8 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)6 ImmutableList (com.google.common.collect.ImmutableList)5 Assignments (io.trino.sql.planner.plan.Assignments)5 Expression (io.trino.sql.tree.Expression)5 List (java.util.List)5 Optional (java.util.Optional)5 ImmutableSet (com.google.common.collect.ImmutableSet)4 Captures (io.trino.matching.Captures)4 Pattern (io.trino.matching.Pattern)4 Rule (io.trino.sql.planner.iterative.Rule)4 Iterables.getOnlyElement (com.google.common.collect.Iterables.getOnlyElement)3 Session (io.trino.Session)3 Pattern.nonEmpty (io.trino.matching.Pattern.nonEmpty)3 Metadata (io.trino.metadata.Metadata)3 BIGINT (io.trino.spi.type.BigintType.BIGINT)3 SymbolsExtractor (io.trino.sql.planner.SymbolsExtractor)3