use of com.apple.foundationdb.record.query.expressions.QueryComponent 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.expressions.QueryComponent in project fdb-record-layer by FoundationDB.
the class CombineFilterRuleTest method doesNotMatchSingleFilter.
@Test
public void doesNotMatchSingleFilter() {
for (RecordQueryPlan basePlan : basePlans) {
QueryComponent filter1 = Query.field("testField").equalsValue(5);
GroupExpressionRef<RelationalExpression> root = GroupExpressionRef.of(buildLogicalFilter(filter1, basePlan));
TestRuleExecution execution = TestRuleExecution.applyRule(blankContext, rule, root);
assertFalse(execution.isRuleMatched());
}
}
use of com.apple.foundationdb.record.query.expressions.QueryComponent in project fdb-record-layer by FoundationDB.
the class FDBLuceneQueryTest method delayFetchOnAndOfLuceneAndFieldFilter.
@ParameterizedTest
@BooleanSource
public void delayFetchOnAndOfLuceneAndFieldFilter(boolean shouldDeferFetch) throws Exception {
initializeFlat();
try (FDBRecordContext context = openContext()) {
openRecordStore(context);
final QueryComponent filter1 = new LuceneQueryComponent("civil blood makes civil hands unclean", Lists.newArrayList());
// Query for full records
QueryComponent filter2 = Query.field("doc_id").equalsValue(2L);
RecordQuery query = RecordQuery.newBuilder().setRecordType(TextIndexTestUtils.SIMPLE_DOC).setFilter(Query.and(filter2, filter1)).build();
setDeferFetchAfterUnionAndIntersection(shouldDeferFetch);
RecordQueryPlan plan = planner.plan(query);
Matcher<RecordQueryPlan> scanMatcher = fetch(filter(filter2, coveringIndexScan(indexScan(allOf(indexScanType(IndexScanType.BY_LUCENE_FULL_TEXT), indexScan("Complex$text_index"), bounds(hasTupleString("[[civil blood makes civil hands unclean],[civil blood makes civil hands unclean]]")))))));
assertThat(plan, scanMatcher);
RecordCursor<FDBQueriedRecord<Message>> primaryKeys;
primaryKeys = recordStore.executeQuery(plan);
final List<Long> keys = primaryKeys.map(FDBQueriedRecord::getPrimaryKey).map(t -> t.getLong(0)).asList().get();
assertEquals(ImmutableSet.of(2L), ImmutableSet.copyOf(keys));
if (shouldDeferFetch) {
assertLoadRecord(3, context);
} else {
assertLoadRecord(4, context);
}
}
}
use of com.apple.foundationdb.record.query.expressions.QueryComponent in project fdb-record-layer by FoundationDB.
the class FDBLuceneQueryTest method delayFetchOnOrOfLuceneFiltersGivesUnion.
@ParameterizedTest
@BooleanSource
public void delayFetchOnOrOfLuceneFiltersGivesUnion(boolean shouldDeferFetch) throws Exception {
initializeFlat();
try (FDBRecordContext context = openContext()) {
openRecordStore(context);
final QueryComponent filter1 = new LuceneQueryComponent("(civil blood makes civil hands unclean)", Lists.newArrayList("text"), true);
final QueryComponent filter2 = new LuceneQueryComponent("(was king from 966 to 1016)", Lists.newArrayList());
// Query for full records
RecordQuery query = RecordQuery.newBuilder().setRecordType(TextIndexTestUtils.SIMPLE_DOC).setFilter(Query.or(filter1, filter2)).build();
setDeferFetchAfterUnionAndIntersection(shouldDeferFetch);
RecordQueryPlan plan = planner.plan(query);
Matcher<RecordQueryPlan> matcher = union(indexScan(allOf(indexScan("Complex$text_index"), indexScanType(IndexScanType.BY_LUCENE_FULL_TEXT), bounds(hasTupleString("[[(civil blood makes civil hands unclean)],[(civil blood makes civil hands unclean)]]")))), indexScan(allOf(indexScan("Complex$text_index"), indexScanType(IndexScanType.BY_LUCENE_FULL_TEXT), bounds(hasTupleString("[[(was king from 966 to 1016)],[(was king from 966 to 1016)]]")))), equalTo(field("doc_id")));
if (shouldDeferFetch) {
matcher = fetch(union(coveringIndexScan(indexScan(allOf(indexScan("Complex$text_index"), indexScanType(IndexScanType.BY_LUCENE_FULL_TEXT), bounds(hasTupleString("[[(civil blood makes civil hands unclean)],[(civil blood makes civil hands unclean)]]"))))), coveringIndexScan(indexScan(allOf(indexScan("Complex$text_index"), indexScanType(IndexScanType.BY_LUCENE_FULL_TEXT), bounds(hasTupleString("[[(was king from 966 to 1016)],[(was king from 966 to 1016)]]"))))), equalTo(field("doc_id"))));
}
assertThat(plan, matcher);
List<Long> primaryKeys = recordStore.executeQuery(plan).map(FDBQueriedRecord::getPrimaryKey).map(t -> t.getLong(0)).asList().get();
assertEquals(ImmutableSet.of(1L, 2L, 4L), ImmutableSet.copyOf(primaryKeys));
if (shouldDeferFetch) {
assertLoadRecord(5, context);
} else {
assertLoadRecord(6, context);
}
}
}
use of com.apple.foundationdb.record.query.expressions.QueryComponent in project fdb-record-layer by FoundationDB.
the class FDBLuceneQueryTest method delayFetchOnAndOfLuceneFilters.
@ParameterizedTest
@BooleanSource
public void delayFetchOnAndOfLuceneFilters(boolean shouldDeferFetch) throws Exception {
initializeFlat();
try (FDBRecordContext context = openContext()) {
openRecordStore(context);
final QueryComponent filter1 = new LuceneQueryComponent("the continuance", Lists.newArrayList());
final QueryComponent filter2 = new LuceneQueryComponent("grudge", Lists.newArrayList());
// Query for full records
RecordQuery query = RecordQuery.newBuilder().setRecordType(TextIndexTestUtils.SIMPLE_DOC).setFilter(Query.and(filter1, filter2)).build();
setDeferFetchAfterUnionAndIntersection(shouldDeferFetch);
RecordQueryPlan plan = planner.plan(query);
Matcher<RecordQueryPlan> matcher = indexScan(allOf(indexScanType(IndexScanType.BY_LUCENE_FULL_TEXT), indexName("Complex$text_index"), bounds(hasTupleString("[[(the continuance) AND (grudge)],[(the continuance) AND (grudge)]]"))));
assertThat(plan, matcher);
List<Long> primaryKeys = recordStore.executeQuery(plan).map(FDBQueriedRecord::getPrimaryKey).map(t -> t.getLong(0)).asList().get();
assertEquals(ImmutableSet.of(4L), ImmutableSet.copyOf(primaryKeys));
if (shouldDeferFetch) {
assertLoadRecord(3, context);
} else {
assertLoadRecord(4, context);
}
}
}
Aggregations