Search in sources :

Example 51 with DynamicFilterId

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

the class TestDynamicFilterService method testDynamicFilterSummaryCompletion.

@Test
public void testDynamicFilterSummaryCompletion() {
    DynamicFilterService dynamicFilterService = createDynamicFilterService();
    DynamicFilterId filterId = new DynamicFilterId("df");
    QueryId queryId = new QueryId("query");
    StageId stageId = new StageId(queryId, 0);
    dynamicFilterService.registerQuery(queryId, session, ImmutableSet.of(filterId), ImmutableSet.of(filterId), ImmutableSet.of());
    dynamicFilterService.stageCannotScheduleMoreTasks(stageId, 0, 3);
    assertFalse(dynamicFilterService.getSummary(queryId, filterId).isPresent());
    // assert initial dynamic filtering stats
    DynamicFiltersStats stats = dynamicFilterService.getDynamicFilteringStats(queryId, session);
    assertEquals(stats.getTotalDynamicFilters(), 1);
    assertEquals(stats.getDynamicFiltersCompleted(), 0);
    assertEquals(stats.getLazyDynamicFilters(), 1);
    assertEquals(stats.getReplicatedDynamicFilters(), 0);
    dynamicFilterService.addTaskDynamicFilters(new TaskId(stageId, 0, 0), ImmutableMap.of(filterId, singleValue(INTEGER, 1L)));
    assertFalse(dynamicFilterService.getSummary(queryId, filterId).isPresent());
    stats = dynamicFilterService.getDynamicFilteringStats(queryId, session);
    assertEquals(stats.getDynamicFiltersCompleted(), 0);
    dynamicFilterService.addTaskDynamicFilters(new TaskId(stageId, 1, 0), ImmutableMap.of(filterId, singleValue(INTEGER, 2L)));
    assertFalse(dynamicFilterService.getSummary(queryId, filterId).isPresent());
    stats = dynamicFilterService.getDynamicFilteringStats(queryId, session);
    assertEquals(stats.getDynamicFiltersCompleted(), 0);
    dynamicFilterService.addTaskDynamicFilters(new TaskId(stageId, 2, 0), ImmutableMap.of(filterId, singleValue(INTEGER, 3L)));
    Optional<Domain> summary = dynamicFilterService.getSummary(queryId, filterId);
    assertTrue(summary.isPresent());
    assertEquals(summary.get(), multipleValues(INTEGER, ImmutableList.of(1L, 2L, 3L)));
    stats = dynamicFilterService.getDynamicFilteringStats(queryId, session);
    assertEquals(stats.getDynamicFiltersCompleted(), 1);
    assertEquals(stats.getLazyDynamicFilters(), 1);
    assertEquals(stats.getReplicatedDynamicFilters(), 0);
    assertEquals(stats.getDynamicFilterDomainStats(), ImmutableList.of(new DynamicFilterDomainStats(filterId, getSimplifiedDomainString(1L, 3L, 3, INTEGER))));
}
Also used : TaskId(io.trino.execution.TaskId) DynamicFilterDomainStats(io.trino.server.DynamicFilterService.DynamicFilterDomainStats) QueryId(io.trino.spi.QueryId) StageId(io.trino.execution.StageId) DynamicFiltersStats(io.trino.server.DynamicFilterService.DynamicFiltersStats) Domain(io.trino.spi.predicate.Domain) TupleDomain(io.trino.spi.predicate.TupleDomain) DynamicFilterId(io.trino.sql.planner.plan.DynamicFilterId) Test(org.testng.annotations.Test)

Example 52 with DynamicFilterId

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

the class DynamicFilterService method collectDynamicFilters.

private void collectDynamicFilters(StageId stageId, Optional<Set<DynamicFilterId>> selectedFilters) {
    DynamicFilterContext context = dynamicFilterContexts.get(stageId.getQueryId());
    if (context == null) {
        // query has been removed
        return;
    }
    OptionalInt stageNumberOfTasks = context.getNumberOfTasks(stageId);
    Map<DynamicFilterId, List<Domain>> newDynamicFilters = context.getTaskDynamicFilters(stageId, selectedFilters).entrySet().stream().filter(stageDomains -> {
        if (stageDomains.getValue().stream().anyMatch(Domain::isAll)) {
            // if one of the domains is all, we don't need to get dynamic filters from all tasks
            return true;
        }
        if (!stageDomains.getValue().isEmpty() && context.getReplicatedDynamicFilters().contains(stageDomains.getKey())) {
            // for replicated dynamic filters it's enough to get dynamic filter from a single task
            checkState(stageDomains.getValue().size() == 1, "Replicated dynamic filter should be collected from single task");
            return true;
        }
        // check if all tasks of a dynamic filter source have reported dynamic filter summary
        return stageNumberOfTasks.isPresent() && stageDomains.getValue().size() == stageNumberOfTasks.getAsInt();
    }).collect(toImmutableMap(Map.Entry::getKey, Map.Entry::getValue));
    context.addDynamicFilters(newDynamicFilters);
}
Also used : JsonProperty(com.fasterxml.jackson.annotation.JsonProperty) QueryId(io.trino.spi.QueryId) PlanFragment(io.trino.sql.planner.PlanFragment) EMPTY(io.trino.spi.connector.DynamicFilter.EMPTY) Inject(com.google.inject.Inject) DynamicFilters.extractDynamicFilters(io.trino.sql.DynamicFilters.extractDynamicFilters) Duration.succinctNanos(io.airlift.units.Duration.succinctNanos) Domain.union(io.trino.spi.predicate.Domain.union) TypeOperators(io.trino.spi.type.TypeOperators) SettableFuture(com.google.common.util.concurrent.SettableFuture) Duration(io.airlift.units.Duration) PlanNode(io.trino.sql.planner.plan.PlanNode) PreDestroy(javax.annotation.PreDestroy) Sets.difference(com.google.common.collect.Sets.difference) HashMultimap(com.google.common.collect.HashMultimap) DynamicFilters.extractSourceSymbols(io.trino.sql.DynamicFilters.extractSourceSymbols) DynamicFilters(io.trino.sql.DynamicFilters) PlanNodeSearcher(io.trino.sql.planner.optimizations.PlanNodeSearcher) Map(java.util.Map) Sets.union(com.google.common.collect.Sets.union) ExpressionExtractor.extractExpressions(io.trino.sql.planner.ExpressionExtractor.extractExpressions) JoinNode(io.trino.sql.planner.plan.JoinNode) Functions.identity(com.google.common.base.Functions.identity) ImmutableSet(com.google.common.collect.ImmutableSet) ImmutableMap(com.google.common.collect.ImmutableMap) Domain(io.trino.spi.predicate.Domain) Collection(java.util.Collection) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) SemiJoinNode(io.trino.sql.planner.plan.SemiJoinNode) ThreadSafe(javax.annotation.concurrent.ThreadSafe) GuardedBy(javax.annotation.concurrent.GuardedBy) TaskId(io.trino.execution.TaskId) JoinUtils(io.trino.operator.join.JoinUtils) String.format(java.lang.String.format) Preconditions.checkState(com.google.common.base.Preconditions.checkState) Objects(java.util.Objects) List(java.util.List) ImmutableMap.toImmutableMap(com.google.common.collect.ImmutableMap.toImmutableMap) SubPlan(io.trino.sql.planner.SubPlan) DynamicFilter(io.trino.spi.connector.DynamicFilter) Optional(java.util.Optional) MoreFutures.whenAnyComplete(io.airlift.concurrent.MoreFutures.whenAnyComplete) MoreFutures.unmodifiableFuture(io.airlift.concurrent.MoreFutures.unmodifiableFuture) Session(io.trino.Session) MoreObjects.toStringHelper(com.google.common.base.MoreObjects.toStringHelper) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) StageId(io.trino.execution.StageId) Type(io.trino.spi.type.Type) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) Multimap(com.google.common.collect.Multimap) OptionalInt(java.util.OptionalInt) AtomicReference(java.util.concurrent.atomic.AtomicReference) DynamicFilterId(io.trino.sql.planner.plan.DynamicFilterId) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) Threads.daemonThreadsNamed(io.airlift.concurrent.Threads.daemonThreadsNamed) Objects.requireNonNull(java.util.Objects.requireNonNull) ColumnHandle(io.trino.spi.connector.ColumnHandle) ImmutableSet.toImmutableSet(com.google.common.collect.ImmutableSet.toImmutableSet) DynamicFilterConfig(io.trino.execution.DynamicFilterConfig) ExecutorService(java.util.concurrent.ExecutorService) MoreFutures.toCompletableFuture(io.airlift.concurrent.MoreFutures.toCompletableFuture) Symbol(io.trino.sql.planner.Symbol) SqlQueryExecution(io.trino.execution.SqlQueryExecution) Sets.newConcurrentHashSet(com.google.common.collect.Sets.newConcurrentHashSet) ConnectorSession(io.trino.spi.connector.ConnectorSession) TupleDomain(io.trino.spi.predicate.TupleDomain) SetMultimap(com.google.common.collect.SetMultimap) Executors.newFixedThreadPool(java.util.concurrent.Executors.newFixedThreadPool) FunctionManager(io.trino.metadata.FunctionManager) Consumer(java.util.function.Consumer) MorePredicates.isInstanceOfAny(io.trino.util.MorePredicates.isInstanceOfAny) Sets.intersection(com.google.common.collect.Sets.intersection) DomainCoercer.applySaturatedCasts(io.trino.sql.planner.DomainCoercer.applySaturatedCasts) SOURCE_DISTRIBUTION(io.trino.sql.planner.SystemPartitioningHandle.SOURCE_DISTRIBUTION) JsonCreator(com.fasterxml.jackson.annotation.JsonCreator) Metadata(io.trino.metadata.Metadata) TypeProvider(io.trino.sql.planner.TypeProvider) VisibleForTesting(com.google.common.annotations.VisibleForTesting) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) List(java.util.List) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) OptionalInt(java.util.OptionalInt) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) ImmutableMap.toImmutableMap(com.google.common.collect.ImmutableMap.toImmutableMap) HashMap(java.util.HashMap) DynamicFilterId(io.trino.sql.planner.plan.DynamicFilterId)

Example 53 with DynamicFilterId

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

the class DynamicFilterService method registerQuery.

public void registerQuery(SqlQueryExecution sqlQueryExecution, SubPlan fragmentedPlan) {
    PlanNode queryPlan = sqlQueryExecution.getQueryPlan().getRoot();
    Set<DynamicFilterId> dynamicFilters = getProducedDynamicFilters(queryPlan);
    Set<DynamicFilterId> replicatedDynamicFilters = getReplicatedDynamicFilters(queryPlan);
    Set<DynamicFilterId> lazyDynamicFilters = fragmentedPlan.getAllFragments().stream().flatMap(plan -> getLazyDynamicFilters(plan).stream()).collect(toImmutableSet());
    // register query only if it contains dynamic filters
    if (!dynamicFilters.isEmpty()) {
        registerQuery(sqlQueryExecution.getQueryId(), sqlQueryExecution.getSession(), dynamicFilters, lazyDynamicFilters, replicatedDynamicFilters);
    }
}
Also used : JsonProperty(com.fasterxml.jackson.annotation.JsonProperty) QueryId(io.trino.spi.QueryId) PlanFragment(io.trino.sql.planner.PlanFragment) EMPTY(io.trino.spi.connector.DynamicFilter.EMPTY) Inject(com.google.inject.Inject) DynamicFilters.extractDynamicFilters(io.trino.sql.DynamicFilters.extractDynamicFilters) Duration.succinctNanos(io.airlift.units.Duration.succinctNanos) Domain.union(io.trino.spi.predicate.Domain.union) TypeOperators(io.trino.spi.type.TypeOperators) SettableFuture(com.google.common.util.concurrent.SettableFuture) Duration(io.airlift.units.Duration) PlanNode(io.trino.sql.planner.plan.PlanNode) PreDestroy(javax.annotation.PreDestroy) Sets.difference(com.google.common.collect.Sets.difference) HashMultimap(com.google.common.collect.HashMultimap) DynamicFilters.extractSourceSymbols(io.trino.sql.DynamicFilters.extractSourceSymbols) DynamicFilters(io.trino.sql.DynamicFilters) PlanNodeSearcher(io.trino.sql.planner.optimizations.PlanNodeSearcher) Map(java.util.Map) Sets.union(com.google.common.collect.Sets.union) ExpressionExtractor.extractExpressions(io.trino.sql.planner.ExpressionExtractor.extractExpressions) JoinNode(io.trino.sql.planner.plan.JoinNode) Functions.identity(com.google.common.base.Functions.identity) ImmutableSet(com.google.common.collect.ImmutableSet) ImmutableMap(com.google.common.collect.ImmutableMap) Domain(io.trino.spi.predicate.Domain) Collection(java.util.Collection) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) SemiJoinNode(io.trino.sql.planner.plan.SemiJoinNode) ThreadSafe(javax.annotation.concurrent.ThreadSafe) GuardedBy(javax.annotation.concurrent.GuardedBy) TaskId(io.trino.execution.TaskId) JoinUtils(io.trino.operator.join.JoinUtils) String.format(java.lang.String.format) Preconditions.checkState(com.google.common.base.Preconditions.checkState) Objects(java.util.Objects) List(java.util.List) ImmutableMap.toImmutableMap(com.google.common.collect.ImmutableMap.toImmutableMap) SubPlan(io.trino.sql.planner.SubPlan) DynamicFilter(io.trino.spi.connector.DynamicFilter) Optional(java.util.Optional) MoreFutures.whenAnyComplete(io.airlift.concurrent.MoreFutures.whenAnyComplete) MoreFutures.unmodifiableFuture(io.airlift.concurrent.MoreFutures.unmodifiableFuture) Session(io.trino.Session) MoreObjects.toStringHelper(com.google.common.base.MoreObjects.toStringHelper) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) StageId(io.trino.execution.StageId) Type(io.trino.spi.type.Type) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) Multimap(com.google.common.collect.Multimap) OptionalInt(java.util.OptionalInt) AtomicReference(java.util.concurrent.atomic.AtomicReference) DynamicFilterId(io.trino.sql.planner.plan.DynamicFilterId) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) Threads.daemonThreadsNamed(io.airlift.concurrent.Threads.daemonThreadsNamed) Objects.requireNonNull(java.util.Objects.requireNonNull) ColumnHandle(io.trino.spi.connector.ColumnHandle) ImmutableSet.toImmutableSet(com.google.common.collect.ImmutableSet.toImmutableSet) DynamicFilterConfig(io.trino.execution.DynamicFilterConfig) ExecutorService(java.util.concurrent.ExecutorService) MoreFutures.toCompletableFuture(io.airlift.concurrent.MoreFutures.toCompletableFuture) Symbol(io.trino.sql.planner.Symbol) SqlQueryExecution(io.trino.execution.SqlQueryExecution) Sets.newConcurrentHashSet(com.google.common.collect.Sets.newConcurrentHashSet) ConnectorSession(io.trino.spi.connector.ConnectorSession) TupleDomain(io.trino.spi.predicate.TupleDomain) SetMultimap(com.google.common.collect.SetMultimap) Executors.newFixedThreadPool(java.util.concurrent.Executors.newFixedThreadPool) FunctionManager(io.trino.metadata.FunctionManager) Consumer(java.util.function.Consumer) MorePredicates.isInstanceOfAny(io.trino.util.MorePredicates.isInstanceOfAny) Sets.intersection(com.google.common.collect.Sets.intersection) DomainCoercer.applySaturatedCasts(io.trino.sql.planner.DomainCoercer.applySaturatedCasts) SOURCE_DISTRIBUTION(io.trino.sql.planner.SystemPartitioningHandle.SOURCE_DISTRIBUTION) JsonCreator(com.fasterxml.jackson.annotation.JsonCreator) Metadata(io.trino.metadata.Metadata) TypeProvider(io.trino.sql.planner.TypeProvider) VisibleForTesting(com.google.common.annotations.VisibleForTesting) PlanNode(io.trino.sql.planner.plan.PlanNode) DynamicFilterId(io.trino.sql.planner.plan.DynamicFilterId)

Example 54 with DynamicFilterId

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

the class DynamicFilterService method getSourceStageInnerLazyDynamicFilters.

@VisibleForTesting
static Set<DynamicFilterId> getSourceStageInnerLazyDynamicFilters(PlanFragment plan) {
    if (!plan.getPartitioning().equals(SOURCE_DISTRIBUTION)) {
        // dynamic filtering collecting task can be added.
        return ImmutableSet.of();
    }
    PlanNode planNode = plan.getRoot();
    Set<DynamicFilterId> innerStageDynamicFilters = intersection(getProducedDynamicFilters(planNode), getConsumedDynamicFilters(planNode));
    Set<DynamicFilterId> replicatedDynamicFilters = getReplicatedDynamicFilters(planNode);
    return ImmutableSet.copyOf(intersection(innerStageDynamicFilters, replicatedDynamicFilters));
}
Also used : PlanNode(io.trino.sql.planner.plan.PlanNode) DynamicFilterId(io.trino.sql.planner.plan.DynamicFilterId) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 55 with DynamicFilterId

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

the class JoinMatcher method matchDynamicFilters.

private boolean matchDynamicFilters(JoinNode joinNode, SymbolAliases symbolAliases) {
    if (expectedDynamicFilter.isEmpty()) {
        return true;
    }
    Set<DynamicFilterId> dynamicFilterIds = joinNode.getDynamicFilters().keySet();
    List<DynamicFilters.Descriptor> descriptors = searchFrom(joinNode.getLeft()).where(FilterNode.class::isInstance).findAll().stream().flatMap(filterNode -> extractExpressions(filterNode).stream()).flatMap(expression -> extractDynamicFilters(expression).getDynamicConjuncts().stream()).filter(descriptor -> dynamicFilterIds.contains(descriptor.getId())).collect(toImmutableList());
    Map<DynamicFilterId, Symbol> idToBuildSymbolMap = joinNode.getDynamicFilters();
    Set<Expression> actual = new HashSet<>();
    for (DynamicFilters.Descriptor descriptor : descriptors) {
        Expression probe = descriptor.getInput();
        Symbol build = idToBuildSymbolMap.get(descriptor.getId());
        if (build == null) {
            return false;
        }
        Expression expression;
        if (descriptor.isNullAllowed()) {
            expression = new NotExpression(new ComparisonExpression(IS_DISTINCT_FROM, probe, build.toSymbolReference()));
        } else {
            expression = new ComparisonExpression(descriptor.getOperator(), probe, build.toSymbolReference());
        }
        actual.add(expression);
    }
    Set<Expression> expected = expectedDynamicFilter.get().stream().map(pattern -> pattern.getExpression(symbolAliases)).collect(toImmutableSet());
    return expected.equals(actual);
}
Also used : PlanNodeSearcher.searchFrom(io.trino.sql.planner.optimizations.PlanNodeSearcher.searchFrom) DynamicFilters.extractDynamicFilters(io.trino.sql.DynamicFilters.extractDynamicFilters) FilterNode(io.trino.sql.planner.plan.FilterNode) DynamicFilterId(io.trino.sql.planner.plan.DynamicFilterId) PlanNode(io.trino.sql.planner.plan.PlanNode) HashSet(java.util.HashSet) DynamicFilters(io.trino.sql.DynamicFilters) DistributionType(io.trino.sql.planner.plan.JoinNode.DistributionType) IS_DISTINCT_FROM(io.trino.sql.tree.ComparisonExpression.Operator.IS_DISTINCT_FROM) NotExpression(io.trino.sql.tree.NotExpression) Map(java.util.Map) Objects.requireNonNull(java.util.Objects.requireNonNull) ExpressionExtractor.extractExpressions(io.trino.sql.planner.ExpressionExtractor.extractExpressions) ImmutableSet.toImmutableSet(com.google.common.collect.ImmutableSet.toImmutableSet) DynamicFilterPattern(io.trino.sql.planner.assertions.PlanMatchPattern.DynamicFilterPattern) JoinNode(io.trino.sql.planner.plan.JoinNode) Symbol(io.trino.sql.planner.Symbol) ImmutableSet(com.google.common.collect.ImmutableSet) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) Set(java.util.Set) StatsProvider(io.trino.cost.StatsProvider) ComparisonExpression(io.trino.sql.tree.ComparisonExpression) Preconditions.checkState(com.google.common.base.Preconditions.checkState) List(java.util.List) Metadata(io.trino.metadata.Metadata) Optional(java.util.Optional) NO_MATCH(io.trino.sql.planner.assertions.MatchResult.NO_MATCH) Expression(io.trino.sql.tree.Expression) Session(io.trino.Session) MoreObjects.toStringHelper(com.google.common.base.MoreObjects.toStringHelper) Symbol(io.trino.sql.planner.Symbol) FilterNode(io.trino.sql.planner.plan.FilterNode) NotExpression(io.trino.sql.tree.NotExpression) ComparisonExpression(io.trino.sql.tree.ComparisonExpression) DynamicFilters.extractDynamicFilters(io.trino.sql.DynamicFilters.extractDynamicFilters) DynamicFilters(io.trino.sql.DynamicFilters) NotExpression(io.trino.sql.tree.NotExpression) ComparisonExpression(io.trino.sql.tree.ComparisonExpression) Expression(io.trino.sql.tree.Expression) DynamicFilterId(io.trino.sql.planner.plan.DynamicFilterId) HashSet(java.util.HashSet)

Aggregations

DynamicFilterId (io.trino.sql.planner.plan.DynamicFilterId)85 Test (org.testng.annotations.Test)73 PlanNode (io.trino.sql.planner.plan.PlanNode)32 BasePlanTest (io.trino.sql.planner.assertions.BasePlanTest)31 Symbol (io.trino.sql.planner.Symbol)29 TupleDomain (io.trino.spi.predicate.TupleDomain)26 DynamicFilter (io.trino.spi.connector.DynamicFilter)24 ColumnHandle (io.trino.spi.connector.ColumnHandle)21 TestingColumnHandle (io.trino.spi.connector.TestingColumnHandle)20 JoinNode (io.trino.sql.planner.plan.JoinNode)19 Domain (io.trino.spi.predicate.Domain)18 QueryId (io.trino.spi.QueryId)17 StageId (io.trino.execution.StageId)16 TaskId (io.trino.execution.TaskId)15 Page (io.trino.spi.Page)15 Map (java.util.Map)15 ImmutableMap (com.google.common.collect.ImmutableMap)14 Expression (io.trino.sql.tree.Expression)13 VerifyException (com.google.common.base.VerifyException)11 SymbolAllocator (io.trino.sql.planner.SymbolAllocator)11