Search in sources :

Example 1 with AvailableFields

use of com.apple.foundationdb.record.query.plan.AvailableFields in project fdb-record-layer by FoundationDB.

the class RecordQueryPlannerSubstitutionVisitor method removeIndexFetch.

@Nullable
public static RecordQueryPlan removeIndexFetch(@Nonnull RecordMetaData recordMetaData, @Nonnull PlannableIndexTypes indexTypes, @Nullable KeyExpression commonPrimaryKey, @Nonnull RecordQueryPlan plan, @Nonnull Set<KeyExpression> requiredFields) {
    if (plan instanceof RecordQueryPlanWithIndex) {
        RecordQueryPlanWithIndex indexPlan = (RecordQueryPlanWithIndex) plan;
        Index index = recordMetaData.getIndex(indexPlan.getIndexName());
        final Collection<RecordType> recordTypes = recordMetaData.recordTypesForIndex(index);
        if (recordTypes.size() != 1) {
            return null;
        }
        final RecordType recordType = Iterables.getOnlyElement(recordTypes);
        AvailableFields fieldsFromIndex = AvailableFields.fromIndex(recordType, index, indexTypes, commonPrimaryKey);
        Set<KeyExpression> fields = new HashSet<>(requiredFields);
        if (commonPrimaryKey != null) {
            // Need the primary key, even if it wasn't one of the explicit result fields.
            fields.addAll(commonPrimaryKey.normalizeKeyForPositions());
        }
        if (fieldsFromIndex.containsAll(fields)) {
            final IndexKeyValueToPartialRecord keyValueToPartialRecord = fieldsFromIndex.buildIndexKeyValueToPartialRecord(recordType).build();
            if (keyValueToPartialRecord != null) {
                return new RecordQueryCoveringIndexPlan(indexPlan, recordType.getName(), fieldsFromIndex, keyValueToPartialRecord);
            }
        }
    } else if (plan instanceof RecordQueryFetchFromPartialRecordPlan) {
        RecordQueryFetchFromPartialRecordPlan fetchPlan = (RecordQueryFetchFromPartialRecordPlan) plan;
        if (fetchPlan.getChild().getAvailableFields().containsAll(requiredFields)) {
            return ((RecordQueryFetchFromPartialRecordPlan) plan).getChild();
        }
    }
    return null;
}
Also used : AvailableFields(com.apple.foundationdb.record.query.plan.AvailableFields) RecordQueryFetchFromPartialRecordPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryFetchFromPartialRecordPlan) RecordType(com.apple.foundationdb.record.metadata.RecordType) IndexKeyValueToPartialRecord(com.apple.foundationdb.record.query.plan.IndexKeyValueToPartialRecord) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) RecordQueryPlanWithIndex(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlanWithIndex) RecordQueryCoveringIndexPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryCoveringIndexPlan) RecordQueryPlanWithIndex(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlanWithIndex) Index(com.apple.foundationdb.record.metadata.Index) HashSet(java.util.HashSet) Nullable(javax.annotation.Nullable)

Example 2 with AvailableFields

use of com.apple.foundationdb.record.query.plan.AvailableFields in project fdb-record-layer by FoundationDB.

the class FilterVisitor method postVisit.

@Nonnull
@Override
public RecordQueryPlan postVisit(@Nonnull RecordQueryPlan recordQueryPlan) {
    if (recordQueryPlan instanceof RecordQueryFilterPlan) {
        final RecordQueryFilterPlan filterPlan = (RecordQueryFilterPlan) recordQueryPlan;
        final List<QueryComponent> filters = filterPlan.getFilters();
        final AvailableFields availableFields = availableFields(((RecordQueryFilterPlan) recordQueryPlan).getInnerPlan());
        // Partition the filters according to whether they can be evaluated using just the fields from the index or
        // if they need a full record.
        final List<QueryComponent> indexFilters = Lists.newArrayListWithCapacity(filters.size());
        final List<QueryComponent> residualFilters = Lists.newArrayListWithCapacity(filters.size());
        final Set<KeyExpression> allReferencedFields = new HashSet<>();
        partitionFilters(filters, availableFields, indexFilters, residualFilters, allReferencedFields);
        Verify.verify(indexFilters.size() + residualFilters.size() == filters.size());
        if (indexFilters.isEmpty()) {
            return recordQueryPlan;
        }
        @Nullable RecordQueryPlan removedFetchPlan = removeIndexFetch(filterPlan.getChild(), allReferencedFields);
        if (removedFetchPlan == null) {
            return recordQueryPlan;
        }
        recordQueryPlan = new RecordQueryFetchFromPartialRecordPlan(new RecordQueryFilterPlan(removedFetchPlan, indexFilters), TranslateValueFunction.unableToTranslate());
        if (!residualFilters.isEmpty()) {
            recordQueryPlan = new RecordQueryFilterPlan(recordQueryPlan, residualFilters);
        }
    }
    return recordQueryPlan;
}
Also used : RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) AvailableFields(com.apple.foundationdb.record.query.plan.AvailableFields) RecordQueryFilterPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryFilterPlan) RecordQueryFetchFromPartialRecordPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryFetchFromPartialRecordPlan) FunctionKeyExpression(com.apple.foundationdb.record.metadata.expressions.FunctionKeyExpression) LiteralKeyExpression(com.apple.foundationdb.record.metadata.expressions.LiteralKeyExpression) FieldKeyExpression(com.apple.foundationdb.record.metadata.expressions.FieldKeyExpression) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) QueryableKeyExpression(com.apple.foundationdb.record.metadata.expressions.QueryableKeyExpression) ThenKeyExpression(com.apple.foundationdb.record.metadata.expressions.ThenKeyExpression) Nullable(javax.annotation.Nullable) HashSet(java.util.HashSet) Nonnull(javax.annotation.Nonnull)

Aggregations

KeyExpression (com.apple.foundationdb.record.metadata.expressions.KeyExpression)2 AvailableFields (com.apple.foundationdb.record.query.plan.AvailableFields)2 RecordQueryFetchFromPartialRecordPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryFetchFromPartialRecordPlan)2 HashSet (java.util.HashSet)2 Nullable (javax.annotation.Nullable)2 Index (com.apple.foundationdb.record.metadata.Index)1 RecordType (com.apple.foundationdb.record.metadata.RecordType)1 FieldKeyExpression (com.apple.foundationdb.record.metadata.expressions.FieldKeyExpression)1 FunctionKeyExpression (com.apple.foundationdb.record.metadata.expressions.FunctionKeyExpression)1 LiteralKeyExpression (com.apple.foundationdb.record.metadata.expressions.LiteralKeyExpression)1 QueryableKeyExpression (com.apple.foundationdb.record.metadata.expressions.QueryableKeyExpression)1 ThenKeyExpression (com.apple.foundationdb.record.metadata.expressions.ThenKeyExpression)1 QueryComponent (com.apple.foundationdb.record.query.expressions.QueryComponent)1 IndexKeyValueToPartialRecord (com.apple.foundationdb.record.query.plan.IndexKeyValueToPartialRecord)1 RecordQueryCoveringIndexPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryCoveringIndexPlan)1 RecordQueryFilterPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryFilterPlan)1 RecordQueryPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan)1 RecordQueryPlanWithIndex (com.apple.foundationdb.record.query.plan.plans.RecordQueryPlanWithIndex)1 Nonnull (javax.annotation.Nonnull)1