Search in sources :

Example 31 with AndFilter

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

the class HiveCnfHelper method generateAllCombinations.

// A helper function adapted from Apache Hive, see:
// https://github.com/apache/hive/blob/branch-2.0/storage-api/src/java/org/apache/hadoop/hive/ql/io/sarg/SearchArgumentImpl.java
private static void generateAllCombinations(List<Filter> result, List<Filter> andList, List<Filter> nonAndList) {
    List<Filter> children = new ArrayList<>(((AndFilter) andList.get(0)).getFilters());
    if (result.isEmpty()) {
        for (Filter child : children) {
            List<Filter> a = new ArrayList<>(nonAndList);
            a.add(child);
            // Result must receive an actual OrFilter, so wrap if Filters.or managed to un-OR it.
            result.add(idempotentOr(Filters.or(a)));
        }
    } else {
        List<Filter> work = new ArrayList<>(result);
        result.clear();
        for (Filter child : children) {
            for (Filter or : work) {
                List<Filter> a = new ArrayList<>((((OrFilter) or).getFilters()));
                a.add(child);
                // Result must receive an actual OrFilter.
                result.add(idempotentOr(Filters.or(a)));
            }
        }
    }
    if (andList.size() > 1) {
        generateAllCombinations(result, andList.subList(1, andList.size()), nonAndList);
    }
}
Also used : BooleanFilter(org.apache.druid.query.filter.BooleanFilter) AndFilter(org.apache.druid.segment.filter.AndFilter) OrFilter(org.apache.druid.segment.filter.OrFilter) NotFilter(org.apache.druid.segment.filter.NotFilter) Filter(org.apache.druid.query.filter.Filter) ArrayList(java.util.ArrayList) OrFilter(org.apache.druid.segment.filter.OrFilter)

Example 32 with AndFilter

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

the class HiveCnfHelper method flatten.

public static Filter flatten(Filter root) {
    if (root instanceof BooleanFilter) {
        List<Filter> children = new ArrayList<>(((BooleanFilter) root).getFilters());
        // they don't get re-visited
        for (int i = 0; i < children.size(); ++i) {
            Filter child = flatten(children.get(i));
            // do we need to flatten?
            if (child.getClass() == root.getClass() && !(child instanceof NotFilter)) {
                boolean first = true;
                List<Filter> grandKids = new ArrayList<>(((BooleanFilter) child).getFilters());
                for (Filter grandkid : grandKids) {
                    // for the first grandkid replace the original parent
                    if (first) {
                        first = false;
                        children.set(i, grandkid);
                    } else {
                        children.add(++i, grandkid);
                    }
                }
            } else {
                children.set(i, child);
            }
        }
        // if we have a singleton AND or OR, just return the child
        if (children.size() == 1 && (root instanceof AndFilter || root instanceof OrFilter)) {
            return children.get(0);
        }
        if (root instanceof AndFilter) {
            return new AndFilter(children);
        } else if (root instanceof OrFilter) {
            return new OrFilter(children);
        }
    }
    return root;
}
Also used : BooleanFilter(org.apache.druid.query.filter.BooleanFilter) AndFilter(org.apache.druid.segment.filter.AndFilter) BooleanFilter(org.apache.druid.query.filter.BooleanFilter) AndFilter(org.apache.druid.segment.filter.AndFilter) OrFilter(org.apache.druid.segment.filter.OrFilter) NotFilter(org.apache.druid.segment.filter.NotFilter) Filter(org.apache.druid.query.filter.Filter) NotFilter(org.apache.druid.segment.filter.NotFilter) ArrayList(java.util.ArrayList) OrFilter(org.apache.druid.segment.filter.OrFilter)

Example 33 with AndFilter

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

the class HiveCnfHelper method convertToCnf.

public static Filter convertToCnf(Filter current) {
    if (current instanceof NotFilter) {
        return new NotFilter(convertToCnf(((NotFilter) current).getBaseFilter()));
    }
    if (current instanceof AndFilter) {
        List<Filter> children = new ArrayList<>();
        for (Filter child : ((AndFilter) current).getFilters()) {
            children.add(convertToCnf(child));
        }
        return Filters.and(children);
    }
    if (current instanceof OrFilter) {
        // a list of leaves that weren't under AND expressions
        List<Filter> nonAndList = new ArrayList<>();
        // a list of AND expressions that we need to distribute
        List<Filter> andList = new ArrayList<>();
        for (Filter child : ((OrFilter) current).getFilters()) {
            if (child instanceof AndFilter) {
                andList.add(child);
            } else if (child instanceof OrFilter) {
                // pull apart the kids of the OR expression
                nonAndList.addAll(((OrFilter) child).getFilters());
            } else {
                nonAndList.add(child);
            }
        }
        if (!andList.isEmpty()) {
            List<Filter> result = new ArrayList<>();
            generateAllCombinations(result, andList, nonAndList);
            return Filters.and(result);
        }
    }
    return current;
}
Also used : AndFilter(org.apache.druid.segment.filter.AndFilter) BooleanFilter(org.apache.druid.query.filter.BooleanFilter) AndFilter(org.apache.druid.segment.filter.AndFilter) OrFilter(org.apache.druid.segment.filter.OrFilter) NotFilter(org.apache.druid.segment.filter.NotFilter) Filter(org.apache.druid.query.filter.Filter) NotFilter(org.apache.druid.segment.filter.NotFilter) ArrayList(java.util.ArrayList) OrFilter(org.apache.druid.segment.filter.OrFilter)

Example 34 with AndFilter

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

the class QueryableIndexStorageAdapter method analyzeFilter.

@VisibleForTesting
public FilterAnalysis analyzeFilter(@Nullable final Filter filter, ColumnSelectorBitmapIndexSelector indexSelector, @Nullable QueryMetrics queryMetrics) {
    final int totalRows = index.getNumRows();
    /*
     * Filters can be applied in two stages:
     * pre-filtering: Use bitmap indexes to prune the set of rows to be scanned.
     * post-filtering: Iterate through rows and apply the filter to the row values
     *
     * The pre-filter and post-filter step have an implicit AND relationship. (i.e., final rows are those that
     * were not pruned AND those that matched the filter during row scanning)
     *
     * An AND filter can have its subfilters partitioned across the two steps. The subfilters that can be
     * processed entirely with bitmap indexes (subfilter returns true for supportsBitmapIndex())
     * will be moved to the pre-filtering stage.
     *
     * Any subfilters that cannot be processed entirely with bitmap indexes will be moved to the post-filtering stage.
     */
    final List<Filter> preFilters;
    final List<Filter> postFilters = new ArrayList<>();
    int preFilteredRows = totalRows;
    if (filter == null) {
        preFilters = Collections.emptyList();
    } else {
        preFilters = new ArrayList<>();
        if (filter instanceof AndFilter) {
            // If we get an AndFilter, we can split the subfilters across both filtering stages
            for (Filter subfilter : ((AndFilter) filter).getFilters()) {
                if (subfilter.supportsBitmapIndex(indexSelector) && subfilter.shouldUseBitmapIndex(indexSelector)) {
                    preFilters.add(subfilter);
                } else {
                    postFilters.add(subfilter);
                }
            }
        } else {
            // If we get an OrFilter or a single filter, handle the filter in one stage
            if (filter.supportsBitmapIndex(indexSelector) && filter.shouldUseBitmapIndex(indexSelector)) {
                preFilters.add(filter);
            } else {
                postFilters.add(filter);
            }
        }
    }
    final ImmutableBitmap preFilterBitmap;
    if (preFilters.isEmpty()) {
        preFilterBitmap = null;
    } else {
        if (queryMetrics != null) {
            BitmapResultFactory<?> bitmapResultFactory = queryMetrics.makeBitmapResultFactory(indexSelector.getBitmapFactory());
            long bitmapConstructionStartNs = System.nanoTime();
            // Use AndFilter.getBitmapResult to intersect the preFilters to get its short-circuiting behavior.
            preFilterBitmap = AndFilter.getBitmapIndex(indexSelector, bitmapResultFactory, preFilters);
            preFilteredRows = preFilterBitmap.size();
            queryMetrics.reportBitmapConstructionTime(System.nanoTime() - bitmapConstructionStartNs);
        } else {
            BitmapResultFactory<?> bitmapResultFactory = new DefaultBitmapResultFactory(indexSelector.getBitmapFactory());
            preFilterBitmap = AndFilter.getBitmapIndex(indexSelector, bitmapResultFactory, preFilters);
        }
    }
    if (queryMetrics != null) {
        queryMetrics.preFilters(new ArrayList<>(preFilters));
        queryMetrics.postFilters(postFilters);
        queryMetrics.reportSegmentRows(totalRows);
        queryMetrics.reportPreFilteredRows(preFilteredRows);
    }
    return new FilterAnalysis(preFilterBitmap, Filters.maybeAnd(postFilters).orElse(null));
}
Also used : AndFilter(org.apache.druid.segment.filter.AndFilter) AndFilter(org.apache.druid.segment.filter.AndFilter) Filter(org.apache.druid.query.filter.Filter) ImmutableBitmap(org.apache.druid.collections.bitmap.ImmutableBitmap) ArrayList(java.util.ArrayList) DefaultBitmapResultFactory(org.apache.druid.query.DefaultBitmapResultFactory) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Aggregations

Filter (org.apache.druid.query.filter.Filter)34 AndFilter (org.apache.druid.segment.filter.AndFilter)34 OrFilter (org.apache.druid.segment.filter.OrFilter)33 BoundDimFilter (org.apache.druid.query.filter.BoundDimFilter)30 BoundFilter (org.apache.druid.segment.filter.BoundFilter)30 SelectorFilter (org.apache.druid.segment.filter.SelectorFilter)30 ExpressionDimFilter (org.apache.druid.query.filter.ExpressionDimFilter)27 InDimFilter (org.apache.druid.query.filter.InDimFilter)27 FalseFilter (org.apache.druid.segment.filter.FalseFilter)27 JoinFilterPreAnalysis (org.apache.druid.segment.join.filter.JoinFilterPreAnalysis)27 JoinFilterSplit (org.apache.druid.segment.join.filter.JoinFilterSplit)26 Test (org.junit.Test)26 IndexedTableJoinable (org.apache.druid.segment.join.table.IndexedTableJoinable)5 ExpressionVirtualColumn (org.apache.druid.segment.virtual.ExpressionVirtualColumn)5 ArrayList (java.util.ArrayList)4 AndDimFilter (org.apache.druid.query.filter.AndDimFilter)3 BooleanFilter (org.apache.druid.query.filter.BooleanFilter)3 DimFilter (org.apache.druid.query.filter.DimFilter)3 OrDimFilter (org.apache.druid.query.filter.OrDimFilter)3 SelectorDimFilter (org.apache.druid.query.filter.SelectorDimFilter)3