use of io.trino.spi.connector.DynamicFilter in project trino by trinodb.
the class TestBackgroundHiveSplitLoader method testIncompleteDynamicFilterTimeout.
@Test(timeOut = 30_000)
public void testIncompleteDynamicFilterTimeout() throws Exception {
BackgroundHiveSplitLoader backgroundHiveSplitLoader = backgroundHiveSplitLoader(new DynamicFilter() {
@Override
public Set<ColumnHandle> getColumnsCovered() {
return ImmutableSet.of();
}
@Override
public CompletableFuture<?> isBlocked() {
return unmodifiableFuture(CompletableFuture.runAsync(() -> {
try {
TimeUnit.HOURS.sleep(1);
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
}));
}
@Override
public boolean isComplete() {
return false;
}
@Override
public boolean isAwaitable() {
return true;
}
@Override
public TupleDomain<ColumnHandle> getCurrentPredicate() {
return TupleDomain.all();
}
}, new Duration(1, SECONDS));
HiveSplitSource hiveSplitSource = hiveSplitSource(backgroundHiveSplitLoader);
backgroundHiveSplitLoader.start(hiveSplitSource);
assertEquals(drain(hiveSplitSource).size(), 2);
assertTrue(hiveSplitSource.isFinished());
}
use of io.trino.spi.connector.DynamicFilter in project trino by trinodb.
the class TestLocalDynamicFiltersCollector method testDynamicFilterCoercion.
@Test
public void testDynamicFilterCoercion() {
LocalDynamicFiltersCollector collector = new LocalDynamicFiltersCollector(TEST_SESSION);
DynamicFilterId filterId = new DynamicFilterId("filter");
collector.register(ImmutableSet.of(filterId));
SymbolAllocator symbolAllocator = new SymbolAllocator();
Symbol symbol = symbolAllocator.newSymbol("symbol", INTEGER);
ColumnHandle column = new TestingColumnHandle("column");
DynamicFilter filter = createDynamicFilter(collector, ImmutableList.of(new DynamicFilters.Descriptor(filterId, new Cast(symbol.toSymbolReference(), toSqlType(BIGINT)))), ImmutableMap.of(symbol, column), symbolAllocator.getTypes());
assertEquals(filter.getColumnsCovered(), Set.of(column), "columns covered");
// Filter is blocked and not completed.
CompletableFuture<?> isBlocked = filter.isBlocked();
assertFalse(filter.isComplete());
assertTrue(filter.isAwaitable());
assertFalse(isBlocked.isDone());
assertEquals(filter.getCurrentPredicate(), TupleDomain.all());
Domain domain = Domain.singleValue(BIGINT, 7L);
collector.collectDynamicFilterDomains(ImmutableMap.of(filterId, domain));
// Unblocked and completed.
assertTrue(filter.isComplete());
assertFalse(filter.isAwaitable());
assertTrue(isBlocked.isDone());
assertEquals(filter.getCurrentPredicate(), TupleDomain.withColumnDomains(ImmutableMap.of(column, Domain.singleValue(INTEGER, 7L))));
}
use of io.trino.spi.connector.DynamicFilter in project trino by trinodb.
the class TestLocalDynamicFiltersCollector method testMultipleBuildColumnsSingleProbeColumn.
@Test
public void testMultipleBuildColumnsSingleProbeColumn() {
LocalDynamicFiltersCollector collector = new LocalDynamicFiltersCollector(TEST_SESSION);
DynamicFilterId filter1 = new DynamicFilterId("filter1");
DynamicFilterId filter2 = new DynamicFilterId("filter2");
collector.register(ImmutableSet.of(filter1));
collector.register(ImmutableSet.of(filter2));
// Multiple build-side columns matching the same probe-side column.
SymbolAllocator symbolAllocator = new SymbolAllocator();
Symbol symbol = symbolAllocator.newSymbol("symbol", BIGINT);
ColumnHandle column = new TestingColumnHandle("column");
DynamicFilter filter = createDynamicFilter(collector, ImmutableList.of(new DynamicFilters.Descriptor(filter1, symbol.toSymbolReference()), new DynamicFilters.Descriptor(filter2, symbol.toSymbolReference())), ImmutableMap.of(symbol, column), symbolAllocator.getTypes());
assertEquals(filter.getColumnsCovered(), Set.of(column), "columns covered");
// Filter is blocking and not completed.
CompletableFuture<?> isBlocked = filter.isBlocked();
assertFalse(filter.isComplete());
assertTrue(filter.isAwaitable());
assertFalse(isBlocked.isDone());
assertEquals(filter.getCurrentPredicate(), TupleDomain.all());
collector.collectDynamicFilterDomains(ImmutableMap.of(filter1, Domain.multipleValues(BIGINT, ImmutableList.of(1L, 2L, 3L))));
// Unblocked, but not completed.
assertFalse(filter.isComplete());
assertTrue(filter.isAwaitable());
assertTrue(isBlocked.isDone());
assertEquals(filter.getCurrentPredicate(), TupleDomain.withColumnDomains(ImmutableMap.of(column, Domain.multipleValues(BIGINT, ImmutableList.of(1L, 2L, 3L)))));
// Create a new blocking future, waiting for next completion.
isBlocked = filter.isBlocked();
assertFalse(isBlocked.isDone());
assertFalse(filter.isComplete());
assertTrue(filter.isAwaitable());
collector.collectDynamicFilterDomains(ImmutableMap.of(filter2, Domain.multipleValues(BIGINT, ImmutableList.of(2L, 3L, 4L))));
// Unblocked and completed.
assertTrue(filter.isComplete());
assertFalse(filter.isAwaitable());
assertTrue(isBlocked.isDone());
assertEquals(filter.getCurrentPredicate(), TupleDomain.withColumnDomains(ImmutableMap.of(column, Domain.multipleValues(BIGINT, ImmutableList.of(2L, 3L)))));
}
use of io.trino.spi.connector.DynamicFilter in project trino by trinodb.
the class LocalDynamicFiltersCollector method createDynamicFilter.
// Called during TableScan planning (no need to be synchronized as local planning is single threaded)
public DynamicFilter createDynamicFilter(List<Descriptor> descriptors, Map<Symbol, ColumnHandle> columnsMap, TypeProvider typeProvider, PlannerContext plannerContext) {
Multimap<DynamicFilterId, Descriptor> descriptorMap = extractSourceSymbols(descriptors);
// Iterate over dynamic filters that are collected (correspond to one of the futures), and required for filtering (correspond to one of the descriptors).
// It is possible that some dynamic filters are collected in a different stage - and will not available here.
// It is also possible that not all local dynamic filters are needed for this specific table scan.
List<ListenableFuture<TupleDomain<ColumnHandle>>> predicateFutures = descriptorMap.keySet().stream().filter(futures.keySet()::contains).map(filterId -> {
// Probe-side columns that can be filtered with this dynamic filter resulting domain.
return Futures.transform(requireNonNull(futures.get(filterId), () -> format("Missing dynamic filter %s", filterId)), // Construct a probe-side predicate by duplicating the resulting domain over the corresponding columns.
domain -> TupleDomain.withColumnDomains(descriptorMap.get(filterId).stream().collect(toImmutableMap(descriptor -> {
Symbol probeSymbol = Symbol.from(descriptor.getInput());
return requireNonNull(columnsMap.get(probeSymbol), () -> format("Missing probe column for %s", probeSymbol));
}, descriptor -> {
Type targetType = typeProvider.get(Symbol.from(descriptor.getInput()));
Domain updatedDomain = descriptor.applyComparison(domain);
if (!updatedDomain.getType().equals(targetType)) {
return applySaturatedCasts(plannerContext.getMetadata(), plannerContext.getFunctionManager(), plannerContext.getTypeOperators(), session, updatedDomain, targetType);
}
return updatedDomain;
}))), directExecutor());
}).collect(toImmutableList());
Set<ColumnHandle> columnsCovered = descriptorMap.values().stream().map(Descriptor::getInput).map(Symbol::from).map(probeSymbol -> requireNonNull(columnsMap.get(probeSymbol), () -> "Missing probe column for " + probeSymbol)).collect(toImmutableSet());
return new TableSpecificDynamicFilter(columnsCovered, predicateFutures);
}
use of io.trino.spi.connector.DynamicFilter in project trino by trinodb.
the class TestDynamicFilterService method testMultipleColumnMapping.
@Test
public void testMultipleColumnMapping() {
DynamicFilterService dynamicFilterService = createDynamicFilterService();
DynamicFilterId filterId1 = new DynamicFilterId("df1");
SymbolAllocator symbolAllocator = new SymbolAllocator();
Symbol symbol1 = symbolAllocator.newSymbol("DF_SYMBOL1", INTEGER);
Symbol symbol2 = symbolAllocator.newSymbol("DF_SYMBOL2", INTEGER);
Expression df1 = symbol1.toSymbolReference();
Expression df2 = symbol2.toSymbolReference();
QueryId queryId = new QueryId("query");
StageId stageId1 = new StageId(queryId, 1);
dynamicFilterService.registerQuery(queryId, session, ImmutableSet.of(filterId1), ImmutableSet.of(filterId1), ImmutableSet.of());
dynamicFilterService.stageCannotScheduleMoreTasks(stageId1, 0, 1);
TestingColumnHandle column1 = new TestingColumnHandle("probeColumnA");
TestingColumnHandle column2 = new TestingColumnHandle("probeColumnB");
DynamicFilter dynamicFilter = dynamicFilterService.createDynamicFilter(queryId, ImmutableList.of(new DynamicFilters.Descriptor(filterId1, df1), new DynamicFilters.Descriptor(filterId1, df2)), ImmutableMap.of(symbol1, column1, symbol2, column2), symbolAllocator.getTypes());
assertEquals(dynamicFilter.getColumnsCovered(), Set.of(column1, column2), "columns covered");
Domain domain = singleValue(INTEGER, 1L);
dynamicFilterService.addTaskDynamicFilters(new TaskId(stageId1, 0, 0), ImmutableMap.of(filterId1, domain));
assertEquals(dynamicFilter.getCurrentPredicate(), TupleDomain.withColumnDomains(ImmutableMap.of(column1, domain, column2, domain)));
}
Aggregations