use of io.trino.sql.planner.Symbol in project trino by trinodb.
the class PushTopNThroughOuterJoin method apply.
@Override
public Result apply(TopNNode parent, Captures captures, Context context) {
JoinNode joinNode = captures.get(JOIN_CHILD);
List<Symbol> orderBySymbols = parent.getOrderingScheme().getOrderBy();
PlanNode left = joinNode.getLeft();
PlanNode right = joinNode.getRight();
JoinNode.Type type = joinNode.getType();
if ((type == LEFT) && ImmutableSet.copyOf(left.getOutputSymbols()).containsAll(orderBySymbols) && !isAtMost(left, context.getLookup(), parent.getCount())) {
return Result.ofPlanNode(joinNode.replaceChildren(ImmutableList.of(parent.replaceChildren(ImmutableList.of(left)), right)));
}
if ((type == RIGHT) && ImmutableSet.copyOf(right.getOutputSymbols()).containsAll(orderBySymbols) && !isAtMost(right, context.getLookup(), parent.getCount())) {
return Result.ofPlanNode(joinNode.replaceChildren(ImmutableList.of(left, parent.replaceChildren(ImmutableList.of(right)))));
}
return Result.empty();
}
use of io.trino.sql.planner.Symbol in project trino by trinodb.
the class PushTopNThroughProject method symbolMapper.
private Optional<SymbolMapper> symbolMapper(List<Symbol> symbols, Assignments assignments) {
SymbolMapper.Builder mapper = SymbolMapper.builder();
for (Symbol symbol : symbols) {
Expression expression = assignments.get(symbol);
if (!(expression instanceof SymbolReference)) {
return Optional.empty();
}
mapper.put(symbol, Symbol.from(expression));
}
return Optional.of(mapper.build());
}
use of io.trino.sql.planner.Symbol in project trino by trinodb.
the class PushTopNThroughUnion method apply.
@Override
public Result apply(TopNNode topNNode, Captures captures, Context context) {
UnionNode unionNode = captures.get(CHILD);
ImmutableList.Builder<PlanNode> sources = ImmutableList.builder();
for (PlanNode source : unionNode.getSources()) {
SymbolMapper.Builder symbolMapper = SymbolMapper.builder();
Set<Symbol> sourceOutputSymbols = ImmutableSet.copyOf(source.getOutputSymbols());
for (Symbol unionOutput : unionNode.getOutputSymbols()) {
Set<Symbol> inputSymbols = ImmutableSet.copyOf(unionNode.getSymbolMapping().get(unionOutput));
Symbol unionInput = getLast(intersection(inputSymbols, sourceOutputSymbols));
symbolMapper.put(unionOutput, unionInput);
}
sources.add(symbolMapper.build().map(topNNode, source, context.getIdAllocator().getNextId()));
}
return Result.ofPlanNode(new UnionNode(unionNode.getId(), sources.build(), unionNode.getSymbolMapping(), unionNode.getOutputSymbols()));
}
use of io.trino.sql.planner.Symbol in project trino by trinodb.
the class PushdownFilterIntoWindow method apply.
@Override
public Result apply(FilterNode node, Captures captures, Context context) {
Session session = context.getSession();
TypeProvider types = context.getSymbolAllocator().getTypes();
WindowNode windowNode = captures.get(childCapture);
DomainTranslator.ExtractionResult extractionResult = DomainTranslator.getExtractionResult(plannerContext, session, node.getPredicate(), types);
TupleDomain<Symbol> tupleDomain = extractionResult.getTupleDomain();
Optional<RankingType> rankingType = toTopNRankingType(windowNode);
Symbol rankingSymbol = getOnlyElement(windowNode.getWindowFunctions().keySet());
OptionalInt upperBound = extractUpperBound(tupleDomain, rankingSymbol);
if (upperBound.isEmpty()) {
return Result.empty();
}
if (upperBound.getAsInt() <= 0) {
return Result.ofPlanNode(new ValuesNode(node.getId(), node.getOutputSymbols(), ImmutableList.of()));
}
TopNRankingNode newSource = new TopNRankingNode(windowNode.getId(), windowNode.getSource(), windowNode.getSpecification(), rankingType.get(), rankingSymbol, upperBound.getAsInt(), false, Optional.empty());
if (!allRowNumberValuesInDomain(tupleDomain, rankingSymbol, upperBound.getAsInt())) {
return Result.ofPlanNode(new FilterNode(node.getId(), newSource, node.getPredicate()));
}
// Remove the row number domain because it is absorbed into the node
TupleDomain<Symbol> newTupleDomain = tupleDomain.filter((symbol, domain) -> !symbol.equals(rankingSymbol));
Expression newPredicate = ExpressionUtils.combineConjuncts(plannerContext.getMetadata(), extractionResult.getRemainingExpression(), new DomainTranslator(plannerContext).toPredicate(session, newTupleDomain));
if (newPredicate.equals(BooleanLiteral.TRUE_LITERAL)) {
return Result.ofPlanNode(newSource);
}
return Result.ofPlanNode(new FilterNode(node.getId(), newSource, newPredicate));
}
use of io.trino.sql.planner.Symbol in project trino by trinodb.
the class TransformUncorrelatedSubqueryToJoin method apply.
@Override
public Result apply(CorrelatedJoinNode correlatedJoinNode, Captures captures, Context context) {
// handle INNER and LEFT correlated join
if (correlatedJoinNode.getType() == INNER || correlatedJoinNode.getType() == LEFT) {
return Result.ofPlanNode(rewriteToJoin(correlatedJoinNode, correlatedJoinNode.getType().toJoinNodeType(), correlatedJoinNode.getFilter()));
}
checkState(correlatedJoinNode.getType() == RIGHT || correlatedJoinNode.getType() == FULL, "unexpected CorrelatedJoin type: " + correlatedJoinNode.getType());
// handle RIGHT and FULL correlated join ON TRUE
JoinNode.Type type;
if (correlatedJoinNode.getType() == RIGHT) {
type = JoinNode.Type.INNER;
} else {
type = JoinNode.Type.LEFT;
}
JoinNode joinNode = rewriteToJoin(correlatedJoinNode, type, TRUE_LITERAL);
if (correlatedJoinNode.getFilter().equals(TRUE_LITERAL)) {
return Result.ofPlanNode(joinNode);
}
// handle RIGHT correlated join on condition other than TRUE
if (correlatedJoinNode.getType() == RIGHT) {
Assignments.Builder assignments = Assignments.builder();
assignments.putIdentities(Sets.intersection(ImmutableSet.copyOf(correlatedJoinNode.getSubquery().getOutputSymbols()), ImmutableSet.copyOf(correlatedJoinNode.getOutputSymbols())));
for (Symbol inputSymbol : Sets.intersection(ImmutableSet.copyOf(correlatedJoinNode.getInput().getOutputSymbols()), ImmutableSet.copyOf(correlatedJoinNode.getOutputSymbols()))) {
assignments.put(inputSymbol, new IfExpression(correlatedJoinNode.getFilter(), inputSymbol.toSymbolReference(), new NullLiteral()));
}
ProjectNode projectNode = new ProjectNode(context.getIdAllocator().getNextId(), joinNode, assignments.build());
return Result.ofPlanNode(projectNode);
}
// no support for FULL correlated join on condition other than TRUE
return Result.empty();
}
Aggregations