use of com.apple.foundationdb.record.provider.foundationdb.FDBRecordStore 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.provider.foundationdb.FDBRecordStore 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.provider.foundationdb.FDBRecordStore 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);
}
}
use of com.apple.foundationdb.record.provider.foundationdb.FDBRecordStore in project fdb-record-layer by FoundationDB.
the class SyntheticRecordPlannerTest method selfJoin.
@Test
public void selfJoin() throws Exception {
metaDataBuilder.addIndex("MySimpleRecord", "other_rec_no");
final JoinedRecordTypeBuilder joined = metaDataBuilder.addJoinedRecordType("SelfJoin");
joined.addConstituent("simple1", "MySimpleRecord");
joined.addConstituent("simple2", "MySimpleRecord");
joined.addJoin("simple1", "other_rec_no", "simple2", "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(i + 1);
recordStore.saveRecord(simple.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("SelfJoin"));
Multiset<Tuple> expected1 = ImmutableMultiset.of(Tuple.from(-1, Tuple.from(0), Tuple.from(1)), Tuple.from(-1, Tuple.from(1), Tuple.from(2)));
Multiset<Tuple> results1 = HashMultiset.create(plan1.execute(recordStore).map(FDBSyntheticRecord::getPrimaryKey).asList().join());
assertEquals(expected1, results1);
FDBStoredRecord<Message> record = recordStore.loadRecord(Tuple.from(1));
SyntheticRecordFromStoredRecordPlan plan2 = planner.fromStoredType(record.getRecordType(), false);
Multiset<Tuple> expected2 = ImmutableMultiset.of(Tuple.from(-1, Tuple.from(0), Tuple.from(1)), Tuple.from(-1, Tuple.from(1), Tuple.from(2)));
Multiset<Tuple> results2 = HashMultiset.create(plan2.execute(recordStore, record).map(FDBSyntheticRecord::getPrimaryKey).asList().join());
assertEquals(expected2, results2);
}
}
use of com.apple.foundationdb.record.provider.foundationdb.FDBRecordStore in project fdb-record-layer by FoundationDB.
the class SyntheticRecordPlannerTest method outerJoins.
@Test
public void outerJoins() throws Exception {
metaDataBuilder.addIndex("MySimpleRecord", "other_rec_no");
final JoinedRecordTypeBuilder innerJoined = metaDataBuilder.addJoinedRecordType("InnerJoined");
innerJoined.addConstituent("simple", "MySimpleRecord");
innerJoined.addConstituent("other", "MyOtherRecord");
innerJoined.addJoin("simple", "other_rec_no", "other", "rec_no");
final JoinedRecordTypeBuilder leftJoined = metaDataBuilder.addJoinedRecordType("LeftJoined");
leftJoined.addConstituent("simple", "MySimpleRecord");
leftJoined.addConstituent("other", metaDataBuilder.getRecordType("MyOtherRecord"), true);
leftJoined.addJoin("simple", "other_rec_no", "other", "rec_no");
final JoinedRecordTypeBuilder fullOuterJoined = metaDataBuilder.addJoinedRecordType("FullOuterJoined");
fullOuterJoined.addConstituent("simple", metaDataBuilder.getRecordType("MySimpleRecord"), true);
fullOuterJoined.addConstituent("other", metaDataBuilder.getRecordType("MyOtherRecord"), true);
fullOuterJoined.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(1001 + 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("InnerJoined"));
Multiset<Tuple> expected1 = ImmutableMultiset.of(Tuple.from(-1, Tuple.from(0), Tuple.from(1001)), Tuple.from(-1, Tuple.from(1), Tuple.from(1002)));
Multiset<Tuple> results1 = HashMultiset.create(plan1.execute(recordStore).map(FDBSyntheticRecord::getPrimaryKey).asList().join());
assertEquals(expected1, results1);
SyntheticRecordPlan plan2 = planner.scanForType(recordStore.getRecordMetaData().getSyntheticRecordType("LeftJoined"));
Multiset<Tuple> expected2 = ImmutableMultiset.of(Tuple.from(-2, Tuple.from(0), Tuple.from(1001)), Tuple.from(-2, Tuple.from(1), Tuple.from(1002)), Tuple.from(-2, Tuple.from(2), null));
Multiset<Tuple> results2 = HashMultiset.create(plan2.execute(recordStore).map(FDBSyntheticRecord::getPrimaryKey).asList().join());
assertEquals(expected2, results2);
SyntheticRecordPlan plan3 = planner.scanForType(recordStore.getRecordMetaData().getSyntheticRecordType("FullOuterJoined"));
Multiset<Tuple> expected3 = ImmutableMultiset.of(Tuple.from(-3, null, Tuple.from(1000)), Tuple.from(-3, Tuple.from(0), Tuple.from(1001)), Tuple.from(-3, Tuple.from(1), Tuple.from(1002)), Tuple.from(-3, Tuple.from(2), null));
Multiset<Tuple> results3 = HashMultiset.create(plan3.execute(recordStore).map(FDBSyntheticRecord::getPrimaryKey).asList().join());
assertEquals(expected3, results3);
FDBStoredRecord<Message> record = recordStore.loadRecord(Tuple.from(2));
SyntheticRecordFromStoredRecordPlan plan4 = planner.fromStoredType(record.getRecordType(), false);
Multiset<Tuple> expected4 = ImmutableMultiset.of(Tuple.from(-2, Tuple.from(2), null), Tuple.from(-3, Tuple.from(2), null));
Multiset<Tuple> results4 = HashMultiset.create(plan4.execute(recordStore, record).map(FDBSyntheticRecord::getPrimaryKey).asList().join());
assertEquals(expected4, results4);
}
}
Aggregations