Search in sources :

Example 1 with QueryToKeyMatcher

use of com.apple.foundationdb.record.query.QueryToKeyMatcher 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 2 with QueryToKeyMatcher

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

the class IndexAggregateGroupKeys method conditionsToGroupKeys.

@SuppressWarnings("PMD.EmptyCatchBlock")
public static Optional<IndexAggregateGroupKeys> conditionsToGroupKeys(@Nonnull KeyExpression operand, @Nullable QueryComponent conditions) {
    final KeyExpression groupingKey = IndexFunctionHelper.getGroupingKey(operand);
    if (conditions == null) {
        if (groupingKey.getColumnSize() == 0) {
            return Optional.of(new Conditions(Collections.emptyList()));
        }
    } else {
        final QueryToKeyMatcher matcher = new QueryToKeyMatcher(conditions);
        final QueryToKeyMatcher.Match match = matcher.matchesSatisfyingQuery(groupingKey);
        if (match.getType() != QueryToKeyMatcher.MatchType.NO_MATCH) {
            return Optional.of(new Conditions(match.getEqualityComparisons()));
        }
    }
    return Optional.empty();
}
Also used : KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) QueryToKeyMatcher(com.apple.foundationdb.record.query.QueryToKeyMatcher)

Example 3 with QueryToKeyMatcher

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

the class IndexFunctionHelper method recordFunctionWithSubrecordCondition.

/**
 * Given an index record function and condition on repeated fields (such as a key for a map-like field), return a function suitable for use with
 * {@link #recordFunctionIndexEntry} to get the matching index entry.
 * @param store store against which function will be evaluated
 * @param recordFunction function to be evaluated
 * @param record record against which to evaluate
 * @param condition condition on fields of index entry
 * @param <T> return type of function
 * @return a new function that remembers the condition for matching
 */
@Nonnull
public static <T> IndexRecordFunction<T> recordFunctionWithSubrecordCondition(@Nonnull FDBRecordStore store, @Nonnull IndexRecordFunction<T> recordFunction, @Nonnull FDBRecord<?> record, @Nonnull QueryComponent condition) {
    final IndexMaintainer indexMaintainer = indexMaintainerForRecordFunction(store, recordFunction, record).orElseThrow(() -> new RecordCoreException("Record function " + recordFunction + " requires appropriate index on " + record.getRecordType().getName()));
    final Index index = indexMaintainer.state.index;
    final List<KeyExpression> indexFields = index.getRootExpression().normalizeKeyForPositions();
    int scalarPrefixCount = 0;
    KeyExpression firstRepeated = null;
    for (KeyExpression indexField : indexFields) {
        if (indexField.createsDuplicates()) {
            firstRepeated = indexField;
            break;
        }
        scalarPrefixCount++;
    }
    if (firstRepeated == null) {
        throw new RecordCoreException("Record function " + recordFunction + " condition " + condition + " does not select a repeated field in " + indexMaintainer.state.index.getName());
    }
    final QueryToKeyMatcher matcher = new QueryToKeyMatcher(condition);
    final QueryToKeyMatcher.Match match = matcher.matchesSatisfyingQuery(firstRepeated);
    if (match.getType() != QueryToKeyMatcher.MatchType.EQUALITY) {
        throw new RecordCoreException("Record function " + recordFunction + " condition " + condition + " does not match " + indexMaintainer.state.index.getName());
    }
    return new IndexRecordFunctionWithSubrecordValues<>(recordFunction, index, scalarPrefixCount, match);
}
Also used : RecordCoreException(com.apple.foundationdb.record.RecordCoreException) NestingKeyExpression(com.apple.foundationdb.record.metadata.expressions.NestingKeyExpression) GroupingKeyExpression(com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression) EmptyKeyExpression(com.apple.foundationdb.record.metadata.expressions.EmptyKeyExpression) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) ThenKeyExpression(com.apple.foundationdb.record.metadata.expressions.ThenKeyExpression) Index(com.apple.foundationdb.record.metadata.Index) QueryToKeyMatcher(com.apple.foundationdb.record.query.QueryToKeyMatcher) Nonnull(javax.annotation.Nonnull)

Example 4 with QueryToKeyMatcher

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

the class ComposedBitmapIndexAggregate method separateGroupFilters.

private static boolean separateGroupFilters(@Nonnull QueryComponent filter, @Nonnull IndexAggregateFunctionCall indexAggregateFunctionCall, @Nonnull List<QueryComponent> commonFilters, @Nonnull List<QueryComponent> indexFilters) {
    QueryToKeyMatcher matcher = new QueryToKeyMatcher(filter);
    FilterSatisfiedMask filterMask = FilterSatisfiedMask.of(filter);
    QueryToKeyMatcher.Match match = matcher.matchesCoveringKey(indexAggregateFunctionCall.getGroupingKeyExpression().getGroupingSubKey(), filterMask);
    if (match.getType() != QueryToKeyMatcher.MatchType.EQUALITY) {
        // Did not manage to fully restrict the grouping key.
        return false;
    }
    // The position key(s) can also be constrained with inequalities and those go among the group filters.
    matcher.matchesCoveringKey(indexAggregateFunctionCall.getGroupedExpression(), filterMask);
    if (filterMask.allSatisfied()) {
        // Not enough conditions left over.
        return false;
    }
    for (FilterSatisfiedMask child : filterMask.getChildren()) {
        // Any left-over filter not matching either of those must match some per-index key.
        if (child.allSatisfied()) {
            commonFilters.add(child.getFilter());
        } else {
            indexFilters.add(child.getFilter());
        }
    }
    return true;
}
Also used : FilterSatisfiedMask(com.apple.foundationdb.record.query.plan.planning.FilterSatisfiedMask) QueryToKeyMatcher(com.apple.foundationdb.record.query.QueryToKeyMatcher)

Example 5 with QueryToKeyMatcher

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

the class TextScanPlanner method getScanForQuery.

/**
 * Get a scan that matches a filter in the list of filters provided. It looks to satisfy the grouping
 * key of the index, and then it looks for a text filter within the list of filters and checks to
 * see if the given index is compatible with the filter. If it is, it will construct a scan that
 * satisfies that filter using the index.
 *
 * @param index the text index to check
 * @param filter a filter that the query must satisfy
 * @param hasSort whether the query has a sort associated with it
 * @param filterMask a mask over the filter containing state about which filters have been satisfied
 * @return a text scan or <code>null</code> if none is found
 */
@Nullable
public static TextScan getScanForQuery(@Nonnull Index index, @Nonnull QueryComponent filter, boolean hasSort, @Nonnull FilterSatisfiedMask filterMask) {
    final KeyExpression indexExpression = index.getRootExpression();
    final KeyExpression groupedKey;
    final FilterSatisfiedMask localMask = FilterSatisfiedMask.of(filter);
    final ScanComparisons groupingComparisons;
    if (indexExpression instanceof GroupingKeyExpression) {
        // Grouping expression present. Make sure this is satisfied.
        final KeyExpression groupingKey = ((GroupingKeyExpression) indexExpression).getGroupingSubKey();
        groupedKey = ((GroupingKeyExpression) indexExpression).getGroupedSubKey();
        QueryToKeyMatcher groupingQueryMatcher = new QueryToKeyMatcher(filter);
        QueryToKeyMatcher.Match groupingMatch = groupingQueryMatcher.matchesCoveringKey(groupingKey, localMask);
        if (!groupingMatch.getType().equals(QueryToKeyMatcher.MatchType.EQUALITY)) {
            return null;
        }
        groupingComparisons = new ScanComparisons(groupingMatch.getEqualityComparisons(), Collections.emptySet());
    } else {
        // Grouping expression not present. Use first column.
        groupedKey = indexExpression;
        groupingComparisons = null;
    }
    final KeyExpression textExpression = groupedKey.getSubKey(0, 1);
    final TextScan foundScan = getScanForFilter(index, textExpression, filter, groupingComparisons, hasSort, localMask);
    if (foundScan != null) {
        filterMask.mergeWith(localMask);
        return foundScan;
    }
    return null;
}
Also used : ScanComparisons(com.apple.foundationdb.record.query.plan.ScanComparisons) 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) GroupingKeyExpression(com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression) TextScan(com.apple.foundationdb.record.query.plan.TextScan) QueryToKeyMatcher(com.apple.foundationdb.record.query.QueryToKeyMatcher) Nullable(javax.annotation.Nullable)

Aggregations

QueryToKeyMatcher (com.apple.foundationdb.record.query.QueryToKeyMatcher)5 KeyExpression (com.apple.foundationdb.record.metadata.expressions.KeyExpression)4 GroupingKeyExpression (com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression)3 NestingKeyExpression (com.apple.foundationdb.record.metadata.expressions.NestingKeyExpression)2 ScanComparisons (com.apple.foundationdb.record.query.plan.ScanComparisons)2 FilterSatisfiedMask (com.apple.foundationdb.record.query.plan.planning.FilterSatisfiedMask)2 RecordCoreException (com.apple.foundationdb.record.RecordCoreException)1 Index (com.apple.foundationdb.record.metadata.Index)1 EmptyKeyExpression (com.apple.foundationdb.record.metadata.expressions.EmptyKeyExpression)1 FieldKeyExpression (com.apple.foundationdb.record.metadata.expressions.FieldKeyExpression)1 ThenKeyExpression (com.apple.foundationdb.record.metadata.expressions.ThenKeyExpression)1 TextScan (com.apple.foundationdb.record.query.plan.TextScan)1 RecordQueryPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan)1 Nonnull (javax.annotation.Nonnull)1 Nullable (javax.annotation.Nullable)1