Search in sources :

Example 1 with RecordQueryPlanWithIndex

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

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

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

the class RecordQueryPlannerSubstitutionVisitor method availableFields.

@Nonnull
public static AvailableFields availableFields(@Nonnull RecordMetaData recordMetaData, @Nonnull PlannableIndexTypes indexTypes, @Nullable KeyExpression commonPrimaryKey, @Nonnull RecordQueryPlan plan) {
    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 AvailableFields.NO_FIELDS;
        }
        final RecordType recordType = Iterables.getOnlyElement(recordTypes);
        return AvailableFields.fromIndex(recordType, index, indexTypes, commonPrimaryKey);
    } else if (plan instanceof RecordQueryFetchFromPartialRecordPlan) {
        RecordQueryFetchFromPartialRecordPlan fetchPlan = (RecordQueryFetchFromPartialRecordPlan) plan;
        return fetchPlan.getChild().getAvailableFields();
    }
    return AvailableFields.NO_FIELDS;
}
Also used : RecordQueryFetchFromPartialRecordPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryFetchFromPartialRecordPlan) RecordType(com.apple.foundationdb.record.metadata.RecordType) 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 4 with RecordQueryPlanWithIndex

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

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

the class PlanOrderingKey method forPlan.

@Nullable
public static PlanOrderingKey forPlan(@Nonnull RecordMetaData metaData, @Nonnull RecordQueryPlan queryPlan, @Nullable KeyExpression primaryKey) {
    if (primaryKey == null) {
        return null;
    }
    while (queryPlan instanceof RecordQueryFilterPlan) {
        queryPlan = ((RecordQueryFilterPlan) queryPlan).getInnerPlan();
    }
    if (queryPlan instanceof RecordQueryPlanWithIndex) {
        final RecordQueryPlanWithIndex indexPlan = (RecordQueryPlanWithIndex) queryPlan;
        final Index index = metaData.getIndex(indexPlan.getIndexName());
        final List<KeyExpression> keys = new ArrayList<>(index.getRootExpression().normalizeKeyForPositions());
        int pkeyStart = keys.size();
        int pKeyTail = pkeyStart;
        // Primary keys come after index value keys, unless they were already part of it.
        for (KeyExpression pkey : primaryKey.normalizeKeyForPositions()) {
            int pos = keys.indexOf(pkey);
            if (pos < 0) {
                keys.add(pkey);
            } else if (pkeyStart > pos) {
                pkeyStart = pos;
            }
        }
        final int prefixSize;
        if (indexPlan instanceof RecordQueryIndexPlan) {
            prefixSize = ((RecordQueryIndexPlan) indexPlan).getComparisons().getEqualitySize();
        } else if (indexPlan instanceof RecordQueryTextIndexPlan) {
            final TextScan textScan = ((RecordQueryTextIndexPlan) indexPlan).getTextScan();
            int groupingSize = textScan.getGroupingComparisons() != null ? textScan.getGroupingComparisons().getEqualitySize() : 0;
            int suffixSize = textScan.getSuffixComparisons() != null ? textScan.getSuffixComparisons().getEqualitySize() : 0;
            if (textScan.getTextComparison().getType().isEquality()) {
                // Can use the equality comparisons in the grouping columns and any columns after the text index
                // plus the text column itself.
                prefixSize = groupingSize + suffixSize + 1;
            } else {
                // by the token that the prefix scan just so happened to hit.
                return null;
            }
        } else {
            // Some unknown index plan. Maybe this should throw an error?
            return null;
        }
        return new PlanOrderingKey(keys, prefixSize, pkeyStart, pKeyTail);
    } else if (queryPlan instanceof RecordQueryScanPlan) {
        final RecordQueryScanPlan scanPlan = (RecordQueryScanPlan) queryPlan;
        return new PlanOrderingKey(primaryKey.normalizeKeyForPositions(), scanPlan.getComparisons().getEqualitySize(), 0, 0);
    } else if (queryPlan instanceof RecordQueryIntersectionPlan) {
        return forComparisonKey(((RecordQueryIntersectionPlan) queryPlan).getComparisonKey(), primaryKey);
    } else if (queryPlan instanceof RecordQueryUnionPlan) {
        return forComparisonKey(((RecordQueryUnionPlan) queryPlan).getComparisonKey(), primaryKey);
    } else {
        return null;
    }
}
Also used : RecordQueryUnionPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryUnionPlan) RecordQueryScanPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryScanPlan) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) ThenKeyExpression(com.apple.foundationdb.record.metadata.expressions.ThenKeyExpression) ArrayList(java.util.ArrayList) RecordQueryIndexPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryIndexPlan) RecordQueryPlanWithIndex(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlanWithIndex) Index(com.apple.foundationdb.record.metadata.Index) RecordQueryTextIndexPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryTextIndexPlan) RecordQueryIntersectionPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryIntersectionPlan) RecordQueryFilterPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryFilterPlan) RecordQueryPlanWithIndex(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlanWithIndex) Nullable(javax.annotation.Nullable)

Aggregations

RecordQueryPlanWithIndex (com.apple.foundationdb.record.query.plan.plans.RecordQueryPlanWithIndex)7 Index (com.apple.foundationdb.record.metadata.Index)5 RecordType (com.apple.foundationdb.record.metadata.RecordType)5 RecordQueryCoveringIndexPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryCoveringIndexPlan)4 Nonnull (javax.annotation.Nonnull)4 KeyExpression (com.apple.foundationdb.record.metadata.expressions.KeyExpression)3 RecordQueryFetchFromPartialRecordPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryFetchFromPartialRecordPlan)3 RecordQueryIndexPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryIndexPlan)3 AvailableFields (com.apple.foundationdb.record.query.plan.AvailableFields)2 IndexKeyValueToPartialRecord (com.apple.foundationdb.record.query.plan.IndexKeyValueToPartialRecord)2 ScanComparisons (com.apple.foundationdb.record.query.plan.ScanComparisons)2 RecordQueryScanPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryScanPlan)2 ArrayList (java.util.ArrayList)2 Nullable (javax.annotation.Nullable)2 RecordCoreException (com.apple.foundationdb.record.RecordCoreException)1 RecordMetaData (com.apple.foundationdb.record.RecordMetaData)1 ThenKeyExpression (com.apple.foundationdb.record.metadata.expressions.ThenKeyExpression)1 IndexScanParameters (com.apple.foundationdb.record.provider.foundationdb.IndexScanParameters)1 QueryComponent (com.apple.foundationdb.record.query.expressions.QueryComponent)1 RecordQueryFilterPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryFilterPlan)1