Search in sources :

Example 26 with BoundDimFilter

use of org.apache.druid.query.filter.BoundDimFilter in project druid by druid-io.

the class BoundFilter method rewriteRequiredColumns.

@Override
public Filter rewriteRequiredColumns(Map<String, String> columnRewrites) {
    String rewriteDimensionTo = columnRewrites.get(boundDimFilter.getDimension());
    if (rewriteDimensionTo == null) {
        throw new IAE("Received a non-applicable rewrite: %s, filter's dimension: %s", columnRewrites, boundDimFilter.getDimension());
    }
    BoundDimFilter newDimFilter = new BoundDimFilter(rewriteDimensionTo, boundDimFilter.getLower(), boundDimFilter.getUpper(), boundDimFilter.isLowerStrict(), boundDimFilter.isUpperStrict(), null, boundDimFilter.getExtractionFn(), boundDimFilter.getOrdering());
    return new BoundFilter(newDimFilter);
}
Also used : BoundDimFilter(org.apache.druid.query.filter.BoundDimFilter) IAE(org.apache.druid.java.util.common.IAE)

Example 27 with BoundDimFilter

use of org.apache.druid.query.filter.BoundDimFilter in project druid by druid-io.

the class SchemaEvolutionTest method testNumericEvolutionFiltering.

@Test
@Parameters(method = "doVectorize")
public void testNumericEvolutionFiltering(boolean doVectorize) {
    final TimeseriesQueryRunnerFactory factory = QueryRunnerTestHelper.newTimeseriesQueryRunnerFactory();
    // "c1" changes from string(1) -> long(2) -> float(3) -> nonexistent(4)
    // test behavior of filtering
    final TimeseriesQuery query = Druids.newTimeseriesQueryBuilder().dataSource(DATA_SOURCE).intervals("1000/3000").filters(new BoundDimFilter("c1", "9", "11", false, false, null, null, StringComparators.NUMERIC)).aggregators(ImmutableList.of(new LongSumAggregatorFactory("a", "c1"), new DoubleSumAggregatorFactory("b", "c1"), new FloatSumAggregatorFactory("d", "c1"), new LongMinAggregatorFactory("e", "c1"), new CountAggregatorFactory("c"))).context(ImmutableMap.of(QueryContexts.VECTORIZE_KEY, doVectorize)).build();
    // Only string(1) -- which we can filter but not aggregate
    Assert.assertEquals(timeseriesResult(ImmutableMap.of("a", 19L, "b", 19.1, "c", 2L, "d", 19.1f, "e", 9L)), runQuery(query, factory, ImmutableList.of(index1)));
    // Only long(2) -- which we can filter and aggregate
    Assert.assertEquals(timeseriesResult(ImmutableMap.of("a", 19L, "b", 19.0, "c", 2L, "d", 19.0f, "e", 9L)), runQuery(query, factory, ImmutableList.of(index2)));
    // Only float(3) -- which we can't filter, but can aggregate
    Assert.assertEquals(timeseriesResult(ImmutableMap.of("a", 19L, "b", 19.1, "c", 2L, "d", 19.1f, "e", 9L)), runQuery(query, factory, ImmutableList.of(index3)));
    // Only nonexistent(4)
    Assert.assertEquals(timeseriesResult(TestHelper.createExpectedMap("a", NullHandling.defaultLongValue(), "b", NullHandling.defaultDoubleValue(), "c", 0L, "d", NullHandling.defaultFloatValue(), "e", NullHandling.sqlCompatible() ? null : Long.MAX_VALUE)), runQuery(query, factory, ImmutableList.of(index4)));
    // string(1) + long(2) + float(3) + nonexistent(4)
    Assert.assertEquals(timeseriesResult(ImmutableMap.of("a", 57L, "b", 57.2, "c", 6L, "d", 57.20000076293945, "e", 9L)), runQuery(query, factory, ImmutableList.of(index1, index2, index3, index4)));
}
Also used : TimeseriesQueryRunnerFactory(org.apache.druid.query.timeseries.TimeseriesQueryRunnerFactory) BoundDimFilter(org.apache.druid.query.filter.BoundDimFilter) TimeseriesQuery(org.apache.druid.query.timeseries.TimeseriesQuery) DoubleSumAggregatorFactory(org.apache.druid.query.aggregation.DoubleSumAggregatorFactory) CountAggregatorFactory(org.apache.druid.query.aggregation.CountAggregatorFactory) LongSumAggregatorFactory(org.apache.druid.query.aggregation.LongSumAggregatorFactory) FloatSumAggregatorFactory(org.apache.druid.query.aggregation.FloatSumAggregatorFactory) LongMinAggregatorFactory(org.apache.druid.query.aggregation.LongMinAggregatorFactory) Parameters(junitparams.Parameters) Test(org.junit.Test)

Example 28 with BoundDimFilter

use of org.apache.druid.query.filter.BoundDimFilter in project druid by druid-io.

the class CombineAndSimplifyBounds method doSimplify.

/**
 * Simplify BoundDimFilters that are children of an OR or an AND.
 *
 * @param children    the filters
 * @param disjunction true for OR, false for AND
 *
 * @return simplified filters
 */
private static DimFilter doSimplify(final List<DimFilter> children, boolean disjunction) {
    // Copy the list of child filters. We'll modify the copy and eventually return it.
    final List<DimFilter> newChildren = Lists.newArrayList(children);
    // Group Bound filters by dimension, extractionFn, and comparator and compute a RangeSet for each one.
    final Map<BoundRefKey, List<BoundDimFilter>> bounds = new HashMap<>();
    // all and/or filters have at least 1 child
    boolean allFalse = true;
    for (final DimFilter child : newChildren) {
        if (child instanceof BoundDimFilter) {
            final BoundDimFilter bound = (BoundDimFilter) child;
            final BoundRefKey boundRefKey = BoundRefKey.from(bound);
            final List<BoundDimFilter> filterList = bounds.computeIfAbsent(boundRefKey, k -> new ArrayList<>());
            filterList.add(bound);
            allFalse = false;
        } else {
            allFalse &= child instanceof FalseDimFilter;
        }
    }
    // short circuit if can never be true
    if (allFalse) {
        return Filtration.matchNothing();
    }
    // Try to simplify filters within each group.
    for (Map.Entry<BoundRefKey, List<BoundDimFilter>> entry : bounds.entrySet()) {
        final BoundRefKey boundRefKey = entry.getKey();
        final List<BoundDimFilter> filterList = entry.getValue();
        // Create a RangeSet for this group.
        final RangeSet<BoundValue> rangeSet = disjunction ? RangeSets.unionRanges(Bounds.toRanges(filterList)) : RangeSets.intersectRanges(Bounds.toRanges(filterList));
        if (rangeSet.asRanges().size() < filterList.size()) {
            // We found a simplification. Remove the old filters and add new ones.
            for (final BoundDimFilter bound : filterList) {
                if (!newChildren.remove(bound)) {
                    // Don't expect this to happen, but include it as a sanity check.
                    throw new ISE("Tried to remove bound, but couldn't");
                }
            }
            if (rangeSet.asRanges().isEmpty()) {
                // range set matches nothing, equivalent to FALSE
                newChildren.add(Filtration.matchNothing());
            }
            for (final Range<BoundValue> range : rangeSet.asRanges()) {
                if (!range.hasLowerBound() && !range.hasUpperBound()) {
                    // range matches all, equivalent to TRUE
                    newChildren.add(Filtration.matchEverything());
                } else {
                    newChildren.add(Bounds.toFilter(boundRefKey, range));
                }
            }
        }
    }
    // Finally: Go through newChildren, removing or potentially exiting early based on TRUE / FALSE marker filters.
    Preconditions.checkState(newChildren.size() > 0, "newChildren.size > 0");
    final Iterator<DimFilter> iterator = newChildren.iterator();
    while (iterator.hasNext()) {
        final DimFilter newChild = iterator.next();
        if (Filtration.matchNothing().equals(newChild)) {
            // AND with FALSE => always false, short circuit
            if (disjunction) {
                iterator.remove();
            } else {
                return Filtration.matchNothing();
            }
        } else if (Filtration.matchEverything().equals(newChild)) {
            // AND with TRUE => ignore
            if (disjunction) {
                return Filtration.matchEverything();
            } else {
                iterator.remove();
            }
        }
    }
    if (newChildren.isEmpty()) {
        // If "newChildren" is empty at this point, it must have consisted entirely of TRUE / FALSE marker filters.
        if (disjunction) {
            // Must have been all FALSE filters (the only kind we would have removed above).
            return Filtration.matchNothing();
        } else {
            // Must have been all TRUE filters (the only kind we would have removed above).
            return Filtration.matchEverything();
        }
    } else if (newChildren.size() == 1) {
        return newChildren.get(0);
    } else {
        return disjunction ? new OrDimFilter(newChildren) : new AndDimFilter(newChildren);
    }
}
Also used : BoundDimFilter(org.apache.druid.query.filter.BoundDimFilter) AndDimFilter(org.apache.druid.query.filter.AndDimFilter) HashMap(java.util.HashMap) FalseDimFilter(org.apache.druid.query.filter.FalseDimFilter) OrDimFilter(org.apache.druid.query.filter.OrDimFilter) ArrayList(java.util.ArrayList) List(java.util.List) ISE(org.apache.druid.java.util.common.ISE) AndDimFilter(org.apache.druid.query.filter.AndDimFilter) NotDimFilter(org.apache.druid.query.filter.NotDimFilter) FalseDimFilter(org.apache.druid.query.filter.FalseDimFilter) DimFilter(org.apache.druid.query.filter.DimFilter) BoundDimFilter(org.apache.druid.query.filter.BoundDimFilter) OrDimFilter(org.apache.druid.query.filter.OrDimFilter) HashMap(java.util.HashMap) Map(java.util.Map)

Example 29 with BoundDimFilter

use of org.apache.druid.query.filter.BoundDimFilter in project druid by druid-io.

the class ConvertBoundsToSelectors method process.

@Override
public DimFilter process(DimFilter filter) {
    if (filter instanceof BoundDimFilter) {
        final BoundDimFilter bound = (BoundDimFilter) filter;
        final StringComparator comparator = RowSignatures.getNaturalStringComparator(rowSignature, SimpleExtraction.of(bound.getDimension(), bound.getExtractionFn()));
        if (bound.hasUpperBound() && bound.hasLowerBound() && bound.getUpper().equals(bound.getLower()) && !bound.isUpperStrict() && !bound.isLowerStrict() && bound.getOrdering().equals(comparator)) {
            return new SelectorDimFilter(bound.getDimension(), bound.getUpper(), bound.getExtractionFn());
        } else {
            return filter;
        }
    } else {
        return filter;
    }
}
Also used : BoundDimFilter(org.apache.druid.query.filter.BoundDimFilter) SelectorDimFilter(org.apache.druid.query.filter.SelectorDimFilter) StringComparator(org.apache.druid.query.ordering.StringComparator)

Example 30 with BoundDimFilter

use of org.apache.druid.query.filter.BoundDimFilter in project druid by druid-io.

the class TimeseriesBenchmark method setupQueries.

private void setupQueries() {
    // queries for the basic schema
    Map<String, TimeseriesQuery> basicQueries = new LinkedHashMap<>();
    GeneratorSchemaInfo basicSchema = GeneratorBasicSchemas.SCHEMA_MAP.get("basic");
    {
        // basic.A
        QuerySegmentSpec intervalSpec = new MultipleIntervalSegmentSpec(Collections.singletonList(basicSchema.getDataInterval()));
        List<AggregatorFactory> queryAggs = new ArrayList<>();
        queryAggs.add(new LongSumAggregatorFactory("sumLongSequential", "sumLongSequential"));
        queryAggs.add(new LongMaxAggregatorFactory("maxLongUniform", "maxLongUniform"));
        queryAggs.add(new DoubleSumAggregatorFactory("sumFloatNormal", "sumFloatNormal"));
        queryAggs.add(new DoubleMinAggregatorFactory("minFloatZipf", "minFloatZipf"));
        queryAggs.add(new HyperUniquesAggregatorFactory("hyperUniquesMet", "hyper"));
        TimeseriesQuery queryA = Druids.newTimeseriesQueryBuilder().dataSource("blah").granularity(Granularities.ALL).intervals(intervalSpec).aggregators(queryAggs).descending(descending).build();
        basicQueries.put("A", queryA);
    }
    {
        QuerySegmentSpec intervalSpec = new MultipleIntervalSegmentSpec(Collections.singletonList(basicSchema.getDataInterval()));
        List<AggregatorFactory> queryAggs = new ArrayList<>();
        LongSumAggregatorFactory lsaf = new LongSumAggregatorFactory("sumLongSequential", "sumLongSequential");
        BoundDimFilter timeFilter = new BoundDimFilter(ColumnHolder.TIME_COLUMN_NAME, "200000", "300000", false, false, null, null, StringComparators.NUMERIC);
        queryAggs.add(new FilteredAggregatorFactory(lsaf, timeFilter));
        TimeseriesQuery timeFilterQuery = Druids.newTimeseriesQueryBuilder().dataSource("blah").granularity(Granularities.ALL).intervals(intervalSpec).aggregators(queryAggs).descending(descending).build();
        basicQueries.put("timeFilterNumeric", timeFilterQuery);
    }
    {
        QuerySegmentSpec intervalSpec = new MultipleIntervalSegmentSpec(Collections.singletonList(basicSchema.getDataInterval()));
        List<AggregatorFactory> queryAggs = new ArrayList<>();
        LongSumAggregatorFactory lsaf = new LongSumAggregatorFactory("sumLongSequential", "sumLongSequential");
        BoundDimFilter timeFilter = new BoundDimFilter(ColumnHolder.TIME_COLUMN_NAME, "200000", "300000", false, false, null, null, StringComparators.ALPHANUMERIC);
        queryAggs.add(new FilteredAggregatorFactory(lsaf, timeFilter));
        TimeseriesQuery timeFilterQuery = Druids.newTimeseriesQueryBuilder().dataSource("blah").granularity(Granularities.ALL).intervals(intervalSpec).aggregators(queryAggs).descending(descending).build();
        basicQueries.put("timeFilterAlphanumeric", timeFilterQuery);
    }
    {
        QuerySegmentSpec intervalSpec = new MultipleIntervalSegmentSpec(Collections.singletonList(Intervals.utc(200000, 300000)));
        List<AggregatorFactory> queryAggs = new ArrayList<>();
        LongSumAggregatorFactory lsaf = new LongSumAggregatorFactory("sumLongSequential", "sumLongSequential");
        queryAggs.add(lsaf);
        TimeseriesQuery timeFilterQuery = Druids.newTimeseriesQueryBuilder().dataSource("blah").granularity(Granularities.ALL).intervals(intervalSpec).aggregators(queryAggs).descending(descending).build();
        basicQueries.put("timeFilterByInterval", timeFilterQuery);
    }
    SCHEMA_QUERY_MAP.put("basic", basicQueries);
}
Also used : FilteredAggregatorFactory(org.apache.druid.query.aggregation.FilteredAggregatorFactory) BoundDimFilter(org.apache.druid.query.filter.BoundDimFilter) TimeseriesQuery(org.apache.druid.query.timeseries.TimeseriesQuery) DoubleSumAggregatorFactory(org.apache.druid.query.aggregation.DoubleSumAggregatorFactory) GeneratorSchemaInfo(org.apache.druid.segment.generator.GeneratorSchemaInfo) LongSumAggregatorFactory(org.apache.druid.query.aggregation.LongSumAggregatorFactory) MultipleIntervalSegmentSpec(org.apache.druid.query.spec.MultipleIntervalSegmentSpec) DoubleMinAggregatorFactory(org.apache.druid.query.aggregation.DoubleMinAggregatorFactory) LinkedHashMap(java.util.LinkedHashMap) HyperUniquesAggregatorFactory(org.apache.druid.query.aggregation.hyperloglog.HyperUniquesAggregatorFactory) QuerySegmentSpec(org.apache.druid.query.spec.QuerySegmentSpec) List(java.util.List) ArrayList(java.util.ArrayList) LongMaxAggregatorFactory(org.apache.druid.query.aggregation.LongMaxAggregatorFactory)

Aggregations

BoundDimFilter (org.apache.druid.query.filter.BoundDimFilter)66 Test (org.junit.Test)46 SelectorDimFilter (org.apache.druid.query.filter.SelectorDimFilter)28 InDimFilter (org.apache.druid.query.filter.InDimFilter)23 ArrayList (java.util.ArrayList)18 AndDimFilter (org.apache.druid.query.filter.AndDimFilter)16 OrDimFilter (org.apache.druid.query.filter.OrDimFilter)15 DimFilter (org.apache.druid.query.filter.DimFilter)14 RegexDimFilter (org.apache.druid.query.filter.RegexDimFilter)12 SearchQueryDimFilter (org.apache.druid.query.filter.SearchQueryDimFilter)12 ContainsSearchQuerySpec (org.apache.druid.query.search.ContainsSearchQuerySpec)12 LongSumAggregatorFactory (org.apache.druid.query.aggregation.LongSumAggregatorFactory)11 JavaScriptDimFilter (org.apache.druid.query.filter.JavaScriptDimFilter)11 DefaultDimensionSpec (org.apache.druid.query.dimension.DefaultDimensionSpec)10 InitializedNullHandlingTest (org.apache.druid.testing.InitializedNullHandlingTest)10 QuerySegmentSpec (org.apache.druid.query.spec.QuerySegmentSpec)8 MultipleIntervalSegmentSpec (org.apache.druid.query.spec.MultipleIntervalSegmentSpec)7 HashMap (java.util.HashMap)6 List (java.util.List)6 DoubleSumAggregatorFactory (org.apache.druid.query.aggregation.DoubleSumAggregatorFactory)6