use of com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan in project fdb-record-layer by FoundationDB.
the class FDBInQueryTest method enumIn.
/**
* Verify that enum field indexes are used to implement IN clauses.
*/
@DualPlannerTest
void enumIn() throws Exception {
RecordMetaDataHook hook = metaData -> {
final RecordTypeBuilder type = metaData.getRecordType("MyShapeRecord");
metaData.addIndex(type, new Index("color", field("color")));
};
setupEnumShapes(hook);
final var redBlue = asList(TestRecordsEnumProto.MyShapeRecord.Color.RED, TestRecordsEnumProto.MyShapeRecord.Color.BLUE);
RecordQuery query = RecordQuery.newBuilder().setRecordType("MyShapeRecord").setFilter(Query.field("color").in(redBlue)).build();
// Index(color [EQUALS $__in_color__0]) WHERE __in_color__0 IN [RED, BLUE]
RecordQueryPlan plan = planner.plan(query);
if (planner instanceof RecordQueryPlanner) {
assertMatchesExactly(plan, descendantPlans(indexPlan().where(indexName("color"))));
assertFalse(plan.hasRecordScan(), "should not use record scan");
assertEquals(-520431454, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(1447363737, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(1442809521, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
} else {
assertMatchesExactly(plan, fetchFromPartialRecordPlan(inValuesJoinPlan(coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("color")).and(scanComparisons(equalities(exactly(anyParameterComparison()))))))).where(inValuesList(equalsObject(redBlue)))));
assertFalse(plan.hasRecordScan(), "should not use record scan");
assertEquals(1174038242, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(-1089300981, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-1677589406, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
}
try (FDBRecordContext context = openContext()) {
openEnumRecordStore(context, hook);
int i = 0;
try (RecordCursorIterator<FDBQueriedRecord<Message>> cursor = recordStore.executeQuery(plan).asIterator()) {
while (cursor.hasNext()) {
FDBQueriedRecord<Message> rec = cursor.next();
TestRecordsEnumProto.MyShapeRecord.Builder shapeRec = TestRecordsEnumProto.MyShapeRecord.newBuilder();
shapeRec.mergeFrom(Objects.requireNonNull(rec).getRecord());
assertThat(shapeRec.getColor(), is(oneOf(TestRecordsEnumProto.MyShapeRecord.Color.RED, TestRecordsEnumProto.MyShapeRecord.Color.BLUE)));
i++;
}
}
assertEquals(18, i);
TestHelpers.assertDiscardedNone(context);
}
}
use of com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan in project fdb-record-layer by FoundationDB.
the class FDBInQueryTest method testInQueryParameter2.
/**
* Verify that an IN (with parameter) with an index is implemented as an index scan, with an IN union in the presence
* of other equality-bound index parts.
*/
@DualPlannerTest
void testInQueryParameter2() throws Exception {
RecordMetaDataHook hook = metaData -> {
metaData.removeIndex("MySimpleRecord$num_value_3_indexed");
metaData.removeIndex("MySimpleRecord$num_value_unique");
metaData.addIndex("MySimpleRecord", new Index("multi_index", "num_value_3_indexed", "num_value_2", "num_value_unique"));
};
complexQuerySetup(hook);
RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.and(Query.field("num_value_3_indexed").equalsParameter("p"), Query.field("num_value_2").in("valueThrees"))).setSort(Key.Expressions.field("num_value_unique")).build();
planner.setConfiguration(InAsOrUnionMode.AS_UNION.configure(planner.getConfiguration().asBuilder()).build());
RecordQueryPlan plan = planner.plan(query);
if (planner instanceof RecordQueryPlanner) {
assertMatchesExactly(plan, inUnionPlan(indexPlan().where(indexName("multi_index")).and(scanComparisons(range("[EQUALS $p, EQUALS $__in_num_value_2__0]")))).where(inUnionValuesSources(exactly(RecordQueryPlanMatchers.inUnionInParameter(equalsObject("valueThrees"))))));
assertEquals(1360223246, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(2045945193, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(2045945193, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
} else {
assertMatchesExactly(plan, fetchFromPartialRecordPlan(inUnionPlan(coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("multi_index")).and(scanComparisons(equalities(exactly(anyParameterComparison(), anyParameterComparison()))))))).where(RecordQueryPlanMatchers.inUnionValuesSources(exactly(inUnionInParameter(equalsObject("valueThrees")))))));
assertEquals(1947663752, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(1788373323, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(1788373323, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
}
}
use of com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan in project fdb-record-layer by FoundationDB.
the class FDBAndQueryToIntersectionTest method testComplexQueryAndWithTwoChildren2.
/**
* Verify that a complex query with an AND of fields with compatibly ordered indexes generates an intersection plan.
*/
@DualPlannerTest
public void testComplexQueryAndWithTwoChildren2() throws Exception {
RecordMetaDataHook hook = complexQuerySetupHook();
complexQuerySetup(hook);
RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.and(Query.field("str_value_indexed").equalsValue("even"), Query.field("num_value_3_indexed").equalsValue(3))).build();
setDeferFetchAfterUnionAndIntersection(true);
RecordQueryPlan plan = planner.plan(query);
assertThat(plan, fetch(intersection(coveringIndexScan(indexScan(allOf(indexName("MySimpleRecord$str_value_indexed"), bounds(hasTupleString("[[even],[even]]"))))), coveringIndexScan(indexScan(allOf(indexName("MySimpleRecord$num_value_3_indexed"), bounds(hasTupleString("[[3],[3]]"))))), equalTo(field("rec_no")))));
if (planner instanceof RecordQueryPlanner) {
assertEquals(-929788310, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(-1914172894, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-271606869, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
} else {
assertEquals(-70465554, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(2126183202, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-1157469383, 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(rec.getRecord());
assertEquals("even", myrec.getStrValueIndexed());
assertTrue((myrec.getNumValue3Indexed() % 5) == 3);
i++;
}
}
assertEquals(10, i);
assertDiscardedExactly(50, context);
assertLoadRecord(10, context);
}
}
use of com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan in project fdb-record-layer by FoundationDB.
the class FDBAndQueryToIntersectionTest method sortedIntersectionBounded.
/**
* Verify that a query with a sort by primary key and AND clause (with complex limits) is implemented as an
* intersection of index scans, when the primary key is bounded.
*/
@ParameterizedTest
@BooleanSource
public void sortedIntersectionBounded(boolean shouldDeferFetch) throws Exception {
RecordMetaDataHook hook = sortingShapesHook();
setupEnumShapes(hook);
RecordQuery query = RecordQuery.newBuilder().setRecordType("MyShapeRecord").setFilter(Query.and(Query.field("shape").equalsValue(TestRecordsEnumProto.MyShapeRecord.Shape.CIRCLE), Query.field("color").equalsValue(TestRecordsEnumProto.MyShapeRecord.Color.RED), Query.field("rec_no").greaterThanOrEquals(2), Query.field("rec_no").lessThanOrEquals(11))).setSort(field("rec_no")).build();
setDeferFetchAfterUnionAndIntersection(shouldDeferFetch);
// Fetch(Covering(Index(color [[10, 2],[10, 11]]) -> [color: KEY[0], rec_name: KEY[2], rec_no: KEY[1]]) ∩ Covering(Index(shape [[200, 2],[200, 11]]) -> [rec_name: KEY[2], rec_no: KEY[1], shape: KEY[0]]))
// Fetch(Covering(Index(color [[10, 2],[10, 11]]) -> [color: KEY[0], rec_name: KEY[2], rec_no: KEY[1]]) ∩ Covering(Index(shape [[200, 2],[200, 11]]) -> [rec_name: KEY[2], rec_no: KEY[1], shape: KEY[0]]))
RecordQueryPlan plan = planner.plan(query);
if (shouldDeferFetch) {
assertThat(plan, fetch(intersection(coveringIndexScan(indexScan(allOf(indexName("color"), bounds(hasTupleString("[[10, 2],[10, 11]]"))))), coveringIndexScan(indexScan(allOf(indexName("shape"), bounds(hasTupleString("[[200, 2],[200, 11]]"))))))));
assertEquals(1992249868, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(625673791, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-1309396162, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
} else {
assertThat(plan, intersection(indexScan(allOf(indexName("color"), bounds(hasTupleString("[[10, 2],[10, 11]]")))), indexScan(allOf(indexName("shape"), bounds(hasTupleString("[[200, 2],[200, 11]]"))))));
assertEquals(-942526391, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(-1527867032, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(832030311, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
}
try (FDBRecordContext context = openContext()) {
openEnumRecordStore(context, hook);
int i = 0;
try (RecordCursorIterator<FDBQueriedRecord<Message>> cursor = recordStore.executeQuery(plan).asIterator()) {
while (cursor.hasNext()) {
FDBQueriedRecord<Message> rec = cursor.next();
TestRecordsEnumProto.MyShapeRecord.Builder shapeRec = TestRecordsEnumProto.MyShapeRecord.newBuilder();
shapeRec.mergeFrom(rec.getRecord());
assertThat(shapeRec.getRecName(), anyOf(is("SMALL-RED-CIRCLE"), is("MEDIUM-RED-CIRCLE")));
assertThat(shapeRec.getShape(), equalTo(TestRecordsEnumProto.MyShapeRecord.Shape.CIRCLE));
assertThat(shapeRec.getColor(), equalTo(TestRecordsEnumProto.MyShapeRecord.Color.RED));
assertThat(shapeRec.getRecNo(), allOf(greaterThanOrEqualTo(2), lessThanOrEqualTo(11)));
i++;
}
}
assertEquals(2, i);
assertDiscardedAtMost(4, context);
if (shouldDeferFetch) {
assertLoadRecord(2, context);
}
}
}
use of com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan in project fdb-record-layer by FoundationDB.
the class FDBAndQueryToIntersectionTest method sortedIntersectionUnbounded.
/**
* Verify that a query with a sort by primary key and AND clause is implemented as an intersection of index scans,
* when the primary key is unbounded.
*/
@ParameterizedTest
@BooleanSource
public void sortedIntersectionUnbounded(boolean shouldDeferFetch) throws Exception {
RecordMetaDataHook hook = sortingShapesHook();
setupEnumShapes(hook);
RecordQuery query = RecordQuery.newBuilder().setRecordType("MyShapeRecord").setFilter(Query.and(Query.field("shape").equalsValue(TestRecordsEnumProto.MyShapeRecord.Shape.CIRCLE), Query.field("color").equalsValue(TestRecordsEnumProto.MyShapeRecord.Color.RED))).setSort(field("rec_no")).build();
setDeferFetchAfterUnionAndIntersection(shouldDeferFetch);
// Fetch(Covering(Index(color [[10],[10]]) -> [color: KEY[0], rec_name: KEY[2], rec_no: KEY[1]]) ∩ Covering(Index(shape [[200],[200]]) -> [rec_name: KEY[2], rec_no: KEY[1], shape: KEY[0]]))
RecordQueryPlan plan = planner.plan(query);
if (shouldDeferFetch) {
assertThat(plan, fetch(intersection(coveringIndexScan(indexScan(allOf(indexName("color"), bounds(hasTupleString("[[10],[10]]"))))), coveringIndexScan(indexScan(allOf(indexName("shape"), bounds(hasTupleString("[[200],[200]]"))))))));
assertEquals(-2072158516, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(-1707812033, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(1828796254, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
} else {
assertThat(plan, intersection(indexScan(allOf(indexName("color"), bounds(hasTupleString("[[10],[10]]")))), indexScan(allOf(indexName("shape"), bounds(hasTupleString("[[200],[200]]"))))));
assertEquals(-296022647, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(433614440, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-324744569, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
}
try (FDBRecordContext context = openContext()) {
openEnumRecordStore(context, hook);
int i = 0;
try (RecordCursorIterator<FDBQueriedRecord<Message>> cursor = recordStore.executeQuery(plan).asIterator()) {
while (cursor.hasNext()) {
FDBQueriedRecord<Message> rec = cursor.next();
TestRecordsEnumProto.MyShapeRecord.Builder shapeRec = TestRecordsEnumProto.MyShapeRecord.newBuilder();
shapeRec.mergeFrom(rec.getRecord());
assertThat(shapeRec.getRecName(), endsWith("-RED-CIRCLE"));
assertThat(shapeRec.getShape(), equalTo(TestRecordsEnumProto.MyShapeRecord.Shape.CIRCLE));
assertThat(shapeRec.getColor(), equalTo(TestRecordsEnumProto.MyShapeRecord.Color.RED));
i++;
}
}
assertEquals(3, i);
assertDiscardedAtMost(10, context);
if (shouldDeferFetch) {
assertLoadRecord(3, context);
}
}
}
Aggregations