Search in sources :

Example 1 with FilterSatisfiedMask

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

the class QueryToKeyMatcher method matches.

@Nonnull
private Match matches(@Nonnull NestedField query, @Nonnull NestingKeyExpression key, @Nonnull MatchingMode matchingMode, @Nullable FilterSatisfiedMask filterMask) {
    if (key.getParent().getFanType() != KeyExpression.FanType.None) {
        // in theory, maybe, concatenate could work with certain things, but for now, no.
        return Match.none();
    } else {
        if (Objects.equals(query.getFieldName(), key.getParent().getFieldName())) {
            FilterSatisfiedMask childMask = filterMask != null ? filterMask.getChild(query.getChild()) : null;
            Match childMatch = matches(query.getChild(), key.getChild(), matchingMode, childMask);
            if (childMask != null && childMask.isSatisfied() && filterMask.getExpression() == null) {
                filterMask.setExpression(key);
            }
            return childMatch;
        } else {
            return Match.none();
        }
    }
}
Also used : FilterSatisfiedMask(com.apple.foundationdb.record.query.plan.planning.FilterSatisfiedMask) Nonnull(javax.annotation.Nonnull)

Example 2 with FilterSatisfiedMask

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

the class LucenePlanner method getScanForOrLucene.

private LuceneIndexQueryPlan getScanForOrLucene(@Nonnull Index index, final String parentFieldName, final OrComponent filter, final FilterSatisfiedMask filterMask, final ScanComparisons groupingComparisons) {
    final Iterator<FilterSatisfiedMask> subFilterMasks = filterMask != null ? filterMask.getChildren().iterator() : null;
    final List<QueryComponent> filters = filter.getChildren();
    LuceneIndexQueryPlan combinedComparison = null;
    for (QueryComponent subFilter : filters) {
        final FilterSatisfiedMask childMask = subFilterMasks != null ? subFilterMasks.next() : null;
        LuceneIndexQueryPlan childComparison = getComparisonsForLuceneFilter(index, parentFieldName, subFilter, childMask, groupingComparisons);
        if (childComparison != null && childMask != null) {
            childMask.setSatisfied(true);
            combinedComparison = combinedComparison == null ? childComparison : LuceneIndexQueryPlan.merge(childComparison, combinedComparison, "OR");
        }
    }
    if (filterMask != null && filterMask.getUnsatisfiedFilters().isEmpty()) {
        filterMask.setSatisfied(true);
    }
    return combinedComparison;
}
Also used : QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) LuceneQueryComponent(com.apple.foundationdb.record.query.expressions.LuceneQueryComponent) FilterSatisfiedMask(com.apple.foundationdb.record.query.plan.planning.FilterSatisfiedMask)

Example 3 with FilterSatisfiedMask

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

the class LucenePlanner method planLucene.

@Override
protected ScoredPlan planLucene(@Nonnull CandidateScan candidateScan, @Nonnull Index index, @Nonnull QueryComponent filter, @Nullable KeyExpression sort) {
    FilterSatisfiedMask filterMask = FilterSatisfiedMask.of(filter);
    KeyExpression rootExp = index.getRootExpression();
    ScanComparisons groupingComparisons;
    // Getting grouping information from the index key and query filter
    if (rootExp instanceof GroupingKeyExpression) {
        KeyExpression groupingKey = ((GroupingKeyExpression) rootExp).getGroupingSubKey();
        QueryToKeyMatcher.Match groupingMatch = new QueryToKeyMatcher(filter).matchesCoveringKey(groupingKey, filterMask);
        if (!groupingMatch.getType().equals((QueryToKeyMatcher.MatchType.EQUALITY))) {
            return null;
        }
        groupingComparisons = new ScanComparisons(groupingMatch.getEqualityComparisons(), Collections.emptySet());
    } else {
        groupingComparisons = null;
    }
    LuceneIndexQueryPlan lucenePlan = getComparisonsForLuceneFilter(index, null, filter, filterMask, groupingComparisons);
    if (lucenePlan == null) {
        return null;
    }
    RecordQueryPlan plan = lucenePlan;
    plan = addTypeFilterIfNeeded(candidateScan, plan, getPossibleTypes(index));
    if (filterMask.allSatisfied()) {
        filterMask.setSatisfied(true);
    }
    return new ScoredPlan(plan, filterMask.getUnsatisfiedFilters(), Collections.emptyList(), 11 - filterMask.getUnsatisfiedFilters().size(), lucenePlan.createsDuplicates(), null);
}
Also used : RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) ScanComparisons(com.apple.foundationdb.record.query.plan.ScanComparisons) GroupingKeyExpression(com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression) FilterSatisfiedMask(com.apple.foundationdb.record.query.plan.planning.FilterSatisfiedMask) GroupingKeyExpression(com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) QueryToKeyMatcher(com.apple.foundationdb.record.query.QueryToKeyMatcher)

Example 4 with FilterSatisfiedMask

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

the class LucenePlanner method getScanForAndLucene.

private LuceneIndexQueryPlan getScanForAndLucene(@Nonnull Index index, @Nullable String parentFieldName, @Nonnull AndComponent filter, @Nullable FilterSatisfiedMask filterMask, final ScanComparisons groupingComparisons) {
    final Iterator<FilterSatisfiedMask> subFilterMasks = filterMask != null ? filterMask.getChildren().iterator() : null;
    final List<QueryComponent> filters = filter.getChildren();
    LuceneIndexQueryPlan combinedComparison = null;
    for (QueryComponent subFilter : filters) {
        final FilterSatisfiedMask childMask = subFilterMasks != null ? subFilterMasks.next() : null;
        LuceneIndexQueryPlan childComparison = getComparisonsForLuceneFilter(index, parentFieldName, subFilter, childMask, groupingComparisons);
        if (childComparison != null && childMask != null) {
            childMask.setSatisfied(true);
            combinedComparison = combinedComparison == null ? childComparison : LuceneIndexQueryPlan.merge(combinedComparison, childComparison, "AND");
        } else if (combinedComparison != null && childComparison == null) {
            combinedComparison = null;
            break;
        }
    }
    if (filterMask != null && filterMask.getUnsatisfiedFilters().isEmpty()) {
        filterMask.setSatisfied(true);
    }
    return combinedComparison;
}
Also used : QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) LuceneQueryComponent(com.apple.foundationdb.record.query.expressions.LuceneQueryComponent) FilterSatisfiedMask(com.apple.foundationdb.record.query.plan.planning.FilterSatisfiedMask)

Example 5 with FilterSatisfiedMask

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

the class RecordQueryPlanner method planText.

@Nullable
private ScoredPlan planText(@Nonnull CandidateScan candidateScan, @Nonnull Index index, @Nonnull QueryComponent filter, @Nullable KeyExpression sort) {
    if (sort != null) {
        // TODO: Full Text: Sorts are not supported with full text queries (https://github.com/FoundationDB/fdb-record-layer/issues/55)
        return null;
    }
    FilterSatisfiedMask filterMask = FilterSatisfiedMask.of(filter);
    final TextScan scan = TextScanPlanner.getScanForQuery(index, filter, false, filterMask);
    if (scan == null) {
        return null;
    }
    // TODO: Check the rest of the fields of the text index expression to see if the sort and unsatisfied filters can be helped.
    RecordQueryPlan plan = new RecordQueryTextIndexPlan(index.getName(), scan, candidateScan.reverse);
    // Add a type filter if the index is over more types than those the query specifies
    Set<String> possibleTypes = getPossibleTypes(index);
    plan = addTypeFilterIfNeeded(candidateScan, plan, possibleTypes);
    // is "strict", it must be surrounded be a filter plan.
    if (scan.getTextComparison() instanceof Comparisons.TextContainsAllPrefixesComparison) {
        Comparisons.TextContainsAllPrefixesComparison textComparison = (Comparisons.TextContainsAllPrefixesComparison) scan.getTextComparison();
        if (textComparison.isStrict()) {
            plan = new RecordQueryFilterPlan(plan, filter);
            filterMask.setSatisfied(true);
        }
    }
    // than other indexes.
    return new ScoredPlan(plan, filterMask.getUnsatisfiedFilters(), Collections.emptyList(), 10, scan.createsDuplicates(), null);
}
Also used : RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) RecordQueryFilterPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryFilterPlan) TimeWindowScanComparisons(com.apple.foundationdb.record.provider.foundationdb.leaderboard.TimeWindowScanComparisons) IndexScanComparisons(com.apple.foundationdb.record.provider.foundationdb.IndexScanComparisons) RankComparisons(com.apple.foundationdb.record.query.plan.planning.RankComparisons) Comparisons(com.apple.foundationdb.record.query.expressions.Comparisons) FilterSatisfiedMask(com.apple.foundationdb.record.query.plan.planning.FilterSatisfiedMask) RecordQueryTextIndexPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryTextIndexPlan) Nullable(javax.annotation.Nullable)

Aggregations

FilterSatisfiedMask (com.apple.foundationdb.record.query.plan.planning.FilterSatisfiedMask)8 QueryComponent (com.apple.foundationdb.record.query.expressions.QueryComponent)3 Nonnull (javax.annotation.Nonnull)3 GroupingKeyExpression (com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression)2 KeyExpression (com.apple.foundationdb.record.metadata.expressions.KeyExpression)2 QueryToKeyMatcher (com.apple.foundationdb.record.query.QueryToKeyMatcher)2 LuceneQueryComponent (com.apple.foundationdb.record.query.expressions.LuceneQueryComponent)2 RecordQueryPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan)2 BaseKeyExpression (com.apple.foundationdb.record.metadata.expressions.BaseKeyExpression)1 EmptyKeyExpression (com.apple.foundationdb.record.metadata.expressions.EmptyKeyExpression)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 NestingKeyExpression (com.apple.foundationdb.record.metadata.expressions.NestingKeyExpression)1 RecordTypeKeyExpression (com.apple.foundationdb.record.metadata.expressions.RecordTypeKeyExpression)1 ThenKeyExpression (com.apple.foundationdb.record.metadata.expressions.ThenKeyExpression)1 IndexScanComparisons (com.apple.foundationdb.record.provider.foundationdb.IndexScanComparisons)1 TimeWindowScanComparisons (com.apple.foundationdb.record.provider.foundationdb.leaderboard.TimeWindowScanComparisons)1 Comparisons (com.apple.foundationdb.record.query.expressions.Comparisons)1 Comparison (com.apple.foundationdb.record.query.expressions.Comparisons.Comparison)1