Search in sources :

Example 1 with JoinableClauses

use of org.apache.druid.segment.join.filter.JoinableClauses 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 2 with JoinableClauses

use of org.apache.druid.segment.join.filter.JoinableClauses 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 3 with JoinableClauses

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

the class JoinFilterAnalyzerTest method test_filterPushDown_factToRegionToCountryLeftFilterOnPageDisablePushDown.

@Test
public void test_filterPushDown_factToRegionToCountryLeftFilterOnPageDisablePushDown() {
    JoinableClauses joinableClauses = JoinableClauses.fromList(ImmutableList.of(factToRegion(JoinType.LEFT), regionToCountry(JoinType.LEFT)));
    Filter originalFilter = new SelectorFilter("page", "Peremptory norm");
    JoinFilterPreAnalysis joinFilterPreAnalysis = JoinFilterAnalyzer.computeJoinFilterPreAnalysis(new JoinFilterPreAnalysisKey(new JoinFilterRewriteConfig(false, true, 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[] { "Peremptory norm", "New South Wales", "Australia" }));
    JoinFilterSplit expectedFilterSplit = new JoinFilterSplit(null, new SelectorFilter("page", "Peremptory norm"), ImmutableSet.of());
    JoinFilterSplit actualFilterSplit = JoinFilterAnalyzer.splitFilter(joinFilterPreAnalysis);
    Assert.assertEquals(expectedFilterSplit, actualFilterSplit);
}
Also used : 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) JoinFilterPreAnalysisKey(org.apache.druid.segment.join.filter.JoinFilterPreAnalysisKey) JoinFilterSplit(org.apache.druid.segment.join.filter.JoinFilterSplit) JoinFilterRewriteConfig(org.apache.druid.segment.join.filter.rewrite.JoinFilterRewriteConfig) JoinableClauses(org.apache.druid.segment.join.filter.JoinableClauses) Test(org.junit.Test)

Example 4 with JoinableClauses

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

the class JoinableFactoryWrapper method createSegmentMapFn.

/**
 * Creates a Function that maps base segments to {@link HashJoinSegment} if needed (i.e. if the number of join
 * clauses is > 0). If mapping is not needed, this method will return {@link Function#identity()}.
 *
 * @param baseFilter         Filter to apply before the join takes place
 * @param clauses            Pre-joinable clauses
 * @param cpuTimeAccumulator An accumulator that we will add CPU nanos to; this is part of the function to encourage
 *                           callers to remember to track metrics on CPU time required for creation of Joinables
 * @param query              The query that will be run on the mapped segments. Usually this should be
 *                           {@code analysis.getBaseQuery().orElse(query)}, where "analysis" is a
 *                           {@link DataSourceAnalysis} and "query" is the original
 *                           query from the end user.
 */
public Function<SegmentReference, SegmentReference> createSegmentMapFn(@Nullable final Filter baseFilter, final List<PreJoinableClause> clauses, final AtomicLong cpuTimeAccumulator, final Query<?> query) {
    // compute column correlations here and RHS correlated values
    return JvmUtils.safeAccumulateThreadCpuTime(cpuTimeAccumulator, () -> {
        if (clauses.isEmpty()) {
            return Function.identity();
        } else {
            final JoinableClauses joinableClauses = JoinableClauses.createClauses(clauses, joinableFactory);
            final JoinFilterRewriteConfig filterRewriteConfig = JoinFilterRewriteConfig.forQuery(query);
            // Pick off any join clauses that can be converted into filters.
            final Set<String> requiredColumns = query.getRequiredColumns();
            final Filter baseFilterToUse;
            final List<JoinableClause> clausesToUse;
            if (requiredColumns != null && filterRewriteConfig.isEnableRewriteJoinToFilter()) {
                final Pair<List<Filter>, List<JoinableClause>> conversionResult = convertJoinsToFilters(joinableClauses.getJoinableClauses(), requiredColumns, Ints.checkedCast(Math.min(filterRewriteConfig.getFilterRewriteMaxSize(), Integer.MAX_VALUE)));
                baseFilterToUse = Filters.maybeAnd(Lists.newArrayList(Iterables.concat(Collections.singleton(baseFilter), conversionResult.lhs))).orElse(null);
                clausesToUse = conversionResult.rhs;
            } else {
                baseFilterToUse = baseFilter;
                clausesToUse = joinableClauses.getJoinableClauses();
            }
            // Analyze remaining join clauses to see if filters on them can be pushed down.
            final JoinFilterPreAnalysis joinFilterPreAnalysis = JoinFilterAnalyzer.computeJoinFilterPreAnalysis(new JoinFilterPreAnalysisKey(filterRewriteConfig, clausesToUse, query.getVirtualColumns(), Filters.maybeAnd(Arrays.asList(baseFilterToUse, Filters.toFilter(query.getFilter()))).orElse(null)));
            return baseSegment -> new HashJoinSegment(baseSegment, baseFilterToUse, clausesToUse, joinFilterPreAnalysis);
        }
    });
}
Also used : Logger(org.apache.druid.java.util.common.logger.Logger) DataSourceAnalysis(org.apache.druid.query.planning.DataSourceAnalysis) Iterables(com.google.common.collect.Iterables) Arrays(java.util.Arrays) Multiset(com.google.common.collect.Multiset) CacheKeyBuilder(org.apache.druid.query.cache.CacheKeyBuilder) Function(java.util.function.Function) Pair(org.apache.druid.java.util.common.Pair) ArrayList(java.util.ArrayList) SegmentReference(org.apache.druid.segment.SegmentReference) Lists(com.google.common.collect.Lists) Query(org.apache.druid.query.Query) HashMultiset(com.google.common.collect.HashMultiset) JoinFilterPreAnalysisKey(org.apache.druid.segment.join.filter.JoinFilterPreAnalysisKey) IAE(org.apache.druid.java.util.common.IAE) JoinFilterRewriteConfig(org.apache.druid.segment.join.filter.rewrite.JoinFilterRewriteConfig) Nullable(javax.annotation.Nullable) JvmUtils(org.apache.druid.utils.JvmUtils) PreJoinableClause(org.apache.druid.query.planning.PreJoinableClause) Set(java.util.Set) ISE(org.apache.druid.java.util.common.ISE) JoinableClauses(org.apache.druid.segment.join.filter.JoinableClauses) Ints(com.google.common.primitives.Ints) Sets(com.google.common.collect.Sets) JoinFilterPreAnalysis(org.apache.druid.segment.join.filter.JoinFilterPreAnalysis) AtomicLong(java.util.concurrent.atomic.AtomicLong) List(java.util.List) Optional(java.util.Optional) Preconditions(com.google.common.base.Preconditions) JoinFilterAnalyzer(org.apache.druid.segment.join.filter.JoinFilterAnalyzer) VisibleForTesting(com.google.common.annotations.VisibleForTesting) InDimFilter(org.apache.druid.query.filter.InDimFilter) Filters(org.apache.druid.segment.filter.Filters) Collections(java.util.Collections) Filter(org.apache.druid.query.filter.Filter) JoinFilterPreAnalysisKey(org.apache.druid.segment.join.filter.JoinFilterPreAnalysisKey) JoinFilterRewriteConfig(org.apache.druid.segment.join.filter.rewrite.JoinFilterRewriteConfig) PreJoinableClause(org.apache.druid.query.planning.PreJoinableClause) JoinFilterPreAnalysis(org.apache.druid.segment.join.filter.JoinFilterPreAnalysis) InDimFilter(org.apache.druid.query.filter.InDimFilter) Filter(org.apache.druid.query.filter.Filter) ArrayList(java.util.ArrayList) List(java.util.List) JoinableClauses(org.apache.druid.segment.join.filter.JoinableClauses)

Aggregations

Filter (org.apache.druid.query.filter.Filter)4 InDimFilter (org.apache.druid.query.filter.InDimFilter)4 JoinFilterPreAnalysis (org.apache.druid.segment.join.filter.JoinFilterPreAnalysis)4 JoinableClauses (org.apache.druid.segment.join.filter.JoinableClauses)4 BoundDimFilter (org.apache.druid.query.filter.BoundDimFilter)3 ExpressionDimFilter (org.apache.druid.query.filter.ExpressionDimFilter)3 AndFilter (org.apache.druid.segment.filter.AndFilter)3 BoundFilter (org.apache.druid.segment.filter.BoundFilter)3 FalseFilter (org.apache.druid.segment.filter.FalseFilter)3 OrFilter (org.apache.druid.segment.filter.OrFilter)3 SelectorFilter (org.apache.druid.segment.filter.SelectorFilter)3 JoinFilterPreAnalysisKey (org.apache.druid.segment.join.filter.JoinFilterPreAnalysisKey)3 JoinFilterSplit (org.apache.druid.segment.join.filter.JoinFilterSplit)3 JoinFilterRewriteConfig (org.apache.druid.segment.join.filter.rewrite.JoinFilterRewriteConfig)3 Test (org.junit.Test)3 VisibleForTesting (com.google.common.annotations.VisibleForTesting)1 Preconditions (com.google.common.base.Preconditions)1 HashMultiset (com.google.common.collect.HashMultiset)1 Iterables (com.google.common.collect.Iterables)1 Lists (com.google.common.collect.Lists)1