Search in sources :

Example 26 with ValuesNode

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

the class PushPredicateThroughProjectIntoRowNumber method apply.

@Override
public Result apply(FilterNode filter, Captures captures, Context context) {
    ProjectNode project = captures.get(PROJECT);
    RowNumberNode rowNumber = captures.get(ROW_NUMBER);
    Symbol rowNumberSymbol = rowNumber.getRowNumberSymbol();
    if (!project.getAssignments().getSymbols().contains(rowNumberSymbol)) {
        return Result.empty();
    }
    ExtractionResult extractionResult = DomainTranslator.getExtractionResult(plannerContext, context.getSession(), filter.getPredicate(), context.getSymbolAllocator().getTypes());
    TupleDomain<Symbol> tupleDomain = extractionResult.getTupleDomain();
    OptionalInt upperBound = extractUpperBound(tupleDomain, rowNumberSymbol);
    if (upperBound.isEmpty()) {
        return Result.empty();
    }
    if (upperBound.getAsInt() <= 0) {
        return Result.ofPlanNode(new ValuesNode(filter.getId(), filter.getOutputSymbols(), ImmutableList.of()));
    }
    boolean updatedMaxRowCountPerPartition = false;
    if (rowNumber.getMaxRowCountPerPartition().isEmpty() || rowNumber.getMaxRowCountPerPartition().get() > upperBound.getAsInt()) {
        rowNumber = new RowNumberNode(rowNumber.getId(), rowNumber.getSource(), rowNumber.getPartitionBy(), rowNumber.isOrderSensitive(), rowNumber.getRowNumberSymbol(), Optional.of(upperBound.getAsInt()), rowNumber.getHashSymbol());
        project = (ProjectNode) project.replaceChildren(ImmutableList.of(rowNumber));
        updatedMaxRowCountPerPartition = true;
    }
    if (!allRowNumberValuesInDomain(tupleDomain, rowNumberSymbol, rowNumber.getMaxRowCountPerPartition().get())) {
        if (updatedMaxRowCountPerPartition) {
            return Result.ofPlanNode(filter.replaceChildren(ImmutableList.of(project)));
        }
        return Result.empty();
    }
    // Remove the row number domain because it is absorbed into the node
    TupleDomain<Symbol> newTupleDomain = tupleDomain.filter((symbol, domain) -> !symbol.equals(rowNumberSymbol));
    Expression newPredicate = ExpressionUtils.combineConjuncts(plannerContext.getMetadata(), extractionResult.getRemainingExpression(), new DomainTranslator(plannerContext).toPredicate(context.getSession(), newTupleDomain));
    if (newPredicate.equals(TRUE_LITERAL)) {
        return Result.ofPlanNode(project);
    }
    return Result.ofPlanNode(new FilterNode(filter.getId(), project, newPredicate));
}
Also used : ValuesNode(io.trino.sql.planner.plan.ValuesNode) Expression(io.trino.sql.tree.Expression) Symbol(io.trino.sql.planner.Symbol) FilterNode(io.trino.sql.planner.plan.FilterNode) RowNumberNode(io.trino.sql.planner.plan.RowNumberNode) DomainTranslator(io.trino.sql.planner.DomainTranslator) ProjectNode(io.trino.sql.planner.plan.ProjectNode) ExtractionResult(io.trino.sql.planner.DomainTranslator.ExtractionResult) OptionalInt(java.util.OptionalInt)

Example 27 with ValuesNode

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

the class PushPredicateThroughProjectIntoWindow method apply.

@Override
public Result apply(FilterNode filter, Captures captures, Context context) {
    ProjectNode project = captures.get(PROJECT);
    WindowNode window = captures.get(WINDOW);
    Symbol rankingSymbol = getOnlyElement(window.getWindowFunctions().keySet());
    if (!project.getAssignments().getSymbols().contains(rankingSymbol)) {
        return Result.empty();
    }
    DomainTranslator.ExtractionResult extractionResult = DomainTranslator.getExtractionResult(plannerContext, context.getSession(), filter.getPredicate(), context.getSymbolAllocator().getTypes());
    TupleDomain<Symbol> tupleDomain = extractionResult.getTupleDomain();
    OptionalInt upperBound = extractUpperBound(tupleDomain, rankingSymbol);
    if (upperBound.isEmpty()) {
        return Result.empty();
    }
    if (upperBound.getAsInt() <= 0) {
        return Result.ofPlanNode(new ValuesNode(filter.getId(), filter.getOutputSymbols(), ImmutableList.of()));
    }
    RankingType rankingType = toTopNRankingType(window).orElseThrow();
    project = (ProjectNode) project.replaceChildren(ImmutableList.of(new TopNRankingNode(window.getId(), window.getSource(), window.getSpecification(), rankingType, rankingSymbol, upperBound.getAsInt(), false, Optional.empty())));
    if (!allRankingValuesInDomain(tupleDomain, rankingSymbol, upperBound.getAsInt())) {
        return Result.ofPlanNode(filter.replaceChildren(ImmutableList.of(project)));
    }
    // Remove the ranking 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(context.getSession(), newTupleDomain));
    if (newPredicate.equals(TRUE_LITERAL)) {
        return Result.ofPlanNode(project);
    }
    return Result.ofPlanNode(new FilterNode(filter.getId(), project, newPredicate));
}
Also used : WindowNode(io.trino.sql.planner.plan.WindowNode) ValuesNode(io.trino.sql.planner.plan.ValuesNode) Util.toTopNRankingType(io.trino.sql.planner.iterative.rule.Util.toTopNRankingType) RankingType(io.trino.sql.planner.plan.TopNRankingNode.RankingType) TopNRankingNode(io.trino.sql.planner.plan.TopNRankingNode) Expression(io.trino.sql.tree.Expression) Symbol(io.trino.sql.planner.Symbol) FilterNode(io.trino.sql.planner.plan.FilterNode) DomainTranslator(io.trino.sql.planner.DomainTranslator) ProjectNode(io.trino.sql.planner.plan.ProjectNode) OptionalInt(java.util.OptionalInt)

Example 28 with ValuesNode

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

the class PushdownFilterIntoRowNumber method apply.

@Override
public Result apply(FilterNode node, Captures captures, Context context) {
    Session session = context.getSession();
    TypeProvider types = context.getSymbolAllocator().getTypes();
    DomainTranslator.ExtractionResult extractionResult = DomainTranslator.getExtractionResult(plannerContext, session, node.getPredicate(), types);
    TupleDomain<Symbol> tupleDomain = extractionResult.getTupleDomain();
    RowNumberNode source = captures.get(CHILD);
    Symbol rowNumberSymbol = source.getRowNumberSymbol();
    OptionalInt upperBound = extractUpperBound(tupleDomain, rowNumberSymbol);
    if (upperBound.isEmpty()) {
        return Result.empty();
    }
    if (upperBound.getAsInt() <= 0) {
        return Result.ofPlanNode(new ValuesNode(node.getId(), node.getOutputSymbols(), ImmutableList.of()));
    }
    RowNumberNode merged = mergeLimit(source, upperBound.getAsInt());
    boolean needRewriteSource = !merged.getMaxRowCountPerPartition().equals(source.getMaxRowCountPerPartition());
    if (needRewriteSource) {
        source = merged;
    }
    if (!allRowNumberValuesInDomain(tupleDomain, rowNumberSymbol, source.getMaxRowCountPerPartition().get())) {
        if (needRewriteSource) {
            return Result.ofPlanNode(new FilterNode(node.getId(), source, node.getPredicate()));
        } else {
            return Result.empty();
        }
    }
    TupleDomain<Symbol> newTupleDomain = tupleDomain.filter((symbol, domain) -> !symbol.equals(rowNumberSymbol));
    Expression newPredicate = ExpressionUtils.combineConjuncts(plannerContext.getMetadata(), extractionResult.getRemainingExpression(), new DomainTranslator(plannerContext).toPredicate(session, newTupleDomain));
    if (newPredicate.equals(BooleanLiteral.TRUE_LITERAL)) {
        return Result.ofPlanNode(source);
    }
    if (!newPredicate.equals(node.getPredicate())) {
        return Result.ofPlanNode(new FilterNode(node.getId(), source, newPredicate));
    }
    return Result.empty();
}
Also used : ValuesNode(io.trino.sql.planner.plan.ValuesNode) Expression(io.trino.sql.tree.Expression) Symbol(io.trino.sql.planner.Symbol) FilterNode(io.trino.sql.planner.plan.FilterNode) TypeProvider(io.trino.sql.planner.TypeProvider) DomainTranslator(io.trino.sql.planner.DomainTranslator) RowNumberNode(io.trino.sql.planner.plan.RowNumberNode) OptionalInt(java.util.OptionalInt) Session(io.trino.Session)

Example 29 with ValuesNode

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

the class ReplaceJoinOverConstantWithProject method appendProjection.

private ProjectNode appendProjection(PlanNode source, List<Symbol> sourceOutputs, PlanNode constantSource, List<Symbol> constantOutputs, PlanNodeIdAllocator idAllocator) {
    ValuesNode values = (ValuesNode) constantSource;
    Row row = (Row) getOnlyElement(values.getRows().get());
    Map<Symbol, Expression> mapping = new HashMap<>();
    for (int i = 0; i < values.getOutputSymbols().size(); i++) {
        mapping.put(values.getOutputSymbols().get(i), row.getItems().get(i));
    }
    Assignments.Builder assignments = Assignments.builder().putIdentities(sourceOutputs);
    constantOutputs.stream().forEach(symbol -> assignments.put(symbol, mapping.get(symbol)));
    return new ProjectNode(idAllocator.getNextId(), source, assignments.build());
}
Also used : ValuesNode(io.trino.sql.planner.plan.ValuesNode) Expression(io.trino.sql.tree.Expression) HashMap(java.util.HashMap) Symbol(io.trino.sql.planner.Symbol) Assignments(io.trino.sql.planner.plan.Assignments) ProjectNode(io.trino.sql.planner.plan.ProjectNode) Row(io.trino.sql.tree.Row)

Example 30 with ValuesNode

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

the class RemoveEmptyUnionBranches method apply.

@Override
public Result apply(UnionNode node, Captures captures, Context context) {
    long emptyBranches = node.getSources().stream().filter(source -> isEmpty(source, context.getLookup())).count();
    if (emptyBranches == 0) {
        return Result.empty();
    }
    if (emptyBranches == node.getSources().size()) {
        return Result.ofPlanNode(new ValuesNode(node.getId(), node.getOutputSymbols(), ImmutableList.of()));
    }
    ImmutableList.Builder<PlanNode> newSourcesBuilder = ImmutableList.builder();
    ImmutableListMultimap.Builder<Symbol, Symbol> outputsToInputsBuilder = ImmutableListMultimap.builder();
    for (int i = 0; i < node.getSources().size(); i++) {
        PlanNode source = node.getSources().get(i);
        if (!isEmpty(source, context.getLookup())) {
            newSourcesBuilder.add(source);
            for (Symbol column : node.getOutputSymbols()) {
                outputsToInputsBuilder.put(column, node.getSymbolMapping().get(column).get(i));
            }
        }
    }
    List<PlanNode> newSources = newSourcesBuilder.build();
    ListMultimap<Symbol, Symbol> outputsToInputs = outputsToInputsBuilder.build();
    if (newSources.size() == 1) {
        Assignments.Builder assignments = Assignments.builder();
        outputsToInputs.entries().stream().forEach(entry -> assignments.put(entry.getKey(), entry.getValue().toSymbolReference()));
        return Result.ofPlanNode(new ProjectNode(node.getId(), newSources.get(0), assignments.build()));
    }
    return Result.ofPlanNode(new UnionNode(node.getId(), newSources, outputsToInputs, node.getOutputSymbols()));
}
Also used : Symbol(io.trino.sql.planner.Symbol) UnionNode(io.trino.sql.planner.plan.UnionNode) ListMultimap(com.google.common.collect.ListMultimap) Assignments(io.trino.sql.planner.plan.Assignments) QueryCardinalityUtil.isEmpty(io.trino.sql.planner.optimizations.QueryCardinalityUtil.isEmpty) PlanNode(io.trino.sql.planner.plan.PlanNode) List(java.util.List) Pattern(io.trino.matching.Pattern) ImmutableList(com.google.common.collect.ImmutableList) Captures(io.trino.matching.Captures) ImmutableListMultimap(com.google.common.collect.ImmutableListMultimap) Rule(io.trino.sql.planner.iterative.Rule) Patterns.union(io.trino.sql.planner.plan.Patterns.union) ValuesNode(io.trino.sql.planner.plan.ValuesNode) ProjectNode(io.trino.sql.planner.plan.ProjectNode) ValuesNode(io.trino.sql.planner.plan.ValuesNode) ImmutableList(com.google.common.collect.ImmutableList) Symbol(io.trino.sql.planner.Symbol) Assignments(io.trino.sql.planner.plan.Assignments) PlanNode(io.trino.sql.planner.plan.PlanNode) UnionNode(io.trino.sql.planner.plan.UnionNode) ImmutableListMultimap(com.google.common.collect.ImmutableListMultimap) ProjectNode(io.trino.sql.planner.plan.ProjectNode)

Aggregations

ValuesNode (io.trino.sql.planner.plan.ValuesNode)36 Symbol (io.trino.sql.planner.Symbol)25 Expression (io.trino.sql.tree.Expression)15 PlanNode (io.trino.sql.planner.plan.PlanNode)14 Test (org.testng.annotations.Test)12 Row (io.trino.sql.tree.Row)11 JoinNode (io.trino.sql.planner.plan.JoinNode)10 ProjectNode (io.trino.sql.planner.plan.ProjectNode)10 ImmutableList (com.google.common.collect.ImmutableList)9 PlanNodeIdAllocator (io.trino.sql.planner.PlanNodeIdAllocator)8 PlanBuilder (io.trino.sql.planner.iterative.rule.test.PlanBuilder)8 FilterNode (io.trino.sql.planner.plan.FilterNode)8 ImmutableMap (com.google.common.collect.ImmutableMap)7 Session (io.trino.Session)7 MultiJoinNode (io.trino.sql.planner.iterative.rule.ReorderJoins.MultiJoinNode)7 MultiJoinNode.toMultiJoinNode (io.trino.sql.planner.iterative.rule.ReorderJoins.MultiJoinNode.toMultiJoinNode)7 List (java.util.List)7 Type (io.trino.spi.type.Type)6 DomainTranslator (io.trino.sql.planner.DomainTranslator)6 Map (java.util.Map)6