Search in sources :

Example 1 with ApplyNode

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();
}
Also used : Symbol(io.trino.sql.planner.Symbol) ApplyNode(io.trino.sql.planner.plan.ApplyNode) Assignments(io.trino.sql.planner.plan.Assignments) PlanNode(io.trino.sql.planner.plan.PlanNode) ImmutableSet(com.google.common.collect.ImmutableSet) Expression(io.trino.sql.tree.Expression) Map(java.util.Map)

Example 2 with ApplyNode

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())));
}
Also used : Assignment(io.trino.sql.planner.plan.Assignments.Assignment) Symbol(io.trino.sql.planner.Symbol) RowType(io.trino.spi.type.RowType) BiFunction(java.util.function.BiFunction) Type(io.trino.spi.type.Type) Assignments(io.trino.sql.planner.plan.Assignments) InPredicate(io.trino.sql.tree.InPredicate) SubscriptExpression(io.trino.sql.tree.SubscriptExpression) Pattern(io.trino.matching.Pattern) TypeAnalyzer(io.trino.sql.planner.TypeAnalyzer) QuantifiedComparisonExpression(io.trino.sql.tree.QuantifiedComparisonExpression) Captures(io.trino.matching.Captures) LongLiteral(io.trino.sql.tree.LongLiteral) Map(java.util.Map) Objects.requireNonNull(java.util.Objects.requireNonNull) ApplyNode(io.trino.sql.planner.plan.ApplyNode) Optional(java.util.Optional) Rule(io.trino.sql.planner.iterative.Rule) Expression(io.trino.sql.tree.Expression) Patterns.applyNode(io.trino.sql.planner.plan.Patterns.applyNode) ProjectNode(io.trino.sql.planner.plan.ProjectNode) Symbol(io.trino.sql.planner.Symbol) ApplyNode(io.trino.sql.planner.plan.ApplyNode) Assignments(io.trino.sql.planner.plan.Assignments) QuantifiedComparisonExpression(io.trino.sql.tree.QuantifiedComparisonExpression) InPredicate(io.trino.sql.tree.InPredicate) SubscriptExpression(io.trino.sql.tree.SubscriptExpression) QuantifiedComparisonExpression(io.trino.sql.tree.QuantifiedComparisonExpression) Expression(io.trino.sql.tree.Expression) ProjectNode(io.trino.sql.planner.plan.ProjectNode) Map(java.util.Map)

Example 3 with ApplyNode

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));
}
Also used : ApplyNode(io.trino.sql.planner.plan.ApplyNode) PlanAndMappings(io.trino.sql.planner.QueryPlanner.PlanAndMappings) QuantifiedComparisonExpression(io.trino.sql.tree.QuantifiedComparisonExpression) PlanBuilder.newPlanBuilder(io.trino.sql.planner.PlanBuilder.newPlanBuilder)

Example 4 with ApplyNode

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));
}
Also used : ApplyNode(io.trino.sql.planner.plan.ApplyNode) PlanAndMappings(io.trino.sql.planner.QueryPlanner.PlanAndMappings) InPredicate(io.trino.sql.tree.InPredicate) PlanBuilder.newPlanBuilder(io.trino.sql.planner.PlanBuilder.newPlanBuilder)

Example 5 with ApplyNode

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));
}
Also used : ComparisonExpression(io.trino.sql.tree.ComparisonExpression) QuantifiedComparisonExpression(io.trino.sql.tree.QuantifiedComparisonExpression) Expression(io.trino.sql.tree.Expression) SubqueryExpression(io.trino.sql.tree.SubqueryExpression) NotExpression(io.trino.sql.tree.NotExpression) ExistsPredicate(io.trino.sql.tree.ExistsPredicate) ApplyNode(io.trino.sql.planner.plan.ApplyNode) PlanBuilder.newPlanBuilder(io.trino.sql.planner.PlanBuilder.newPlanBuilder)

Aggregations

ApplyNode (io.trino.sql.planner.plan.ApplyNode)7 PlanBuilder.newPlanBuilder (io.trino.sql.planner.PlanBuilder.newPlanBuilder)3 Symbol (io.trino.sql.planner.Symbol)3 Expression (io.trino.sql.tree.Expression)3 QuantifiedComparisonExpression (io.trino.sql.tree.QuantifiedComparisonExpression)3 PlanAndMappings (io.trino.sql.planner.QueryPlanner.PlanAndMappings)2 Assignments (io.trino.sql.planner.plan.Assignments)2 InPredicate (io.trino.sql.tree.InPredicate)2 Map (java.util.Map)2 ImmutableSet (com.google.common.collect.ImmutableSet)1 Captures (io.trino.matching.Captures)1 Pattern (io.trino.matching.Pattern)1 RowType (io.trino.spi.type.RowType)1 Type (io.trino.spi.type.Type)1 TypeAnalyzer (io.trino.sql.planner.TypeAnalyzer)1 Rule (io.trino.sql.planner.iterative.Rule)1 Assignment (io.trino.sql.planner.plan.Assignments.Assignment)1 CorrelatedJoinNode (io.trino.sql.planner.plan.CorrelatedJoinNode)1 Patterns.applyNode (io.trino.sql.planner.plan.Patterns.applyNode)1 PlanNode (io.trino.sql.planner.plan.PlanNode)1