Search in sources :

Example 1 with DynamicFilterId

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

the class DynamicFilterSourceOperator method finish.

@Override
public void finish() {
    if (finished) {
        // NOTE: finish() may be called multiple times (see comment at Driver::processInternal).
        return;
    }
    finished = true;
    ImmutableMap.Builder<DynamicFilterId, Domain> domainsBuilder = ImmutableMap.builder();
    if (valueSets == null) {
        if (minValues == null) {
            // else it was notified with 'all' in handleMinMaxCollectionLimitExceeded
            return;
        }
        // valueSets became too large, create TupleDomain from min/max values
        for (Integer channelIndex : minMaxChannels) {
            Type type = channels.get(channelIndex).type;
            if (minValues[channelIndex] == null) {
                // all values were null
                domainsBuilder.put(channels.get(channelIndex).filterId, Domain.none(type));
                continue;
            }
            Object min = readNativeValue(type, minValues[channelIndex], 0);
            Object max = readNativeValue(type, maxValues[channelIndex], 0);
            Domain domain = Domain.create(ValueSet.ofRanges(range(type, min, true, max, true)), false);
            domainsBuilder.put(channels.get(channelIndex).filterId, domain);
        }
        minValues = null;
        maxValues = null;
        dynamicPredicateConsumer.accept(TupleDomain.withColumnDomains(domainsBuilder.buildOrThrow()));
        return;
    }
    for (int channelIndex = 0; channelIndex < channels.size(); ++channelIndex) {
        Block block = blockBuilders[channelIndex].build();
        Type type = channels.get(channelIndex).type;
        domainsBuilder.put(channels.get(channelIndex).filterId, convertToDomain(type, block));
    }
    valueSets = null;
    blockBuilders = null;
    dynamicPredicateConsumer.accept(TupleDomain.withColumnDomains(domainsBuilder.buildOrThrow()));
}
Also used : Type(io.trino.spi.type.Type) Block(io.trino.spi.block.Block) Domain(io.trino.spi.predicate.Domain) TupleDomain(io.trino.spi.predicate.TupleDomain) ImmutableMap(com.google.common.collect.ImmutableMap) DynamicFilterId(io.trino.sql.planner.plan.DynamicFilterId)

Example 2 with DynamicFilterId

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

the class DynamicFilters method getDescriptor.

public static Optional<Descriptor> getDescriptor(Expression expression) {
    if (!(expression instanceof FunctionCall)) {
        return Optional.empty();
    }
    FunctionCall functionCall = (FunctionCall) expression;
    if (!isDynamicFilterFunction(functionCall)) {
        return Optional.empty();
    }
    List<Expression> arguments = functionCall.getArguments();
    checkArgument(arguments.size() == 4, "invalid arguments count: %s", arguments.size());
    Expression probeSymbol = arguments.get(0);
    Expression operatorExpression = arguments.get(1);
    checkArgument(operatorExpression instanceof StringLiteral, "operatorExpression is expected to be an instance of StringLiteral: %s", operatorExpression.getClass().getSimpleName());
    String operatorExpressionString = ((StringLiteral) operatorExpression).getValue();
    ComparisonExpression.Operator operator = ComparisonExpression.Operator.valueOf(operatorExpressionString);
    Expression idExpression = arguments.get(2);
    checkArgument(idExpression instanceof StringLiteral, "id is expected to be an instance of StringLiteral: %s", idExpression.getClass().getSimpleName());
    String id = ((StringLiteral) idExpression).getValue();
    Expression nullAllowedExpression = arguments.get(3);
    checkArgument(nullAllowedExpression instanceof BooleanLiteral, "nullAllowedExpression is expected to be an instance of BooleanLiteral: %s", nullAllowedExpression.getClass().getSimpleName());
    boolean nullAllowed = ((BooleanLiteral) nullAllowedExpression).getValue();
    return Optional.of(new Descriptor(new DynamicFilterId(id), probeSymbol, operator, nullAllowed));
}
Also used : ComparisonExpression(io.trino.sql.tree.ComparisonExpression) StringLiteral(io.trino.sql.tree.StringLiteral) ComparisonExpression(io.trino.sql.tree.ComparisonExpression) Expression(io.trino.sql.tree.Expression) BooleanLiteral(io.trino.sql.tree.BooleanLiteral) FunctionCall(io.trino.sql.tree.FunctionCall) DynamicFilterId(io.trino.sql.planner.plan.DynamicFilterId)

Example 3 with DynamicFilterId

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

the class DynamicFilterService method getDynamicFilteringStats.

public DynamicFiltersStats getDynamicFilteringStats(QueryId queryId, Session session) {
    DynamicFilterContext context = dynamicFilterContexts.get(queryId);
    if (context == null) {
        // query has been removed or dynamic filtering is not enabled
        return DynamicFiltersStats.EMPTY;
    }
    int lazyFilters = context.getLazyDynamicFilters().size();
    int replicatedFilters = context.getReplicatedDynamicFilters().size();
    int totalDynamicFilters = context.getTotalDynamicFilters();
    ConnectorSession connectorSession = session.toConnectorSession();
    List<DynamicFilterDomainStats> dynamicFilterDomainStats = context.getDynamicFilterSummaries().entrySet().stream().map(entry -> {
        DynamicFilterId dynamicFilterId = entry.getKey();
        return new DynamicFilterDomainStats(dynamicFilterId, // use small limit for readability
        entry.getValue().toString(connectorSession, 2), context.getDynamicFilterCollectionDuration(dynamicFilterId));
    }).collect(toImmutableList());
    return new DynamicFiltersStats(dynamicFilterDomainStats, lazyFilters, replicatedFilters, totalDynamicFilters, dynamicFilterDomainStats.size());
}
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) ConnectorSession(io.trino.spi.connector.ConnectorSession) DynamicFilterId(io.trino.sql.planner.plan.DynamicFilterId)

Example 4 with DynamicFilterId

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

the class TestSqlTask method testDynamicFilters.

@Test(timeOut = 30_000)
public void testDynamicFilters() throws Exception {
    SqlTask sqlTask = createInitialTask();
    sqlTask.updateTask(TEST_SESSION, Optional.of(PLAN_FRAGMENT), ImmutableList.of(new SplitAssignment(TABLE_SCAN_NODE_ID, ImmutableSet.of(SPLIT), false)), createInitialEmptyOutputBuffers(PARTITIONED).withBuffer(OUT, 0).withNoMoreBufferIds(), ImmutableMap.of());
    assertEquals(sqlTask.getTaskStatus().getDynamicFiltersVersion(), INITIAL_DYNAMIC_FILTERS_VERSION);
    TaskContext taskContext = sqlTask.getQueryContext().getTaskContextByTaskId(sqlTask.getTaskId());
    ListenableFuture<?> future = sqlTask.getTaskStatus(STARTING_VERSION);
    assertFalse(future.isDone());
    // make sure future gets unblocked when dynamic filters version is updated
    taskContext.updateDomains(ImmutableMap.of(new DynamicFilterId("filter"), Domain.none(BIGINT)));
    assertEquals(sqlTask.getTaskStatus().getVersion(), STARTING_VERSION + 1);
    assertEquals(sqlTask.getTaskStatus().getDynamicFiltersVersion(), INITIAL_DYNAMIC_FILTERS_VERSION + 1);
    future.get();
}
Also used : SqlTask.createSqlTask(io.trino.execution.SqlTask.createSqlTask) TaskContext(io.trino.operator.TaskContext) DynamicFilterId(io.trino.sql.planner.plan.DynamicFilterId) Test(org.testng.annotations.Test)

Example 5 with DynamicFilterId

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

the class TestDynamicFilterSourceOperator method testMultipleColumnsCollectMinMaxRangeWhenTooManyDistinctValues.

@Test
public void testMultipleColumnsCollectMinMaxRangeWhenTooManyDistinctValues() {
    int maxDistinctValues = 100;
    Page largePage = new Page(createLongSequenceBlock(0, 101), createColorRepeatBlock(100, 101), createLongRepeatBlock(200, 101));
    List<TupleDomain<DynamicFilterId>> expectedTupleDomains = ImmutableList.of(TupleDomain.withColumnDomains(ImmutableMap.of(new DynamicFilterId("0"), Domain.create(ValueSet.ofRanges(range(BIGINT, 0L, true, 100L, true)), false), new DynamicFilterId("2"), Domain.create(ValueSet.ofRanges(equal(BIGINT, 200L)), false))));
    assertDynamicFilters(maxDistinctValues, ImmutableList.of(BIGINT, COLOR, BIGINT), ImmutableList.of(largePage), expectedTupleDomains);
}
Also used : TupleDomain(io.trino.spi.predicate.TupleDomain) Page(io.trino.spi.Page) DynamicFilterId(io.trino.sql.planner.plan.DynamicFilterId) Test(org.testng.annotations.Test)

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