Search in sources :

Example 6 with TopNNode

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

the class PushDownDereferencesThroughTopN method apply.

@Override
public Result apply(ProjectNode projectNode, Captures captures, Context context) {
    TopNNode topNNode = 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 orderBy
    dereferences = dereferences.stream().filter(expression -> !topNNode.getOrderingScheme().getOrderBy().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(), topNNode.replaceChildren(ImmutableList.of(new ProjectNode(context.getIdAllocator().getNextId(), topNNode.getSource(), Assignments.builder().putIdentities(topNNode.getSource().getOutputSymbols()).putAll(dereferenceAssignments).build()))), newAssignments));
}
Also used : Patterns.topN(io.trino.sql.planner.plan.Patterns.topN) 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) Assignments(io.trino.sql.planner.plan.Assignments) TopNNode(io.trino.sql.planner.plan.TopNNode) Set(java.util.Set) 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) ExpressionNodeInliner.replaceExpression(io.trino.sql.planner.ExpressionNodeInliner.replaceExpression) Expression(io.trino.sql.tree.Expression) Patterns.project(io.trino.sql.planner.plan.Patterns.project) SubscriptExpression(io.trino.sql.tree.SubscriptExpression) ExpressionNodeInliner.replaceExpression(io.trino.sql.planner.ExpressionNodeInliner.replaceExpression) Expression(io.trino.sql.tree.Expression) SymbolReference(io.trino.sql.tree.SymbolReference) Assignments(io.trino.sql.planner.plan.Assignments) 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) TopNNode(io.trino.sql.planner.plan.TopNNode)

Example 7 with TopNNode

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

the class PushTopNIntoTableScan method apply.

@Override
public Result apply(TopNNode topNNode, Captures captures, Context context) {
    TableScanNode tableScan = captures.get(TABLE_SCAN);
    long topNCount = topNNode.getCount();
    List<SortItem> sortItems = topNNode.getOrderingScheme().toSortItems();
    Map<String, ColumnHandle> assignments = tableScan.getAssignments().entrySet().stream().collect(toImmutableMap(entry -> entry.getKey().getName(), Map.Entry::getValue));
    return metadata.applyTopN(context.getSession(), tableScan.getTable(), topNCount, sortItems, assignments).map(result -> {
        PlanNode node = new TableScanNode(context.getIdAllocator().getNextId(), result.getHandle(), tableScan.getOutputSymbols(), tableScan.getAssignments(), TupleDomain.all(), deriveTableStatisticsForPushdown(context.getStatsProvider(), context.getSession(), result.isPrecalculateStatistics(), result.isTopNGuaranteed() ? topNNode : tableScan), tableScan.isUpdateTarget(), // table scan partitioning might have changed with new table handle
        Optional.empty());
        if (!result.isTopNGuaranteed()) {
            node = topNNode.replaceChildren(ImmutableList.of(node));
        }
        return Result.ofPlanNode(node);
    }).orElseGet(Result::empty);
}
Also used : Rules.deriveTableStatisticsForPushdown(io.trino.sql.planner.iterative.rule.Rules.deriveTableStatisticsForPushdown) SortItem(io.trino.spi.connector.SortItem) TopNNode(io.trino.sql.planner.plan.TopNNode) Patterns.topN(io.trino.sql.planner.plan.Patterns.topN) TupleDomain(io.trino.spi.predicate.TupleDomain) Patterns.tableScan(io.trino.sql.planner.plan.Patterns.tableScan) Capture.newCapture(io.trino.matching.Capture.newCapture) Capture(io.trino.matching.Capture) PlanNode(io.trino.sql.planner.plan.PlanNode) List(java.util.List) ImmutableMap.toImmutableMap(com.google.common.collect.ImmutableMap.toImmutableMap) Pattern(io.trino.matching.Pattern) SystemSessionProperties.isAllowPushdownIntoConnectors(io.trino.SystemSessionProperties.isAllowPushdownIntoConnectors) ImmutableList(com.google.common.collect.ImmutableList) Patterns.source(io.trino.sql.planner.plan.Patterns.source) Captures(io.trino.matching.Captures) Map(java.util.Map) Metadata(io.trino.metadata.Metadata) ColumnHandle(io.trino.spi.connector.ColumnHandle) Optional(java.util.Optional) Rule(io.trino.sql.planner.iterative.Rule) TableScanNode(io.trino.sql.planner.plan.TableScanNode) Session(io.trino.Session) ColumnHandle(io.trino.spi.connector.ColumnHandle) SortItem(io.trino.spi.connector.SortItem) PlanNode(io.trino.sql.planner.plan.PlanNode) TableScanNode(io.trino.sql.planner.plan.TableScanNode) ImmutableMap.toImmutableMap(com.google.common.collect.ImmutableMap.toImmutableMap) Map(java.util.Map)

Example 8 with TopNNode

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

the class PushTopNThroughProject method apply.

@Override
public Result apply(TopNNode parent, Captures captures, Context context) {
    ProjectNode projectNode = captures.get(PROJECT_CHILD);
    // Do not push down if the projection is made up of symbol references and exclusive dereferences. This prevents
    // undoing of PushDownDereferencesThroughTopN. We still push topN in the case of overlapping dereferences since
    // it enables PushDownDereferencesThroughTopN rule to push optimal dereferences.
    Set<Expression> projections = ImmutableSet.copyOf(projectNode.getAssignments().getExpressions());
    if (!extractRowSubscripts(projections, false, context.getSession(), typeAnalyzer, context.getSymbolAllocator().getTypes()).isEmpty() && exclusiveDereferences(projections, context.getSession(), typeAnalyzer, context.getSymbolAllocator().getTypes())) {
        return Result.empty();
    }
    // do not push topN between projection and filter(table scan) so that they can be merged into a PageProcessor
    PlanNode projectSource = context.getLookup().resolve(projectNode.getSource());
    if (projectSource instanceof FilterNode) {
        PlanNode filterSource = context.getLookup().resolve(((FilterNode) projectSource).getSource());
        if (filterSource instanceof TableScanNode) {
            return Result.empty();
        }
    }
    Optional<SymbolMapper> symbolMapper = symbolMapper(parent.getOrderingScheme().getOrderBy(), projectNode.getAssignments());
    if (symbolMapper.isEmpty()) {
        return Result.empty();
    }
    TopNNode mappedTopN = symbolMapper.get().map(parent, projectNode.getSource(), context.getIdAllocator().getNextId());
    return Result.ofPlanNode(projectNode.replaceChildren(ImmutableList.of(mappedTopN)));
}
Also used : PlanNode(io.trino.sql.planner.plan.PlanNode) TableScanNode(io.trino.sql.planner.plan.TableScanNode) Expression(io.trino.sql.tree.Expression) SymbolMapper(io.trino.sql.planner.optimizations.SymbolMapper) FilterNode(io.trino.sql.planner.plan.FilterNode) ProjectNode(io.trino.sql.planner.plan.ProjectNode) TopNNode(io.trino.sql.planner.plan.TopNNode)

Example 9 with TopNNode

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

the class TestEffectivePredicateExtractor method testTopN.

@Test
public void testTopN() {
    PlanNode node = new TopNNode(newId(), filter(baseTableScan, and(equals(AE, BE), equals(BE, CE), lessThan(CE, bigintLiteral(10)))), 1, new OrderingScheme(ImmutableList.of(A), ImmutableMap.of(A, SortOrder.ASC_NULLS_LAST)), TopNNode.Step.PARTIAL);
    Expression effectivePredicate = effectivePredicateExtractor.extract(SESSION, node, TypeProvider.empty(), typeAnalyzer);
    // Pass through
    assertEquals(normalizeConjuncts(effectivePredicate), normalizeConjuncts(equals(AE, BE), equals(BE, CE), lessThan(CE, bigintLiteral(10))));
}
Also used : PlanNode(io.trino.sql.planner.plan.PlanNode) InListExpression(io.trino.sql.tree.InListExpression) NotExpression(io.trino.sql.tree.NotExpression) ComparisonExpression(io.trino.sql.tree.ComparisonExpression) Expression(io.trino.sql.tree.Expression) TopNNode(io.trino.sql.planner.plan.TopNNode) Test(org.testng.annotations.Test)

Aggregations

TopNNode (io.trino.sql.planner.plan.TopNNode)9 PlanNode (io.trino.sql.planner.plan.PlanNode)5 Pattern (io.trino.matching.Pattern)4 ProjectNode (io.trino.sql.planner.plan.ProjectNode)4 Expression (io.trino.sql.tree.Expression)4 ImmutableList (com.google.common.collect.ImmutableList)3 Session (io.trino.Session)3 Captures (io.trino.matching.Captures)3 Rule (io.trino.sql.planner.iterative.Rule)3 Patterns.topN (io.trino.sql.planner.plan.Patterns.topN)3 List (java.util.List)3 Map (java.util.Map)3 Optional (java.util.Optional)3 ImmutableMap.toImmutableMap (com.google.common.collect.ImmutableMap.toImmutableMap)2 Capture (io.trino.matching.Capture)2 Capture.newCapture (io.trino.matching.Capture.newCapture)2 Metadata (io.trino.metadata.Metadata)2 Symbol (io.trino.sql.planner.Symbol)2 Lookup (io.trino.sql.planner.iterative.Lookup)2 Assignments (io.trino.sql.planner.plan.Assignments)2