use of com.apple.foundationdb.record.query.predicates.QueryPredicate in project fdb-record-layer by FoundationDB.
the class PushDistinctBelowFilterRule method onMatch.
@Override
public void onMatch(@Nonnull PlannerRuleCall call) {
final ExpressionRef<? extends RelationalExpression> inner = call.get(innerRefMatcher);
final Quantifier.Physical qun = call.get(innerQuantifierMatcher);
final RecordQueryPredicatesFilterPlan filterPlan = call.get(filterPlanMatcher);
final RecordQueryUnorderedPrimaryKeyDistinctPlan newDistinctPlan = new RecordQueryUnorderedPrimaryKeyDistinctPlan(Quantifier.physical(inner));
final Quantifier.Physical newQun = Quantifier.physical(call.ref(newDistinctPlan));
final List<QueryPredicate> rebasedPredicates = filterPlan.getPredicates().stream().map(queryPredicate -> queryPredicate.rebase(Quantifiers.translate(qun, newQun))).collect(ImmutableList.toImmutableList());
call.yield(call.ref(new RecordQueryPredicatesFilterPlan(newQun, rebasedPredicates)));
}
use of com.apple.foundationdb.record.query.predicates.QueryPredicate in project fdb-record-layer by FoundationDB.
the class ImplementFilterRule method onMatch.
@Override
public void onMatch(@Nonnull PlannerRuleCall call) {
final PlannerBindings bindings = call.getBindings();
final Collection<? extends RecordQueryPlan> innerPlans = bindings.get(innerPlansMatcher);
final Quantifier.ForEach innerQuantifier = bindings.get(innerQuantifierMatcher);
final List<? extends QueryPredicate> queryPredicates = bindings.getAll(filterMatcher);
final GroupExpressionRef<? extends RecordQueryPlan> referenceOverPlans = GroupExpressionRef.from(innerPlans);
if (queryPredicates.stream().allMatch(QueryPredicate::isTautology)) {
call.yield(referenceOverPlans);
} else {
call.yield(GroupExpressionRef.of(new RecordQueryPredicatesFilterPlan(Quantifier.physicalBuilder().morphFrom(innerQuantifier).build(referenceOverPlans), queryPredicates)));
}
}
use of com.apple.foundationdb.record.query.predicates.QueryPredicate in project fdb-record-layer by FoundationDB.
the class AbstractDataAccessRule method maximumCoverageMatches.
/**
* Private helper method to eliminate {@link PartialMatch}es whose coverage is entirely contained in other matches
* (among the matches given).
* @param matches candidate matches
* @param interestedOrderings a set of interesting orderings
* @return a list of {@link PartialMatch}es that are the maximum coverage matches among the matches handed in
*/
@Nonnull
@SuppressWarnings({ "java:S1905", "java:S135" })
private static List<PartialMatch> maximumCoverageMatches(@Nonnull final Collection<PartialMatch> matches, @Nonnull final Set<RequestedOrdering> interestedOrderings) {
final ImmutableList<Pair<PartialMatch, Map<QueryPredicate, BoundKeyPart>>> boundKeyPartMapsForMatches = matches.stream().filter(partialMatch -> !satisfiedOrderings(partialMatch, interestedOrderings).isEmpty()).map(partialMatch -> Pair.of(partialMatch, computeBoundKeyPartMap(partialMatch))).sorted(Comparator.comparing((Function<Pair<PartialMatch, Map<QueryPredicate, BoundKeyPart>>, Integer>) p -> p.getValue().size()).reversed()).collect(ImmutableList.toImmutableList());
final ImmutableList.Builder<PartialMatch> maximumCoverageMatchesBuilder = ImmutableList.builder();
for (int i = 0; i < boundKeyPartMapsForMatches.size(); i++) {
final PartialMatch outerMatch = boundKeyPartMapsForMatches.get(i).getKey();
final Map<QueryPredicate, BoundKeyPart> outer = boundKeyPartMapsForMatches.get(i).getValue();
boolean foundContainingInner = false;
for (int j = 0; j < boundKeyPartMapsForMatches.size(); j++) {
final Map<QueryPredicate, BoundKeyPart> inner = boundKeyPartMapsForMatches.get(j).getValue();
// check if outer is completely contained in inner
if (outer.size() >= inner.size()) {
break;
}
if (i != j) {
final boolean allContained = outer.entrySet().stream().allMatch(outerEntry -> inner.containsKey(outerEntry.getKey()));
if (allContained) {
foundContainingInner = true;
break;
}
}
}
if (!foundContainingInner) {
//
// no other partial match completely contained this one
//
maximumCoverageMatchesBuilder.add(outerMatch);
}
}
return maximumCoverageMatchesBuilder.build();
}
use of com.apple.foundationdb.record.query.predicates.QueryPredicate in project fdb-record-layer by FoundationDB.
the class BooleanPredicateNormalizerTest method assertExpectedNormalization.
protected static void assertExpectedNormalization(@Nonnull final BooleanPredicateNormalizer normalizer, @Nonnull final QueryPredicate expected, @Nonnull final QueryPredicate given) {
final QueryPredicate normalized = normalizer.normalize(given).orElse(given);
assertFilterEquals(expected, Objects.requireNonNull(normalized));
assertEquals(normalized, normalizer.normalize(normalized).orElse(normalized), "Normalized form should be stable");
}
use of com.apple.foundationdb.record.query.predicates.QueryPredicate in project fdb-record-layer by FoundationDB.
the class BooleanPredicateNormalizerTest method bigCnfThatWouldOverflow.
@Test
void bigCnfThatWouldOverflow() {
// A CNF who's DNF size doesn't fit in an int.
final List<QueryPredicate> conjuncts = new ArrayList<>();
for (int i = 0; i < 32; i++) {
final List<QueryPredicate> disjuncts = new ArrayList<>();
for (int j = 0; j < 2; j++) {
disjuncts.add(new ValuePredicate(F, new Comparisons.SimpleComparison(Comparisons.Type.EQUALS, i * 100 + j)));
}
conjuncts.add(or(disjuncts));
}
final QueryPredicate cnf = and(conjuncts);
final BooleanPredicateNormalizer normalizer = BooleanPredicateNormalizer.getDefaultInstanceForDnf();
assertThrows(ArithmeticException.class, () -> normalizer.getNormalizedSize(cnf));
assertThrows(BooleanPredicateNormalizer.NormalFormTooLargeException.class, () -> normalizer.normalize(cnf));
assertEquals(cnf, normalizer.normalizeIfPossible(cnf).orElse(cnf));
}
Aggregations