Search in sources :

Example 26 with RecordTypeBuilder

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

the class FDBRecordStoreQueryTest method enumFields.

/**
 * Verify that enum field indexes are used.
 */
@DualPlannerTest
void enumFields() throws Exception {
    RecordMetaDataHook hook = metaData -> {
        final RecordTypeBuilder type = metaData.getRecordType("MyShapeRecord");
        metaData.addIndex(type, new Index("size", field("size")));
        metaData.addIndex(type, new Index("color", field("color")));
        metaData.addIndex(type, new Index("shape", field("shape")));
    };
    setupEnumShapes(hook);
    RecordQuery query = RecordQuery.newBuilder().setRecordType("MyShapeRecord").setFilter(Query.field("color").equalsValue(TestRecordsEnumProto.MyShapeRecord.Color.RED)).build();
    // Index(color [[10],[10]])
    RecordQueryPlan plan = planner.plan(query);
    assertMatchesExactly(plan, indexPlan().where(indexName("color")));
    assertFalse(plan.hasRecordScan(), "should not use record scan");
    assertEquals(1393755963, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
    assertEquals(-14917443, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
    assertEquals(-2083866282, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
    try (FDBRecordContext context = openContext()) {
        openEnumRecordStore(context, hook);
        int i = 0;
        try (RecordCursorIterator<FDBQueriedRecord<Message>> cursor = recordStore.executeQuery(plan).asIterator()) {
            while (cursor.hasNext()) {
                FDBQueriedRecord<Message> rec = cursor.next();
                TestRecordsEnumProto.MyShapeRecord.Builder shapeRec = TestRecordsEnumProto.MyShapeRecord.newBuilder();
                shapeRec.mergeFrom(rec.getRecord());
                assertEquals(TestRecordsEnumProto.MyShapeRecord.Color.RED, shapeRec.getColor());
                i++;
            }
        }
        assertEquals(9, i);
        assertDiscardedNone(context);
    }
}
Also used : Arrays(java.util.Arrays) RecordQueryPlanMatchers.scanPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.scanPlan) Bindings(com.apple.foundationdb.record.Bindings) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) RecordQueryPlanMatchers.predicates(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.predicates) RecordQueryPlanner(com.apple.foundationdb.record.query.plan.RecordQueryPlanner) TestHelpers.assertDiscardedNone(com.apple.foundationdb.record.TestHelpers.assertDiscardedNone) TestRecordsMultiProto(com.apple.foundationdb.record.TestRecordsMultiProto) Tuple(com.apple.foundationdb.tuple.Tuple) RecordCursorResult(com.apple.foundationdb.record.RecordCursorResult) ListMatcher.only(com.apple.foundationdb.record.query.plan.temp.matchers.ListMatcher.only) Assertions.assertFalse(org.junit.jupiter.api.Assertions.assertFalse) RecordQueryPlanMatchers.indexName(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.indexName) Tag(org.junit.jupiter.api.Tag) Query(com.apple.foundationdb.record.query.expressions.Query) ImmutableSet(com.google.common.collect.ImmutableSet) TestRecords1Proto(com.apple.foundationdb.record.TestRecords1Proto) RecordQueryPlanMatchers.recordTypes(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.recordTypes) UUID(java.util.UUID) Collectors(java.util.stream.Collectors) Test(org.junit.jupiter.api.Test) Objects(java.util.Objects) List(java.util.List) ScanComparisons.range(com.apple.foundationdb.record.query.plan.ScanComparisons.range) Matchers.containsInAnyOrder(org.hamcrest.Matchers.containsInAnyOrder) EvaluationContext(com.apple.foundationdb.record.EvaluationContext) FDBQueriedRecord(com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) TestRecordsEnumProto(com.apple.foundationdb.record.TestRecordsEnumProto) RecordQueryPlanComplexityException(com.apple.foundationdb.record.query.plan.RecordQueryPlanComplexityException) RecordQueryPlanMatchers.unionPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.unionPlan) RecordQueryPlanMatchers(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers) RecordQueryPlanMatchers.predicatesFilterPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.predicatesFilterPlan) IntStream(java.util.stream.IntStream) Assertions.assertThrows(org.junit.jupiter.api.Assertions.assertThrows) Assertions.fail(org.junit.jupiter.api.Assertions.fail) ValueMatchers.anyValue(com.apple.foundationdb.record.query.plan.temp.matchers.ValueMatchers.anyValue) RecordQuery(com.apple.foundationdb.record.query.RecordQuery) PrimitiveMatchers.equalsObject(com.apple.foundationdb.record.query.plan.temp.matchers.PrimitiveMatchers.equalsObject) QueryPredicateMatchers.queryComponentPredicate(com.apple.foundationdb.record.query.plan.temp.matchers.QueryPredicateMatchers.queryComponentPredicate) TestRecordsTupleFieldsProto(com.apple.foundationdb.record.TestRecordsTupleFieldsProto) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) PlanHashable(com.apple.foundationdb.record.PlanHashable) ArrayList(java.util.ArrayList) ExecuteProperties(com.apple.foundationdb.record.ExecuteProperties) Lists(com.google.common.collect.Lists) RecordCursorIterator(com.apple.foundationdb.record.RecordCursorIterator) RecordQueryPlanMatchers.scanComparisons(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.scanComparisons) RecordQueryPlanMatchers.unorderedPrimaryKeyDistinctPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.unorderedPrimaryKeyDistinctPlan) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) Expressions.field(com.apple.foundationdb.record.metadata.Key.Expressions.field) FDBStoredRecord(com.apple.foundationdb.record.provider.foundationdb.FDBStoredRecord) IsolationLevel(com.apple.foundationdb.record.IsolationLevel) LongStream(java.util.stream.LongStream) ScanComparisons.unbounded(com.apple.foundationdb.record.query.plan.ScanComparisons.unbounded) RecordTypeBuilder(com.apple.foundationdb.record.metadata.RecordTypeBuilder) TupleFieldsHelper(com.apple.foundationdb.record.metadata.expressions.TupleFieldsHelper) Tags(com.apple.test.Tags) QueryPredicateMatchers.valuePredicate(com.apple.foundationdb.record.query.plan.temp.matchers.QueryPredicateMatchers.valuePredicate) PrimitiveMatchers.containsAll(com.apple.foundationdb.record.query.plan.temp.matchers.PrimitiveMatchers.containsAll) RecordQueryPlanMatchers.queryComponents(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.queryComponents) RecordQueryPlanMatchers.typeFilterPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.typeFilterPlan) Comparisons(com.apple.foundationdb.record.query.expressions.Comparisons) RecordQueryPlanMatchers.filterPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.filterPlan) Index(com.apple.foundationdb.record.metadata.Index) RecordQueryPlanMatchers.indexPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.indexPlan) TestHelpers.assertDiscardedAtMost(com.apple.foundationdb.record.TestHelpers.assertDiscardedAtMost) Message(com.google.protobuf.Message) RecordCursor(com.apple.foundationdb.record.RecordCursor) QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) ListMatcher.exactly(com.apple.foundationdb.record.query.plan.temp.matchers.ListMatcher.exactly) Collections(java.util.Collections) TestRecordsBytesProto(com.apple.foundationdb.record.TestRecordsBytesProto) ValueMatchers.fieldValue(com.apple.foundationdb.record.query.plan.temp.matchers.ValueMatchers.fieldValue) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) Message(com.google.protobuf.Message) Index(com.apple.foundationdb.record.metadata.Index) RecordTypeBuilder(com.apple.foundationdb.record.metadata.RecordTypeBuilder) FDBQueriedRecord(com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) RecordQuery(com.apple.foundationdb.record.query.RecordQuery)

Example 27 with RecordTypeBuilder

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

the class RecordMetaDataBuilder method updateUnionFieldsAndRecordTypes.

private void updateUnionFieldsAndRecordTypes(@Nonnull Descriptors.Descriptor union, boolean processExtensionOptions) {
    final Map<String, RecordTypeBuilder> oldRecordTypes = ImmutableMap.copyOf(recordTypes);
    recordTypes.clear();
    unionFields.clear();
    for (Descriptors.FieldDescriptor unionField : union.getFields()) {
        Descriptors.Descriptor newDescriptor = unionField.getMessageType();
        Descriptors.Descriptor oldDescriptor = findOldDescriptor(unionField, union);
        if (unionFields.containsKey(newDescriptor)) {
            if (!recordTypes.containsKey(newDescriptor.getName())) {
                // Union field was seen before but the record type is unknown? This must not happen.
                throw new MetaDataException("Unknown record type for union field " + unionField.getName());
            }
            // For existing record types, the preferred field is the last one, except if there is one whose name matches.
            remapUnionField(newDescriptor, unionField);
        } else if (oldDescriptor == null) {
            // New field and record type.
            RecordTypeBuilder recordType = processRecordType(unionField, processExtensionOptions);
            if (recordType.getSinceVersion() != null && recordType.getSinceVersion() != version) {
                throw new MetaDataException(String.format("Record type version (%d) does not match meta-data version (%d)", recordType.getSinceVersion(), version));
            } else {
                recordType.setSinceVersion(version);
            }
            unionFields.put(newDescriptor, unionField);
        } else {
            updateRecordType(oldRecordTypes, oldDescriptor, newDescriptor);
            unionFields.put(newDescriptor, unionField);
        }
    }
}
Also used : Descriptors(com.google.protobuf.Descriptors) SyntheticRecordTypeBuilder(com.apple.foundationdb.record.metadata.SyntheticRecordTypeBuilder) RecordTypeBuilder(com.apple.foundationdb.record.metadata.RecordTypeBuilder) JoinedRecordTypeBuilder(com.apple.foundationdb.record.metadata.JoinedRecordTypeBuilder) MetaDataException(com.apple.foundationdb.record.metadata.MetaDataException)

Example 28 with RecordTypeBuilder

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

the class RecordMetaDataBuilder method build.

/**
 * Build and validate meta-data with specific index registry.
 * @param validate {@code true} to validate the new meta-data
 * @return new meta-data
 */
@Nonnull
public RecordMetaData build(boolean validate) {
    Map<String, RecordType> builtRecordTypes = Maps.newHashMapWithExpectedSize(recordTypes.size());
    Map<String, SyntheticRecordType<?>> builtSyntheticRecordTypes = Maps.newHashMapWithExpectedSize(syntheticRecordTypes.size());
    RecordMetaData metaData = new RecordMetaData(recordsDescriptor, getUnionDescriptor(), unionFields, builtRecordTypes, builtSyntheticRecordTypes, indexes, universalIndexes, formerIndexes, splitLongRecords, storeRecordVersions, version, subspaceKeyCounter, usesSubspaceKeyCounter, recordCountKey, localFileDescriptor != null);
    for (RecordTypeBuilder recordTypeBuilder : recordTypes.values()) {
        KeyExpression primaryKey = recordTypeBuilder.getPrimaryKey();
        if (primaryKey != null) {
            builtRecordTypes.put(recordTypeBuilder.getName(), recordTypeBuilder.build(metaData));
            for (Index index : recordTypeBuilder.getIndexes()) {
                index.setPrimaryKeyComponentPositions(buildPrimaryKeyComponentPositions(index.getRootExpression(), primaryKey));
            }
        } else {
            throw new MetaDataException("Record type " + recordTypeBuilder.getName() + " must have a primary key");
        }
    }
    if (!syntheticRecordTypes.isEmpty()) {
        DescriptorProtos.FileDescriptorProto.Builder fileBuilder = DescriptorProtos.FileDescriptorProto.newBuilder();
        fileBuilder.setName("_synthetic");
        fileBuilder.addDependency(unionDescriptor.getFile().getName());
        syntheticRecordTypes.values().forEach(recordTypeBuilder -> recordTypeBuilder.buildDescriptor(fileBuilder));
        final Descriptors.FileDescriptor fileDescriptor;
        try {
            final Descriptors.FileDescriptor[] dependencies = new Descriptors.FileDescriptor[] { unionDescriptor.getFile() };
            fileDescriptor = Descriptors.FileDescriptor.buildFrom(fileBuilder.build(), dependencies);
        } catch (Descriptors.DescriptorValidationException ex) {
            throw new MetaDataException("Could not build synthesized file descriptor", ex);
        }
        for (SyntheticRecordTypeBuilder<?> recordTypeBuilder : syntheticRecordTypes.values()) {
            builtSyntheticRecordTypes.put(recordTypeBuilder.getName(), recordTypeBuilder.build(metaData, fileDescriptor));
        }
    }
    if (validate) {
        final MetaDataValidator validator = new MetaDataValidator(metaData, indexMaintainerRegistry);
        validator.validate();
    }
    return metaData;
}
Also used : SyntheticRecordType(com.apple.foundationdb.record.metadata.SyntheticRecordType) LiteralKeyExpression(com.apple.foundationdb.record.metadata.expressions.LiteralKeyExpression) FieldKeyExpression(com.apple.foundationdb.record.metadata.expressions.FieldKeyExpression) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) FormerIndex(com.apple.foundationdb.record.metadata.FormerIndex) Index(com.apple.foundationdb.record.metadata.Index) SyntheticRecordTypeBuilder(com.apple.foundationdb.record.metadata.SyntheticRecordTypeBuilder) RecordTypeBuilder(com.apple.foundationdb.record.metadata.RecordTypeBuilder) JoinedRecordTypeBuilder(com.apple.foundationdb.record.metadata.JoinedRecordTypeBuilder) MetaDataException(com.apple.foundationdb.record.metadata.MetaDataException) RecordType(com.apple.foundationdb.record.metadata.RecordType) SyntheticRecordType(com.apple.foundationdb.record.metadata.SyntheticRecordType) Descriptors(com.google.protobuf.Descriptors) MetaDataValidator(com.apple.foundationdb.record.metadata.MetaDataValidator) Nonnull(javax.annotation.Nonnull)

Example 29 with RecordTypeBuilder

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

the class FDBMetaDataStore method addMultiTypeIndexAsync.

/**
 * Add a new index to the record meta-data that contains multiple record types asynchronously.
 * If the list is null or empty, the resulting index will include all record types.
 * If the list has one element it will just be a normal single record type index.
 * @param recordTypes a list of record types that the index will include
 * @param index the index to be added
 * @return a future that completes when the index is added
 */
@Nonnull
public CompletableFuture<Void> addMultiTypeIndexAsync(@Nullable List<String> recordTypes, @Nonnull Index index) {
    return loadCurrentProto().thenCompose(metaDataProto -> {
        RecordMetaDataBuilder recordMetaDataBuilder = createMetaDataBuilder(metaDataProto);
        List<RecordTypeBuilder> recordTypeBuilders = new ArrayList<>();
        if (recordTypes != null) {
            for (String type : recordTypes) {
                recordTypeBuilders.add(recordMetaDataBuilder.getRecordType(type));
            }
        }
        recordMetaDataBuilder.addMultiTypeIndex(recordTypeBuilders, index);
        return saveAndSetCurrent(recordMetaDataBuilder.getRecordMetaData().toProto());
    });
}
Also used : RecordMetaDataBuilder(com.apple.foundationdb.record.RecordMetaDataBuilder) ArrayList(java.util.ArrayList) RecordTypeBuilder(com.apple.foundationdb.record.metadata.RecordTypeBuilder) Nonnull(javax.annotation.Nonnull)

Aggregations

RecordTypeBuilder (com.apple.foundationdb.record.metadata.RecordTypeBuilder)29 Index (com.apple.foundationdb.record.metadata.Index)22 Test (org.junit.jupiter.api.Test)21 RecordMetaDataBuilder (com.apple.foundationdb.record.RecordMetaDataBuilder)20 ArrayList (java.util.ArrayList)20 KeyExpression (com.apple.foundationdb.record.metadata.expressions.KeyExpression)19 Nonnull (javax.annotation.Nonnull)19 Expressions.field (com.apple.foundationdb.record.metadata.Key.Expressions.field)18 MetaDataException (com.apple.foundationdb.record.metadata.MetaDataException)18 Query (com.apple.foundationdb.record.query.expressions.Query)18 Tags (com.apple.test.Tags)18 Collections (java.util.Collections)18 List (java.util.List)18 Tag (org.junit.jupiter.api.Tag)18 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)18 RecordMetaData (com.apple.foundationdb.record.RecordMetaData)17 Expressions.concat (com.apple.foundationdb.record.metadata.Key.Expressions.concat)17 Tuple (com.apple.foundationdb.tuple.Tuple)17 Message (com.google.protobuf.Message)17 Arrays (java.util.Arrays)17