Search in sources :

Example 1 with SelectorFilter

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

the class JoinFilterAnalyzer method rewriteOrFilter.

/**
 * Potentially rewrite the subfilters of an OR filter so that the whole OR filter can be pushed down to
 * the base table.
 *
 * @param orFilter                          OrFilter to be rewritten
 * @param joinFilterPreAnalysis             The pre-analysis computed by {@link #computeJoinFilterPreAnalysis)}
 * @param pushDownVirtualColumnsForLhsExprs See comments on {@link #analyzeJoinFilterClause}
 *
 * @return A JoinFilterAnalysis indicating how to handle the potentially rewritten filter
 */
private static JoinFilterAnalysis rewriteOrFilter(OrFilter orFilter, JoinFilterPreAnalysis joinFilterPreAnalysis, Map<Expr, VirtualColumn> pushDownVirtualColumnsForLhsExprs) {
    List<Filter> newFilters = new ArrayList<>();
    boolean retainRhs = false;
    for (Filter filter : orFilter.getFilters()) {
        if (!joinFilterPreAnalysis.getJoinableClauses().areSomeColumnsFromJoin(filter.getRequiredColumns())) {
            newFilters.add(filter);
            continue;
        }
        JoinFilterAnalysis rewritten = null;
        if (joinFilterPreAnalysis.getEquiconditions().doesFilterSupportDirectJoinFilterRewrite(filter)) {
            rewritten = rewriteFilterDirect(filter, joinFilterPreAnalysis, pushDownVirtualColumnsForLhsExprs);
        } else if (filter instanceof SelectorFilter) {
            retainRhs = true;
            // We could optimize retainRhs handling further by introducing a "filter to retain" property to the
            // analysis, and only keeping the subfilters that need to be retained
            rewritten = rewriteSelectorFilter((SelectorFilter) filter, joinFilterPreAnalysis, pushDownVirtualColumnsForLhsExprs);
        }
        if (rewritten == null || !rewritten.isCanPushDown()) {
            return JoinFilterAnalysis.createNoPushdownFilterAnalysis(orFilter);
        } else {
            // noinspection OptionalGetWithoutIsPresent isCanPushDown checks isPresent
            newFilters.add(rewritten.getPushDownFilter().get());
        }
    }
    return new JoinFilterAnalysis(retainRhs, orFilter, Filters.maybeOr(newFilters).orElse(null));
}
Also used : SelectorFilter(org.apache.druid.segment.filter.SelectorFilter) 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) ArrayList(java.util.ArrayList)

Example 2 with SelectorFilter

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

the class JoinFilterAnalyzerTest method test_filterPushDown_factToRegionFilterOnRHSRegionNameExprVirtualColumn.

@Test
public void test_filterPushDown_factToRegionFilterOnRHSRegionNameExprVirtualColumn() {
    // If our query had a filter that uses expressions, such as upper(r1.regionName) == 'VIRGINIA', this plans into
    // a selector filter on an ExpressionVirtualColumn
    Filter originalFilter = new SelectorFilter("v0", "VIRGINIA");
    VirtualColumns virtualColumns = VirtualColumns.create(ImmutableList.of(new ExpressionVirtualColumn("v0", "upper(\"r1.regionName\")", ColumnType.STRING, TestExprMacroTable.INSTANCE)));
    JoinableClauses joinableClauses = JoinableClauses.fromList(ImmutableList.of(factToRegion(JoinType.LEFT)));
    JoinFilterPreAnalysis joinFilterPreAnalysis = makeDefaultConfigPreAnalysis(originalFilter, joinableClauses.getJoinableClauses(), virtualColumns);
    HashJoinSegmentStorageAdapter adapter = new HashJoinSegmentStorageAdapter(factSegment.asStorageAdapter(), joinableClauses.getJoinableClauses(), joinFilterPreAnalysis);
    JoinTestHelper.verifyCursors(adapter.makeCursors(originalFilter, Intervals.ETERNITY, virtualColumns, Granularities.ALL, false, null), ImmutableList.of("page", "v0"), ImmutableList.of(new Object[] { "Old Anatolian Turkish", "VIRGINIA" }));
    JoinFilterSplit expectedFilterSplit = new JoinFilterSplit(null, new SelectorFilter("v0", "VIRGINIA"), ImmutableSet.of());
    JoinFilterSplit actualFilterSplit = JoinFilterAnalyzer.splitFilter(joinFilterPreAnalysis);
    Assert.assertEquals(expectedFilterSplit, actualFilterSplit);
}
Also used : SelectorFilter(org.apache.druid.segment.filter.SelectorFilter) ExpressionVirtualColumn(org.apache.druid.segment.virtual.ExpressionVirtualColumn) JoinFilterPreAnalysis(org.apache.druid.segment.join.filter.JoinFilterPreAnalysis) FalseFilter(org.apache.druid.segment.filter.FalseFilter) OrFilter(org.apache.druid.segment.filter.OrFilter) BoundDimFilter(org.apache.druid.query.filter.BoundDimFilter) SelectorFilter(org.apache.druid.segment.filter.SelectorFilter) AndFilter(org.apache.druid.segment.filter.AndFilter) BoundFilter(org.apache.druid.segment.filter.BoundFilter) InDimFilter(org.apache.druid.query.filter.InDimFilter) ExpressionDimFilter(org.apache.druid.query.filter.ExpressionDimFilter) Filter(org.apache.druid.query.filter.Filter) JoinFilterSplit(org.apache.druid.segment.join.filter.JoinFilterSplit) VirtualColumns(org.apache.druid.segment.VirtualColumns) JoinableClauses(org.apache.druid.segment.join.filter.JoinableClauses) Test(org.junit.Test)

Example 3 with SelectorFilter

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

the class JoinFilterAnalyzerTest method test_filterPushDown_factToRegionToCountryLeftEnablePushDownDisableRewrite.

@Test
public void test_filterPushDown_factToRegionToCountryLeftEnablePushDownDisableRewrite() {
    JoinableClauses joinableClauses = JoinableClauses.fromList(ImmutableList.of(factToRegion(JoinType.LEFT), regionToCountry(JoinType.LEFT)));
    Filter originalFilter = new AndFilter(ImmutableList.of(new SelectorFilter("channel", "#en.wikipedia"), new SelectorFilter("rtc.countryName", "United States"), new OrFilter(ImmutableList.of(new SelectorFilter("page", "DirecTV"), new SelectorFilter("rtc.countryIsoCode", "US"))), new BoundFilter(new BoundDimFilter("namespace", "Main", "Main", false, false, null, null, null))));
    JoinFilterPreAnalysis joinFilterPreAnalysis = JoinFilterAnalyzer.computeJoinFilterPreAnalysis(new JoinFilterPreAnalysisKey(new JoinFilterRewriteConfig(true, false, true, QueryContexts.DEFAULT_ENABLE_REWRITE_JOIN_TO_FILTER, QueryContexts.DEFAULT_ENABLE_JOIN_FILTER_REWRITE_MAX_SIZE), joinableClauses.getJoinableClauses(), VirtualColumns.EMPTY, originalFilter));
    HashJoinSegmentStorageAdapter adapter = new HashJoinSegmentStorageAdapter(factSegment.asStorageAdapter(), joinableClauses.getJoinableClauses(), joinFilterPreAnalysis);
    JoinTestHelper.verifyCursors(adapter.makeCursors(originalFilter, Intervals.ETERNITY, VirtualColumns.EMPTY, Granularities.ALL, false, null), ImmutableList.of("page", FACT_TO_REGION_PREFIX + "regionName", REGION_TO_COUNTRY_PREFIX + "countryName"), ImmutableList.of(new Object[] { "President of India", "California", "United States" }, new Object[] { "Otjiwarongo Airport", "California", "United States" }, new Object[] { "DirecTV", "North Carolina", "United States" }, new Object[] { "Carlo Curti", "California", "United States" }, new Object[] { "Old Anatolian Turkish", "Virginia", "United States" }));
    JoinFilterSplit expectedFilterSplit = new JoinFilterSplit(new AndFilter(ImmutableList.of(new SelectorFilter("channel", "#en.wikipedia"), new BoundFilter(new BoundDimFilter("namespace", "Main", "Main", false, false, null, null, null)))), new AndFilter(ImmutableList.of(new SelectorFilter("rtc.countryName", "United States"), new OrFilter(ImmutableList.of(new SelectorFilter("page", "DirecTV"), new SelectorFilter("rtc.countryIsoCode", "US"))))), ImmutableSet.of());
    JoinFilterSplit actualFilterSplit = JoinFilterAnalyzer.splitFilter(joinFilterPreAnalysis);
    Assert.assertEquals(expectedFilterSplit, actualFilterSplit);
}
Also used : BoundDimFilter(org.apache.druid.query.filter.BoundDimFilter) BoundFilter(org.apache.druid.segment.filter.BoundFilter) JoinFilterPreAnalysisKey(org.apache.druid.segment.join.filter.JoinFilterPreAnalysisKey) JoinFilterSplit(org.apache.druid.segment.join.filter.JoinFilterSplit) OrFilter(org.apache.druid.segment.filter.OrFilter) JoinFilterRewriteConfig(org.apache.druid.segment.join.filter.rewrite.JoinFilterRewriteConfig) AndFilter(org.apache.druid.segment.filter.AndFilter) SelectorFilter(org.apache.druid.segment.filter.SelectorFilter) JoinFilterPreAnalysis(org.apache.druid.segment.join.filter.JoinFilterPreAnalysis) FalseFilter(org.apache.druid.segment.filter.FalseFilter) OrFilter(org.apache.druid.segment.filter.OrFilter) BoundDimFilter(org.apache.druid.query.filter.BoundDimFilter) SelectorFilter(org.apache.druid.segment.filter.SelectorFilter) AndFilter(org.apache.druid.segment.filter.AndFilter) BoundFilter(org.apache.druid.segment.filter.BoundFilter) InDimFilter(org.apache.druid.query.filter.InDimFilter) ExpressionDimFilter(org.apache.druid.query.filter.ExpressionDimFilter) Filter(org.apache.druid.query.filter.Filter) JoinableClauses(org.apache.druid.segment.join.filter.JoinableClauses) Test(org.junit.Test)

Example 4 with SelectorFilter

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

the class JoinFilterAnalyzerTest method test_filterPushDown_factToCountryFullWithFilterOnNulls.

@Test
public void test_filterPushDown_factToCountryFullWithFilterOnNulls() {
    List<JoinableClause> joinableClauses = ImmutableList.of(factToCountryOnIsoCode(JoinType.FULL));
    Filter originalFilter = new AndFilter(ImmutableList.of(new SelectorFilter("channel", null), new SelectorFilter(FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "countryName", null)));
    JoinFilterPreAnalysis joinFilterPreAnalysis = makeDefaultConfigPreAnalysis(originalFilter, joinableClauses, VirtualColumns.EMPTY);
    HashJoinSegmentStorageAdapter adapter = new HashJoinSegmentStorageAdapter(factSegment.asStorageAdapter(), joinableClauses, joinFilterPreAnalysis);
    JoinTestHelper.verifyCursors(adapter.makeCursors(originalFilter, Intervals.ETERNITY, VirtualColumns.EMPTY, Granularities.ALL, false, null), ImmutableList.of("page", "countryIsoCode", "countryNumber", FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "countryIsoCode", FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "countryName", FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "countryNumber"), ImmutableList.of());
    JoinFilterSplit expectedFilterSplit = new JoinFilterSplit(null, new AndFilter(ImmutableList.of(new SelectorFilter("channel", null), new SelectorFilter(FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "countryName", null))), ImmutableSet.of());
    JoinFilterSplit actualFilterSplit = JoinFilterAnalyzer.splitFilter(joinFilterPreAnalysis);
    Assert.assertEquals(expectedFilterSplit, actualFilterSplit);
}
Also used : AndFilter(org.apache.druid.segment.filter.AndFilter) SelectorFilter(org.apache.druid.segment.filter.SelectorFilter) JoinFilterPreAnalysis(org.apache.druid.segment.join.filter.JoinFilterPreAnalysis) FalseFilter(org.apache.druid.segment.filter.FalseFilter) OrFilter(org.apache.druid.segment.filter.OrFilter) BoundDimFilter(org.apache.druid.query.filter.BoundDimFilter) SelectorFilter(org.apache.druid.segment.filter.SelectorFilter) AndFilter(org.apache.druid.segment.filter.AndFilter) BoundFilter(org.apache.druid.segment.filter.BoundFilter) InDimFilter(org.apache.druid.query.filter.InDimFilter) ExpressionDimFilter(org.apache.druid.query.filter.ExpressionDimFilter) Filter(org.apache.druid.query.filter.Filter) JoinFilterSplit(org.apache.druid.segment.join.filter.JoinFilterSplit) Test(org.junit.Test)

Example 5 with SelectorFilter

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

the class JoinFilterAnalyzerTest method test_filterPushDown_factToCountryInnerUsingCountryNumberFilterOnNulls.

@Test
public void test_filterPushDown_factToCountryInnerUsingCountryNumberFilterOnNulls() {
    List<JoinableClause> joinableClauses = ImmutableList.of(factToCountryOnNumber(JoinType.INNER));
    Filter originalFilter = new AndFilter(ImmutableList.of(new SelectorFilter("channel", null), new SelectorFilter(FACT_TO_COUNTRY_ON_NUMBER_PREFIX + "countryName", null)));
    JoinFilterPreAnalysis joinFilterPreAnalysis = makeDefaultConfigPreAnalysis(originalFilter, joinableClauses, VirtualColumns.EMPTY);
    HashJoinSegmentStorageAdapter adapter = new HashJoinSegmentStorageAdapter(factSegment.asStorageAdapter(), joinableClauses, joinFilterPreAnalysis);
    JoinTestHelper.verifyCursors(adapter.makeCursors(originalFilter, Intervals.ETERNITY, VirtualColumns.EMPTY, Granularities.ALL, false, null), ImmutableList.of("page", "countryIsoCode", FACT_TO_COUNTRY_ON_NUMBER_PREFIX + "countryIsoCode", FACT_TO_COUNTRY_ON_NUMBER_PREFIX + "countryName", FACT_TO_COUNTRY_ON_NUMBER_PREFIX + "countryNumber"), ImmutableList.of());
    JoinFilterSplit expectedFilterSplit = new JoinFilterSplit(null, new AndFilter(ImmutableList.of(new SelectorFilter("channel", null), new SelectorFilter(FACT_TO_COUNTRY_ON_NUMBER_PREFIX + "countryName", null))), ImmutableSet.of());
    JoinFilterSplit actualFilterSplit = JoinFilterAnalyzer.splitFilter(joinFilterPreAnalysis);
    Assert.assertEquals(expectedFilterSplit, actualFilterSplit);
}
Also used : AndFilter(org.apache.druid.segment.filter.AndFilter) SelectorFilter(org.apache.druid.segment.filter.SelectorFilter) JoinFilterPreAnalysis(org.apache.druid.segment.join.filter.JoinFilterPreAnalysis) FalseFilter(org.apache.druid.segment.filter.FalseFilter) OrFilter(org.apache.druid.segment.filter.OrFilter) BoundDimFilter(org.apache.druid.query.filter.BoundDimFilter) SelectorFilter(org.apache.druid.segment.filter.SelectorFilter) AndFilter(org.apache.druid.segment.filter.AndFilter) BoundFilter(org.apache.druid.segment.filter.BoundFilter) InDimFilter(org.apache.druid.query.filter.InDimFilter) ExpressionDimFilter(org.apache.druid.query.filter.ExpressionDimFilter) Filter(org.apache.druid.query.filter.Filter) JoinFilterSplit(org.apache.druid.segment.join.filter.JoinFilterSplit) 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