use of io.druid.query.filter.AndDimFilter in project druid by druid-io.
the class Expressions method toFilter.
/**
* Translates "condition" to a Druid filter, or returns null if we cannot translate the condition.
*
* @param plannerContext planner context
* @param rowSignature row signature of the dataSource to be filtered
* @param expression Calcite row expression
*/
public static DimFilter toFilter(final DruidOperatorTable operatorTable, final PlannerContext plannerContext, final RowSignature rowSignature, final RexNode expression) {
if (expression.getKind() == SqlKind.AND || expression.getKind() == SqlKind.OR || expression.getKind() == SqlKind.NOT) {
final List<DimFilter> filters = Lists.newArrayList();
for (final RexNode rexNode : ((RexCall) expression).getOperands()) {
final DimFilter nextFilter = toFilter(operatorTable, plannerContext, rowSignature, rexNode);
if (nextFilter == null) {
return null;
}
filters.add(nextFilter);
}
if (expression.getKind() == SqlKind.AND) {
return new AndDimFilter(filters);
} else if (expression.getKind() == SqlKind.OR) {
return new OrDimFilter(filters);
} else {
assert expression.getKind() == SqlKind.NOT;
return new NotDimFilter(Iterables.getOnlyElement(filters));
}
} else {
// Handle filter conditions on everything else.
return toLeafFilter(operatorTable, plannerContext, rowSignature, expression);
}
}
use of io.druid.query.filter.AndDimFilter in project druid by druid-io.
the class CombineAndSimplifyBounds method process.
@Override
public DimFilter process(DimFilter filter) {
if (filter instanceof AndDimFilter) {
final List<DimFilter> children = getAndFilterChildren((AndDimFilter) filter);
final DimFilter one = doSimplifyAnd(children);
final DimFilter two = negate(doSimplifyOr(negateAll(children)));
return computeCost(one) <= computeCost(two) ? one : two;
} else if (filter instanceof OrDimFilter) {
final List<DimFilter> children = getOrFilterChildren((OrDimFilter) filter);
final DimFilter one = doSimplifyOr(children);
final DimFilter two = negate(doSimplifyAnd(negateAll(children)));
return computeCost(one) <= computeCost(two) ? one : two;
} else if (filter instanceof NotDimFilter) {
final DimFilter field = ((NotDimFilter) filter).getField();
final DimFilter candidate;
if (field instanceof OrDimFilter) {
candidate = doSimplifyAnd(negateAll(getOrFilterChildren((OrDimFilter) field)));
} else if (field instanceof AndDimFilter) {
candidate = doSimplifyOr(negateAll(getAndFilterChildren((AndDimFilter) field)));
} else {
candidate = negate(field);
}
return computeCost(filter) <= computeCost(candidate) ? filter : candidate;
} else {
return filter;
}
}
use of io.druid.query.filter.AndDimFilter 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 disjunction, false for conjunction
*
* @return simplified filters
*/
private static DimFilter doSimplify(final List<DimFilter> children, boolean disjunction) {
// Copy children list
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 = Maps.newHashMap();
final Iterator<DimFilter> iterator = newChildren.iterator();
while (iterator.hasNext()) {
final DimFilter child = iterator.next();
if (child.equals(Filtration.matchNothing())) {
// AND with FALSE => always false, short circuit
if (disjunction) {
iterator.remove();
} else {
return Filtration.matchNothing();
}
} else if (child.equals(Filtration.matchEverything())) {
// AND with TRUE => ignore
if (disjunction) {
return Filtration.matchEverything();
} else {
iterator.remove();
}
} else if (child instanceof BoundDimFilter) {
final BoundDimFilter bound = (BoundDimFilter) child;
final BoundRefKey boundRefKey = BoundRefKey.from(bound);
List<BoundDimFilter> filterList = bounds.get(boundRefKey);
if (filterList == null) {
filterList = Lists.newArrayList();
bounds.put(boundRefKey, filterList);
}
filterList.add(bound);
}
}
// 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)) {
throw new ISE("WTF?! Tried to remove bound but couldn't?");
}
}
if (rangeSet.asRanges().isEmpty()) {
// AND with FALSE => always false, short circuit
if (disjunction) {
newChildren.add(Filtration.matchNothing());
} else {
return Filtration.matchNothing();
}
}
for (final Range<BoundValue> range : rangeSet.asRanges()) {
if (!range.hasLowerBound() && !range.hasUpperBound()) {
// OR with TRUE => always true; short circuit
if (disjunction) {
return Filtration.matchEverything();
} else {
newChildren.add(Filtration.matchEverything());
}
} else {
newChildren.add(Bounds.toFilter(boundRefKey, range));
}
}
}
}
Preconditions.checkState(newChildren.size() > 0, "newChildren.size > 0");
if (newChildren.size() == 1) {
return newChildren.get(0);
} else {
return disjunction ? new OrDimFilter(newChildren) : new AndDimFilter(newChildren);
}
}
use of io.druid.query.filter.AndDimFilter in project druid by druid-io.
the class AndFilterTest method testNotAnd.
@Test
public void testNotAnd() {
assertFilterMatches(new NotDimFilter(new AndDimFilter(ImmutableList.<DimFilter>of(new SelectorDimFilter("dim0", "0", null), new SelectorDimFilter("dim1", "0", null)))), ImmutableList.of("1", "2", "3", "4", "5"));
assertFilterMatches(new NotDimFilter(new AndDimFilter(ImmutableList.<DimFilter>of(new SelectorDimFilter("dim0", "0", null), new SelectorDimFilter("dim1", "1", null)))), ImmutableList.<String>of("0", "1", "2", "3", "4", "5"));
assertFilterMatches(new NotDimFilter(new AndDimFilter(ImmutableList.<DimFilter>of(new SelectorDimFilter("dim0", "1", null), new SelectorDimFilter("dim1", "0", null)))), ImmutableList.of("0", "2", "3", "4", "5"));
assertFilterMatches(new NotDimFilter(new AndDimFilter(ImmutableList.<DimFilter>of(new SelectorDimFilter("dim0", "1", null), new SelectorDimFilter("dim1", "1", null)))), ImmutableList.<String>of("0", "1", "2", "3", "4", "5"));
assertFilterMatches(new NotDimFilter(new AndDimFilter(ImmutableList.<DimFilter>of(new NotDimFilter(new SelectorDimFilter("dim0", "1", null)), new NotDimFilter(new SelectorDimFilter("dim1", "1", null))))), ImmutableList.of("1"));
assertFilterMatches(new NotDimFilter(new AndDimFilter(ImmutableList.<DimFilter>of(new NotDimFilter(new SelectorDimFilter("dim0", "0", null)), new NotDimFilter(new SelectorDimFilter("dim1", "0", null))))), ImmutableList.<String>of("0", "1", "2", "3", "4", "5"));
}
use of io.druid.query.filter.AndDimFilter in project druid by druid-io.
the class FilterPartitionTest method testDistributeOrCNF.
@Test
public void testDistributeOrCNF() {
DimFilter dimFilter1 = new OrDimFilter(Arrays.<DimFilter>asList(new SelectorDimFilter("dim0", "6", null), new AndDimFilter(Arrays.<DimFilter>asList(new NoBitmapSelectorDimFilter("dim1", "def", null), new SelectorDimFilter("dim2", "c", null)))));
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", "2", null), new SelectorDimFilter("dim0", "3", null), new AndDimFilter(Arrays.<DimFilter>asList(new NoBitmapSelectorDimFilter("dim1", "HELLO", null), new SelectorDimFilter("dim2", "foo", null)))));
assertFilterMatches(dimFilter2, ImmutableList.of("2", "3", "7"));
DimFilter dimFilter3 = new OrDimFilter(Arrays.<DimFilter>asList(dimFilter1, dimFilter2, new AndDimFilter(Arrays.<DimFilter>asList(new NoBitmapSelectorDimFilter("dim1", "1", null), new SelectorDimFilter("dim2", "foo", null)))));
assertFilterMatches(dimFilter3, ImmutableList.of("2", "3", "4", "6", "7", "9"));
}
Aggregations