use of com.apple.foundationdb.record.query.plan.temp.matchers.BindingMatcher in project fdb-record-layer by FoundationDB.
the class FDBCoveringIndexQueryTest method coveringWithAdditionalFilter.
/**
* Verify that a filter not satisfied by the index scan itself but using fields present in the index
* can still allow a covering scan with the filter on the partial records.
*/
@DualPlannerTest
void coveringWithAdditionalFilter() throws Exception {
RecordMetaDataHook hook = metaData -> {
metaData.removeIndex("MySimpleRecord$num_value_3_indexed");
metaData.addIndex("MySimpleRecord", new Index("multi_index", "num_value_3_indexed", "num_value_2"));
};
complexQuerySetup(hook);
RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.and(Query.field("num_value_3_indexed").lessThan(1), Query.field("num_value_2").lessThan(2))).setRequiredResults(Collections.singletonList(field("num_value_3_indexed"))).build();
// Covering(Index(multi_index ([null],[1])) -> [num_value_2: KEY[1], num_value_3_indexed: KEY[0], rec_no: KEY[2]]) | num_value_2 LESS_THAN 2
RecordQueryPlan plan = planner.plan(query);
if (planner instanceof RecordQueryPlanner) {
final BindingMatcher<? extends RecordQueryPlan> planMatcher = filterPlan(coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("multi_index")).and(scanComparisons(range("([null],[1])")))))).where(queryComponents(exactly(equalsObject(Query.field("num_value_2").lessThan(2)))));
assertMatchesExactly(plan, planMatcher);
assertEquals(-1374002128, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(1359983418, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-1492450855, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
} else {
final BindingMatcher<? extends RecordQueryPlan> planMatcher = predicatesFilterPlan(coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("multi_index")).and(scanComparisons(range("([null],[1])")))))).where(predicates(only(valuePredicate(fieldValue("num_value_2"), new Comparisons.SimpleComparison(Comparisons.Type.LESS_THAN, 2)))));
assertMatchesExactly(plan, planMatcher);
assertEquals(762957369, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(-2135370744, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-692837721, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
}
}
use of com.apple.foundationdb.record.query.plan.temp.matchers.BindingMatcher in project fdb-record-layer by FoundationDB.
the class FDBCoveringIndexQueryTest method coveringConcatenatedFields.
/**
* Verify that if given a concatenated required-results field that a covering index is returned.
*/
@DualPlannerTest
void coveringConcatenatedFields() throws Exception {
RecordMetaDataHook hook = metaData -> metaData.addIndex("MySimpleRecord", "MySimpleRecord$2+3", concatenateFields("num_value_2", "num_value_3_indexed"));
complexQuerySetup(hook);
RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.and(Query.field("num_value_2").greaterThan(0), Query.field("num_value_2").lessThan(10))).setRequiredResults(Collections.singletonList(concatenateFields("num_value_2", "num_value_3_indexed"))).build();
// Covering(Index(MySimpleRecord$2+3 ([0],[10])) -> [num_value_2: KEY[0], num_value_3_indexed: KEY[1], rec_no: KEY[2]])
RecordQueryPlan plan = planner.plan(query);
final BindingMatcher<? extends RecordQueryPlan> planMatcher = coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("MySimpleRecord$2+3")).and(scanComparisons(range("([0],[10])")))));
assertMatchesExactly(plan, planMatcher);
assertEquals(1722836804, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(-992322107, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(2083564653, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
try (FDBRecordContext context = openContext()) {
openSimpleRecordStore(context, hook);
try (RecordCursorIterator<FDBQueriedRecord<Message>> cursor = recordStore.executeQuery(plan).asIterator()) {
while (cursor.hasNext()) {
FDBQueriedRecord<Message> rec = cursor.next();
TestRecords1Proto.MySimpleRecord.Builder myrec = TestRecords1Proto.MySimpleRecord.newBuilder();
myrec.mergeFrom(Objects.requireNonNull(rec).getRecord());
assertThat(myrec.getNumValue2(), greaterThan(0));
assertThat(myrec.getNumValue2(), lessThan(10));
assertThat(myrec.hasNumValue3Indexed(), is(true));
}
}
commit(context);
assertDiscardedNone(context);
}
}
use of com.apple.foundationdb.record.query.plan.temp.matchers.BindingMatcher in project fdb-record-layer by FoundationDB.
the class FDBCoveringIndexQueryTest method notCoveringWithRequiredFieldsNotAvailable.
/**
* Verify that covering indexes are not used when the an outer "header" field is missing from the primary key,
* even though the index has all of the fields that the query actually asks for.
*/
@DualPlannerTest
void notCoveringWithRequiredFieldsNotAvailable() throws Exception {
RecordMetaDataHook hook = metaData -> {
metaData.getRecordType("MyRecord").setPrimaryKey(field("header").nest(field("rec_no")));
metaData.addIndex("MyRecord", "str_value");
};
try (FDBRecordContext context = openContext()) {
openRecordWithHeader(context, hook);
}
RecordQuery query = RecordQuery.newBuilder().setRecordType("MyRecord").setFilter(Query.field("str_value").equalsValue("lion")).setRequiredResults(Collections.singletonList(field("header").nest("rec_no"))).build();
// Index(MyRecord$str_value [[lion],[lion]])
RecordQueryPlan plan = planner.plan(query);
final BindingMatcher<? extends RecordQueryPlan> planMatcher = indexPlan().where(indexName("MyRecord$str_value")).and(scanComparisons(range("[[lion],[lion]]")));
assertMatchesExactly(plan, planMatcher);
assertEquals(-629018945, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(2065541259, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-2063034193, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
}
use of com.apple.foundationdb.record.query.plan.temp.matchers.BindingMatcher in project fdb-record-layer by FoundationDB.
the class FDBOrQueryToUnionTest method testOrQueryNoIndex.
/**
* Verify that queries with an OR of predicates with a common scan and different filters does not bother with a Union.
*/
@DualPlannerTest
void testOrQueryNoIndex() throws Exception {
RecordMetaDataHook hook = metadata -> metadata.removeIndex("MySimpleRecord$num_value_3_indexed");
complexQuerySetup(hook);
QueryComponent orComponent = Query.or(Query.field("num_value_3_indexed").equalsValue(1), Query.field("num_value_3_indexed").equalsValue(2), Query.field("num_value_3_indexed").equalsValue(4));
RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.and(Query.field("str_value_indexed").equalsValue("even"), orComponent)).build();
// Index(MySimpleRecord$str_value_indexed [[even],[even]]) | Or([num_value_3_indexed EQUALS 1, num_value_3_indexed EQUALS 2, num_value_3_indexed EQUALS 4])
RecordQueryPlan plan = planner.plan(query);
if (planner instanceof RecordQueryPlanner) {
final BindingMatcher<? extends RecordQueryPlan> planMatcher = filterPlan(indexPlan().where(indexName("MySimpleRecord$str_value_indexed")).and(scanComparisons(range("[[even],[even]]")))).where(queryComponents(exactly(equalsObject(orComponent))));
assertMatchesExactly(plan, planMatcher);
assertEquals(-1553701984, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(1108620348, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(1573180943, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
} else {
final BindingMatcher<? extends RecordQueryPlan> planMatcher = predicatesFilterPlan(indexPlan().where(indexName("MySimpleRecord$str_value_indexed")).and(scanComparisons(range("[[even],[even]]")))).where(predicates(only(orPredicate(exactly(valuePredicate(fieldValue("num_value_3_indexed"), new Comparisons.SimpleComparison(Comparisons.Type.EQUALS, 1)), valuePredicate(fieldValue("num_value_3_indexed"), new Comparisons.SimpleComparison(Comparisons.Type.EQUALS, 2)), valuePredicate(fieldValue("num_value_3_indexed"), new Comparisons.SimpleComparison(Comparisons.Type.EQUALS, 4)))))));
assertMatchesExactly(plan, planMatcher);
assertEquals(-1029166388, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(1957223857, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-1873182844, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
}
try (FDBRecordContext context = openContext()) {
openSimpleRecordStore(context, hook);
int i = 0;
try (RecordCursorIterator<FDBQueriedRecord<Message>> cursor = recordStore.executeQuery(plan).asIterator()) {
while (cursor.hasNext()) {
FDBQueriedRecord<Message> rec = cursor.next();
TestRecords1Proto.MySimpleRecord.Builder myrec = TestRecords1Proto.MySimpleRecord.newBuilder();
myrec.mergeFrom(Objects.requireNonNull(rec).getRecord());
assertEquals("even", myrec.getStrValueIndexed());
assertTrue(myrec.getNumValue3Indexed() == 1 || myrec.getNumValue3Indexed() == 2 || myrec.getNumValue3Indexed() == 4);
i++;
}
}
assertEquals(10 + 10 + 10, i);
assertDiscardedExactly(10 + 10, context);
}
}
Aggregations