use of com.apple.foundationdb.record.provider.foundationdb.FDBSyntheticRecord in project fdb-record-layer by FoundationDB.
the class SyntheticRecordConcatPlan method execute.
@Override
@Nonnull
public <M extends Message> RecordCursor<FDBSyntheticRecord> execute(@Nonnull FDBRecordStore store, @Nonnull FDBStoredRecord<M> record, @Nullable byte[] continuation, @Nonnull ExecuteProperties executeProperties) {
final ExecuteProperties baseProperties = executeProperties.clearSkipAndLimit();
RecordCursor<FDBSyntheticRecord> cursor = RecordCursor.flatMapPipelined(outerContinuation -> RecordCursor.fromList(store.getExecutor(), subPlans, outerContinuation), (subPlan, innerContinuation) -> subPlan.execute(store, record, innerContinuation, baseProperties), continuation, store.getPipelineSize(PipelineOperation.SYNTHETIC_RECORD_JOIN));
if (needDistinct) {
cursor = addDistinct(cursor);
}
cursor = cursor.skipThenLimit(executeProperties.getSkip(), executeProperties.getReturnedRowLimit());
return cursor;
}
use of com.apple.foundationdb.record.provider.foundationdb.FDBSyntheticRecord in project fdb-record-layer by FoundationDB.
the class SyntheticRecordPlannerTest method rankJoinIndex.
@Test
public void rankJoinIndex() throws Exception {
final JoinedRecordTypeBuilder joined = metaDataBuilder.addJoinedRecordType("JoinedForRank");
joined.addConstituent("simple", "MySimpleRecord");
joined.addConstituent("other", "MyOtherRecord");
joined.addJoin("simple", "other_rec_no", "other", "rec_no");
final GroupingKeyExpression group = field("simple").nest("num_value_2").groupBy(field("other").nest("num_value"));
metaDataBuilder.addIndex(joined, new Index("simple.num_value_2_by_other.num_value", group, IndexTypes.RANK));
try (FDBRecordContext context = openContext()) {
final FDBRecordStore recordStore = recordStoreBuilder.setContext(context).create();
for (int i = 0; i < 4; i++) {
for (int j = 0; j < i; j++) {
TestRecordsJoinIndexProto.MySimpleRecord.Builder simple = TestRecordsJoinIndexProto.MySimpleRecord.newBuilder();
simple.setRecNo(100 * i + j).setOtherRecNo(1000 + i);
simple.setNumValue2(i + j);
recordStore.saveRecord(simple.build());
}
TestRecordsJoinIndexProto.MyOtherRecord.Builder other = TestRecordsJoinIndexProto.MyOtherRecord.newBuilder();
other.setRecNo(1000 + i);
other.setNumValue(i % 2);
recordStore.saveRecord(other.build());
}
context.commit();
}
try (FDBRecordContext context = openContext()) {
final FDBRecordStore recordStore = recordStoreBuilder.setContext(context).open();
Index index = recordStore.getRecordMetaData().getIndex("simple.num_value_2_by_other.num_value");
RecordCursor<IndexEntry> cursor = recordStore.scanIndex(index, IndexScanType.BY_RANK, TupleRange.allOf(Tuple.from(0, 1)), null, ScanProperties.FORWARD_SCAN);
Tuple pkey = cursor.first().get().map(IndexEntry::getPrimaryKey).orElse(null);
assertFalse(cursor.getNext().hasNext());
// 201, 1002 and 200, 1003 both have score 3, but in different groups.
assertEquals(Tuple.from(-1, Tuple.from(201), Tuple.from(1002)), pkey);
FDBSyntheticRecord record = recordStore.loadSyntheticRecord(pkey).join();
IndexRecordFunction<Long> rankFunction = ((IndexRecordFunction<Long>) Query.rank(group).getFunction()).cloneWithIndex(index.getName());
assertEquals(1, recordStore.evaluateRecordFunction(rankFunction, record).join().longValue());
}
}
use of com.apple.foundationdb.record.provider.foundationdb.FDBSyntheticRecord in project fdb-record-layer by FoundationDB.
the class SyntheticRecordPlannerTest method multiFieldKeys.
@Test
public void multiFieldKeys() throws Exception {
metaDataBuilder.getRecordType("MySimpleRecord").setPrimaryKey(concatenateFields("num_value", "rec_no"));
metaDataBuilder.getRecordType("MyOtherRecord").setPrimaryKey(concatenateFields("num_value", "rec_no"));
final JoinedRecordTypeBuilder joined = metaDataBuilder.addJoinedRecordType("MultiFieldJoin");
joined.addConstituent("simple", "MySimpleRecord");
joined.addConstituent("other", "MyOtherRecord");
// TODO: Not supported alternative would be to join concatenateFields("num_value", "other_rec_no") with concatenateFields("num_value", "rec_no").
joined.addJoin("simple", "num_value", "other", "num_value");
joined.addJoin("simple", "other_rec_no", "other", "rec_no");
metaDataBuilder.addIndex(joined, new Index("simple.str_value_other.num_value_3", concat(field("simple").nest("str_value"), field("other").nest("num_value_3"))));
try (FDBRecordContext context = openContext()) {
final FDBRecordStore recordStore = recordStoreBuilder.setContext(context).create();
for (int n = 1; n <= 2; n++) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < i; j++) {
TestRecordsJoinIndexProto.MySimpleRecord.Builder simple = TestRecordsJoinIndexProto.MySimpleRecord.newBuilder();
simple.setNumValue(n);
simple.setRecNo(100 * i + j).setOtherRecNo(1000 + i);
simple.setStrValue((i + j) % 2 == 0 ? "even" : "odd");
recordStore.saveRecord(simple.build());
}
TestRecordsJoinIndexProto.MyOtherRecord.Builder other = TestRecordsJoinIndexProto.MyOtherRecord.newBuilder();
other.setNumValue(n);
other.setRecNo(1000 + i);
other.setNumValue3(i);
recordStore.saveRecord(other.build());
}
}
context.commit();
}
try (FDBRecordContext context = openContext()) {
final FDBRecordStore recordStore = recordStoreBuilder.setContext(context).open();
List<FDBSyntheticRecord> recs = recordStore.scanIndex(recordStore.getRecordMetaData().getIndex("simple.str_value_other.num_value_3"), IndexScanType.BY_VALUE, TupleRange.allOf(Tuple.from("even", 2)), null, ScanProperties.FORWARD_SCAN).mapPipelined(entry -> recordStore.loadSyntheticRecord(entry.getPrimaryKey()), 1).asList().join();
for (FDBSyntheticRecord record : recs) {
TestRecordsJoinIndexProto.MySimpleRecord.Builder simple = TestRecordsJoinIndexProto.MySimpleRecord.newBuilder();
TestRecordsJoinIndexProto.MyOtherRecord.Builder other = TestRecordsJoinIndexProto.MyOtherRecord.newBuilder();
simple.mergeFrom(record.getConstituent("simple").getRecord());
other.mergeFrom(record.getConstituent("other").getRecord());
assertEquals(200, simple.getRecNo());
assertEquals(1002, other.getRecNo());
assertEquals(record.getPrimaryKey(), record.getRecordType().getPrimaryKey().evaluateSingleton(record).toTuple());
}
}
}
use of com.apple.foundationdb.record.provider.foundationdb.FDBSyntheticRecord in project fdb-record-layer by FoundationDB.
the class SyntheticRecordScanPlan method execute.
@Override
@Nonnull
public RecordCursor<FDBSyntheticRecord> execute(@Nonnull FDBRecordStore store, @Nullable byte[] continuation, @Nonnull ExecuteProperties executeProperties) {
final ExecuteProperties baseProperties = executeProperties.clearSkipAndLimit();
RecordCursor<FDBSyntheticRecord> cursor = RecordCursor.flatMapPipelined(outerContinuation -> store.executeQuery(recordPlan, outerContinuation, baseProperties), (queriedRecord, innerContinuation) -> syntheticRecordPlan.execute(store, queriedRecord.getStoredRecord(), innerContinuation, baseProperties), continuation, store.getPipelineSize(PipelineOperation.SYNTHETIC_RECORD_JOIN));
if (needDistinct) {
cursor = SyntheticRecordConcatPlan.addDistinct(cursor);
}
cursor = cursor.skipThenLimit(executeProperties.getSkip(), executeProperties.getReturnedRowLimit());
return cursor;
}
Aggregations