Search in sources :

Example 16 with FilterNode

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

the class SimpleFilterProjectSemiJoinStatsRule method calculate.

private Optional<PlanNodeStatsEstimate> calculate(FilterNode filterNode, SemiJoinNode semiJoinNode, StatsProvider statsProvider, Session session, TypeProvider types) {
    PlanNodeStatsEstimate sourceStats = statsProvider.getStats(semiJoinNode.getSource());
    PlanNodeStatsEstimate filteringSourceStats = statsProvider.getStats(semiJoinNode.getFilteringSource());
    Symbol filteringSourceJoinSymbol = semiJoinNode.getFilteringSourceJoinSymbol();
    Symbol sourceJoinSymbol = semiJoinNode.getSourceJoinSymbol();
    Optional<SemiJoinOutputFilter> semiJoinOutputFilter = extractSemiJoinOutputFilter(filterNode.getPredicate(), semiJoinNode.getSemiJoinOutput());
    if (semiJoinOutputFilter.isEmpty()) {
        return Optional.empty();
    }
    PlanNodeStatsEstimate semiJoinStats;
    if (semiJoinOutputFilter.get().isNegated()) {
        semiJoinStats = computeAntiJoin(sourceStats, filteringSourceStats, sourceJoinSymbol, filteringSourceJoinSymbol);
    } else {
        semiJoinStats = computeSemiJoin(sourceStats, filteringSourceStats, sourceJoinSymbol, filteringSourceJoinSymbol);
    }
    if (semiJoinStats.isOutputRowCountUnknown()) {
        return Optional.of(PlanNodeStatsEstimate.unknown());
    }
    // apply remaining predicate
    PlanNodeStatsEstimate filteredStats = filterStatsCalculator.filterStats(semiJoinStats, semiJoinOutputFilter.get().getRemainingPredicate(), session, types);
    if (filteredStats.isOutputRowCountUnknown()) {
        return Optional.of(semiJoinStats.mapOutputRowCount(rowCount -> rowCount * UNKNOWN_FILTER_COEFFICIENT));
    }
    return Optional.of(filteredStats);
}
Also used : Symbol(io.trino.sql.planner.Symbol) Iterables(com.google.common.collect.Iterables) Lookup(io.trino.sql.planner.iterative.Lookup) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) Patterns.filter(io.trino.sql.planner.plan.Patterns.filter) SemiJoinNode(io.trino.sql.planner.plan.SemiJoinNode) UNKNOWN_FILTER_COEFFICIENT(io.trino.cost.FilterStatsCalculator.UNKNOWN_FILTER_COEFFICIENT) FilterNode(io.trino.sql.planner.plan.FilterNode) PlanNode(io.trino.sql.planner.plan.PlanNode) SemiJoinStatsCalculator.computeSemiJoin(io.trino.cost.SemiJoinStatsCalculator.computeSemiJoin) List(java.util.List) Pattern(io.trino.matching.Pattern) SymbolReference(io.trino.sql.tree.SymbolReference) SemiJoinStatsCalculator.computeAntiJoin(io.trino.cost.SemiJoinStatsCalculator.computeAntiJoin) NotExpression(io.trino.sql.tree.NotExpression) Objects.requireNonNull(java.util.Objects.requireNonNull) Metadata(io.trino.metadata.Metadata) TypeProvider(io.trino.sql.planner.TypeProvider) Optional(java.util.Optional) Expression(io.trino.sql.tree.Expression) ExpressionUtils.extractConjuncts(io.trino.sql.ExpressionUtils.extractConjuncts) ExpressionUtils.combineConjuncts(io.trino.sql.ExpressionUtils.combineConjuncts) ProjectNode(io.trino.sql.planner.plan.ProjectNode) Session(io.trino.Session) Symbol(io.trino.sql.planner.Symbol)

Example 17 with FilterNode

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

the class RelationPlanner method addRowFilters.

public RelationPlan addRowFilters(Table node, RelationPlan plan, Function<Expression, Expression> predicateTransformation, Function<Table, Scope> accessControlScope) {
    List<Expression> filters = analysis.getRowFilters(node);
    if (filters.isEmpty()) {
        return plan;
    }
    PlanBuilder planBuilder = newPlanBuilder(plan, analysis, lambdaDeclarationToSymbolMap).withScope(accessControlScope.apply(node), // The fields in the access control scope has the same layout as those for the table scope
    plan.getFieldMappings());
    for (Expression filter : filters) {
        planBuilder = subqueryPlanner.handleSubqueries(planBuilder, filter, analysis.getSubqueries(filter));
        Expression predicate = planBuilder.rewrite(filter);
        predicate = predicateTransformation.apply(predicate);
        planBuilder = planBuilder.withNewRoot(new FilterNode(idAllocator.getNextId(), planBuilder.getRoot(), predicate));
    }
    return new RelationPlan(planBuilder.getRoot(), plan.getScope(), plan.getFieldMappings(), outerContext);
}
Also used : ComparisonExpression(io.trino.sql.tree.ComparisonExpression) CoalesceExpression(io.trino.sql.tree.CoalesceExpression) Expression(io.trino.sql.tree.Expression) SubqueryExpression(io.trino.sql.tree.SubqueryExpression) FilterNode(io.trino.sql.planner.plan.FilterNode) PlanBuilder.newPlanBuilder(io.trino.sql.planner.PlanBuilder.newPlanBuilder)

Example 18 with FilterNode

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

the class FilterMatcher method detailMatches.

@Override
public MatchResult detailMatches(PlanNode node, StatsProvider stats, Session session, Metadata metadata, SymbolAliases symbolAliases) {
    checkState(shapeMatches(node), "Plan testing framework error: shapeMatches returned false in detailMatches in %s", this.getClass().getName());
    FilterNode filterNode = (FilterNode) node;
    Expression filterPredicate = filterNode.getPredicate();
    ExpressionVerifier verifier = new ExpressionVerifier(symbolAliases);
    if (dynamicFilter.isPresent()) {
        return new MatchResult(verifier.process(filterPredicate, combineConjuncts(metadata, predicate, dynamicFilter.get())));
    }
    DynamicFilters.ExtractResult extractResult = extractDynamicFilters(filterPredicate);
    return new MatchResult(verifier.process(combineConjuncts(metadata, extractResult.getStaticConjuncts()), predicate));
}
Also used : DynamicFilters.extractDynamicFilters(io.trino.sql.DynamicFilters.extractDynamicFilters) DynamicFilters(io.trino.sql.DynamicFilters) Expression(io.trino.sql.tree.Expression) FilterNode(io.trino.sql.planner.plan.FilterNode)

Example 19 with FilterNode

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

the class TestRuleIndex method testWithPlanNodeHierarchy.

@Test
public void testWithPlanNodeHierarchy() {
    Rule<?> projectRule1 = new NoOpRule<>(Pattern.typeOf(ProjectNode.class));
    Rule<?> projectRule2 = new NoOpRule<>(Pattern.typeOf(ProjectNode.class));
    Rule<?> filterRule = new NoOpRule<>(Pattern.typeOf(FilterNode.class));
    Rule<?> anyRule = new NoOpRule<>(Pattern.any());
    RuleIndex ruleIndex = RuleIndex.builder().register(projectRule1).register(projectRule2).register(filterRule).register(anyRule).build();
    ProjectNode projectNode = planBuilder.project(Assignments.of(), planBuilder.values());
    FilterNode filterNode = planBuilder.filter(BooleanLiteral.TRUE_LITERAL, planBuilder.values());
    ValuesNode valuesNode = planBuilder.values();
    assertEquals(ruleIndex.getCandidates(projectNode).collect(toSet()), ImmutableSet.of(projectRule1, projectRule2, anyRule));
    assertEquals(ruleIndex.getCandidates(filterNode).collect(toSet()), ImmutableSet.of(filterRule, anyRule));
    assertEquals(ruleIndex.getCandidates(valuesNode).collect(toSet()), ImmutableSet.of(anyRule));
}
Also used : ValuesNode(io.trino.sql.planner.plan.ValuesNode) FilterNode(io.trino.sql.planner.plan.FilterNode) ProjectNode(io.trino.sql.planner.plan.ProjectNode) Test(org.testng.annotations.Test)

Example 20 with FilterNode

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

the class SemiJoinMatcher method detailMatches.

@Override
public MatchResult detailMatches(PlanNode node, StatsProvider stats, Session session, Metadata metadata, SymbolAliases symbolAliases) {
    checkState(shapeMatches(node), "Plan testing framework error: shapeMatches returned false in detailMatches in %s", this.getClass().getName());
    SemiJoinNode semiJoinNode = (SemiJoinNode) node;
    if (!(symbolAliases.get(sourceSymbolAlias).equals(semiJoinNode.getSourceJoinSymbol().toSymbolReference()) && symbolAliases.get(filteringSymbolAlias).equals(semiJoinNode.getFilteringSourceJoinSymbol().toSymbolReference()))) {
        return NO_MATCH;
    }
    if (distributionType.isPresent() && !distributionType.equals(semiJoinNode.getDistributionType())) {
        return NO_MATCH;
    }
    if (hasDynamicFilter.isPresent()) {
        if (hasDynamicFilter.get()) {
            if (semiJoinNode.getDynamicFilterId().isEmpty()) {
                return NO_MATCH;
            }
            DynamicFilterId dynamicFilterId = semiJoinNode.getDynamicFilterId().get();
            List<DynamicFilters.Descriptor> matchingDescriptors = searchFrom(semiJoinNode.getSource()).where(FilterNode.class::isInstance).findAll().stream().flatMap(filterNode -> extractExpressions(filterNode).stream()).flatMap(expression -> extractDynamicFilters(expression).getDynamicConjuncts().stream()).filter(descriptor -> descriptor.getId().equals(dynamicFilterId)).collect(toImmutableList());
            boolean sourceSymbolsMatch = matchingDescriptors.stream().map(descriptor -> Symbol.from(descriptor.getInput())).allMatch(sourceSymbol -> symbolAliases.get(sourceSymbolAlias).equals(sourceSymbol.toSymbolReference()));
            if (!matchingDescriptors.isEmpty() && sourceSymbolsMatch) {
                return match(outputAlias, semiJoinNode.getSemiJoinOutput().toSymbolReference());
            }
            return NO_MATCH;
        }
        if (semiJoinNode.getDynamicFilterId().isPresent()) {
            return NO_MATCH;
        }
    }
    return match(outputAlias, semiJoinNode.getSemiJoinOutput().toSymbolReference());
}
Also used : Symbol(io.trino.sql.planner.Symbol) MatchResult.match(io.trino.sql.planner.assertions.MatchResult.match) PlanNodeSearcher.searchFrom(io.trino.sql.planner.optimizations.PlanNodeSearcher.searchFrom) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) DynamicFilters.extractDynamicFilters(io.trino.sql.DynamicFilters.extractDynamicFilters) SemiJoinNode(io.trino.sql.planner.plan.SemiJoinNode) StatsProvider(io.trino.cost.StatsProvider) FilterNode(io.trino.sql.planner.plan.FilterNode) DynamicFilterId(io.trino.sql.planner.plan.DynamicFilterId) PlanNode(io.trino.sql.planner.plan.PlanNode) Preconditions.checkState(com.google.common.base.Preconditions.checkState) List(java.util.List) DynamicFilters(io.trino.sql.DynamicFilters) Objects.requireNonNull(java.util.Objects.requireNonNull) ExpressionExtractor.extractExpressions(io.trino.sql.planner.ExpressionExtractor.extractExpressions) Metadata(io.trino.metadata.Metadata) Optional(java.util.Optional) NO_MATCH(io.trino.sql.planner.assertions.MatchResult.NO_MATCH) Session(io.trino.Session) MoreObjects.toStringHelper(com.google.common.base.MoreObjects.toStringHelper) FilterNode(io.trino.sql.planner.plan.FilterNode) SemiJoinNode(io.trino.sql.planner.plan.SemiJoinNode) DynamicFilterId(io.trino.sql.planner.plan.DynamicFilterId)

Aggregations

FilterNode (io.trino.sql.planner.plan.FilterNode)46 Expression (io.trino.sql.tree.Expression)33 PlanNode (io.trino.sql.planner.plan.PlanNode)20 ProjectNode (io.trino.sql.planner.plan.ProjectNode)20 Symbol (io.trino.sql.planner.Symbol)19 TableScanNode (io.trino.sql.planner.plan.TableScanNode)19 ComparisonExpression (io.trino.sql.tree.ComparisonExpression)19 ImmutableList (com.google.common.collect.ImmutableList)16 JoinNode (io.trino.sql.planner.plan.JoinNode)14 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)13 Session (io.trino.Session)11 ColumnHandle (io.trino.spi.connector.ColumnHandle)11 Test (org.testng.annotations.Test)10 SemiJoinNode (io.trino.sql.planner.plan.SemiJoinNode)9 NotExpression (io.trino.sql.tree.NotExpression)9 Map (java.util.Map)9 ValuesNode (io.trino.sql.planner.plan.ValuesNode)8 DomainTranslator (io.trino.sql.planner.DomainTranslator)7 List (java.util.List)7 InListExpression (io.trino.sql.tree.InListExpression)6