Search in sources :

Example 6 with JoinedRecordTypeBuilder

use of com.apple.foundationdb.record.metadata.JoinedRecordTypeBuilder 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);
    }
}
Also used : Message(com.google.protobuf.Message) FDBRecordStore(com.apple.foundationdb.record.provider.foundationdb.FDBRecordStore) JoinedRecordTypeBuilder(com.apple.foundationdb.record.metadata.JoinedRecordTypeBuilder) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) Tuple(com.apple.foundationdb.tuple.Tuple) Test(org.junit.jupiter.api.Test)

Example 7 with JoinedRecordTypeBuilder

use of com.apple.foundationdb.record.metadata.JoinedRecordTypeBuilder 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);
    }
}
Also used : Message(com.google.protobuf.Message) FDBRecordStore(com.apple.foundationdb.record.provider.foundationdb.FDBRecordStore) JoinedRecordTypeBuilder(com.apple.foundationdb.record.metadata.JoinedRecordTypeBuilder) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) Tuple(com.apple.foundationdb.tuple.Tuple) Test(org.junit.jupiter.api.Test)

Example 8 with JoinedRecordTypeBuilder

use of com.apple.foundationdb.record.metadata.JoinedRecordTypeBuilder 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());
    }
}
Also used : IndexRecordFunction(com.apple.foundationdb.record.metadata.IndexRecordFunction) GroupingKeyExpression(com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression) FDBSyntheticRecord(com.apple.foundationdb.record.provider.foundationdb.FDBSyntheticRecord) IndexEntry(com.apple.foundationdb.record.IndexEntry) Index(com.apple.foundationdb.record.metadata.Index) FDBRecordStore(com.apple.foundationdb.record.provider.foundationdb.FDBRecordStore) JoinedRecordTypeBuilder(com.apple.foundationdb.record.metadata.JoinedRecordTypeBuilder) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) Tuple(com.apple.foundationdb.tuple.Tuple) Test(org.junit.jupiter.api.Test)

Example 9 with JoinedRecordTypeBuilder

use of com.apple.foundationdb.record.metadata.JoinedRecordTypeBuilder in project fdb-record-layer by FoundationDB.

the class SyntheticRecordPlannerTest method manyToMany.

@Test
public void manyToMany() throws Exception {
    final JoinedRecordTypeBuilder joined = metaDataBuilder.addJoinedRecordType("ManyToMany");
    joined.addConstituent("simple", "MySimpleRecord");
    joined.addConstituent("other", "MyOtherRecord");
    joined.addConstituent("joining", "JoiningRecord");
    joined.addJoin("joining", "simple_rec_no", "simple", "rec_no");
    joined.addJoin("joining", "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);
            recordStore.saveRecord(simple.build());
            TestRecordsJoinIndexProto.MyOtherRecord.Builder other = TestRecordsJoinIndexProto.MyOtherRecord.newBuilder();
            other.setRecNo(1000 + i);
            recordStore.saveRecord(other.build());
        }
        TestRecordsJoinIndexProto.JoiningRecord.Builder joining = TestRecordsJoinIndexProto.JoiningRecord.newBuilder();
        joining.setRecNo(100).setSimpleRecNo(1).setOtherRecNo(1000);
        recordStore.saveRecord(joining.build());
        joining.setRecNo(101).setSimpleRecNo(2).setOtherRecNo(1000);
        recordStore.saveRecord(joining.build());
        joining.setRecNo(102).setSimpleRecNo(2).setOtherRecNo(1002);
        recordStore.saveRecord(joining.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("ManyToMany"));
        Multiset<Tuple> expected1 = ImmutableMultiset.of(Tuple.from(-1, Tuple.from(1), Tuple.from(1000), Tuple.from(100)), Tuple.from(-1, Tuple.from(2), Tuple.from(1000), Tuple.from(101)), Tuple.from(-1, Tuple.from(2), Tuple.from(1002), Tuple.from(102)));
        Multiset<Tuple> results1 = HashMultiset.create(plan1.execute(recordStore).map(FDBSyntheticRecord::getPrimaryKey).asList().join());
        assertEquals(expected1, results1);
    }
}
Also used : FDBRecordStore(com.apple.foundationdb.record.provider.foundationdb.FDBRecordStore) JoinedRecordTypeBuilder(com.apple.foundationdb.record.metadata.JoinedRecordTypeBuilder) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) Tuple(com.apple.foundationdb.tuple.Tuple) Test(org.junit.jupiter.api.Test)

Example 10 with JoinedRecordTypeBuilder

use of com.apple.foundationdb.record.metadata.JoinedRecordTypeBuilder in project fdb-record-layer by FoundationDB.

the class SyntheticRecordPlannerTest method manyToOne.

@Test
public void manyToOne() throws Exception {
    metaDataBuilder.addIndex("MySimpleRecord", "other_rec_no");
    final JoinedRecordTypeBuilder joined = metaDataBuilder.addJoinedRecordType("ManyToOne");
    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++) {
            for (int j = 0; j < i; j++) {
                TestRecordsJoinIndexProto.MySimpleRecord.Builder simple = TestRecordsJoinIndexProto.MySimpleRecord.newBuilder();
                simple.setRecNo(100 * i + j).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("ManyToOne"));
        Multiset<Tuple> expected1 = ImmutableMultiset.of(Tuple.from(-1, Tuple.from(100), Tuple.from(1001)), Tuple.from(-1, Tuple.from(200), Tuple.from(1002)), Tuple.from(-1, Tuple.from(201), Tuple.from(1002)));
        Multiset<Tuple> results1 = HashMultiset.create(plan1.execute(recordStore).map(FDBSyntheticRecord::getPrimaryKey).asList().join());
        assertEquals(expected1, results1);
        FDBStoredRecord<Message> record = recordStore.loadRecord(Tuple.from(1002));
        SyntheticRecordFromStoredRecordPlan plan2 = planner.fromStoredType(record.getRecordType(), false);
        Multiset<Tuple> expected2 = ImmutableMultiset.of(Tuple.from(-1, Tuple.from(200), Tuple.from(1002)), Tuple.from(-1, Tuple.from(201), Tuple.from(1002)));
        Multiset<Tuple> results2 = HashMultiset.create(plan2.execute(recordStore, record).map(FDBSyntheticRecord::getPrimaryKey).asList().join());
        assertEquals(expected2, results2);
    }
}
Also used : Message(com.google.protobuf.Message) FDBRecordStore(com.apple.foundationdb.record.provider.foundationdb.FDBRecordStore) JoinedRecordTypeBuilder(com.apple.foundationdb.record.metadata.JoinedRecordTypeBuilder) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) Tuple(com.apple.foundationdb.tuple.Tuple) Test(org.junit.jupiter.api.Test)

Aggregations

JoinedRecordTypeBuilder (com.apple.foundationdb.record.metadata.JoinedRecordTypeBuilder)14 FDBRecordContext (com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext)12 FDBRecordStore (com.apple.foundationdb.record.provider.foundationdb.FDBRecordStore)12 Test (org.junit.jupiter.api.Test)12 Tuple (com.apple.foundationdb.tuple.Tuple)11 Index (com.apple.foundationdb.record.metadata.Index)7 Message (com.google.protobuf.Message)5 IndexEntry (com.apple.foundationdb.record.IndexEntry)3 GroupingKeyExpression (com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression)3 KeyExpression (com.apple.foundationdb.record.metadata.expressions.KeyExpression)3 RecordMetaDataBuilder (com.apple.foundationdb.record.RecordMetaDataBuilder)2 TupleRange (com.apple.foundationdb.record.TupleRange)2 FDBSyntheticRecord (com.apple.foundationdb.record.provider.foundationdb.FDBSyntheticRecord)2 Comparisons (com.apple.foundationdb.record.query.expressions.Comparisons)2 ScanComparisons (com.apple.foundationdb.record.query.plan.ScanComparisons)2 API (com.apple.foundationdb.annotation.API)1 FormerIndex (com.apple.foundationdb.record.metadata.FormerIndex)1 IndexAggregateFunction (com.apple.foundationdb.record.metadata.IndexAggregateFunction)1 IndexRecordFunction (com.apple.foundationdb.record.metadata.IndexRecordFunction)1 MetaDataException (com.apple.foundationdb.record.metadata.MetaDataException)1