Search in sources :

Example 6 with LimitNode

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

the class MergeLimits method apply.

@Override
public Result apply(LimitNode parent, Captures captures, Context context) {
    LimitNode child = captures.get(CHILD);
    List<Symbol> sortedInputs = ImmutableList.of();
    if (child.requiresPreSortedInputs()) {
        sortedInputs = child.getPreSortedInputs();
    } else if (parent.requiresPreSortedInputs()) {
        sortedInputs = parent.getPreSortedInputs();
    }
    // parent and child are without ties
    if (!child.isWithTies()) {
        return Result.ofPlanNode(new LimitNode(parent.getId(), child.getSource(), Math.min(parent.getCount(), child.getCount()), parent.getTiesResolvingScheme(), parent.isPartial(), sortedInputs));
    }
    // parent is without ties and child is with ties
    if (parent.getCount() > child.getCount()) {
        return Result.ofPlanNode(child.replaceChildren(ImmutableList.of(parent.replaceChildren(ImmutableList.of(child.getSource())))));
    }
    return Result.ofPlanNode(parent.replaceChildren(ImmutableList.of(child.getSource())));
}
Also used : LimitNode(io.trino.sql.planner.plan.LimitNode) Symbol(io.trino.sql.planner.Symbol)

Example 7 with LimitNode

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

the class LimitMatcher method detailMatches.

@Override
public MatchResult detailMatches(PlanNode node, StatsProvider stats, Session session, Metadata metadata, SymbolAliases symbolAliases) {
    checkState(shapeMatches(node));
    LimitNode limitNode = (LimitNode) node;
    if (!limitNode.isWithTies()) {
        return match();
    }
    OrderingScheme tiesResolvingScheme = limitNode.getTiesResolvingScheme().get();
    if (orderingSchemeMatches(tiesResolvers, tiesResolvingScheme, symbolAliases)) {
        return match();
    }
    if (!limitNode.requiresPreSortedInputs()) {
        return match();
    }
    if (preSortedInputs.stream().map(alias -> alias.toSymbol(symbolAliases)).collect(toImmutableSet()).equals(ImmutableSet.copyOf(limitNode.getPreSortedInputs()))) {
        return match();
    }
    return NO_MATCH;
}
Also used : OrderingScheme(io.trino.sql.planner.OrderingScheme) LimitNode(io.trino.sql.planner.plan.LimitNode)

Example 8 with LimitNode

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

the class PushDownDereferencesThroughLimit method apply.

@Override
public Result apply(ProjectNode projectNode, Captures captures, Context context) {
    LimitNode limitNode = captures.get(CHILD);
    // Extract dereferences from project node assignments for pushdown
    Set<SubscriptExpression> dereferences = extractRowSubscripts(projectNode.getAssignments().getExpressions(), false, context.getSession(), typeAnalyzer, context.getSymbolAllocator().getTypes());
    // Exclude dereferences on symbols being used in tiesResolvingScheme and requiresPreSortedInputs
    Set<Symbol> excludedSymbols = ImmutableSet.<Symbol>builder().addAll(limitNode.getTiesResolvingScheme().map(OrderingScheme::getOrderBy).orElse(ImmutableList.of())).addAll(limitNode.getPreSortedInputs()).build();
    dereferences = dereferences.stream().filter(expression -> !excludedSymbols.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));
    return Result.ofPlanNode(new ProjectNode(context.getIdAllocator().getNextId(), limitNode.replaceChildren(ImmutableList.of(new ProjectNode(context.getIdAllocator().getNextId(), limitNode.getSource(), Assignments.builder().putIdentities(limitNode.getSource().getOutputSymbols()).putAll(dereferenceAssignments).build()))), newAssignments));
}
Also used : LimitNode(io.trino.sql.planner.plan.LimitNode) 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) 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) ImmutableSet(com.google.common.collect.ImmutableSet) Assignments(io.trino.sql.planner.plan.Assignments) Set(java.util.Set) OrderingScheme(io.trino.sql.planner.OrderingScheme) 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) Patterns.limit(io.trino.sql.planner.plan.Patterns.limit) ExpressionNodeInliner.replaceExpression(io.trino.sql.planner.ExpressionNodeInliner.replaceExpression) Expression(io.trino.sql.tree.Expression) Patterns.project(io.trino.sql.planner.plan.Patterns.project) OrderingScheme(io.trino.sql.planner.OrderingScheme) Symbol(io.trino.sql.planner.Symbol) SymbolReference(io.trino.sql.tree.SymbolReference) Assignments(io.trino.sql.planner.plan.Assignments) LimitNode(io.trino.sql.planner.plan.LimitNode) 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)

Example 9 with LimitNode

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

the class PushLimitThroughUnion method apply.

@Override
public Result apply(LimitNode parent, Captures captures, Context context) {
    UnionNode unionNode = captures.get(CHILD);
    ImmutableList.Builder<PlanNode> builder = ImmutableList.builder();
    boolean shouldApply = false;
    for (PlanNode source : unionNode.getSources()) {
        // This check is to ensure that we don't fire the optimizer if it was previously applied.
        if (isAtMost(source, context.getLookup(), parent.getCount())) {
            builder.add(source);
        } else {
            shouldApply = true;
            builder.add(new LimitNode(context.getIdAllocator().getNextId(), source, parent.getCount(), true));
        }
    }
    if (!shouldApply) {
        return Result.empty();
    }
    return Result.ofPlanNode(parent.replaceChildren(ImmutableList.of(unionNode.replaceChildren(builder.build()))));
}
Also used : PlanNode(io.trino.sql.planner.plan.PlanNode) UnionNode(io.trino.sql.planner.plan.UnionNode) LimitNode(io.trino.sql.planner.plan.LimitNode) ImmutableList(com.google.common.collect.ImmutableList)

Example 10 with LimitNode

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

the class PushLimitThroughOffset method apply.

@Override
public Result apply(LimitNode parent, Captures captures, Context context) {
    OffsetNode child = captures.get(CHILD);
    long count;
    try {
        count = addExact(parent.getCount(), child.getCount());
    } catch (ArithmeticException e) {
        return Result.empty();
    }
    return Result.ofPlanNode(child.replaceChildren(ImmutableList.of(new LimitNode(parent.getId(), child.getSource(), count, parent.getTiesResolvingScheme(), parent.isPartial(), parent.getPreSortedInputs()))));
}
Also used : LimitNode(io.trino.sql.planner.plan.LimitNode) OffsetNode(io.trino.sql.planner.plan.OffsetNode)

Aggregations

LimitNode (io.trino.sql.planner.plan.LimitNode)12 PlanNode (io.trino.sql.planner.plan.PlanNode)6 Symbol (io.trino.sql.planner.Symbol)5 ProjectNode (io.trino.sql.planner.plan.ProjectNode)4 Expression (io.trino.sql.tree.Expression)4 ImmutableList (com.google.common.collect.ImmutableList)3 Assignments (io.trino.sql.planner.plan.Assignments)3 ImmutableSet (com.google.common.collect.ImmutableSet)2 Captures (io.trino.matching.Captures)2 Pattern (io.trino.matching.Pattern)2 TypeSignatureTranslator.toSqlType (io.trino.sql.analyzer.TypeSignatureTranslator.toSqlType)2 OrderingScheme (io.trino.sql.planner.OrderingScheme)2 Rule (io.trino.sql.planner.iterative.Rule)2 ComparisonExpression (io.trino.sql.tree.ComparisonExpression)2 Objects.requireNonNull (java.util.Objects.requireNonNull)2 Test (org.testng.annotations.Test)2 HashBiMap (com.google.common.collect.HashBiMap)1 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)1 ImmutableMap (com.google.common.collect.ImmutableMap)1 ImmutableMap.toImmutableMap (com.google.common.collect.ImmutableMap.toImmutableMap)1