Search in sources :

Example 36 with DimFilter

use of io.druid.query.filter.DimFilter in project druid by druid-io.

the class GroupByRules method applyAggregate.

/**
   * Applies a filter -> project -> aggregate chain to a druidRel. Do not call this method unless
   * {@link #canApplyAggregate(DruidRel, Filter, Project, Aggregate)} returns true.
   *
   * @return new rel, or null if the chain cannot be applied
   */
private static DruidRel applyAggregate(final DruidRel druidRel, final Filter filter0, final Project project0, final Aggregate aggregate, final DruidOperatorTable operatorTable, final boolean approximateCountDistinct) {
    Preconditions.checkState(canApplyAggregate(druidRel, filter0, project0, aggregate), "Cannot applyAggregate.");
    final RowSignature sourceRowSignature;
    final boolean isNestedQuery = druidRel.getQueryBuilder().getGrouping() != null;
    if (isNestedQuery) {
        // Nested groupBy; source row signature is the output signature of druidRel.
        sourceRowSignature = druidRel.getOutputRowSignature();
    } else {
        sourceRowSignature = druidRel.getSourceRowSignature();
    }
    // Filter that should be applied before aggregating.
    final DimFilter filter;
    if (filter0 != null) {
        filter = Expressions.toFilter(operatorTable, druidRel.getPlannerContext(), sourceRowSignature, filter0.getCondition());
        if (filter == null) {
            // Can't plan this filter.
            return null;
        }
    } else if (druidRel.getQueryBuilder().getFilter() != null && !isNestedQuery) {
        // We're going to replace the existing druidRel, so inherit its filter.
        filter = druidRel.getQueryBuilder().getFilter();
    } else {
        filter = null;
    }
    // Projection that should be applied before aggregating.
    final Project project;
    if (project0 != null) {
        project = project0;
    } else if (druidRel.getQueryBuilder().getSelectProjection() != null && !isNestedQuery) {
        // We're going to replace the existing druidRel, so inherit its projection.
        project = druidRel.getQueryBuilder().getSelectProjection().getProject();
    } else {
        project = null;
    }
    final List<DimensionSpec> dimensions = Lists.newArrayList();
    final List<Aggregation> aggregations = Lists.newArrayList();
    final List<String> rowOrder = Lists.newArrayList();
    // Translate groupSet.
    final ImmutableBitSet groupSet = aggregate.getGroupSet();
    int dimOutputNameCounter = 0;
    for (int i : groupSet) {
        if (project != null && project.getChildExps().get(i) instanceof RexLiteral) {
            // Ignore literals in GROUP BY, so a user can write e.g. "GROUP BY 'dummy'" to group everything into a single
            // row. Add dummy rowOrder entry so NULLs come out. This is not strictly correct but it works as long as
            // nobody actually expects to see the literal.
            rowOrder.add(dimOutputName(dimOutputNameCounter++));
        } else {
            final RexNode rexNode = Expressions.fromFieldAccess(sourceRowSignature, project, i);
            final RowExtraction rex = Expressions.toRowExtraction(operatorTable, druidRel.getPlannerContext(), sourceRowSignature.getRowOrder(), rexNode);
            if (rex == null) {
                return null;
            }
            final SqlTypeName sqlTypeName = rexNode.getType().getSqlTypeName();
            final ValueType outputType = Calcites.getValueTypeForSqlTypeName(sqlTypeName);
            if (outputType == null) {
                throw new ISE("Cannot translate sqlTypeName[%s] to Druid type for field[%s]", sqlTypeName, rowOrder.get(i));
            }
            final DimensionSpec dimensionSpec = rex.toDimensionSpec(sourceRowSignature, dimOutputName(dimOutputNameCounter++), outputType);
            if (dimensionSpec == null) {
                return null;
            }
            dimensions.add(dimensionSpec);
            rowOrder.add(dimensionSpec.getOutputName());
        }
    }
    // Translate aggregates.
    for (int i = 0; i < aggregate.getAggCallList().size(); i++) {
        final AggregateCall aggCall = aggregate.getAggCallList().get(i);
        final Aggregation aggregation = translateAggregateCall(druidRel.getPlannerContext(), sourceRowSignature, project, aggCall, operatorTable, aggregations, i, approximateCountDistinct);
        if (aggregation == null) {
            return null;
        }
        aggregations.add(aggregation);
        rowOrder.add(aggregation.getOutputName());
    }
    if (isNestedQuery) {
        // Nested groupBy.
        return DruidNestedGroupBy.from(druidRel, filter, Grouping.create(dimensions, aggregations), aggregate.getRowType(), rowOrder);
    } else {
        // groupBy on a base dataSource.
        return druidRel.withQueryBuilder(druidRel.getQueryBuilder().withFilter(filter).withGrouping(Grouping.create(dimensions, aggregations), aggregate.getRowType(), rowOrder));
    }
}
Also used : DimensionSpec(io.druid.query.dimension.DimensionSpec) RexLiteral(org.apache.calcite.rex.RexLiteral) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) SqlTypeName(org.apache.calcite.sql.type.SqlTypeName) ValueType(io.druid.segment.column.ValueType) RowExtraction(io.druid.sql.calcite.expression.RowExtraction) Aggregation(io.druid.sql.calcite.aggregation.Aggregation) AggregateCall(org.apache.calcite.rel.core.AggregateCall) Project(org.apache.calcite.rel.core.Project) ISE(io.druid.java.util.common.ISE) RowSignature(io.druid.sql.calcite.table.RowSignature) DimFilter(io.druid.query.filter.DimFilter) NotDimFilter(io.druid.query.filter.NotDimFilter) AndDimFilter(io.druid.query.filter.AndDimFilter) RexNode(org.apache.calcite.rex.RexNode)

Example 37 with DimFilter

use of io.druid.query.filter.DimFilter in project druid by druid-io.

the class AndFilterTest method testAnd.

@Test
public void testAnd() {
    assertFilterMatches(new AndDimFilter(ImmutableList.<DimFilter>of(new SelectorDimFilter("dim0", "0", null), new SelectorDimFilter("dim1", "0", null))), ImmutableList.of("0"));
    assertFilterMatches(new AndDimFilter(ImmutableList.<DimFilter>of(new SelectorDimFilter("dim0", "0", null), new SelectorDimFilter("dim1", "1", null))), ImmutableList.<String>of());
    assertFilterMatches(new AndDimFilter(ImmutableList.<DimFilter>of(new SelectorDimFilter("dim0", "1", null), new SelectorDimFilter("dim1", "0", null))), ImmutableList.of("1"));
    assertFilterMatches(new AndDimFilter(ImmutableList.<DimFilter>of(new SelectorDimFilter("dim0", "1", null), new SelectorDimFilter("dim1", "1", null))), ImmutableList.<String>of());
    assertFilterMatches(new AndDimFilter(ImmutableList.<DimFilter>of(new NotDimFilter(new SelectorDimFilter("dim0", "1", null)), new NotDimFilter(new SelectorDimFilter("dim1", "1", null)))), ImmutableList.of("0", "2", "3", "4", "5"));
    assertFilterMatches(new AndDimFilter(ImmutableList.<DimFilter>of(new NotDimFilter(new SelectorDimFilter("dim0", "0", null)), new NotDimFilter(new SelectorDimFilter("dim1", "0", null)))), ImmutableList.<String>of());
}
Also used : NotDimFilter(io.druid.query.filter.NotDimFilter) AndDimFilter(io.druid.query.filter.AndDimFilter) SelectorDimFilter(io.druid.query.filter.SelectorDimFilter) SelectorDimFilter(io.druid.query.filter.SelectorDimFilter) DimFilter(io.druid.query.filter.DimFilter) NotDimFilter(io.druid.query.filter.NotDimFilter) AndDimFilter(io.druid.query.filter.AndDimFilter) Test(org.junit.Test)

Example 38 with DimFilter

use of io.druid.query.filter.DimFilter in project druid by druid-io.

the class BaseFilterTest method makeFilter.

private Filter makeFilter(final DimFilter dimFilter) {
    if (dimFilter == null) {
        return null;
    }
    final DimFilter maybeOptimized = optimize ? dimFilter.optimize() : dimFilter;
    final Filter filter = maybeOptimized.toFilter();
    return cnf ? Filters.convertToCNF(filter) : filter;
}
Also used : DimFilter(io.druid.query.filter.DimFilter) Filter(io.druid.query.filter.Filter) DimFilter(io.druid.query.filter.DimFilter)

Example 39 with DimFilter

use of io.druid.query.filter.DimFilter in project druid by druid-io.

the class BaseFilterTest method selectColumnValuesMatchingFilterUsingPostFiltering.

private List<String> selectColumnValuesMatchingFilterUsingPostFiltering(final DimFilter filter, final String selectColumn) {
    final Filter theFilter = makeFilter(filter);
    final Filter postFilteringFilter = new Filter() {

        @Override
        public ImmutableBitmap getBitmapIndex(BitmapIndexSelector selector) {
            throw new UnsupportedOperationException();
        }

        @Override
        public ValueMatcher makeMatcher(ColumnSelectorFactory factory) {
            return theFilter.makeMatcher(factory);
        }

        @Override
        public boolean supportsBitmapIndex(BitmapIndexSelector selector) {
            return false;
        }

        @Override
        public boolean supportsSelectivityEstimation(ColumnSelector columnSelector, BitmapIndexSelector indexSelector) {
            return false;
        }

        @Override
        public double estimateSelectivity(BitmapIndexSelector indexSelector) {
            return 1.0;
        }
    };
    final Sequence<Cursor> cursors = makeCursorSequence(postFilteringFilter);
    Sequence<List<String>> seq = Sequences.map(cursors, new Function<Cursor, List<String>>() {

        @Override
        public List<String> apply(Cursor input) {
            final DimensionSelector selector = input.makeDimensionSelector(new DefaultDimensionSpec(selectColumn, selectColumn));
            final List<String> values = Lists.newArrayList();
            while (!input.isDone()) {
                IndexedInts row = selector.getRow();
                Preconditions.checkState(row.size() == 1);
                values.add(selector.lookupName(row.get(0)));
                input.advance();
            }
            return values;
        }
    });
    return Sequences.toList(seq, new ArrayList<List<String>>()).get(0);
}
Also used : DimensionSelector(io.druid.segment.DimensionSelector) RowBasedColumnSelectorFactory(io.druid.query.groupby.RowBasedColumnSelectorFactory) ColumnSelectorFactory(io.druid.segment.ColumnSelectorFactory) ArrayList(java.util.ArrayList) Cursor(io.druid.segment.Cursor) DefaultDimensionSpec(io.druid.query.dimension.DefaultDimensionSpec) DimFilter(io.druid.query.filter.DimFilter) Filter(io.druid.query.filter.Filter) ColumnSelector(io.druid.segment.ColumnSelector) IndexedInts(io.druid.segment.data.IndexedInts) BitmapIndexSelector(io.druid.query.filter.BitmapIndexSelector) List(java.util.List) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList)

Example 40 with DimFilter

use of io.druid.query.filter.DimFilter in project druid by druid-io.

the class FilterPartitionTest method testDistributeOrCNFExtractionFn.

@Test
public void testDistributeOrCNFExtractionFn() {
    DimFilter dimFilter1 = new OrDimFilter(Arrays.<DimFilter>asList(new SelectorDimFilter("dim0", "super-6", JS_EXTRACTION_FN), new AndDimFilter(Arrays.<DimFilter>asList(new NoBitmapSelectorDimFilter("dim1", "super-def", JS_EXTRACTION_FN), new SelectorDimFilter("dim2", "super-c", JS_EXTRACTION_FN)))));
    Filter filter1 = dimFilter1.toFilter();
    Filter filter1CNF = Filters.convertToCNF(filter1);
    Assert.assertEquals(AndFilter.class, filter1CNF.getClass());
    Assert.assertEquals(2, ((AndFilter) filter1CNF).getFilters().size());
    assertFilterMatches(dimFilter1, ImmutableList.of("4", "6"));
    DimFilter dimFilter2 = new OrDimFilter(Arrays.<DimFilter>asList(new SelectorDimFilter("dim0", "super-2", JS_EXTRACTION_FN), new SelectorDimFilter("dim0", "super-3", JS_EXTRACTION_FN), new AndDimFilter(Arrays.<DimFilter>asList(new NoBitmapSelectorDimFilter("dim1", "super-HELLO", JS_EXTRACTION_FN), new SelectorDimFilter("dim2", "super-foo", JS_EXTRACTION_FN)))));
    assertFilterMatches(dimFilter2, ImmutableList.of("2", "3", "7"));
    DimFilter dimFilter3 = new OrDimFilter(Arrays.<DimFilter>asList(dimFilter1, dimFilter2, new AndDimFilter(Arrays.<DimFilter>asList(new NoBitmapSelectorDimFilter("dim1", "super-1", JS_EXTRACTION_FN), new SelectorDimFilter("dim2", "super-foo", JS_EXTRACTION_FN)))));
    Filter filter3 = dimFilter3.toFilter();
    Filter filter3CNF = Filters.convertToCNF(dimFilter3.toFilter());
    assertFilterMatches(dimFilter3, ImmutableList.of("2", "3", "4", "6", "7", "9"));
}
Also used : AndDimFilter(io.druid.query.filter.AndDimFilter) OrDimFilter(io.druid.query.filter.OrDimFilter) SelectorDimFilter(io.druid.query.filter.SelectorDimFilter) DimFilter(io.druid.query.filter.DimFilter) Filter(io.druid.query.filter.Filter) AndDimFilter(io.druid.query.filter.AndDimFilter) SelectorDimFilter(io.druid.query.filter.SelectorDimFilter) OrDimFilter(io.druid.query.filter.OrDimFilter) OrDimFilter(io.druid.query.filter.OrDimFilter) SelectorDimFilter(io.druid.query.filter.SelectorDimFilter) DimFilter(io.druid.query.filter.DimFilter) AndDimFilter(io.druid.query.filter.AndDimFilter) Test(org.junit.Test)

Aggregations

DimFilter (io.druid.query.filter.DimFilter)56 AndDimFilter (io.druid.query.filter.AndDimFilter)45 SelectorDimFilter (io.druid.query.filter.SelectorDimFilter)39 Test (org.junit.Test)32 BoundDimFilter (io.druid.query.filter.BoundDimFilter)30 OrDimFilter (io.druid.query.filter.OrDimFilter)27 InDimFilter (io.druid.query.filter.InDimFilter)24 NotDimFilter (io.druid.query.filter.NotDimFilter)19 RegexDimFilter (io.druid.query.filter.RegexDimFilter)18 Result (io.druid.query.Result)14 ExtractionDimFilter (io.druid.query.filter.ExtractionDimFilter)14 DateTime (org.joda.time.DateTime)14 JavaScriptDimFilter (io.druid.query.filter.JavaScriptDimFilter)11 SearchQueryDimFilter (io.druid.query.filter.SearchQueryDimFilter)11 List (java.util.List)11 DefaultDimensionSpec (io.druid.query.dimension.DefaultDimensionSpec)10 ArrayList (java.util.ArrayList)9 LongSumAggregatorFactory (io.druid.query.aggregation.LongSumAggregatorFactory)8 DimensionSpec (io.druid.query.dimension.DimensionSpec)7 Row (io.druid.data.input.Row)6