use of com.apple.foundationdb.record.query.RecordQuery in project fdb-record-layer by FoundationDB.
the class FDBInQueryTest method testInQueryIndex.
/**
* Verify that an IN with an index is implemented as an index scan, with an IN join.
*/
@DualPlannerTest
void testInQueryIndex() throws Exception {
complexQuerySetup(NO_HOOK);
List<Integer> ls = asList(1, 2, 4);
RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.field("num_value_3_indexed").in(ls)).setSort(field("num_value_3_indexed")).build();
planner.setConfiguration(InAsOrUnionMode.AS_UNION.configure(planner.getConfiguration().asBuilder()).build());
RecordQueryPlan plan = planner.plan(query);
if (planner instanceof RecordQueryPlanner) {
// Index(MySimpleRecord$num_value_3_indexed [EQUALS $__in_num_value_3_indexed__0]) WHERE __in_num_value_3_indexed__0 IN [1, 2, 4]
assertMatchesExactly(plan, inValuesJoinPlan(indexPlan().where(indexName("MySimpleRecord$num_value_3_indexed")).and(scanComparisons(range("[EQUALS $__in_num_value_3_indexed__0]")))).where(inValuesList(equalsObject(ls))));
assertEquals(-2004060309, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(571226247, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(571195399, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
} else {
assertMatchesExactly(plan, fetchFromPartialRecordPlan(inValuesJoinPlan(coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("MySimpleRecord$num_value_3_indexed")).and(scanComparisons(equalities(only(anyParameterComparison()))))))).where(inValuesList(equalsObject(ls)))));
assertEquals(-2068499040, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(-992959779, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-1998042418, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
}
assertEquals(60, querySimpleRecordStore(NO_HOOK, plan, EvaluationContext::empty, record -> assertThat(record.getNumValue3Indexed(), anyOf(is(1), is(2), is(4))), TestHelpers::assertDiscardedNone));
}
use of com.apple.foundationdb.record.query.RecordQuery in project fdb-record-layer by FoundationDB.
the class FDBInQueryTest method testMultipleInQueryIndex.
/**
* Verify that a query with multiple INs is translated into an index scan within multiple IN joins.
*/
@DualPlannerTest
void testMultipleInQueryIndex() throws Exception {
final RecordMetaDataHook recordMetaDataHook = metaData -> {
metaData.getRecordType("MyRecord").setPrimaryKey(field("str_value"));
metaData.addIndex("MyRecord", "ind", field("header").nest(field("rec_no"), field("path")));
};
setupRecordsWithHeader(recordMetaDataHook, (i, record) -> {
record.setStrValue("_" + i);
record.getHeaderBuilder().setRecNo(i % 5).setPath("String" + i % 50).setNum(i);
});
List<Long> longList = asList(1L, 4L);
List<String> stringList = asList("String6", "String25", "String1", "String34");
RecordQuery query = RecordQuery.newBuilder().setRecordType("MyRecord").setFilter(Query.field("header").matches(Query.and(Query.field("rec_no").in(longList), Query.field("path").in(stringList)))).build();
// Index(ind [EQUALS $__in_rec_no__0, EQUALS $__in_path__1]) WHERE __in_path__1 IN [String6, String25, String1, String34] WHERE __in_rec_no__0 IN [1, 4]
RecordQueryPlan plan = planner.plan(query);
if (planner instanceof RecordQueryPlanner) {
final BindingMatcher<RecordQueryIndexPlan> indexPlanMatcher = indexPlan().where(indexName("ind")).and(scanComparisons(range("[EQUALS $__in_rec_no__0, EQUALS $__in_path__1]")));
assertMatchesExactly(plan, inValuesJoinPlan(inValuesJoinPlan(indexPlanMatcher).where(inValuesList(equalsObject(stringList)))).where(inValuesList(equalsObject(longList))).or(inValuesJoinPlan(inValuesJoinPlan(indexPlanMatcher).where(inValuesList(equalsObject(longList)))).where(inValuesList(equalsObject(stringList)))));
assertEquals(-1869764109, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(1234840472, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(297055958, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
} else {
assertMatchesExactly(plan, fetchFromPartialRecordPlan(inValuesJoinPlan(inValuesJoinPlan(coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("ind")).and(scanComparisons(equalities(exactly(anyParameterComparison(), anyParameterComparison()))))))).where(inValuesList(equalsObject(longList)))).where(inValuesList(equalsObject(stringList)))));
assertEquals(-2124922292, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(2055315359, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(1810804415, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
}
queryRecordsWithHeader(recordMetaDataHook, plan, cursor -> assertEquals(asList("_56", "_6", "_1", "_51", "_34", "_84"), cursor.map(TestRecordsWithHeaderProto.MyRecord.Builder::getStrValue).asList().get()), TestHelpers::assertDiscardedNone);
}
use of com.apple.foundationdb.record.query.RecordQuery in project fdb-record-layer by FoundationDB.
the class FDBInQueryTest method testInQueryParameter.
/**
* Verify that an IN (with parameter) with an index is implemented as an index scan, with an IN join.
*/
@DualPlannerTest
void testInQueryParameter() throws Exception {
complexQuerySetup(NO_HOOK);
RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.field("num_value_3_indexed").in("valueThrees")).build();
planner.setConfiguration(InAsOrUnionMode.AS_UNION.configure(planner.getConfiguration().asBuilder()).build());
RecordQueryPlan plan = planner.plan(query);
if (planner instanceof RecordQueryPlanner) {
// Index(MySimpleRecord$num_value_3_indexed [EQUALS $__in_num_value_3_indexed__0]) WHERE __in_num_value_3_indexed__0 IN $valueThrees
assertMatchesExactly(plan, inParameterJoinPlan(indexPlan().where(indexName("MySimpleRecord$num_value_3_indexed")).and(scanComparisons(range("[EQUALS $__in_num_value_3_indexed__0]")))).where(RecordQueryPlanMatchers.inParameter(equalsObject("valueThrees"))));
assertEquals(883815022, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(514739864, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(514739864, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
} else {
assertMatchesExactly(plan, fetchFromPartialRecordPlan(inParameterJoinPlan(coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("MySimpleRecord$num_value_3_indexed")).and(scanComparisons(equalities(only(anyParameterComparison()))))))).where(RecordQueryPlanMatchers.inParameter(equalsObject("valueThrees")))));
assertEquals(1152354842, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(-1759971309, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-1759971309, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
}
int count = querySimpleRecordStore(NO_HOOK, plan, () -> EvaluationContext.forBinding("valueThrees", asList(1, 3, 4)), myrec -> assertThat(myrec.getNumValue3Indexed(), anyOf(is(1), is(3), is(4))), TestHelpers::assertDiscardedNone);
assertEquals(60, count);
}
use of com.apple.foundationdb.record.query.RecordQuery in project fdb-record-layer by FoundationDB.
the class FDBInQueryTest method testInQueryNoIndex.
/**
* Verify that an IN without an index is implemented as a filter on a scan, as opposed to a loop of a filter on a scan.
*/
@DualPlannerTest
void testInQueryNoIndex() throws Exception {
complexQuerySetup(NO_HOOK);
final QueryComponent filter = Query.field("num_value_2").in(asList(0, 2));
RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(filter).build();
// Scan(<,>) | [MySimpleRecord] | num_value_2 IN [0, 2]
RecordQueryPlan plan = planner.plan(query);
if (planner instanceof RecordQueryPlanner) {
assertMatchesExactly(plan, filterPlan(descendantPlans(scanPlan().where(scanComparisons(unbounded())))).where(queryComponents(exactly(equalsObject(filter)))));
assertEquals(-1139367278, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(-1907300063, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-1694772440, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
} else {
assertMatchesExactly(plan, predicatesFilterPlan(descendantPlans(scanPlan().where(scanComparisons(unbounded())))).where(predicates(valuePredicate(fieldValue("num_value_2"), new Comparisons.ListComparison(Comparisons.Type.IN, ImmutableList.of(0, 2))))));
assertEquals(997592219, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(-1107686929, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-895159306, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
}
assertEquals(67, querySimpleRecordStore(NO_HOOK, plan, EvaluationContext::empty, record -> assertThat(record.getNumValue2(), anyOf(is(0), is(2))), context -> assertDiscardedAtMost(33, context)));
}
use of com.apple.foundationdb.record.query.RecordQuery in project fdb-record-layer by FoundationDB.
the class FDBRecordStoreQueryTest method query.
@DualPlannerTest
void query() throws Exception {
try (FDBRecordContext context = openContext()) {
openSimpleRecordStore(context);
for (int i = 0; i < 100; i++) {
TestRecords1Proto.MySimpleRecord.Builder recBuilder = TestRecords1Proto.MySimpleRecord.newBuilder();
recBuilder.setRecNo(i);
recBuilder.setStrValueIndexed((i & 1) == 1 ? "odd" : "even");
recBuilder.setNumValueUnique(i + 1000);
recordStore.saveRecord(recBuilder.build());
}
commit(context);
}
RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.field("str_value_indexed").equalsValue("even")).build();
RecordQueryPlan plan = planner.plan(query);
try (FDBRecordContext context = openContext()) {
openSimpleRecordStore(context);
int i = 0;
try (RecordCursorIterator<FDBQueriedRecord<Message>> cursor = recordStore.executeQuery(plan).asIterator()) {
while (cursor.hasNext()) {
FDBQueriedRecord<Message> rec = Objects.requireNonNull(cursor.next());
TestRecords1Proto.MySimpleRecord.Builder myrec = TestRecords1Proto.MySimpleRecord.newBuilder();
myrec.mergeFrom(rec.getRecord());
assertEquals(0, myrec.getNumValueUnique() % 2);
i++;
}
}
assertEquals(50, i);
assertDiscardedNone(context);
}
}
Aggregations