use of com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord in project fdb-record-layer by FoundationDB.
the class FDBCoveringIndexQueryTest method coveringWithHeader.
/**
* Verify that an index can be covering if the required fields are in the primary key.
*/
@DualPlannerTest
void coveringWithHeader() throws Exception {
RecordMetaDataHook hook = metaData -> {
metaData.getRecordType("MyRecord").setPrimaryKey(field("header").nest(concatenateFields("path", "rec_no")));
metaData.addIndex("MyRecord", "str_value");
};
try (FDBRecordContext context = openContext()) {
openRecordWithHeader(context, hook);
saveHeaderRecord(1, "a", 0, "lynx");
saveHeaderRecord(2, "a", 1, "bobcat");
saveHeaderRecord(3, "a", 2, "panther");
saveHeaderRecord(1, "b", 3, "jaguar");
saveHeaderRecord(2, "b", 4, "leopard");
saveHeaderRecord(3, "b", 5, "lion");
saveHeaderRecord(4, "b", 6, "tiger");
context.commit();
}
RecordQuery query = RecordQuery.newBuilder().setRecordType("MyRecord").setFilter(Query.field("str_value").equalsValue("lion")).setRequiredResults(Collections.singletonList(field("header").nest("rec_no"))).build();
// Covering(Index(MyRecord$str_value [[lion],[lion]]) -> [str_value: KEY[0], header: [path: KEY[1], rec_no: KEY[2]]])
RecordQueryPlan plan = planner.plan(query);
BindingMatcher<? extends RecordQueryPlan> planMatcher = coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("MyRecord$str_value")).and(scanComparisons(range("[[lion],[lion]]")))));
assertMatchesExactly(plan, planMatcher);
assertEquals(-629018945, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(177826375, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(344218219, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
try (FDBRecordContext context = openContext()) {
openRecordWithHeader(context, hook);
try (RecordCursorIterator<FDBQueriedRecord<Message>> cursor = recordStore.executeQuery(plan).asIterator()) {
while (cursor.hasNext()) {
FDBQueriedRecord<Message> rec = cursor.next();
TestRecordsWithHeaderProto.MyRecord.Builder myrec = TestRecordsWithHeaderProto.MyRecord.newBuilder();
myrec.mergeFrom(Objects.requireNonNull(rec).getRecord());
assertEquals(3, myrec.getHeader().getRecNo());
}
}
context.commit();
assertDiscardedNone(context);
}
query = RecordQuery.newBuilder().setRecordType("MyRecord").setFilter(Query.field("str_value").startsWith("l")).setRequiredResults(Arrays.asList(field("header").nest(concatenateFields("path", "rec_no")), field("str_value"))).build();
// Covering(Index(MyRecord$str_value {[l],[l]}) -> [str_value: KEY[0], header: [path: KEY[1], rec_no: KEY[2]]])
plan = planner.plan(query);
planMatcher = coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("MyRecord$str_value")).and(scanComparisons(range("{[l],[l]}")))));
assertMatchesExactly(plan, planMatcher);
assertEquals(-1471907004, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(-1581115138, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(1123663700, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
try (FDBRecordContext context = openContext()) {
openRecordWithHeader(context, hook);
List<Pair<String, Long>> results = new ArrayList<>();
try (RecordCursorIterator<FDBQueriedRecord<Message>> cursor = recordStore.executeQuery(plan).asIterator()) {
while (cursor.hasNext()) {
FDBQueriedRecord<Message> rec = cursor.next();
TestRecordsWithHeaderProto.MyRecord.Builder myrec = TestRecordsWithHeaderProto.MyRecord.newBuilder();
myrec.mergeFrom(Objects.requireNonNull(rec).getRecord());
assertThat(myrec.getStrValue(), startsWith("l"));
assertThat(myrec.getHeader().hasPath(), is(true));
assertThat(myrec.getHeader().hasRecNo(), is(true));
results.add(Pair.of(myrec.getHeader().getPath(), myrec.getHeader().getRecNo()));
}
}
assertEquals(Arrays.asList(Pair.of("b", 2L), Pair.of("b", 3L), Pair.of("a", 1L)), results);
context.commit();
assertDiscardedNone(context);
}
}
use of com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord in project fdb-record-layer by FoundationDB.
the class FDBCoveringIndexQueryTest method coveringMulti.
/**
* Verify that an index can be covering if more than one field is required and they are in the key.
*/
@DualPlannerTest
void coveringMulti() throws Exception {
RecordMetaDataHook hook = metaData -> {
metaData.removeIndex("MySimpleRecord$num_value_unique");
metaData.addIndex("MySimpleRecord", new Index("multi_index", "num_value_unique", "num_value_2"));
};
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 ([990],>) -> [num_value_2: KEY[1], num_value_unique: KEY[0], rec_no: KEY[2]])
RecordQueryPlan plan = planner.plan(query);
final BindingMatcher<? extends RecordQueryPlan> planMatcher = coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("multi_index")).and(scanComparisons(range("([990],>")))));
assertMatchesExactly(plan, planMatcher);
assertEquals(291429560, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(1065678, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-80338730, 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);
}
}
use of com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord in project fdb-record-layer by FoundationDB.
the class FDBCrossRecordQueryTest method testCrossRecordTypeQuery.
/**
* Verify that sorting by a common field on a universal index returns all types of records in an index scan.
*/
@DualPlannerTest
public void testCrossRecordTypeQuery() throws Exception {
try (FDBRecordContext context = openContext()) {
openUnionRecordStore(context);
saveSimpleRecord(100, "first", 1);
saveSimpleRecord(110, "second", 2);
saveSimpleRecord2("third", 3);
saveSimpleRecord2("fourth", 4);
saveSimpleRecord(80, "fifth", 5);
saveSimpleRecord2("sixth", 6);
saveSimpleRecord2("seventh", 7);
saveSimpleRecord(60, "seventh", 7);
saveSimpleRecord2("seventh again", 7);
saveSimpleRecord3("eighth", 8);
commit(context);
}
RecordQuery query = RecordQuery.newBuilder().setSort(field("etag")).build();
// Index(versions <,>)
RecordQueryPlan plan = planner.plan(query);
MatcherAssert.assertThat(plan, indexScan(allOf(indexName("versions"), unbounded())));
assertEquals(1555932709, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(155792354, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(155792354, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
List<String> names = new ArrayList<>();
List<Integer> etags = new ArrayList<>();
try (FDBRecordContext context = openContext()) {
openUnionRecordStore(context);
try (RecordCursorIterator<FDBQueriedRecord<Message>> cursor = recordStore.executeQuery(plan).asIterator()) {
while (cursor.hasNext()) {
final Message record = cursor.next().getRecord();
names.add((String) record.getField(record.getDescriptorForType().findFieldByName("str_value_indexed")));
etags.add((int) record.getField(record.getDescriptorForType().findFieldByName("etag")));
}
}
assertDiscardedNone(context);
}
assertEquals(Arrays.asList("first", "second", "third", "fourth", "fifth", "sixth"), names.subList(0, 6));
assertThat(names.subList(6, 9), containsInAnyOrder("seventh", "seventh", "seventh again"));
assertEquals(1555932709, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(155792354, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(155792354, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
assertEquals("eighth", names.get(9));
assertEquals(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 7, 7, 8), etags);
}
use of com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord in project fdb-record-layer by FoundationDB.
the class FDBOrQueryToUnionTest method testOrQueryDenorm.
/**
* Verify that boolean normalization of a complex AND/OR expression produces simple plans.
* In particular, verify that an AND of OR still uses a union of index scans (an OR of AND).
*/
@DualPlannerTest
void testOrQueryDenorm() throws Exception {
// new Index("multi_index", "str_value_indexed", "num_value_2", "num_value_3_indexed")
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_2").equalsValue(0), Query.or(Query.field("num_value_3_indexed").equalsValue(0), Query.and(Query.field("num_value_3_indexed").greaterThanOrEquals(2), Query.field("num_value_3_indexed").lessThanOrEquals(3))))).build();
// Index(multi_index [[even, 0, 0],[even, 0, 0]]) ∪[Field { 'num_value_3_indexed' None}, Field { 'rec_no' None}] Index(multi_index [[even, 0, 2],[even, 0, 3]])
RecordQueryPlan plan = planner.plan(query);
if (planner instanceof RecordQueryPlanner) {
final BindingMatcher<? extends RecordQueryPlan> planMatcher = unionPlan(indexPlan().where(indexName("multi_index")).and(scanComparisons(range("[[even, 0, 0],[even, 0, 0]]"))), indexPlan().where(indexName("multi_index")).and(scanComparisons(range("[[even, 0, 2],[even, 0, 3]]")))).where(comparisonKey(concat(field("num_value_3_indexed"), primaryKey("MySimpleRecord"))));
assertMatchesExactly(plan, planMatcher);
assertEquals(-2074065439, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(-1146901452, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(1940448631, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
} else {
final BindingMatcher<? extends RecordQueryPlan> planMatcher = fetchFromPartialRecordPlan(unionPlan(coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("multi_index")).and(scanComparisons(range("[[even, 0, 0],[even, 0, 0]]"))))), coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("multi_index")).and(scanComparisons(range("[[even, 0, 2],[even, 0, 3]]")))))).where(comparisonKey(concat(field("num_value_3_indexed"), primaryKey("MySimpleRecord")))));
assertMatchesExactly(plan, planMatcher);
assertEquals(-1633556172, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(1006639371, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-200977842, 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());
assertEquals(0, (myrec.getNumValue2() % 3));
assertThat(myrec.getNumValue3Indexed() % 5, anyOf(is(0), allOf(greaterThanOrEqualTo(2), lessThanOrEqualTo(3))));
i++;
}
}
assertEquals(10, i);
assertDiscardedNone(context);
}
}
use of com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord in project fdb-record-layer by FoundationDB.
the class FDBOrQueryToUnionTest method testOrQuery7.
/**
* Verify that an OR with complex limits is implemented as a union, where the comparison key is constructed
* without repetition out of the index key and primary key (see note).
*/
@DualPlannerTest
void testOrQuery7() throws Exception {
RecordMetaDataHook hook = complexPrimaryKeyHook(true);
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_3_indexed").equalsValue(1), Query.field("num_value_3_indexed").greaterThan(3)))).build();
// Index(str_value_3_index [[even, 1],[even, 1]]) ∪[Field { 'str_value_indexed' None}, Field { 'num_value_3_indexed' None}, Field { 'num_value_unique' None}] Index(str_value_3_index ([even, 3],[even]])
RecordQueryPlan plan = planner.plan(query);
if (planner instanceof RecordQueryPlanner) {
final BindingMatcher<? extends RecordQueryPlan> planMatcher = fetchFromPartialRecordPlan(unionPlan(coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("str_value_3_index")).and(scanComparisons(range("[[even, 1],[even, 1]]"))))), coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("str_value_3_index")).and(scanComparisons(range("([even, 3],[even]]")))))).where(comparisonKey(concat(Key.Expressions.field("str_value_indexed"), field("num_value_3_indexed"), field("num_value_unique")))));
assertMatchesExactly(plan, planMatcher);
assertEquals(-664830657, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(1572009327, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-1251823795, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
} else {
final BindingMatcher<? extends RecordQueryPlan> planMatcher = fetchFromPartialRecordPlan(unionPlan(coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("str_value_3_index")).and(scanComparisons(range("[[even, 1],[even, 1]]"))))), coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("str_value_3_index")).and(scanComparisons(range("([even, 3],[even]]")))))).where(comparisonKey(concat(field("num_value_3_indexed"), field("num_value_unique")))));
assertMatchesExactly(plan, planMatcher);
assertEquals(-60058062, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(-1391842890, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(79291284, 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.getNumValue3Indexed() > 3);
i++;
}
}
assertEquals(10 + 10, i);
assertDiscardedNone(context);
}
}
Aggregations