Search in sources :

Example 1 with RecordQueryFilterPlan

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

the class RecordQueryPlanner method handleNonSargables.

@Nonnull
private ScoredPlan handleNonSargables(@Nonnull ScoredPlan bestPlan, @Nonnull List<ScoredPlan> intersectionCandidates, @Nonnull PlanContext planContext) {
    if (planContext.commonPrimaryKey != null && !intersectionCandidates.isEmpty()) {
        KeyExpression comparisonKey = planContext.commonPrimaryKey;
        final KeyExpression sort = planContext.query.getSort();
        comparisonKey = getKeyForMerge(sort, comparisonKey);
        ScoredPlan intersectionPlan = planIntersection(intersectionCandidates, comparisonKey);
        if (intersectionPlan != null) {
            if (intersectionPlan.unsatisfiedFilters.isEmpty()) {
                return intersectionPlan;
            } else if (bestPlan.getNumNonSargables() > intersectionPlan.getNumNonSargables()) {
                bestPlan = intersectionPlan;
            }
        }
    }
    if (bestPlan.getNumNonSargables() > 0) {
        final RecordQueryPlan filtered = new RecordQueryFilterPlan(bestPlan.plan, planContext.rankComparisons.planComparisonSubstitutes(bestPlan.combineNonSargables()));
        // TODO: further optimization requires knowing which filters are satisfied
        return new ScoredPlan(filtered, Collections.emptyList(), Collections.emptyList(), bestPlan.score, bestPlan.createsDuplicates, bestPlan.includedRankComparisons);
    } else {
        return bestPlan;
    }
}
Also used : RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) RecordQueryFilterPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryFilterPlan) 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) Nonnull(javax.annotation.Nonnull)

Example 2 with RecordQueryFilterPlan

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

the class FieldWithComparisonCountProperty method evaluateAtExpression.

@Nonnull
@Override
public Integer evaluateAtExpression(@Nonnull RelationalExpression expression, @Nonnull List<Integer> childResults) {
    int total = 0;
    if (expression instanceof RecordQueryFilterPlan) {
        QueryComponent filter = ((RecordQueryFilterPlan) expression).getConjunctedFilter();
        total = getFieldWithComparisonCount(filter);
    }
    for (Integer childCount : childResults) {
        if (childCount != null) {
            total += childCount;
        }
    }
    return total;
}
Also used : QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) RecordQueryFilterPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryFilterPlan) Nonnull(javax.annotation.Nonnull)

Example 3 with RecordQueryFilterPlan

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

the class UnionVisitor method postVisit.

@Nonnull
@Override
public RecordQueryPlan postVisit(@Nonnull final RecordQueryPlan recordQueryPlan) {
    if (recordQueryPlan instanceof RecordQueryUnionPlanBase) {
        RecordQueryUnionPlanBase unionPlan = (RecordQueryUnionPlanBase) recordQueryPlan;
        final Set<KeyExpression> requiredFields = unionPlan.getRequiredFields();
        boolean shouldPullOutFilter = false;
        QueryComponent filter = null;
        if (unionPlan.getChildren().stream().allMatch(child -> child instanceof RecordQueryFilterPlan)) {
            filter = ((RecordQueryFilterPlan) unionPlan.getChildren().get(0)).getConjunctedFilter();
            // needed for lambda expression
            final QueryComponent finalFilter = filter;
            shouldPullOutFilter = unionPlan.getChildren().stream().allMatch(plan -> ((RecordQueryFilterPlan) plan).getConjunctedFilter().equals(finalFilter));
        }
        List<ExpressionRef<RecordQueryPlan>> newChildren = new ArrayList<>(unionPlan.getChildren().size());
        for (RecordQueryPlan plan : unionPlan.getChildren()) {
            if (shouldPullOutFilter) {
                // Check if the plan under the filter can have its index fetch removed.
                if (!(plan instanceof RecordQueryFilterPlan)) {
                    throw new RecordCoreException("serious logic error: thought this was a filter plan but it wasn't");
                }
                plan = ((RecordQueryFilterPlan) plan).getChild();
            }
            @Nullable RecordQueryPlan newPlan = removeIndexFetch(plan, requiredFields);
            if (newPlan == null) {
                // can't remove index fetch, so give up
                return recordQueryPlan;
            }
            newChildren.add(GroupExpressionRef.of(newPlan));
        }
        RecordQueryPlan newUnionPlan = new RecordQueryFetchFromPartialRecordPlan(unionPlan.withChildrenReferences(newChildren), TranslateValueFunction.unableToTranslate());
        if (shouldPullOutFilter) {
            return new RecordQueryFilterPlan(newUnionPlan, filter);
        } else {
            return newUnionPlan;
        }
    }
    return recordQueryPlan;
}
Also used : TranslateValueFunction(com.apple.foundationdb.record.query.plan.plans.TranslateValueFunction) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) RecordQueryFilterPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryFilterPlan) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) RecordQueryFetchFromPartialRecordPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryFetchFromPartialRecordPlan) Set(java.util.Set) PlannableIndexTypes(com.apple.foundationdb.record.query.plan.PlannableIndexTypes) GroupExpressionRef(com.apple.foundationdb.record.query.plan.temp.GroupExpressionRef) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) ArrayList(java.util.ArrayList) List(java.util.List) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) ExpressionRef(com.apple.foundationdb.record.query.plan.temp.ExpressionRef) Nonnull(javax.annotation.Nonnull) RecordQueryUnionPlanBase(com.apple.foundationdb.record.query.plan.plans.RecordQueryUnionPlanBase) Nullable(javax.annotation.Nullable) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) RecordQueryUnionPlanBase(com.apple.foundationdb.record.query.plan.plans.RecordQueryUnionPlanBase) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) ArrayList(java.util.ArrayList) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) RecordQueryFilterPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryFilterPlan) RecordQueryFetchFromPartialRecordPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryFetchFromPartialRecordPlan) GroupExpressionRef(com.apple.foundationdb.record.query.plan.temp.GroupExpressionRef) ExpressionRef(com.apple.foundationdb.record.query.plan.temp.ExpressionRef) Nullable(javax.annotation.Nullable) Nonnull(javax.annotation.Nonnull)

Example 4 with RecordQueryFilterPlan

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

Example 5 with RecordQueryFilterPlan

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

the class QueryPlanCursorTest method filter.

@Test
public void filter() throws Exception {
    final RecordQueryPlan plan = new RecordQueryFilterPlan(indexPlanEquals("MySimpleRecord$num_value_3_indexed", 2), Query.field("str_value_indexed").equalsValue("even"));
    compareSkipsAndCursors(plan);
}
Also used : RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) RecordQueryFilterPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryFilterPlan) Test(org.junit.jupiter.api.Test)

Aggregations

RecordQueryFilterPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryFilterPlan)10 RecordQueryPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan)8 KeyExpression (com.apple.foundationdb.record.metadata.expressions.KeyExpression)5 QueryComponent (com.apple.foundationdb.record.query.expressions.QueryComponent)5 Nonnull (javax.annotation.Nonnull)5 Nullable (javax.annotation.Nullable)5 ThenKeyExpression (com.apple.foundationdb.record.metadata.expressions.ThenKeyExpression)4 FieldKeyExpression (com.apple.foundationdb.record.metadata.expressions.FieldKeyExpression)3 RecordQueryIndexPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryIndexPlan)3 RecordQueryScanPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryScanPlan)3 RecordQueryTextIndexPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryTextIndexPlan)3 ArrayList (java.util.ArrayList)3 RecordCoreException (com.apple.foundationdb.record.RecordCoreException)2 RecordMetaData (com.apple.foundationdb.record.RecordMetaData)2 Index (com.apple.foundationdb.record.metadata.Index)2 EmptyKeyExpression (com.apple.foundationdb.record.metadata.expressions.EmptyKeyExpression)2 GroupingKeyExpression (com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression)2 IndexScanComparisons (com.apple.foundationdb.record.provider.foundationdb.IndexScanComparisons)2 IndexScanParameters (com.apple.foundationdb.record.provider.foundationdb.IndexScanParameters)2 TimeWindowScanComparisons (com.apple.foundationdb.record.provider.foundationdb.leaderboard.TimeWindowScanComparisons)2