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));
}
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));
}
Aggregations