Search in sources :

Example 46 with SelectorFilter

use of org.apache.druid.segment.filter.SelectorFilter in project druid by druid-io.

the class JoinFilterAnalyzer method rewriteSelectorFilter.

/**
 * Rewrites a selector filter on a join table into an IN filter on the base table.
 *
 * @param selectorFilter                    SelectorFilter to be rewritten
 * @param joinFilterPreAnalysis             The pre-analysis computed by {@link #computeJoinFilterPreAnalysis)}
 * @param pushDownVirtualColumnsForLhsExprs See comments on {@link #analyzeJoinFilterClause}
 *
 * @return A JoinFilterAnalysis that indicates how to handle the potentially rewritten filter
 */
private static JoinFilterAnalysis rewriteSelectorFilter(SelectorFilter selectorFilter, JoinFilterPreAnalysis joinFilterPreAnalysis, Map<Expr, VirtualColumn> pushDownVirtualColumnsForLhsExprs) {
    List<Filter> newFilters = new ArrayList<>();
    String filteringColumn = selectorFilter.getDimension();
    String filteringValue = selectorFilter.getValue();
    if (areSomeColumnsFromPostJoinVirtualColumns(joinFilterPreAnalysis.getPostJoinVirtualColumns(), selectorFilter.getRequiredColumns())) {
        return JoinFilterAnalysis.createNoPushdownFilterAnalysis(selectorFilter);
    }
    if (!joinFilterPreAnalysis.getJoinableClauses().areSomeColumnsFromJoin(selectorFilter.getRequiredColumns())) {
        return new JoinFilterAnalysis(false, selectorFilter, selectorFilter);
    }
    List<JoinFilterColumnCorrelationAnalysis> correlationAnalyses = joinFilterPreAnalysis.getCorrelationsByFilteringColumn().get(filteringColumn);
    if (correlationAnalyses == null) {
        return JoinFilterAnalysis.createNoPushdownFilterAnalysis(selectorFilter);
    }
    for (JoinFilterColumnCorrelationAnalysis correlationAnalysis : correlationAnalyses) {
        if (correlationAnalysis.supportsPushDown()) {
            Optional<Set<String>> correlatedValues = correlationAnalysis.getCorrelatedValuesMap().get(Pair.of(filteringColumn, filteringValue));
            if (!correlatedValues.isPresent()) {
                return JoinFilterAnalysis.createNoPushdownFilterAnalysis(selectorFilter);
            }
            Set<String> newFilterValues = correlatedValues.get();
            // in nothing => match nothing
            if (newFilterValues.isEmpty()) {
                return new JoinFilterAnalysis(true, selectorFilter, FalseFilter.instance());
            }
            for (String correlatedBaseColumn : correlationAnalysis.getBaseColumns()) {
                Filter rewrittenFilter = new InDimFilter(correlatedBaseColumn, newFilterValues).toFilter();
                newFilters.add(rewrittenFilter);
            }
            for (Expr correlatedBaseExpr : correlationAnalysis.getBaseExpressions()) {
                // We need to create a virtual column for the expressions when pushing down
                VirtualColumn pushDownVirtualColumn = pushDownVirtualColumnsForLhsExprs.computeIfAbsent(correlatedBaseExpr, (expr) -> {
                    String vcName = getCorrelatedBaseExprVirtualColumnName(pushDownVirtualColumnsForLhsExprs.size());
                    return new ExpressionVirtualColumn(vcName, correlatedBaseExpr, ColumnType.STRING);
                });
                Filter rewrittenFilter = new InDimFilter(pushDownVirtualColumn.getOutputName(), newFilterValues).toFilter();
                newFilters.add(rewrittenFilter);
            }
        }
    }
    if (newFilters.isEmpty()) {
        return JoinFilterAnalysis.createNoPushdownFilterAnalysis(selectorFilter);
    }
    return new JoinFilterAnalysis(true, selectorFilter, Filters.maybeAnd(newFilters).orElse(null));
}
Also used : ImmutableSet(com.google.common.collect.ImmutableSet) Set(java.util.Set) HashSet(java.util.HashSet) ArrayList(java.util.ArrayList) ExpressionVirtualColumn(org.apache.druid.segment.virtual.ExpressionVirtualColumn) Expr(org.apache.druid.math.expr.Expr) SelectorFilter(org.apache.druid.segment.filter.SelectorFilter) FalseFilter(org.apache.druid.segment.filter.FalseFilter) OrFilter(org.apache.druid.segment.filter.OrFilter) InDimFilter(org.apache.druid.query.filter.InDimFilter) Filter(org.apache.druid.query.filter.Filter) InDimFilter(org.apache.druid.query.filter.InDimFilter) VirtualColumn(org.apache.druid.segment.VirtualColumn) ExpressionVirtualColumn(org.apache.druid.segment.virtual.ExpressionVirtualColumn)

Example 47 with SelectorFilter

use of org.apache.druid.segment.filter.SelectorFilter in project druid by druid-io.

the class RhsRewriteCandidates method determineRhsRewriteCandidatesForSingleFilter.

private static Optional<RhsRewriteCandidate> determineRhsRewriteCandidatesForSingleFilter(Filter orClause, Equiconditions equiconditions, JoinableClauses joinableClauses) {
    // Currently, we only support rewrites of filters that operate on a single column for simplicity.
    if (equiconditions.doesFilterSupportDirectJoinFilterRewrite(orClause)) {
        String reqColumn = orClause.getRequiredColumns().iterator().next();
        JoinableClause joinableClause = joinableClauses.getColumnFromJoinIfExists(reqColumn);
        if (joinableClause != null) {
            return Optional.of(new RhsRewriteCandidate(joinableClause, reqColumn, null, true));
        }
    } else if (orClause instanceof SelectorFilter) {
        // this is a candidate for RHS filter rewrite, determine column correlations and correlated values
        String reqColumn = ((SelectorFilter) orClause).getDimension();
        String reqValue = ((SelectorFilter) orClause).getValue();
        JoinableClause joinableClause = joinableClauses.getColumnFromJoinIfExists(reqColumn);
        if (joinableClause != null) {
            return Optional.of(new RhsRewriteCandidate(joinableClause, reqColumn, reqValue, false));
        }
    }
    return Optional.empty();
}
Also used : SelectorFilter(org.apache.druid.segment.filter.SelectorFilter) JoinableClause(org.apache.druid.segment.join.JoinableClause)

Example 48 with SelectorFilter

use of org.apache.druid.segment.filter.SelectorFilter in project druid by druid-io.

the class ListFilteredVirtualColumnSelectorTest method testFilterListFilteredVirtualColumnAllowIndex.

@Test
public void testFilterListFilteredVirtualColumnAllowIndex() {
    ListFilteredVirtualColumn virtualColumn = new ListFilteredVirtualColumn(ALLOW_VIRTUAL_NAME, new DefaultDimensionSpec(COLUMN_NAME, COLUMN_NAME, ColumnType.STRING), ImmutableSet.of("b", "c"), true);
    ColumnSelector selector = EasyMock.createMock(ColumnSelector.class);
    ColumnHolder holder = EasyMock.createMock(ColumnHolder.class);
    BitmapIndex index = EasyMock.createMock(BitmapIndex.class);
    ImmutableBitmap bitmap = EasyMock.createMock(ImmutableBitmap.class);
    BitmapFactory bitmapFactory = EasyMock.createMock(BitmapFactory.class);
    EasyMock.expect(selector.getColumnHolder(COLUMN_NAME)).andReturn(holder).atLeastOnce();
    EasyMock.expect(holder.getBitmapIndex()).andReturn(index).atLeastOnce();
    EasyMock.expect(index.getCardinality()).andReturn(3).atLeastOnce();
    EasyMock.expect(index.getValue(0)).andReturn("a").atLeastOnce();
    EasyMock.expect(index.getValue(1)).andReturn("b").atLeastOnce();
    EasyMock.expect(index.getValue(2)).andReturn("c").atLeastOnce();
    EasyMock.expect(index.getBitmap(2)).andReturn(bitmap).once();
    EasyMock.expect(index.getBitmapFactory()).andReturn(bitmapFactory).once();
    EasyMock.expect(index.hasNulls()).andReturn(true).once();
    EasyMock.replay(selector, holder, index, bitmap, bitmapFactory);
    ColumnSelectorBitmapIndexSelector bitmapIndexSelector = new ColumnSelectorBitmapIndexSelector(new RoaringBitmapFactory(), VirtualColumns.create(Collections.singletonList(virtualColumn)), selector);
    SelectorFilter filter = new SelectorFilter(ALLOW_VIRTUAL_NAME, "a");
    Assert.assertTrue(filter.shouldUseBitmapIndex(bitmapIndexSelector));
    BitmapIndex listFilteredIndex = bitmapIndexSelector.getBitmapIndex(ALLOW_VIRTUAL_NAME);
    Assert.assertEquals(-1, listFilteredIndex.getIndex("a"));
    Assert.assertEquals(0, listFilteredIndex.getIndex("b"));
    Assert.assertEquals(1, listFilteredIndex.getIndex("c"));
    Assert.assertEquals(2, listFilteredIndex.getCardinality());
    Assert.assertEquals("b", listFilteredIndex.getValue(0));
    Assert.assertEquals("c", listFilteredIndex.getValue(1));
    Assert.assertEquals(bitmap, listFilteredIndex.getBitmap(1));
    Assert.assertEquals(bitmapFactory, listFilteredIndex.getBitmapFactory());
    Assert.assertTrue(listFilteredIndex.hasNulls());
    EasyMock.verify(selector, holder, index, bitmap, bitmapFactory);
}
Also used : ColumnSelectorBitmapIndexSelector(org.apache.druid.segment.ColumnSelectorBitmapIndexSelector) ColumnHolder(org.apache.druid.segment.column.ColumnHolder) SelectorFilter(org.apache.druid.segment.filter.SelectorFilter) ColumnSelector(org.apache.druid.segment.ColumnSelector) ImmutableBitmap(org.apache.druid.collections.bitmap.ImmutableBitmap) BitmapIndex(org.apache.druid.segment.column.BitmapIndex) BitmapFactory(org.apache.druid.collections.bitmap.BitmapFactory) RoaringBitmapFactory(org.apache.druid.collections.bitmap.RoaringBitmapFactory) RoaringBitmapFactory(org.apache.druid.collections.bitmap.RoaringBitmapFactory) DefaultDimensionSpec(org.apache.druid.query.dimension.DefaultDimensionSpec) InitializedNullHandlingTest(org.apache.druid.testing.InitializedNullHandlingTest) Test(org.junit.Test)

Aggregations

SelectorFilter (org.apache.druid.segment.filter.SelectorFilter)48 Filter (org.apache.druid.query.filter.Filter)44 OrFilter (org.apache.druid.segment.filter.OrFilter)41 Test (org.junit.Test)40 BoundDimFilter (org.apache.druid.query.filter.BoundDimFilter)39 AndFilter (org.apache.druid.segment.filter.AndFilter)39 BoundFilter (org.apache.druid.segment.filter.BoundFilter)39 ExpressionDimFilter (org.apache.druid.query.filter.ExpressionDimFilter)38 JoinFilterPreAnalysis (org.apache.druid.segment.join.filter.JoinFilterPreAnalysis)38 InDimFilter (org.apache.druid.query.filter.InDimFilter)37 FalseFilter (org.apache.druid.segment.filter.FalseFilter)37 JoinFilterSplit (org.apache.druid.segment.join.filter.JoinFilterSplit)34 IndexedTableJoinable (org.apache.druid.segment.join.table.IndexedTableJoinable)9 OrDimFilter (org.apache.druid.query.filter.OrDimFilter)7 SelectorDimFilter (org.apache.druid.query.filter.SelectorDimFilter)7 ExpressionVirtualColumn (org.apache.druid.segment.virtual.ExpressionVirtualColumn)7 Cursor (org.apache.druid.segment.Cursor)5 AndDimFilter (org.apache.druid.query.filter.AndDimFilter)4 DimFilter (org.apache.druid.query.filter.DimFilter)4 QueryableIndexStorageAdapter (org.apache.druid.segment.QueryableIndexStorageAdapter)4