Search in sources :

Example 1 with RecordQueryCoveringIndexPlan

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

the class OrderingProperty method fromIndexScanOrCoveringIndexScan.

@Nonnull
private static Optional<Ordering> fromIndexScanOrCoveringIndexScan(@Nonnull final PlanContext context, @Nonnull final RecordQueryPlan plan) {
    final RecordQueryIndexPlan recordQueryIndexPlan;
    if (plan instanceof RecordQueryIndexPlan) {
        recordQueryIndexPlan = (RecordQueryIndexPlan) plan;
    } else if (plan instanceof RecordQueryCoveringIndexPlan) {
        final RecordQueryPlanWithIndex planWithIndex = ((RecordQueryCoveringIndexPlan) plan).getIndexPlan();
        if (planWithIndex instanceof RecordQueryIndexPlan) {
            recordQueryIndexPlan = (RecordQueryIndexPlan) planWithIndex;
        } else {
            return Optional.empty();
        }
    } else {
        return Optional.empty();
    }
    final String indexName = recordQueryIndexPlan.getIndexName();
    final RecordMetaData metaData = context.getMetaData();
    final Index index = metaData.getIndex(indexName);
    final Collection<RecordType> recordTypesForIndex = metaData.recordTypesForIndex(index);
    final KeyExpression commonPrimaryKeyForIndex = RecordMetaData.commonPrimaryKey(recordTypesForIndex);
    final KeyExpression keyExpression = ValueIndexExpansionVisitor.fullKey(index, commonPrimaryKeyForIndex);
    final ScanComparisons scanComparisons = recordQueryIndexPlan.getComparisons();
    return fromKeyAndScanComparisons(keyExpression, scanComparisons, plan.isReverse(), index.isUnique());
}
Also used : RecordMetaData(com.apple.foundationdb.record.RecordMetaData) ScanComparisons(com.apple.foundationdb.record.query.plan.ScanComparisons) RecordType(com.apple.foundationdb.record.metadata.RecordType) RecordQueryIndexPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryIndexPlan) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) RecordQueryCoveringIndexPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryCoveringIndexPlan) 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) Nonnull(javax.annotation.Nonnull)

Example 2 with RecordQueryCoveringIndexPlan

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

the class RemoveSortRule method strictlyOrderedIfUnique.

// TODO: This suggests that ordering and distinct should be tracked together.
public static boolean strictlyOrderedIfUnique(@Nonnull RecordQueryPlan orderedPlan, @Nonnull final Function<String, Index> getIndex, final int nkeys) {
    if (orderedPlan instanceof RecordQueryCoveringIndexPlan) {
        orderedPlan = ((RecordQueryCoveringIndexPlan) orderedPlan).getIndexPlan();
    }
    if (orderedPlan instanceof RecordQueryIndexPlan) {
        RecordQueryIndexPlan indexPlan = (RecordQueryIndexPlan) orderedPlan;
        Index index = getIndex.apply(indexPlan.getIndexName());
        return index.isUnique() && nkeys >= index.getColumnSize();
    }
    return false;
}
Also used : RecordQueryIndexPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryIndexPlan) RecordQueryCoveringIndexPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryCoveringIndexPlan) Index(com.apple.foundationdb.record.metadata.Index)

Example 3 with RecordQueryCoveringIndexPlan

use of com.apple.foundationdb.record.query.plan.plans.RecordQueryCoveringIndexPlan 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 4 with RecordQueryCoveringIndexPlan

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

the class ComposedBitmapIndexMatcher method matchesSafely.

@Override
public boolean matchesSafely(@Nonnull RecordQueryPlan plan) {
    if (!(plan instanceof ComposedBitmapIndexQueryPlan)) {
        return false;
    }
    ComposedBitmapIndexQueryPlan composedBitmapPlan = (ComposedBitmapIndexQueryPlan) plan;
    if (!composerMatcher.matches(composedBitmapPlan.getComposer())) {
        return false;
    }
    List<RecordQueryCoveringIndexPlan> childPlans = composedBitmapPlan.getIndexPlans();
    if (childPlans.size() != childMatchers.size()) {
        return false;
    }
    for (int i = 0; i < childMatchers.size(); i++) {
        if (!childMatchers.get(i).matches(childPlans.get(i))) {
            return false;
        }
    }
    return true;
}
Also used : RecordQueryCoveringIndexPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryCoveringIndexPlan) ComposedBitmapIndexQueryPlan(com.apple.foundationdb.record.query.plan.bitmap.ComposedBitmapIndexQueryPlan)

Example 5 with RecordQueryCoveringIndexPlan

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

the class RecordQueryPlanner method planCoveringAggregateIndex.

@Nullable
public RecordQueryCoveringIndexPlan planCoveringAggregateIndex(@Nonnull RecordQuery query, @Nonnull Index index, @Nonnull KeyExpression indexExpr) {
    final Collection<RecordType> recordTypes = metaData.recordTypesForIndex(index);
    if (recordTypes.size() != 1) {
        // Unfortunately, since we materialize partial records, we need a unique type for them.
        return null;
    }
    final RecordType recordType = recordTypes.iterator().next();
    final PlanContext planContext = getPlanContext(query);
    planContext.rankComparisons = new RankComparisons(query.getFilter(), planContext.indexes);
    // Repeated fields will be scanned one at a time by covering aggregate, so there is no issue with fan out.
    planContext.allowDuplicates = true;
    final CandidateScan candidateScan = new CandidateScan(planContext, index, query.isSortReverse());
    final ScoredPlan scoredPlan = planCandidateScan(candidateScan, indexExpr, BooleanNormalizer.forConfiguration(configuration).normalizeIfPossible(query.getFilter()), query.getSort());
    // It would be possible to handle unsatisfiedFilters if they, too, only involved group key (covering) fields.
    if (scoredPlan == null || !scoredPlan.unsatisfiedFilters.isEmpty() || !(scoredPlan.plan instanceof RecordQueryIndexPlan)) {
        return null;
    }
    final IndexKeyValueToPartialRecord.Builder builder = IndexKeyValueToPartialRecord.newBuilder(recordType);
    final List<KeyExpression> keyFields = index.getRootExpression().normalizeKeyForPositions();
    final List<KeyExpression> valueFields = Collections.emptyList();
    for (KeyExpression resultField : query.getRequiredResults()) {
        if (!addCoveringField(resultField, builder, keyFields, valueFields)) {
            return null;
        }
    }
    builder.addRequiredMessageFields();
    if (!builder.isValid(true)) {
        return null;
    }
    RecordQueryIndexPlan plan = (RecordQueryIndexPlan) scoredPlan.plan;
    IndexScanParameters scanParameters = new IndexScanComparisons(IndexScanType.BY_GROUP, plan.getComparisons());
    plan = new RecordQueryIndexPlan(plan.getIndexName(), scanParameters, plan.isReverse());
    return new RecordQueryCoveringIndexPlan(plan, recordType.getName(), AvailableFields.NO_FIELDS, builder.build());
}
Also used : IndexScanParameters(com.apple.foundationdb.record.provider.foundationdb.IndexScanParameters) RankComparisons(com.apple.foundationdb.record.query.plan.planning.RankComparisons) IndexScanComparisons(com.apple.foundationdb.record.provider.foundationdb.IndexScanComparisons) RecordQueryIndexPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryIndexPlan) RecordTypeKeyExpression(com.apple.foundationdb.record.metadata.expressions.RecordTypeKeyExpression) VersionKeyExpression(com.apple.foundationdb.record.metadata.expressions.VersionKeyExpression) GroupingKeyExpression(com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) FieldKeyExpression(com.apple.foundationdb.record.metadata.expressions.FieldKeyExpression) NestingKeyExpression(com.apple.foundationdb.record.metadata.expressions.NestingKeyExpression) EmptyKeyExpression(com.apple.foundationdb.record.metadata.expressions.EmptyKeyExpression) ThenKeyExpression(com.apple.foundationdb.record.metadata.expressions.ThenKeyExpression) RecordQueryCoveringIndexPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryCoveringIndexPlan) RecordType(com.apple.foundationdb.record.metadata.RecordType) Nullable(javax.annotation.Nullable)

Aggregations

RecordQueryCoveringIndexPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryCoveringIndexPlan)8 RecordType (com.apple.foundationdb.record.metadata.RecordType)4 RecordQueryIndexPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryIndexPlan)4 RecordQueryPlanWithIndex (com.apple.foundationdb.record.query.plan.plans.RecordQueryPlanWithIndex)4 Nonnull (javax.annotation.Nonnull)4 Index (com.apple.foundationdb.record.metadata.Index)3 KeyExpression (com.apple.foundationdb.record.metadata.expressions.KeyExpression)3 AvailableFields (com.apple.foundationdb.record.query.plan.AvailableFields)3 Nullable (javax.annotation.Nullable)3 IndexScanParameters (com.apple.foundationdb.record.provider.foundationdb.IndexScanParameters)2 IndexKeyValueToPartialRecord (com.apple.foundationdb.record.query.plan.IndexKeyValueToPartialRecord)2 ScanComparisons (com.apple.foundationdb.record.query.plan.ScanComparisons)2 RecordQueryFetchFromPartialRecordPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryFetchFromPartialRecordPlan)2 Value (com.apple.foundationdb.record.query.predicates.Value)2 API (com.apple.foundationdb.annotation.API)1 EvaluationContext (com.apple.foundationdb.record.EvaluationContext)1 ExecuteProperties (com.apple.foundationdb.record.ExecuteProperties)1 IndexEntry (com.apple.foundationdb.record.IndexEntry)1 ObjectPlanHash (com.apple.foundationdb.record.ObjectPlanHash)1 PlanHashable (com.apple.foundationdb.record.PlanHashable)1