use of com.apple.foundationdb.record.query.plan.planning.FilterSatisfiedMask in project fdb-record-layer by FoundationDB.
the class ComposedBitmapIndexAggregate method separateGroupFilters.
private static boolean separateGroupFilters(@Nonnull QueryComponent filter, @Nonnull IndexAggregateFunctionCall indexAggregateFunctionCall, @Nonnull List<QueryComponent> commonFilters, @Nonnull List<QueryComponent> indexFilters) {
QueryToKeyMatcher matcher = new QueryToKeyMatcher(filter);
FilterSatisfiedMask filterMask = FilterSatisfiedMask.of(filter);
QueryToKeyMatcher.Match match = matcher.matchesCoveringKey(indexAggregateFunctionCall.getGroupingKeyExpression().getGroupingSubKey(), filterMask);
if (match.getType() != QueryToKeyMatcher.MatchType.EQUALITY) {
// Did not manage to fully restrict the grouping key.
return false;
}
// The position key(s) can also be constrained with inequalities and those go among the group filters.
matcher.matchesCoveringKey(indexAggregateFunctionCall.getGroupedExpression(), filterMask);
if (filterMask.allSatisfied()) {
// Not enough conditions left over.
return false;
}
for (FilterSatisfiedMask child : filterMask.getChildren()) {
// Any left-over filter not matching either of those must match some per-index key.
if (child.allSatisfied()) {
commonFilters.add(child.getFilter());
} else {
indexFilters.add(child.getFilter());
}
}
return true;
}
use of com.apple.foundationdb.record.query.plan.planning.FilterSatisfiedMask in project fdb-record-layer by FoundationDB.
the class QueryToKeyMatcher method matches.
@Nonnull
private Match matches(@Nonnull AndComponent query, @Nonnull KeyExpression key, @Nonnull MatchingMode matchingMode, @Nullable FilterSatisfiedMask filterMask) {
final List<QueryComponent> listOfQueries = query.getChildren();
final Iterator<KeyExpression> keyChildIterator;
final int keyChildSize = key.getColumnSize();
if (key instanceof ThenKeyExpression) {
List<KeyExpression> children = ((ThenKeyExpression) key).getChildren();
keyChildIterator = children.iterator();
} else {
keyChildIterator = Iterators.singletonIterator(key);
}
// Keep a local mask so that if we can only partially fulfill queries we don't pollute the main
// one with our state
FilterSatisfiedMask localMask = FilterSatisfiedMask.of(query);
localMask.setExpression(key);
List<Comparison> comparisons = new ArrayList<>(keyChildSize);
while (keyChildIterator.hasNext()) {
KeyExpression exp = keyChildIterator.next();
// Look for a query segment that matches this expression
boolean found = false;
boolean foundInequality = false;
final Iterator<FilterSatisfiedMask> childMaskIterator = localMask.getChildren().iterator();
for (QueryComponent querySegment : listOfQueries) {
Match match = matches(querySegment, exp, matchingMode, childMaskIterator.next());
if (match.getType() != MatchType.NO_MATCH) {
found = true;
comparisons.addAll(match.getComparisons());
if (match.getType() == MatchType.INEQUALITY) {
foundInequality = true;
}
break;
}
}
if (!found) {
return Match.none();
}
// Only the last comparison in the list can be inequality.
if (localMask.allSatisfied() || foundInequality) {
break;
}
}
if (matchingMode.equals(MatchingMode.SATISFY_QUERY) && !localMask.allSatisfied() || matchingMode.equals(MatchingMode.COVER_KEY) && comparisons.size() < keyChildSize) {
// filters that have not yet been satisfied.
return Match.none();
}
if (filterMask != null) {
filterMask.mergeWith(localMask);
}
return new Match(comparisons);
}
use of com.apple.foundationdb.record.query.plan.planning.FilterSatisfiedMask in project fdb-record-layer by FoundationDB.
the class QueryToKeyMatcher method matches.
@Nonnull
private Match matches(@Nonnull OneOfThemWithComponent query, @Nonnull NestingKeyExpression key, @Nonnull MatchingMode matchingMode, @Nullable FilterSatisfiedMask filterMask) {
if (key.getParent().getFanType() != KeyExpression.FanType.FanOut) {
return Match.none();
} else {
if (Objects.equals(query.getFieldName(), key.getParent().getFieldName())) {
FilterSatisfiedMask childMask = filterMask != null ? filterMask.getChild(query.getChild()) : null;
Match childMatch = matches(query.getChild(), key.getChild(), matchingMode, childMask);
if (childMask != null && childMask.isSatisfied() && filterMask.getExpression() == null) {
filterMask.setExpression(key);
}
return childMatch;
} else {
return Match.none();
}
}
}
Aggregations