use of com.apple.foundationdb.record.query.plan.temp.matchers.BindingMatcher in project fdb-record-layer by FoundationDB.
the class FDBCoveringIndexQueryTest method coveringWithHeaderConcatenatedValue.
/**
* Verify that an index can be covering for concatenated nested fields in the value of the index.
*/
@DualPlannerTest
void coveringWithHeaderConcatenatedValue() throws Exception {
RecordMetaDataHook hook = metaData -> {
metaData.getRecordType("MyRecord").setPrimaryKey(field("header").nest(field("rec_no")));
metaData.addIndex("MyRecord", new Index("MyRecord$str_value", field("str_value"), field("header").nest(concatenateFields("path", "num")), IndexTypes.VALUE, Collections.emptyMap()));
};
try (FDBRecordContext context = openContext()) {
openRecordWithHeader(context, hook);
}
RecordQuery query = RecordQuery.newBuilder().setRecordType("MyRecord").setFilter(Query.field("str_value").equalsValue("leopard")).setRequiredResults(Collections.singletonList(field("header").nest(concatenateFields("num", "path")))).build();
// Covering(Index(MyRecord$str_value [[leopard],[leopard]]) -> [str_value: KEY[0], header: [num: VALUE[1], path: VALUE[0], rec_no: KEY[1]]])
RecordQueryPlan plan = planner.plan(query);
final BindingMatcher<? extends RecordQueryPlan> planMatcher = coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("MyRecord$str_value")).and(scanComparisons(range("[[leopard],[leopard]]")))));
assertMatchesExactly(plan, planMatcher);
assertEquals(-568702564, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(1766803018, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(344218219, 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 testOrQuery6.
/**
* Verify that a complex query with an OR of an AND produces a union plan if appropriate indexes are defined.
* In particular, verify that it can use the last field of an index and does not require primary key ordering
* compatibility.
*/
@DualPlannerTest
void testOrQuery6() throws Exception {
RecordMetaDataHook hook = metaData -> metaData.addIndex("MySimpleRecord", new Index("str_value_3_index", "str_value_indexed", "num_value_3_indexed"));
complexQuerySetup(hook);
RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.or(Query.and(Query.field("str_value_indexed").equalsValue("even"), Query.field("num_value_3_indexed").greaterThan(3)), Query.field("num_value_3_indexed").lessThan(1))).build();
// Index(str_value_3_index ([even, 3],[even]]) ∪[Field { 'num_value_3_indexed' None}, Field { 'rec_no' None}] Index(MySimpleRecord$num_value_3_indexed ([null],[1]))
RecordQueryPlan plan = planner.plan(query);
if (planner instanceof CascadesPlanner) {
final BindingMatcher<? extends RecordQueryPlan> planMatcher = fetchFromPartialRecordPlan(unionPlan(coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("str_value_3_index")).and(scanComparisons(range("([even, 3],[even]]"))))), coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("MySimpleRecord$num_value_3_indexed")).and(scanComparisons(range("([null],[1])")))))).where(comparisonKey(concat(Key.Expressions.field("num_value_3_indexed"), primaryKey("MySimpleRecord")))));
assertMatchesExactly(plan, planMatcher);
assertEquals(-835124758, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(778876973, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(1061354639, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
} else {
final BindingMatcher<? extends RecordQueryPlan> planMatcher = unionPlan(indexPlan().where(indexName("str_value_3_index")).and(scanComparisons(range("([even, 3],[even]]"))), indexPlan().where(indexName("MySimpleRecord$num_value_3_indexed")).and(scanComparisons(range("([null],[1])")))).where(comparisonKey(concat(Key.Expressions.field("num_value_3_indexed"), primaryKey("MySimpleRecord"))));
assertMatchesExactly(plan, planMatcher);
assertEquals(1721396731, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(-1374663850, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-1092186184, 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());
assertTrue((myrec.getStrValueIndexed().equals("even") && myrec.getNumValue3Indexed() > 3) || myrec.getNumValue3Indexed() < 1);
i++;
}
}
assertEquals(20 + 10, i);
assertDiscardedNone(context);
}
}
use of com.apple.foundationdb.record.query.plan.temp.matchers.BindingMatcher in project fdb-record-layer by FoundationDB.
the class FDBOrQueryToUnionTest method testUnorderableOrQueryWithAnd.
/**
* Verify that a complex query with an OR of an AND produces a union plan if the appropriate indexes are defined.
* Unlike {@link #testOrQuery6()}, the legs of the union are not compatibly ordered, so this will revert to using
* an unordered union.
*/
@DualPlannerTest
@ParameterizedTest
@BooleanSource
void testUnorderableOrQueryWithAnd(boolean removesDuplicates) throws Exception {
RecordMetaDataHook hook = metaDataBuilder -> {
complexQuerySetupHook().apply(metaDataBuilder);
metaDataBuilder.addIndex("MySimpleRecord", new Index("multi_index_2", "str_value_indexed", "num_value_3_indexed"));
};
complexQuerySetup(hook);
setDeferFetchAfterUnionAndIntersection(true);
RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.and(Query.field("str_value_indexed").equalsValue("even"), Query.or(Query.field("num_value_2").lessThanOrEquals(1), Query.field("num_value_3_indexed").greaterThanOrEquals(3)))).setRemoveDuplicates(removesDuplicates).build();
// Unordered(Index(multi_index ([even, null],[even, 1]]) ∪ Index(multi_index_2 [[even, 3],[even]]))
RecordQueryPlan plan = planner.plan(query);
BindingMatcher<? extends RecordQueryPlan> planMatcher = unorderedUnionPlan(coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("multi_index")).and(scanComparisons(range("([even, null],[even, 1]]"))))), coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("multi_index_2")).and(scanComparisons(range("[[even, 3],[even]]"))))));
if (removesDuplicates) {
planMatcher = fetchFromPartialRecordPlan(unorderedPrimaryKeyDistinctPlan(planMatcher));
} else {
planMatcher = fetchFromPartialRecordPlan(planMatcher);
}
assertMatchesExactly(plan, planMatcher);
assertEquals(removesDuplicates ? -1216499257 : -1216499264, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(removesDuplicates ? 610131412 : 1405311066, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(removesDuplicates ? 1591758672 : -1908028970, 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());
assertTrue(myrec.getStrValueIndexed().equals("even") && (myrec.getNumValue2() <= 1 || myrec.getNumValue3Indexed() >= 3));
i++;
}
}
if (removesDuplicates) {
assertEquals(40, i);
assertDiscardedAtMost(13, context);
assertLoadRecord(53, context);
} else {
assertEquals(53, i);
assertDiscardedNone(context);
}
}
}
use of com.apple.foundationdb.record.query.plan.temp.matchers.BindingMatcher in project fdb-record-layer by FoundationDB.
the class FDBOrQueryToUnionTest method testOrderedOrQueryWithAnd.
/**
* Verify that a query with an OR of an AND can be implemented as a union of an index scan with an intersection of index scans.
*/
@DualPlannerTest
void testOrderedOrQueryWithAnd() throws Exception {
RecordMetaDataHook hook = metaData -> {
metaData.addIndex("MySimpleRecord", "str_2", concat(field("str_value_indexed"), field("num_value_2")));
metaData.addIndex("MySimpleRecord", "nu_2", concat(field("num_value_unique"), field("num_value_2")));
metaData.addIndex("MySimpleRecord", "n3_2", concat(field("num_value_3_indexed"), field("num_value_2")));
};
complexQuerySetup(hook);
RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.or(Query.field("str_value_indexed").equalsValue("even"), Query.and(Query.field("num_value_3_indexed").equalsValue(1), Query.field("num_value_unique").equalsValue(909)))).setSort(field("num_value_2")).build();
// Index(str_2 [[even],[even]]) ∪[Field { 'num_value_2' None}, Field { 'rec_no' None}] Index(nu_2 [[909],[909]]) ∩ Index(n3_2 [[1],[1]])
RecordQueryPlan plan = planner.plan(query);
if (planner instanceof RecordQueryPlanner) {
final BindingMatcher<? extends RecordQueryPlan> planMatcher = unionPlan(indexPlan().where(indexName("str_2")).and(scanComparisons(range("[[even],[even]]"))), intersectionPlan(indexPlan().where(indexName("nu_2")).and(scanComparisons(range("[[909],[909]]"))), indexPlan().where(indexName("n3_2")).and(scanComparisons(range("[[1],[1]]"))))).where(comparisonKey(concat(field("num_value_2"), primaryKey("MySimpleRecord"))));
assertMatchesExactly(plan, planMatcher);
assertEquals(-1659601413, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(-1344221020, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-1474039530, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
} else {
final BindingMatcher<? extends RecordQueryPlan> planMatcher = fetchFromPartialRecordPlan(unionPlan(coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("str_2")).and(scanComparisons(range("[[even],[even]]"))))), intersectionPlan(coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("nu_2")).and(scanComparisons(range("[[909],[909]]"))))), coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("n3_2")).and(scanComparisons(range("[[1],[1]]"))))))).where(comparisonKey(concat(field("num_value_2"), primaryKey("MySimpleRecord")))));
assertMatchesExactly(plan, planMatcher);
assertEquals(1254181870, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(156652779, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(1906836981, 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());
assertTrue(myrec.getStrValueIndexed().equals("even") || (myrec.getNumValue3Indexed() == 1 && myrec.getNumValueUnique() == 909));
i++;
}
}
assertEquals(51, i);
}
}
use of com.apple.foundationdb.record.query.plan.temp.matchers.BindingMatcher in project fdb-record-layer by FoundationDB.
the class FDBCoveringIndexQueryTest method coveringMultiValue.
/**
* Verify that an index can be covering if some of the required fields are in the value part of the index.
*/
@DualPlannerTest
void coveringMultiValue() throws Exception {
RecordMetaDataHook hook = metaData -> {
metaData.removeIndex("MySimpleRecord$num_value_unique");
metaData.addIndex("MySimpleRecord", new Index("multi_index_value", field("num_value_unique"), field("num_value_2"), IndexTypes.VALUE, IndexOptions.UNIQUE_OPTIONS));
};
complexQuerySetup(hook);
RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.field("num_value_unique").greaterThan(990)).setSort(field("num_value_unique")).setRequiredResults(Arrays.asList(field("num_value_unique"), field("num_value_2"))).build();
// Covering(Index(multi_index_value ([990],>) -> [num_value_2: VALUE[0], num_value_unique: KEY[0], rec_no: KEY[1]])
RecordQueryPlan plan = planner.plan(query);
final BindingMatcher<? extends RecordQueryPlan> planMatcher = coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("multi_index_value")).and(scanComparisons(range("([990],>")))));
assertMatchesExactly(plan, planMatcher);
assertEquals(-782505942, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(450250048, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(368845640, 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());
assertTrue(myrec.getNumValueUnique() > 990);
assertEquals(myrec.getNumValue2(), (999 - i) % 3);
i++;
}
}
assertEquals(10, i);
assertDiscardedNone(context);
}
}
Aggregations