use of io.trino.sql.planner.plan.ApplyNode in project trino by trinodb.
the class PruneApplyColumns method pushDownProjectOff.
@Override
protected Optional<PlanNode> pushDownProjectOff(Context context, ApplyNode applyNode, Set<Symbol> referencedOutputs) {
// remove unused apply node
if (intersection(applyNode.getSubqueryAssignments().getSymbols(), referencedOutputs).isEmpty()) {
return Optional.of(applyNode.getInput());
}
// extract referenced assignments
ImmutableSet.Builder<Symbol> requiredAssignmentsSymbols = ImmutableSet.builder();
Assignments.Builder newSubqueryAssignments = Assignments.builder();
for (Map.Entry<Symbol, Expression> entry : applyNode.getSubqueryAssignments().entrySet()) {
if (referencedOutputs.contains(entry.getKey())) {
requiredAssignmentsSymbols.addAll(extractUnique(entry.getValue()));
newSubqueryAssignments.put(entry);
}
}
// prune subquery symbols
Optional<PlanNode> newSubquery = restrictOutputs(context.getIdAllocator(), applyNode.getSubquery(), requiredAssignmentsSymbols.build());
// prune input symbols
Set<Symbol> requiredInputSymbols = ImmutableSet.<Symbol>builder().addAll(referencedOutputs).addAll(applyNode.getCorrelation()).addAll(requiredAssignmentsSymbols.build()).build();
Optional<PlanNode> newInput = restrictOutputs(context.getIdAllocator(), applyNode.getInput(), requiredInputSymbols);
boolean pruned = newSubquery.isPresent() || newInput.isPresent() || newSubqueryAssignments.build().size() < applyNode.getSubqueryAssignments().size();
if (pruned) {
return Optional.of(new ApplyNode(applyNode.getId(), newInput.orElse(applyNode.getInput()), newSubquery.orElse(applyNode.getSubquery()), newSubqueryAssignments.build(), applyNode.getCorrelation(), applyNode.getOriginSubquery()));
}
return Optional.empty();
}
use of io.trino.sql.planner.plan.ApplyNode in project trino by trinodb.
the class UnwrapSingleColumnRowInApply method apply.
@Override
public Result apply(ApplyNode node, Captures captures, Context context) {
Assignments.Builder inputAssignments = Assignments.builder().putIdentities(node.getInput().getOutputSymbols());
Assignments.Builder nestedPlanAssignments = Assignments.builder().putIdentities(node.getSubquery().getOutputSymbols());
boolean applied = false;
Assignments.Builder applyAssignments = Assignments.builder();
for (Map.Entry<Symbol, Expression> assignment : node.getSubqueryAssignments().entrySet()) {
Symbol output = assignment.getKey();
Expression expression = assignment.getValue();
Optional<Unwrapping> unwrapped = Optional.empty();
if (expression instanceof InPredicate) {
InPredicate predicate = (InPredicate) expression;
unwrapped = unwrapSingleColumnRow(context, predicate.getValue(), predicate.getValueList(), (value, list) -> new InPredicate(value.toSymbolReference(), list.toSymbolReference()));
} else if (expression instanceof QuantifiedComparisonExpression) {
QuantifiedComparisonExpression comparison = (QuantifiedComparisonExpression) expression;
unwrapped = unwrapSingleColumnRow(context, comparison.getValue(), comparison.getSubquery(), (value, list) -> new QuantifiedComparisonExpression(comparison.getOperator(), comparison.getQuantifier(), value.toSymbolReference(), list.toSymbolReference()));
}
if (unwrapped.isPresent()) {
applied = true;
Unwrapping unwrapping = unwrapped.get();
inputAssignments.add(unwrapping.getInputAssignment());
nestedPlanAssignments.add(unwrapping.getNestedPlanAssignment());
applyAssignments.put(output, unwrapping.getExpression());
} else {
applyAssignments.put(assignment);
}
}
if (!applied) {
return Result.empty();
}
return Result.ofPlanNode(new ProjectNode(context.getIdAllocator().getNextId(), new ApplyNode(node.getId(), new ProjectNode(context.getIdAllocator().getNextId(), node.getInput(), inputAssignments.build()), new ProjectNode(context.getIdAllocator().getNextId(), node.getSubquery(), nestedPlanAssignments.build()), applyAssignments.build(), node.getCorrelation(), node.getOriginSubquery()), Assignments.identity(node.getOutputSymbols())));
}
use of io.trino.sql.planner.plan.ApplyNode in project trino by trinodb.
the class SubqueryPlanner method planQuantifiedComparison.
private PlanBuilder planQuantifiedComparison(PlanBuilder subPlan, ComparisonExpression.Operator operator, Quantifier quantifier, Expression value, Expression subquery, Symbol assignment, Analysis.PredicateCoercions predicateCoercions) {
PlanAndMappings subqueryPlan = planSubquery(subquery, predicateCoercions.getSubqueryCoercion(), subPlan.getTranslations());
PlanAndMappings valuePlan = planValue(subPlan, value, predicateCoercions.getValueType(), predicateCoercions.getValueCoercion());
return new PlanBuilder(valuePlan.getSubPlan().getTranslations(), new ApplyNode(idAllocator.getNextId(), valuePlan.getSubPlan().getRoot(), subqueryPlan.getSubPlan().getRoot(), Assignments.of(assignment, new QuantifiedComparisonExpression(operator, quantifier, valuePlan.get(value).toSymbolReference(), subqueryPlan.get(subquery).toSymbolReference())), valuePlan.getSubPlan().getRoot().getOutputSymbols(), subquery));
}
use of io.trino.sql.planner.plan.ApplyNode in project trino by trinodb.
the class SubqueryPlanner method planInPredicate.
/**
* Plans a correlated subquery for value IN (subQuery)
*
* @param originalExpression the original expression from which the IN predicate was derived. Used for subsequent translations.
*/
private PlanBuilder planInPredicate(PlanBuilder subPlan, Expression value, SubqueryExpression subquery, Symbol output, Expression originalExpression, Analysis.PredicateCoercions predicateCoercions) {
PlanAndMappings subqueryPlan = planSubquery(subquery, predicateCoercions.getSubqueryCoercion(), subPlan.getTranslations());
PlanAndMappings valuePlan = planValue(subPlan, value, predicateCoercions.getValueType(), predicateCoercions.getValueCoercion());
return new PlanBuilder(valuePlan.getSubPlan().getTranslations(), new ApplyNode(idAllocator.getNextId(), valuePlan.getSubPlan().getRoot(), subqueryPlan.getSubPlan().getRoot(), Assignments.of(output, new InPredicate(valuePlan.get(value).toSymbolReference(), subqueryPlan.get(subquery).toSymbolReference())), valuePlan.getSubPlan().getRoot().getOutputSymbols(), originalExpression));
}
use of io.trino.sql.planner.plan.ApplyNode in project trino by trinodb.
the class SubqueryPlanner method planExists.
private PlanBuilder planExists(PlanBuilder subPlan, Cluster<ExistsPredicate> cluster) {
// Plan one of the predicates from the cluster
ExistsPredicate existsPredicate = cluster.getRepresentative();
Expression subquery = existsPredicate.getSubquery();
Symbol exists = symbolAllocator.newSymbol("exists", BOOLEAN);
return new PlanBuilder(subPlan.getTranslations().withAdditionalMappings(mapAll(cluster, subPlan.getScope(), exists)), new ApplyNode(idAllocator.getNextId(), subPlan.getRoot(), planSubquery(subquery, subPlan.getTranslations()).getRoot(), Assignments.of(exists, new ExistsPredicate(TRUE_LITERAL)), subPlan.getRoot().getOutputSymbols(), subquery));
}
Aggregations