Search in sources :

Example 1 with RecordType

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

the class RecordQueryPlanner method computeIndexFilters.

private ScoredPlan computeIndexFilters(@Nonnull PlanContext planContext, @Nonnull final ScoredPlan plan) {
    if (plan.plan instanceof RecordQueryPlanWithIndex) {
        final RecordQueryPlanWithIndex indexPlan = (RecordQueryPlanWithIndex) plan.plan;
        final Index index = metaData.getIndex(indexPlan.getIndexName());
        final Collection<RecordType> recordTypes = metaData.recordTypesForIndex(index);
        if (recordTypes.size() != 1) {
            return plan;
        }
        final RecordType recordType = Iterables.getOnlyElement(recordTypes);
        final List<QueryComponent> unsatisfiedFilters = new ArrayList<>(plan.unsatisfiedFilters);
        final AvailableFields availableFieldsFromIndex = AvailableFields.fromIndex(recordType, index, indexTypes, planContext.commonPrimaryKey);
        final List<QueryComponent> indexFilters = Lists.newArrayListWithCapacity(unsatisfiedFilters.size());
        final List<QueryComponent> residualFilters = Lists.newArrayListWithCapacity(unsatisfiedFilters.size());
        FilterVisitor.partitionFilters(unsatisfiedFilters, availableFieldsFromIndex, indexFilters, residualFilters, null);
        if (!indexFilters.isEmpty()) {
            return plan.withFilters(residualFilters, indexFilters);
        }
    }
    return plan;
}
Also used : QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) RecordType(com.apple.foundationdb.record.metadata.RecordType) ArrayList(java.util.ArrayList) RecordQueryPlanWithIndex(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlanWithIndex) RecordQueryPlanWithIndex(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlanWithIndex) Index(com.apple.foundationdb.record.metadata.Index)

Example 2 with RecordType

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

the class IndexingCommon method fillTargetIndexers.

private void fillTargetIndexers(@Nonnull List<Index> targetIndexes, @Nullable Collection<RecordType> recordTypes) {
    boolean presetTypes = false;
    if (recordTypes != null) {
        if (targetIndexes.size() > 1) {
            throw new IndexingBase.ValidationException("Can't use preset record types with multi target indexing");
        }
        presetTypes = true;
    }
    if (recordStoreBuilder.getMetaDataProvider() == null) {
        throw new MetaDataException("record store builder must include metadata");
    }
    final RecordMetaData metaData = recordStoreBuilder.getMetaDataProvider().getRecordMetaData();
    for (Index targetIndex : targetIndexes) {
        Collection<RecordType> types;
        if (presetTypes) {
            types = recordTypes;
        } else {
            types = metaData.recordTypesForIndex(targetIndex);
        }
        boolean isSynthetic = false;
        if (types.stream().anyMatch(RecordType::isSynthetic)) {
            types = new SyntheticRecordPlanner(metaData, new RecordStoreState(null, null)).storedRecordTypesForIndex(targetIndex, types);
            isSynthetic = true;
        }
        targetIndexContexts.add(new IndexContext(targetIndex, types, isSynthetic));
        allRecordTypes.addAll(types);
    }
}
Also used : RecordMetaData(com.apple.foundationdb.record.RecordMetaData) RecordType(com.apple.foundationdb.record.metadata.RecordType) SyntheticRecordPlanner(com.apple.foundationdb.record.query.plan.synthetic.SyntheticRecordPlanner) Index(com.apple.foundationdb.record.metadata.Index) RecordStoreState(com.apple.foundationdb.record.RecordStoreState) MetaDataException(com.apple.foundationdb.record.metadata.MetaDataException)

Example 3 with RecordType

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

the class SyntheticRecordPlanner method forIndex.

/**
 * Construct a plan for generating synthetic records for a given index.
 *
 * The generated records will be of indexed record types.
 *
 * Used by the {@link com.apple.foundationdb.record.provider.foundationdb.OnlineIndexer} to build from a full scan of stored records.
 * @param index an index on synthetic record types
 * @return a plan that can be applied to scanned records to generate synthetic records
 */
@Nonnull
public SyntheticRecordFromStoredRecordPlan forIndex(@Nonnull Index index) {
    final Collection<RecordType> recordTypes = recordMetaData.recordTypesForIndex(index);
    if (recordTypes.size() == 1) {
        final RecordType recordType = recordTypes.iterator().next();
        if (!recordType.isSynthetic()) {
            throw new RecordCoreException("Index does not apply to synthetic record types " + index);
        }
        return forType((SyntheticRecordType<?>) recordType);
    }
    Multimap<String, SyntheticRecordFromStoredRecordPlan> byType = ArrayListMultimap.create();
    for (RecordType recordType : recordTypes) {
        if (!(recordType instanceof JoinedRecordType)) {
            throw unknownSyntheticType(recordType);
        }
        JoinedRecordType joinedRecordType = (JoinedRecordType) recordType;
        Optional<JoinedRecordType.JoinConstituent> maybeConstituent = joinedRecordType.getConstituents().stream().filter(c -> !c.isOuterJoined()).findFirst();
        if (maybeConstituent.isPresent()) {
            addToByType(byType, joinedRecordType, maybeConstituent.get());
        } else {
            for (JoinedRecordType.JoinConstituent joinConstituent : joinedRecordType.getConstituents()) {
                addToByType(byType, joinedRecordType, joinConstituent);
            }
        }
    }
    return createByType(byType);
}
Also used : ArrayListMultimap(com.google.common.collect.ArrayListMultimap) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) HashMap(java.util.HashMap) RecordQuery(com.apple.foundationdb.record.query.RecordQuery) Multimap(com.google.common.collect.Multimap) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) ArrayList(java.util.ArrayList) RecordQueryPlanner(com.apple.foundationdb.record.query.plan.RecordQueryPlanner) HashSet(java.util.HashSet) JoinedRecordType(com.apple.foundationdb.record.metadata.JoinedRecordType) FDBRecordStore(com.apple.foundationdb.record.provider.foundationdb.FDBRecordStore) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) Map(java.util.Map) Nonnull(javax.annotation.Nonnull) Nullable(javax.annotation.Nullable) Collection(java.util.Collection) Set(java.util.Set) RecordCoreArgumentException(com.apple.foundationdb.record.RecordCoreArgumentException) List(java.util.List) RecordType(com.apple.foundationdb.record.metadata.RecordType) SyntheticRecordType(com.apple.foundationdb.record.metadata.SyntheticRecordType) Index(com.apple.foundationdb.record.metadata.Index) RecordStoreState(com.apple.foundationdb.record.RecordStoreState) Optional(java.util.Optional) API(com.apple.foundationdb.annotation.API) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) JoinedRecordType(com.apple.foundationdb.record.metadata.JoinedRecordType) RecordType(com.apple.foundationdb.record.metadata.RecordType) SyntheticRecordType(com.apple.foundationdb.record.metadata.SyntheticRecordType) JoinedRecordType(com.apple.foundationdb.record.metadata.JoinedRecordType) Nonnull(javax.annotation.Nonnull)

Example 4 with RecordType

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

the class SyntheticRecordPlanner method storedRecordTypesForIndex.

/**
 * Determine what stored record types would be need to scanned in order to rebuild a given index.
 *
 * From those scans, queries will be executed to load other record types to complete the synthesis.
 * <p>
 * In cases such as full outer join, there is no single record type from which all joins can be produced.
 * @param index the index that needs to be built
 * @param recordTypes a subset of the index's record types or {@code null} for all
 * @return a set of stored record types that are sufficient to generate the synthesized records for the index
 */
public Set<RecordType> storedRecordTypesForIndex(@Nonnull Index index, @Nullable Collection<RecordType> recordTypes) {
    if (recordTypes == null) {
        recordTypes = recordMetaData.recordTypesForIndex(index);
    }
    Set<RecordType> result = new HashSet<>();
    for (RecordType recordType : recordTypes) {
        if (!(recordType instanceof JoinedRecordType)) {
            throw unknownSyntheticType(recordType);
        }
        JoinedRecordType joinedRecordType = (JoinedRecordType) recordType;
        Optional<JoinedRecordType.JoinConstituent> maybeConstituent = joinedRecordType.getConstituents().stream().filter(c -> !c.isOuterJoined()).findFirst();
        if (maybeConstituent.isPresent()) {
            result.add(maybeConstituent.get().getRecordType());
        } else {
            for (JoinedRecordType.JoinConstituent joinConstituent : joinedRecordType.getConstituents()) {
                result.add(joinConstituent.getRecordType());
            }
        }
    }
    return result;
}
Also used : ArrayListMultimap(com.google.common.collect.ArrayListMultimap) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) HashMap(java.util.HashMap) RecordQuery(com.apple.foundationdb.record.query.RecordQuery) Multimap(com.google.common.collect.Multimap) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) ArrayList(java.util.ArrayList) RecordQueryPlanner(com.apple.foundationdb.record.query.plan.RecordQueryPlanner) HashSet(java.util.HashSet) JoinedRecordType(com.apple.foundationdb.record.metadata.JoinedRecordType) FDBRecordStore(com.apple.foundationdb.record.provider.foundationdb.FDBRecordStore) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) Map(java.util.Map) Nonnull(javax.annotation.Nonnull) Nullable(javax.annotation.Nullable) Collection(java.util.Collection) Set(java.util.Set) RecordCoreArgumentException(com.apple.foundationdb.record.RecordCoreArgumentException) List(java.util.List) RecordType(com.apple.foundationdb.record.metadata.RecordType) SyntheticRecordType(com.apple.foundationdb.record.metadata.SyntheticRecordType) Index(com.apple.foundationdb.record.metadata.Index) RecordStoreState(com.apple.foundationdb.record.RecordStoreState) Optional(java.util.Optional) API(com.apple.foundationdb.annotation.API) JoinedRecordType(com.apple.foundationdb.record.metadata.JoinedRecordType) RecordType(com.apple.foundationdb.record.metadata.RecordType) SyntheticRecordType(com.apple.foundationdb.record.metadata.SyntheticRecordType) JoinedRecordType(com.apple.foundationdb.record.metadata.JoinedRecordType) HashSet(java.util.HashSet)

Example 5 with RecordType

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

the class MatchCandidate method fromIndexDefinition.

@Nonnull
static Optional<MatchCandidate> fromIndexDefinition(@Nonnull final RecordMetaData metaData, @Nonnull final Index index, final boolean isReverse) {
    final Collection<RecordType> recordTypesForIndex = metaData.recordTypesForIndex(index);
    final KeyExpression commonPrimaryKeyForIndex = RecordMetaData.commonPrimaryKey(recordTypesForIndex);
    final ImmutableSet<String> recordTypeNamesForIndex = recordTypesForIndex.stream().map(RecordType::getName).collect(ImmutableSet.toImmutableSet());
    final Set<String> availableRecordTypes = metaData.getRecordTypes().keySet();
    final String type = index.getType();
    if (type.equals(IndexTypes.VALUE)) {
        final Quantifier.ForEach baseQuantifier = createBaseQuantifier(availableRecordTypes, recordTypeNamesForIndex);
        final ValueIndexExpansionVisitor expansionVisitor = new ValueIndexExpansionVisitor(index, recordTypesForIndex);
        try {
            return Optional.of(expansionVisitor.expand(baseQuantifier, commonPrimaryKeyForIndex, isReverse));
        } catch (final UnsupportedOperationException uOE) {
            // just log and return empty
            if (LOGGER.isDebugEnabled()) {
                final String message = KeyValueLogMessage.of("unsupported value index", "reason", uOE.getMessage(), "indexName", index.getName());
                LOGGER.debug(message, uOE);
            }
        }
    }
    return Optional.empty();
}
Also used : RecordType(com.apple.foundationdb.record.metadata.RecordType) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) Nonnull(javax.annotation.Nonnull)

Aggregations

RecordType (com.apple.foundationdb.record.metadata.RecordType)43 Nonnull (javax.annotation.Nonnull)29 Index (com.apple.foundationdb.record.metadata.Index)25 KeyExpression (com.apple.foundationdb.record.metadata.expressions.KeyExpression)24 RecordMetaData (com.apple.foundationdb.record.RecordMetaData)20 Nullable (javax.annotation.Nullable)20 Descriptors (com.google.protobuf.Descriptors)18 SyntheticRecordType (com.apple.foundationdb.record.metadata.SyntheticRecordType)17 ArrayList (java.util.ArrayList)17 RecordCoreException (com.apple.foundationdb.record.RecordCoreException)16 Tuple (com.apple.foundationdb.tuple.Tuple)16 List (java.util.List)15 Collection (java.util.Collection)14 API (com.apple.foundationdb.annotation.API)13 IndexEntry (com.apple.foundationdb.record.IndexEntry)13 Collectors (java.util.stream.Collectors)13 RecordCoreArgumentException (com.apple.foundationdb.record.RecordCoreArgumentException)12 TupleRange (com.apple.foundationdb.record.TupleRange)12 MetaDataException (com.apple.foundationdb.record.metadata.MetaDataException)12 CompletableFuture (java.util.concurrent.CompletableFuture)12