Search in sources :

Example 1 with TextScan

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

the class TextScanPlanner method getScanForNestedField.

@Nullable
private static TextScan getScanForNestedField(@Nonnull Index index, @Nonnull NestingKeyExpression textExpression, @Nonnull NestedField filter, @Nullable ScanComparisons groupingComparisons, boolean hasSort, @Nullable FilterSatisfiedMask filterMask) {
    if (textExpression.getParent().getFanType().equals(KeyExpression.FanType.None) && textExpression.getParent().getFieldName().equals(filter.getFieldName())) {
        final FilterSatisfiedMask childMask = filterMask != null ? filterMask.getChild(filter.getChild()) : null;
        TextScan foundScan = getScanForFilter(index, textExpression.getChild(), filter.getChild(), groupingComparisons, hasSort, childMask);
        if (foundScan != null && filterMask != null && filterMask.getExpression() == null) {
            filterMask.setExpression(textExpression);
        }
        return foundScan;
    }
    return null;
}
Also used : TextScan(com.apple.foundationdb.record.query.plan.TextScan) Nullable(javax.annotation.Nullable)

Example 2 with TextScan

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

the class TextScanPlanner method getScanForRepeatedNestedField.

@Nullable
private static TextScan getScanForRepeatedNestedField(@Nonnull Index index, @Nonnull NestingKeyExpression textExpression, @Nonnull OneOfThemWithComponent filter, @Nullable ScanComparisons groupingComparisons, boolean hasSort, @Nullable FilterSatisfiedMask filterMask) {
    if (textExpression.getParent().getFanType().equals(KeyExpression.FanType.FanOut) && textExpression.getParent().getFieldName().equals(filter.getFieldName())) {
        // This doesn't work for certain complex queries on child fields.
        // There are more details in this issue and there is an example of mis-planned query in the
        // unit tests for this class:
        // FIXME: Full Text: The Planner doesn't always correctly handle ands with nesteds (https://github.com/FoundationDB/fdb-record-layer/issues/53)
        FilterSatisfiedMask childMask = filterMask != null ? filterMask.getChild(filter.getChild()) : null;
        TextScan foundScan = getScanForFilter(index, textExpression.getChild(), filter.getChild(), groupingComparisons, hasSort, childMask);
        if (foundScan != null && filterMask != null && filterMask.getExpression() != null) {
            filterMask.setExpression(textExpression);
        }
        return foundScan;
    }
    return null;
}
Also used : TextScan(com.apple.foundationdb.record.query.plan.TextScan) Nullable(javax.annotation.Nullable)

Example 3 with TextScan

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

the class TextScanPlanner method getScanForAndFilter.

@Nullable
private static TextScan getScanForAndFilter(@Nonnull Index index, @Nonnull KeyExpression textExpression, @Nonnull AndComponent filter, @Nullable ScanComparisons groupingComparisons, boolean hasSort, @Nullable FilterSatisfiedMask filterMask) {
    // Iterate through each of the filters
    final Iterator<FilterSatisfiedMask> subFilterMasks = filterMask != null ? filterMask.getChildren().iterator() : null;
    for (QueryComponent subFilter : filter.getChildren()) {
        final FilterSatisfiedMask childMask = subFilterMasks != null ? subFilterMasks.next() : null;
        TextScan childScan = getScanForFilter(index, textExpression, subFilter, groupingComparisons, hasSort, childMask);
        if (childScan != null) {
            if (filterMask != null && filterMask.getExpression() == null) {
                filterMask.setExpression(textExpression);
            }
            return childScan;
        }
    }
    return null;
}
Also used : QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) TextScan(com.apple.foundationdb.record.query.plan.TextScan) Nullable(javax.annotation.Nullable)

Example 4 with TextScan

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

TextScan (com.apple.foundationdb.record.query.plan.TextScan)4 Nullable (javax.annotation.Nullable)4 FieldKeyExpression (com.apple.foundationdb.record.metadata.expressions.FieldKeyExpression)1 GroupingKeyExpression (com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression)1 KeyExpression (com.apple.foundationdb.record.metadata.expressions.KeyExpression)1 NestingKeyExpression (com.apple.foundationdb.record.metadata.expressions.NestingKeyExpression)1 QueryToKeyMatcher (com.apple.foundationdb.record.query.QueryToKeyMatcher)1 QueryComponent (com.apple.foundationdb.record.query.expressions.QueryComponent)1 ScanComparisons (com.apple.foundationdb.record.query.plan.ScanComparisons)1