use of com.apple.foundationdb.record.RecordCursor in project fdb-record-layer by FoundationDB.
the class FDBRecordStoreScanLimitTest method unorderedIntersectionWithScanLimit.
@ParameterizedTest(name = "unorderedIntersectionWithScanLimit [fail = {0}]")
@BooleanSource
public void unorderedIntersectionWithScanLimit(boolean fail) throws Exception {
// TODO: When there is an UnorderedIntersectionPlan (or whatever) add that to the unordered plans stream
RecordQueryPlanner planner = new RecordQueryPlanner(simpleMetaData(NO_HOOK), new RecordStoreState(null, null));
RecordQueryPlan leftPlan = planner.plan(RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.field("str_value_indexed").startsWith("ev")).build());
RecordQueryPlan rightPlan = planner.plan(RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.field("num_value_3_indexed").lessThanOrEquals(1)).build());
int maximumToScan;
try (FDBRecordContext context = openContext()) {
openSimpleRecordStore(context);
maximumToScan = recordStore.executeQuery(leftPlan).getCount().get() + recordStore.executeQuery(rightPlan).getCount().get();
}
for (int limit = 0; limit < 3 * maximumToScan; limit = 2 * limit + 1) {
final int finalLimit = limit;
Function<byte[], RecordCursor<FDBQueriedRecord<Message>>> cursorFunction = (continuation) -> {
ExecuteProperties executeProperties = ExecuteProperties.newBuilder().setScannedRecordsLimit(finalLimit).setFailOnScanLimitReached(fail).build();
return ProbableIntersectionCursor.create(record -> record.getPrimaryKey().getItems(), Arrays.asList(leftContinuation -> leftPlan.execute(recordStore, EvaluationContext.EMPTY, leftContinuation, executeProperties), rightContinuation -> rightPlan.execute(recordStore, EvaluationContext.EMPTY, rightContinuation, executeProperties)), continuation, recordStore.getTimer());
};
assertNumberOfRecordsScanned(limit, cursorFunction, fail, "should" + (limit >= maximumToScan ? "not " : "") + " be limited by record scan limit");
}
}
use of com.apple.foundationdb.record.RecordCursor in project fdb-record-layer by FoundationDB.
the class FunctionKeyRecordTest method testQueryByRecordId.
@Test
public void testQueryByRecordId() throws Exception {
RecordMetaDataHook hook = setupQueryData();
// Query by leading portion of primary key that is not hidden behind the function
RecordQuery query = RecordQuery.newBuilder().setRecordType("StringRecordId").setFilter(Query.field("rec_id").equalsValue("/s:foo_3_blah")).build();
RecordQueryPlan plan = planner.plan(query);
Assertions.assertEquals("Scan(<,>) | rec_id EQUALS /s:foo_3_blah", plan.toString());
try (FDBRecordContext context = openContext()) {
openRecordStore(context, hook);
try (RecordCursor<FDBQueriedRecord<Message>> cursor = recordStore.executeQuery(plan)) {
AtomicInteger count = new AtomicInteger();
cursor.forEach(queriedRecord -> {
TestRecords8Proto.StringRecordId record = validateQueryData(queriedRecord);
Assertions.assertEquals("/s:foo_3_blah", record.getRecId());
count.incrementAndGet();
}).get();
Assertions.assertEquals(1, count.get(), "Too few records returned");
}
}
}
use of com.apple.foundationdb.record.RecordCursor in project fdb-record-layer by FoundationDB.
the class FunctionKeyRecordTest method testQueryByLeadingPortionOfKey.
@Test
public void testQueryByLeadingPortionOfKey() throws Exception {
RecordMetaDataHook hook = setupQueryData();
// Query by leading portion of primary key that is not hidden behind the function
RecordQuery query = RecordQuery.newBuilder().setRecordType("StringRecordId").setFilter(Query.and(Query.field("int_value").greaterThanOrEquals(1), Query.field("int_value").lessThanOrEquals(2))).build();
RecordQueryPlan plan = planner.plan(query);
Assertions.assertEquals("Scan([[1],[2]])", plan.toString());
try (FDBRecordContext context = openContext()) {
openRecordStore(context, hook);
try (RecordCursor<FDBQueriedRecord<Message>> cursor = recordStore.executeQuery(plan)) {
AtomicInteger count = new AtomicInteger();
cursor.forEach(queriedRecord -> {
TestRecords8Proto.StringRecordId record = validateQueryData(queriedRecord);
Assertions.assertTrue(record.getLongField() % 3 == 1 || record.getLongField() % 3 == 2);
count.incrementAndGet();
}).get();
Assertions.assertEquals(6, count.get(), "Too few records returned");
}
}
}
use of com.apple.foundationdb.record.RecordCursor in project fdb-record-layer by FoundationDB.
the class FunctionKeyRecordTest method testQueryByNonKeyField.
@Test
public void testQueryByNonKeyField() throws Exception {
RecordMetaDataHook hook = setupQueryData();
// Query by non-primary key field and make sure that works.
RecordQuery query = RecordQuery.newBuilder().setRecordType("StringRecordId").setFilter(Query.or(Query.field("str_field").equalsValue("hello_0"), Query.field("str_field").equalsValue("hello_3"), Query.field("str_field").equalsValue("hello_6"))).build();
RecordQueryPlan plan = planner.plan(query);
try (FDBRecordContext context = openContext()) {
openRecordStore(context, hook);
try (RecordCursor<FDBQueriedRecord<Message>> cursor = recordStore.executeQuery(plan)) {
AtomicInteger count = new AtomicInteger();
cursor.forEach(queriedRecord -> {
TestRecords8Proto.StringRecordId record = validateQueryData(queriedRecord);
Assertions.assertTrue(record.getIntValue() >= 0 && record.getIntValue() <= 2, "Unexpected record returned");
count.incrementAndGet();
}).get();
Assertions.assertEquals(3, count.get(), "Too few records returned");
}
}
}
use of com.apple.foundationdb.record.RecordCursor in project fdb-record-layer by FoundationDB.
the class FDBRecordStoreTest method testOverlappingPrimaryKey.
@Test
public void testOverlappingPrimaryKey() {
try (FDBRecordContext context = openContext()) {
RecordMetaDataBuilder builder = RecordMetaData.newBuilder().setRecords(TestRecordsWithHeaderProto.getDescriptor());
builder.getRecordType("MyRecord").setPrimaryKey(field("header").nest(concatenateFields("path", "rec_no")));
builder.addIndex("MyRecord", "MyRecord$path_str", concat(field("header").nest("path"), field("str_value")));
RecordMetaData metaData = builder.getRecordMetaData();
createOrOpenRecordStore(context, metaData);
TestRecordsWithHeaderProto.MyRecord.Builder recBuilder = TestRecordsWithHeaderProto.MyRecord.newBuilder();
TestRecordsWithHeaderProto.HeaderRecord.Builder headerBuilder = recBuilder.getHeaderBuilder();
headerBuilder.setPath("aaa");
headerBuilder.setRecNo(1);
recBuilder.setStrValue("hello");
recordStore.saveRecord(recBuilder.build());
headerBuilder.setPath("aaa");
headerBuilder.setRecNo(2);
recBuilder.setStrValue("goodbye");
recordStore.saveRecord(recBuilder.build());
headerBuilder.setPath("zzz");
headerBuilder.setRecNo(3);
recBuilder.setStrValue("end");
recordStore.saveRecord(recBuilder.build());
List<List<Object>> rows = new ArrayList<>();
Index index = metaData.getIndex("MyRecord$path_str");
ScanComparisons comparisons = ScanComparisons.from(new Comparisons.SimpleComparison(Comparisons.Type.EQUALS, "aaa"));
TupleRange range = comparisons.toTupleRange();
try (RecordCursor<IndexEntry> cursor = recordStore.scanIndex(index, IndexScanType.BY_VALUE, range, null, ScanProperties.FORWARD_SCAN)) {
cursor.forEach(row -> rows.add(row.getKey().getItems())).join();
}
assertEquals(Arrays.asList(Arrays.asList("aaa", "goodbye", 2L), Arrays.asList("aaa", "hello", 1L)), rows);
}
}
Aggregations