use of com.apple.foundationdb.record.query.predicates.QueryPredicate in project fdb-record-layer by FoundationDB.
the class BooleanPredicateNormalizerTest method cnf.
@Test
void cnf() {
final List<QueryPredicate> conjuncts = new ArrayList<>();
for (int i = 0; i < 5; i++) {
final List<QueryPredicate> disjuncts = new ArrayList<>();
for (int j = 0; j < 5; j++) {
disjuncts.add(new ValuePredicate(F, new Comparisons.SimpleComparison(Comparisons.Type.EQUALS, i * 4 + j)));
}
conjuncts.add(or(disjuncts));
}
final QueryPredicate cnf = and(conjuncts);
final BooleanPredicateNormalizer normalizer = BooleanPredicateNormalizer.getDefaultInstanceForDnf();
assertNotEquals(cnf, normalizer.normalize(cnf).orElse(cnf));
assertTrue(numberOfOrTerms(Objects.requireNonNull(normalizer.normalize(cnf).orElse(cnf))) <= normalizer.getNormalizedSize(cnf));
final BooleanPredicateNormalizer lowLimitNormalizer = BooleanPredicateNormalizer.withLimit(DNF, 2);
assertThrows(BooleanPredicateNormalizer.NormalFormTooLargeException.class, () -> lowLimitNormalizer.normalize(cnf));
assertEquals(cnf, lowLimitNormalizer.normalizeIfPossible(cnf).orElse(cnf));
}
use of com.apple.foundationdb.record.query.predicates.QueryPredicate in project fdb-record-layer by FoundationDB.
the class BooleanPredicateNormalizerTest method bigNonCnf.
@Test
void bigNonCnf() {
final QueryPredicate cnf = and(IntStream.rangeClosed(1, 9).boxed().map(i -> or(IntStream.rangeClosed(1, 9).boxed().map(j -> and(new ValuePredicate(new FieldValue(QuantifiedColumnValue.of(CorrelationIdentifier.UNGROUNDED, 0), ImmutableList.of("num_value_3_indexed")), new Comparisons.SimpleComparison(Comparisons.Type.EQUALS, i * 9 + j)), new ValuePredicate(new FieldValue(QuantifiedColumnValue.of(CorrelationIdentifier.UNGROUNDED, 0), ImmutableList.of("str_value_indexed")), new Comparisons.SimpleComparison(Comparisons.Type.EQUALS, "foo")))).collect(Collectors.toList()))).collect(Collectors.toList()));
final BooleanPredicateNormalizer plannerNormalizer = BooleanPredicateNormalizer.forConfiguration(DNF, RecordQueryPlannerConfiguration.builder().build());
assertThrows(BooleanPredicateNormalizer.NormalFormTooLargeException.class, () -> plannerNormalizer.normalize(cnf));
assertEquals(cnf, plannerNormalizer.normalizeIfPossible(cnf).orElse(cnf));
}
use of com.apple.foundationdb.record.query.predicates.QueryPredicate in project fdb-record-layer by FoundationDB.
the class BooleanPredicateNormalizerTest method complexRoundTrip.
@Test
void complexRoundTrip() {
assertExpectedDnf(or(and(P1, P2), and(P1, P3), and(P1, P4), and(P1, P5)), and(P1, or(P2, P3, P4, P5)));
assertExpectedCnf(and(P1, or(P2, P3, P4, P5)), or(and(P1, P2), and(P1, P3), and(P1, P4), and(P1, P5)));
// take an original predicate and DNF it, then CNF it, and DNF its result again
assertExpectedDnf(or(and(P1, P2, P3), and(P1, P4, P5)), and(P1, or(and(P2, P3), and(P4, P5))));
assertExpectedCnf(and(P1, or(P2, P4), or(P3, P4), or(P2, P5), or(P3, P5)), or(and(P1, P2, P3), and(P1, P4, P5)));
assertExpectedDnf(or(and(P1, P2, P3), and(P1, P4, P5)), and(P1, or(P2, P4), or(P3, P4), or(P2, P5), or(P3, P5)));
final BooleanPredicateNormalizer forCnf = BooleanPredicateNormalizer.getDefaultInstanceForCnf();
final BooleanPredicateNormalizer forDnf = BooleanPredicateNormalizer.getDefaultInstanceForDnf();
final QueryPredicate original = and(P1, or(and(P2, P3), and(P4, P5), and(P6, P7)));
final QueryPredicate expectedDnf = or(and(P1, P2, P3), and(P1, P4, P5), and(P1, P6, P7));
assertEquals(expectedDnf, forDnf.normalize(original).orElse(original));
// original -> cnf -> dnf
assertEquals(expectedDnf, forDnf.normalize(forCnf.normalize(original).orElse(original)).orElse(original));
// expected dnf -> cnf -> dnf
assertEquals(expectedDnf, forDnf.normalize(forCnf.normalize(expectedDnf).orElse(expectedDnf)).orElse(expectedDnf));
}
use of com.apple.foundationdb.record.query.predicates.QueryPredicate in project fdb-record-layer by FoundationDB.
the class ExpressionMatcherTest method treeDescentWithMixedBindings.
@Test
public void treeDescentWithMixedBindings() {
// build a relatively complicated matcher
BindingMatcher<? extends ExpressionRef<? extends RelationalExpression>> filterLeafMatcher = ReferenceMatchers.anyRef();
BindingMatcher<QueryPredicate> predicateMatcher = QueryPredicateMatchers.anyPredicate();
final BindingMatcher<LogicalFilterExpression> filterPlanMatcher = RelationalExpressionMatchers.logicalFilterExpression(MultiMatcher.AllMatcher.all(predicateMatcher), AnyMatcher.any(QuantifierMatchers.forEachQuantifierOverRef(filterLeafMatcher)));
BindingMatcher<RecordQueryScanPlan> scanMatcher = RecordQueryPlanMatchers.scanPlan();
BindingMatcher<LogicalUnionExpression> matcher = RelationalExpressionMatchers.logicalUnionExpression(ListMatcher.exactly(QuantifierMatchers.forEachQuantifier(filterPlanMatcher), QuantifierMatchers.forEachQuantifier(scanMatcher)));
// build a relatively complicated expression
QueryComponent andBranch1 = Query.field("field1").greaterThan(6);
QueryComponent andBranch2 = Query.field("field2").equalsParameter("param");
IndexScanParameters fullValueScan = IndexScanComparisons.byValue();
final Quantifier.ForEach quantifier = Quantifier.forEach(GroupExpressionRef.of(new RecordQueryIndexPlan("an_index", fullValueScan, true)));
LogicalFilterExpression filterPlan = new LogicalFilterExpression(Query.and(andBranch1, andBranch2).expand(quantifier.getAlias()).getPredicates(), quantifier);
RecordQueryScanPlan scanPlan = new RecordQueryScanPlan(ScanComparisons.EMPTY, true);
RelationalExpression root = new LogicalUnionExpression(Quantifiers.forEachQuantifiers(ImmutableList.of(GroupExpressionRef.of(filterPlan), GroupExpressionRef.of(scanPlan))));
assertTrue(filterPlanMatcher.bindMatches(PlannerBindings.empty(), filterPlan).findFirst().isPresent());
// try to bind
Optional<PlannerBindings> possibleBindings = matcher.bindMatches(PlannerBindings.empty(), root).findFirst();
// check that all the bindings match what we expect
assertTrue(possibleBindings.isPresent());
PlannerBindings bindings = possibleBindings.get().mergedWith(getExistingBindings());
assertEquals(root, bindings.get(matcher));
assertEquals(filterPlan, bindings.get(filterPlanMatcher));
assertEquals(scanPlan, bindings.get(scanMatcher));
assertEquals(filterPlan.getPredicates(), bindings.getAll(predicateMatcher));
// dereference
assertEquals(filterPlan.getInner().getRangesOver().get(), bindings.get(filterLeafMatcher).get());
}
use of com.apple.foundationdb.record.query.predicates.QueryPredicate in project fdb-record-layer by FoundationDB.
the class PredicateMultiMap method checkConflicts.
private static Optional<SetMultimap<QueryPredicate, PredicateMapping>> checkConflicts(@Nonnull final SetMultimap<QueryPredicate, PredicateMapping> map) {
final Set<QueryPredicate> seenCandidatePredicates = Sets.newIdentityHashSet();
for (final QueryPredicate queryPredicate : map.keySet()) {
final Set<PredicateMapping> candidatePredicateMappings = map.get(queryPredicate);
for (final PredicateMapping candidatePredicateMapping : candidatePredicateMappings) {
final QueryPredicate candidatePredicate = candidatePredicateMapping.getCandidatePredicate();
if (seenCandidatePredicates.contains(candidatePredicate)) {
return Optional.empty();
}
seenCandidatePredicates.add(candidatePredicate);
}
}
return Optional.of(map);
}
Aggregations