use of com.apple.foundationdb.record.metadata.JoinedRecordTypeBuilder in project fdb-record-layer by FoundationDB.
the class RecordMetaDataBuilder method loadProtoExceptRecords.
@SuppressWarnings("deprecation")
private void loadProtoExceptRecords(@Nonnull RecordMetaDataProto.MetaData metaDataProto) {
for (RecordMetaDataProto.Index indexProto : metaDataProto.getIndexesList()) {
List<RecordTypeBuilder> recordTypeBuilders = new ArrayList<>(indexProto.getRecordTypeCount());
for (String recordTypeName : indexProto.getRecordTypeList()) {
recordTypeBuilders.add(getRecordType(recordTypeName));
}
try {
addMultiTypeIndex(recordTypeBuilders, new Index(indexProto));
} catch (KeyExpression.DeserializationException e) {
throw new MetaDataProtoDeserializationException(e);
}
}
for (RecordMetaDataProto.RecordType typeProto : metaDataProto.getRecordTypesList()) {
RecordTypeBuilder typeBuilder = getRecordType(typeProto.getName());
if (typeProto.hasPrimaryKey()) {
try {
typeBuilder.setPrimaryKey(KeyExpression.fromProto(typeProto.getPrimaryKey()));
} catch (KeyExpression.DeserializationException e) {
throw new MetaDataProtoDeserializationException(e);
}
}
if (typeProto.hasSinceVersion()) {
typeBuilder.setSinceVersion(typeProto.getSinceVersion());
}
if (typeProto.hasExplicitKey()) {
typeBuilder.setRecordTypeKey(LiteralKeyExpression.fromProtoValue(typeProto.getExplicitKey()));
}
}
if (metaDataProto.hasSplitLongRecords()) {
splitLongRecords = metaDataProto.getSplitLongRecords();
}
if (metaDataProto.hasStoreRecordVersions()) {
storeRecordVersions = metaDataProto.getStoreRecordVersions();
}
for (RecordMetaDataProto.FormerIndex formerIndex : metaDataProto.getFormerIndexesList()) {
formerIndexes.add(new FormerIndex(formerIndex));
}
if (metaDataProto.hasRecordCountKey()) {
try {
recordCountKey = KeyExpression.fromProto(metaDataProto.getRecordCountKey());
} catch (KeyExpression.DeserializationException e) {
throw new MetaDataProtoDeserializationException(e);
}
}
if (metaDataProto.hasVersion()) {
version = metaDataProto.getVersion();
}
for (RecordMetaDataProto.JoinedRecordType joinedProto : metaDataProto.getJoinedRecordTypesList()) {
JoinedRecordTypeBuilder typeBuilder = new JoinedRecordTypeBuilder(joinedProto, this);
syntheticRecordTypes.put(typeBuilder.getName(), typeBuilder);
}
}
use of com.apple.foundationdb.record.metadata.JoinedRecordTypeBuilder in project fdb-record-layer by FoundationDB.
the class SyntheticRecordPlannerTest method joinIndex.
@Test
public void joinIndex() throws Exception {
metaDataBuilder.addIndex("MySimpleRecord", "other_rec_no");
final JoinedRecordTypeBuilder joined = metaDataBuilder.addJoinedRecordType("Simple_Other");
joined.addConstituent("simple", "MySimpleRecord");
joined.addConstituent("other", "MyOtherRecord");
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 i = 0; i < 3; i++) {
for (int j = 0; j < i; j++) {
TestRecordsJoinIndexProto.MySimpleRecord.Builder simple = TestRecordsJoinIndexProto.MySimpleRecord.newBuilder();
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.setRecNo(1000 + i);
other.setNumValue3(i);
recordStore.saveRecord(other.build());
}
context.commit();
}
try (FDBRecordContext context = openContext()) {
final FDBRecordStore recordStore = recordStoreBuilder.setContext(context).open();
final Index index = recordStore.getRecordMetaData().getIndex("simple.str_value_other.num_value_3");
final TupleRange range = new ScanComparisons.Builder().addEqualityComparison(new Comparisons.SimpleComparison(Comparisons.Type.EQUALS, "even")).addInequalityComparison(new Comparisons.SimpleComparison(Comparisons.Type.GREATER_THAN, 1)).build().toTupleRange();
List<Tuple> expected1 = Arrays.asList(Tuple.from("even", 2, -1, Tuple.from(200), Tuple.from(1002)));
List<Tuple> results1 = recordStore.scanIndex(index, IndexScanType.BY_VALUE, range, null, ScanProperties.FORWARD_SCAN).map(IndexEntry::getKey).asList().join();
assertEquals(expected1, results1);
FDBStoredRecord<Message> record = recordStore.loadRecord(Tuple.from(201));
TestRecordsJoinIndexProto.MySimpleRecord.Builder recordBuilder = TestRecordsJoinIndexProto.MySimpleRecord.newBuilder().mergeFrom(record.getRecord());
recordBuilder.setStrValue("even");
recordStore.saveRecord(recordBuilder.build());
List<Tuple> expected2 = Arrays.asList(Tuple.from("even", 2, -1, Tuple.from(200), Tuple.from(1002)), Tuple.from("even", 2, -1, Tuple.from(201), Tuple.from(1002)));
List<Tuple> results2 = recordStore.scanIndex(index, IndexScanType.BY_VALUE, range, null, ScanProperties.FORWARD_SCAN).map(IndexEntry::getKey).asList().join();
assertEquals(expected2, results2);
recordStore.deleteRecord(Tuple.from(1002));
List<Tuple> expected3 = Arrays.asList();
List<Tuple> results3 = recordStore.scanIndex(index, IndexScanType.BY_VALUE, range, null, ScanProperties.FORWARD_SCAN).map(IndexEntry::getKey).asList().join();
assertEquals(expected3, results3);
}
}
use of com.apple.foundationdb.record.metadata.JoinedRecordTypeBuilder in project fdb-record-layer by FoundationDB.
the class SyntheticRecordPlannerTest method aggregateJoinIndex.
@Test
public void aggregateJoinIndex() throws Exception {
final KeyExpression pkey = concat(recordType(), field("uuid"));
metaDataBuilder.getRecordType("Customer").setPrimaryKey(pkey);
metaDataBuilder.getRecordType("Order").setPrimaryKey(pkey);
metaDataBuilder.getRecordType("Item").setPrimaryKey(pkey);
metaDataBuilder.addIndex("Customer", "name");
metaDataBuilder.addIndex("Order", "order_no");
metaDataBuilder.addIndex("Order", "customer_uuid");
metaDataBuilder.addIndex("Item", "order_uuid");
final JoinedRecordTypeBuilder joined = metaDataBuilder.addJoinedRecordType("COI");
joined.addConstituent("c", "Customer");
joined.addConstituent("o", "Order");
joined.addConstituent("i", "Item");
joined.addJoin("o", "customer_uuid", "c", "uuid");
joined.addJoin("i", "order_uuid", "o", "uuid");
metaDataBuilder.addIndex(joined, new Index("total_price_by_city", field("i").nest("total_price").groupBy(field("c").nest("city")), IndexTypes.SUM));
try (FDBRecordContext context = openContext()) {
final FDBRecordStore recordStore = recordStoreBuilder.setContext(context).create();
TestRecordsJoinIndexProto.Customer.Builder c = TestRecordsJoinIndexProto.Customer.newBuilder();
c.setUuid(TupleFieldsHelper.toProto(UUID.randomUUID())).setName("Jones").setCity("Boston");
recordStore.saveRecord(c.build());
c.setUuid(TupleFieldsHelper.toProto(UUID.randomUUID())).setName("Smith").setCity("New York");
recordStore.saveRecord(c.build());
c.setUuid(TupleFieldsHelper.toProto(UUID.randomUUID())).setName("Lee").setCity("Boston");
recordStore.saveRecord(c.build());
context.commit();
}
final RecordQuery findByName = RecordQuery.newBuilder().setRecordType("Customer").setFilter(Query.field("name").equalsParameter("name")).build();
final RecordQuery findByOrderNo = RecordQuery.newBuilder().setRecordType("Order").setFilter(Query.field("order_no").equalsParameter("order_no")).build();
final Index index = metaDataBuilder.getRecordMetaData().getIndex("total_price_by_city");
final IndexAggregateFunction sumByCity = new IndexAggregateFunction(FunctionNames.SUM, index.getRootExpression(), index.getName());
final List<String> coi = Collections.singletonList("COI");
try (FDBRecordContext context = openContext()) {
final FDBRecordStore recordStore = recordStoreBuilder.setContext(context).open();
TestRecordsJoinIndexProto.Customer.Builder c = TestRecordsJoinIndexProto.Customer.newBuilder();
c.mergeFrom(recordStore.planQuery(findByName).execute(recordStore, EvaluationContext.forBinding("name", "Jones")).first().join().orElseThrow(() -> new RuntimeException("not found")).getRecord());
TestRecordsJoinIndexProto.Order.Builder o = TestRecordsJoinIndexProto.Order.newBuilder();
o.setUuid(TupleFieldsHelper.toProto(UUID.randomUUID())).setOrderNo(1001).setCustomerUuid(c.getUuid());
recordStore.saveRecord(o.build());
TestRecordsJoinIndexProto.Item.Builder i = TestRecordsJoinIndexProto.Item.newBuilder();
i.setUuid(TupleFieldsHelper.toProto(UUID.randomUUID())).setItemNo(123).setQuantity(100).setTotalPrice(200).setOrderUuid(o.getUuid());
recordStore.saveRecord(i.build());
i.setUuid(TupleFieldsHelper.toProto(UUID.randomUUID())).setItemNo(456).setQuantity(10).setTotalPrice(1000).setOrderUuid(o.getUuid());
recordStore.saveRecord(i.build());
context.commit();
}
try (FDBRecordContext context = openContext()) {
final FDBRecordStore recordStore = recordStoreBuilder.setContext(context).open();
TestRecordsJoinIndexProto.Customer.Builder c = TestRecordsJoinIndexProto.Customer.newBuilder();
c.mergeFrom(recordStore.planQuery(findByName).execute(recordStore, EvaluationContext.forBinding("name", "Smith")).first().join().orElseThrow(() -> new RuntimeException("not found")).getRecord());
TestRecordsJoinIndexProto.Order.Builder o = TestRecordsJoinIndexProto.Order.newBuilder();
o.setUuid(TupleFieldsHelper.toProto(UUID.randomUUID())).setOrderNo(1002).setCustomerUuid(c.getUuid());
recordStore.saveRecord(o.build());
TestRecordsJoinIndexProto.Item.Builder i = TestRecordsJoinIndexProto.Item.newBuilder();
i.setUuid(TupleFieldsHelper.toProto(UUID.randomUUID())).setItemNo(789).setQuantity(20).setTotalPrice(200).setOrderUuid(o.getUuid());
recordStore.saveRecord(i.build());
context.commit();
}
try (FDBRecordContext context = openContext()) {
final FDBRecordStore recordStore = recordStoreBuilder.setContext(context).open();
TestRecordsJoinIndexProto.Customer.Builder c = TestRecordsJoinIndexProto.Customer.newBuilder();
c.mergeFrom(recordStore.planQuery(findByName).execute(recordStore, EvaluationContext.forBinding("name", "Lee")).first().join().orElseThrow(() -> new RuntimeException("not found")).getRecord());
TestRecordsJoinIndexProto.Order.Builder o = TestRecordsJoinIndexProto.Order.newBuilder();
o.setUuid(TupleFieldsHelper.toProto(UUID.randomUUID())).setOrderNo(1003).setCustomerUuid(c.getUuid());
recordStore.saveRecord(o.build());
TestRecordsJoinIndexProto.Item.Builder i = TestRecordsJoinIndexProto.Item.newBuilder();
i.setUuid(TupleFieldsHelper.toProto(UUID.randomUUID())).setItemNo(123).setQuantity(150).setTotalPrice(300).setOrderUuid(o.getUuid());
recordStore.saveRecord(i.build());
context.commit();
}
try (FDBRecordContext context = openContext()) {
final FDBRecordStore recordStore = recordStoreBuilder.setContext(context).open();
assertEquals(Tuple.from(1500), recordStore.evaluateAggregateFunction(coi, sumByCity, Key.Evaluated.scalar("Boston"), IsolationLevel.SERIALIZABLE).join());
}
try (FDBRecordContext context = openContext()) {
final FDBRecordStore recordStore = recordStoreBuilder.setContext(context).open();
TestRecordsJoinIndexProto.Customer.Builder c = TestRecordsJoinIndexProto.Customer.newBuilder();
c.mergeFrom(recordStore.planQuery(findByName).execute(recordStore, EvaluationContext.forBinding("name", "Lee")).first().join().orElseThrow(() -> new RuntimeException("not found")).getRecord());
TestRecordsJoinIndexProto.Order.Builder o = TestRecordsJoinIndexProto.Order.newBuilder();
o.setUuid(TupleFieldsHelper.toProto(UUID.randomUUID())).setOrderNo(1004).setCustomerUuid(c.getUuid());
recordStore.saveRecord(o.build());
TestRecordsJoinIndexProto.Item.Builder i = TestRecordsJoinIndexProto.Item.newBuilder();
i.setUuid(TupleFieldsHelper.toProto(UUID.randomUUID())).setItemNo(456).setQuantity(1).setTotalPrice(100).setOrderUuid(o.getUuid());
recordStore.saveRecord(i.build());
context.commit();
}
try (FDBRecordContext context = openContext()) {
final FDBRecordStore recordStore = recordStoreBuilder.setContext(context).open();
assertEquals(Tuple.from(1600), recordStore.evaluateAggregateFunction(coi, sumByCity, Key.Evaluated.scalar("Boston"), IsolationLevel.SERIALIZABLE).join());
}
try (FDBRecordContext context = openContext()) {
final FDBRecordStore recordStore = recordStoreBuilder.setContext(context).open();
TestRecordsJoinIndexProto.Order.Builder o = TestRecordsJoinIndexProto.Order.newBuilder();
o.mergeFrom(recordStore.planQuery(findByOrderNo).execute(recordStore, EvaluationContext.forBinding("order_no", 1003)).first().join().orElseThrow(() -> new RuntimeException("not found")).getRecord());
TestRecordsJoinIndexProto.Item.Builder i = TestRecordsJoinIndexProto.Item.newBuilder();
i.setUuid(TupleFieldsHelper.toProto(UUID.randomUUID())).setItemNo(789).setQuantity(10).setTotalPrice(100).setOrderUuid(o.getUuid());
recordStore.saveRecord(i.build());
context.commit();
}
try (FDBRecordContext context = openContext()) {
final FDBRecordStore recordStore = recordStoreBuilder.setContext(context).open();
assertEquals(Tuple.from(1700), recordStore.evaluateAggregateFunction(coi, sumByCity, Key.Evaluated.scalar("Boston"), IsolationLevel.SERIALIZABLE).join());
}
try (FDBRecordContext context = openContext()) {
final FDBRecordStore recordStore = recordStoreBuilder.setContext(context).open();
TestRecordsJoinIndexProto.Customer.Builder c = TestRecordsJoinIndexProto.Customer.newBuilder();
c.mergeFrom(recordStore.planQuery(findByName).execute(recordStore, EvaluationContext.forBinding("name", "Lee")).first().join().orElseThrow(() -> new RuntimeException("not found")).getRecord());
c.setCity("San Francisco");
recordStore.saveRecord(c.build());
context.commit();
}
try (FDBRecordContext context = openContext()) {
final FDBRecordStore recordStore = recordStoreBuilder.setContext(context).open();
assertEquals(Tuple.from(1200), recordStore.evaluateAggregateFunction(coi, sumByCity, Key.Evaluated.scalar("Boston"), IsolationLevel.SERIALIZABLE).join());
Map<Tuple, Tuple> expected = ImmutableMap.of(Tuple.from("Boston"), Tuple.from(1200), Tuple.from("New York"), Tuple.from(200), Tuple.from("San Francisco"), Tuple.from(500));
Map<Tuple, Tuple> results = recordStore.scanIndex(index, IndexScanType.BY_GROUP, TupleRange.ALL, null, ScanProperties.FORWARD_SCAN).asList().join().stream().collect(Collectors.toMap(IndexEntry::getKey, IndexEntry::getValue));
assertEquals(expected, results);
}
}
use of com.apple.foundationdb.record.metadata.JoinedRecordTypeBuilder in project fdb-record-layer by FoundationDB.
the class SyntheticRecordPlannerTest method buildJoinIndex.
@Test
public void buildJoinIndex() throws Exception {
metaDataBuilder.addIndex("MySimpleRecord", "other_rec_no");
final JoinedRecordTypeBuilder joined = metaDataBuilder.addJoinedRecordType("Simple_Other");
joined.addConstituent("simple", "MySimpleRecord");
joined.addConstituent("other", "MyOtherRecord");
joined.addJoin("simple", "other_rec_no", "other", "rec_no");
try (FDBRecordContext context = openContext()) {
final FDBRecordStore recordStore = recordStoreBuilder.setContext(context).create();
for (int i = 0; i < 3; i++) {
TestRecordsJoinIndexProto.MySimpleRecord.Builder simple = TestRecordsJoinIndexProto.MySimpleRecord.newBuilder();
simple.setRecNo(i).setOtherRecNo(1000 + i);
simple.setNumValue2(i * 2);
recordStore.saveRecord(simple.build());
TestRecordsJoinIndexProto.MyOtherRecord.Builder other = TestRecordsJoinIndexProto.MyOtherRecord.newBuilder();
other.setRecNo(1000 + i);
other.setNumValue3(i * 3);
recordStore.saveRecord(other.build());
}
context.commit();
}
metaDataBuilder.addIndex(joined, new Index("simple.num_value_2_other.num_value_3", concat(field("simple").nest("num_value_2"), field("other").nest("num_value_3"))));
try (FDBRecordContext context = openContext()) {
final FDBRecordStore recordStore = recordStoreBuilder.setContext(context).open();
final Index index = recordStore.getRecordMetaData().getIndex("simple.num_value_2_other.num_value_3");
final TupleRange range = new ScanComparisons.Builder().addEqualityComparison(new Comparisons.SimpleComparison(Comparisons.Type.EQUALS, 2)).addEqualityComparison(new Comparisons.SimpleComparison(Comparisons.Type.EQUALS, 3)).build().toTupleRange();
List<Tuple> expected1 = Arrays.asList(Tuple.from(2, 3, -1, Tuple.from(1), Tuple.from(1001)));
List<Tuple> results1 = recordStore.scanIndex(index, IndexScanType.BY_VALUE, range, null, ScanProperties.FORWARD_SCAN).map(IndexEntry::getKey).asList().join();
assertEquals(expected1, results1);
}
}
use of com.apple.foundationdb.record.metadata.JoinedRecordTypeBuilder in project fdb-record-layer by FoundationDB.
the class SyntheticRecordPlannerTest method oneToOne.
@Test
public void oneToOne() throws Exception {
metaDataBuilder.addIndex("MySimpleRecord", new Index("MySimpleRecord$other_rec_no", field("other_rec_no"), IndexTypes.VALUE, IndexOptions.UNIQUE_OPTIONS));
final JoinedRecordTypeBuilder joined = metaDataBuilder.addJoinedRecordType("OneToOne");
joined.addConstituent("simple", "MySimpleRecord");
joined.addConstituent("other", "MyOtherRecord");
joined.addJoin("simple", "other_rec_no", "other", "rec_no");
try (FDBRecordContext context = openContext()) {
final FDBRecordStore recordStore = recordStoreBuilder.setContext(context).create();
for (int i = 0; i < 3; i++) {
TestRecordsJoinIndexProto.MySimpleRecord.Builder simple = TestRecordsJoinIndexProto.MySimpleRecord.newBuilder();
simple.setRecNo(i).setOtherRecNo(1000 + i);
recordStore.saveRecord(simple.build());
TestRecordsJoinIndexProto.MyOtherRecord.Builder other = TestRecordsJoinIndexProto.MyOtherRecord.newBuilder();
other.setRecNo(1000 + i);
recordStore.saveRecord(other.build());
}
context.commit();
}
try (FDBRecordContext context = openContext()) {
final FDBRecordStore recordStore = recordStoreBuilder.setContext(context).open();
final SyntheticRecordPlanner planner = new SyntheticRecordPlanner(recordStore);
SyntheticRecordPlan plan1 = planner.scanForType(recordStore.getRecordMetaData().getSyntheticRecordType("OneToOne"));
Multiset<Tuple> expected1 = ImmutableMultiset.of(Tuple.from(-1, Tuple.from(0), Tuple.from(1000)), Tuple.from(-1, Tuple.from(1), Tuple.from(1001)), Tuple.from(-1, Tuple.from(2), Tuple.from(1002)));
Multiset<Tuple> results1 = HashMultiset.create(plan1.execute(recordStore).map(FDBSyntheticRecord::getPrimaryKey).asList().join());
assertEquals(expected1, results1);
}
}
Aggregations