Search in sources :

Example 1 with RecordCoreException

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

the class RecordQueryPlanner method planNoFilter.

@Nullable
private RecordQueryPlan planNoFilter(PlanContext planContext, KeyExpression sort, boolean sortReverse) {
    ScoredPlan bestPlan = null;
    Index bestIndex = null;
    if (sort == null) {
        bestPlan = planNoFilterNoSort(planContext, null);
    } else if (planContext.commonPrimaryKey != null) {
        bestPlan = planSortOnly(new CandidateScan(planContext, null, sortReverse), planContext.commonPrimaryKey, sort);
    }
    for (Index index : planContext.indexes) {
        ScoredPlan p;
        if (sort == null) {
            p = planNoFilterNoSort(planContext, index);
        } else {
            p = planSortOnly(new CandidateScan(planContext, index, sortReverse), indexKeyExpressionForPlan(planContext.commonPrimaryKey, index), sort);
        }
        if (p != null) {
            if (bestPlan == null || p.score > bestPlan.score || (p.score == bestPlan.score && compareIndexes(planContext, index, bestIndex) > 0)) {
                bestPlan = p;
                bestIndex = index;
            }
        }
    }
    if (bestPlan != null) {
        bestPlan = planRemoveDuplicates(planContext, bestPlan);
        if (bestPlan == null) {
            throw new RecordCoreException("A common primary key is required to remove duplicates");
        }
        return bestPlan.plan;
    }
    return null;
}
Also used : RecordCoreException(com.apple.foundationdb.record.RecordCoreException) RecordQueryPlanWithIndex(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlanWithIndex) Index(com.apple.foundationdb.record.metadata.Index) Nullable(javax.annotation.Nullable)

Example 2 with RecordCoreException

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

the class RecordQueryInUnionPlan method executePlan.

@Nonnull
@Override
public <M extends Message> RecordCursor<QueryResult> executePlan(@Nonnull final FDBRecordStoreBase<M> store, @Nonnull final EvaluationContext context, @Nullable final byte[] continuation, @Nonnull final ExecuteProperties executeProperties) {
    int size = getValuesSize(context);
    if (size > maxNumberOfValuesAllowed) {
        throw new RecordCoreException("too many IN values").addLogInfo("size", size);
    }
    if (size == 0) {
        return RecordCursor.empty();
    }
    final RecordQueryPlan childPlan = getInnerPlan();
    if (size == 1) {
        final EvaluationContext childContext = getValuesContexts(context).get(0);
        return childPlan.executePlan(store, childContext, continuation, executeProperties);
    }
    final ExecuteProperties childExecuteProperties;
    // Can pass the limit down to all sides, since that is the most we'll take total.
    if (executeProperties.getSkip() > 0) {
        childExecuteProperties = executeProperties.clearSkipAndAdjustLimit();
    } else {
        childExecuteProperties = executeProperties;
    }
    final List<Function<byte[], RecordCursor<FDBQueriedRecord<M>>>> childCursorFunctions = getValuesContexts(context).stream().map(childContext -> (Function<byte[], RecordCursor<FDBQueriedRecord<M>>>) childContinuation -> childPlan.execute(store, childContext, childContinuation, childExecuteProperties)).collect(Collectors.toList());
    return UnionCursor.create(store, comparisonKey, reverse, childCursorFunctions, continuation).skipThenLimit(executeProperties.getSkip(), executeProperties.getReturnedRowLimit()).map(QueryResult::of);
}
Also used : Iterables(com.google.common.collect.Iterables) StoreTimer(com.apple.foundationdb.record.provider.common.StoreTimer) Quantifier(com.apple.foundationdb.record.query.plan.temp.Quantifier) GroupExpressionRef(com.apple.foundationdb.record.query.plan.temp.GroupExpressionRef) Function(java.util.function.Function) Supplier(java.util.function.Supplier) PlanHashable(com.apple.foundationdb.record.PlanHashable) ArrayList(java.util.ArrayList) ExecuteProperties(com.apple.foundationdb.record.ExecuteProperties) ImmutableList(com.google.common.collect.ImmutableList) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) Attribute(com.apple.foundationdb.record.query.plan.temp.explain.Attribute) Suppliers(com.google.common.base.Suppliers) UnionCursor(com.apple.foundationdb.record.provider.foundationdb.cursors.UnionCursor) ExpressionRef(com.apple.foundationdb.record.query.plan.temp.ExpressionRef) AliasMap(com.apple.foundationdb.record.query.plan.temp.AliasMap) Nonnull(javax.annotation.Nonnull) Nullable(javax.annotation.Nullable) FDBRecordStoreBase(com.apple.foundationdb.record.provider.foundationdb.FDBRecordStoreBase) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) ImmutableSet(com.google.common.collect.ImmutableSet) FDBStoreTimer(com.apple.foundationdb.record.provider.foundationdb.FDBStoreTimer) ImmutableMap(com.google.common.collect.ImmutableMap) RelationalExpressionWithChildren(com.apple.foundationdb.record.query.plan.temp.expressions.RelationalExpressionWithChildren) Set(java.util.Set) Collectors(java.util.stream.Collectors) RelationalExpression(com.apple.foundationdb.record.query.plan.temp.RelationalExpression) Objects(java.util.Objects) Value(com.apple.foundationdb.record.query.predicates.Value) List(java.util.List) CorrelationIdentifier(com.apple.foundationdb.record.query.plan.temp.CorrelationIdentifier) EvaluationContext(com.apple.foundationdb.record.EvaluationContext) ObjectPlanHash(com.apple.foundationdb.record.ObjectPlanHash) FDBQueriedRecord(com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord) Message(com.google.protobuf.Message) RecordCursor(com.apple.foundationdb.record.RecordCursor) API(com.apple.foundationdb.annotation.API) PlannerGraph(com.apple.foundationdb.record.query.plan.temp.explain.PlannerGraph) NodeInfo(com.apple.foundationdb.record.query.plan.temp.explain.NodeInfo) Collections(java.util.Collections) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) ExecuteProperties(com.apple.foundationdb.record.ExecuteProperties) Function(java.util.function.Function) FDBQueriedRecord(com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord) EvaluationContext(com.apple.foundationdb.record.EvaluationContext) Nonnull(javax.annotation.Nonnull)

Example 3 with RecordCoreException

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

the class TextScan method getTokenList.

// Get the comparand as a list of strings. This might involve tokenizing the
// query string if the comparison didn't do that already.
private List<String> getTokenList(@Nonnull FDBRecordStoreBase<?> store, @Nonnull EvaluationContext context, boolean removeStopWords) {
    final Object comparand = textComparison.getComparand(store, context);
    List<String> tokenList;
    if (comparand instanceof List<?>) {
        tokenList = ((List<?>) comparand).stream().map(Object::toString).collect(Collectors.toList());
    } else if (comparand instanceof String) {
        TextTokenizer tokenizer = TextIndexMaintainer.getTokenizer(index);
        int tokenizerVersion = TextIndexMaintainer.getIndexTokenizerVersion(index);
        tokenList = tokenizer.tokenizeToList((String) comparand, tokenizerVersion, TextTokenizer.TokenizerMode.QUERY);
    } else {
        throw new RecordCoreException("Comparand for text query of incompatible type: " + (comparand == null ? "null" : comparand.getClass()));
    }
    if (removeStopWords && tokenList.contains("")) {
        // Remove all stop words from this list
        tokenList = tokenList.stream().filter(s -> !s.isEmpty()).collect(Collectors.toList());
    }
    return tokenList;
}
Also used : TextTokenizer(com.apple.foundationdb.record.provider.common.text.TextTokenizer) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) ArrayList(java.util.ArrayList) List(java.util.List)

Example 4 with RecordCoreException

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

the class RankedSetIndexHelper method groupPrefix.

@Nullable
private static Tuple groupPrefix(int groupPrefixSize, @Nonnull TupleRange rankRange, @Nonnull Subspace rankSubspace) {
    if (groupPrefixSize > 0) {
        Tuple lowRank = rankRange.getLow();
        Tuple highRank = rankRange.getHigh();
        if (lowRank == null || lowRank.size() < groupPrefixSize || highRank == null || highRank.size() < groupPrefixSize) {
            throw new RecordCoreException("Ranked scan range does not include group", "rankRange", rankRange, "rankSubspace", ByteArrayUtil2.loggable(rankSubspace.getKey()));
        }
        Tuple prefix = Tuple.fromList(lowRank.getItems().subList(0, groupPrefixSize));
        Tuple highPrefix = Tuple.fromList(highRank.getItems().subList(0, groupPrefixSize));
        if (!prefix.equals(highPrefix)) {
            throw new RecordCoreException("Ranked scan range crosses groups", "rankRange", rankRange, "rankSubspace", ByteArrayUtil2.loggable(rankSubspace.getKey()));
        }
        return prefix;
    } else {
        return null;
    }
}
Also used : RecordCoreException(com.apple.foundationdb.record.RecordCoreException) Tuple(com.apple.foundationdb.tuple.Tuple) Nullable(javax.annotation.Nullable)

Example 5 with RecordCoreException

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

the class TextIndexMaintainer method scan.

/**
 * Scan this index between a range of tokens. This index type requires that it be scanned only
 * by text token. The range to scan can otherwise be between any two entries in the list, and
 * scans over a prefix are supported by passing a value of <code>range</code> that uses
 * {@link com.apple.foundationdb.record.EndpointType#PREFIX_STRING PREFIX_STRING} as both endpoint types.
 * The keys returned in the index entry will include the token that was found in the index
 * when scanning in the column that is used for the text field of the index's root expression.
 * The value portion of each index entry will be a tuple whose first element is the position
 * list for that entry within its associated record's field.
 *
 * @param scanType the {@link IndexScanType type} of scan to perform
 * @param range the range to scan
 * @param continuation any continuation from a previous scan invocation
 * @param scanProperties skip, limit and other properties of the scan
 * @return a cursor over all index entries in <code>range</code>
 * @throws RecordCoreException if <code>scanType</code> is not {@link IndexScanType#BY_TEXT_TOKEN}
 * @see TextCursor
 */
@Nonnull
@Override
// not closing the returned cursor
@SuppressWarnings("squid:S2095")
public RecordCursor<IndexEntry> scan(@Nonnull IndexScanType scanType, @Nonnull TupleRange range, @Nullable byte[] continuation, @Nonnull ScanProperties scanProperties) {
    if (scanType != IndexScanType.BY_TEXT_TOKEN) {
        throw new RecordCoreException("Can only scan text index by text token.");
    }
    int textPosition = textFieldPosition(state.index.getRootExpression());
    TextSubspaceSplitter subspaceSplitter = new TextSubspaceSplitter(state.indexSubspace, textPosition + 1);
    Range byteRange = range.toRange();
    ScanProperties withAdjustedLimit = scanProperties.with(ExecuteProperties::clearSkipAndAdjustLimit);
    ExecuteProperties adjustedExecuteProperties = withAdjustedLimit.getExecuteProperties();
    // Callback for updating the byte scan limit
    final ByteScanLimiter byteScanLimiter = adjustedExecuteProperties.getState().getByteScanLimiter();
    final Consumer<KeyValue> callback = keyValue -> byteScanLimiter.registerScannedBytes(keyValue.getKey().length + keyValue.getValue().length);
    BunchedMapMultiIterator<Tuple, List<Integer>, Tuple> iterator = getBunchedMap(state.context).scanMulti(state.context.readTransaction(adjustedExecuteProperties.getIsolationLevel().isSnapshot()), state.indexSubspace, subspaceSplitter, byteRange.begin, byteRange.end, continuation, adjustedExecuteProperties.getReturnedRowLimit(), callback, scanProperties.isReverse());
    RecordCursor<IndexEntry> cursor = new TextCursor(iterator, state.store.getExecutor(), state.context, withAdjustedLimit, state.index);
    if (scanProperties.getExecuteProperties().getSkip() != 0) {
        cursor = cursor.skip(scanProperties.getExecuteProperties().getSkip());
    }
    return cursor;
}
Also used : IndexEntry(com.apple.foundationdb.record.IndexEntry) LogMessageKeys(com.apple.foundationdb.record.logging.LogMessageKeys) StoreTimer(com.apple.foundationdb.record.provider.common.StoreTimer) IndexMaintainerState(com.apple.foundationdb.record.provider.foundationdb.IndexMaintainerState) LoggerFactory(org.slf4j.LoggerFactory) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) MetaDataException(com.apple.foundationdb.record.metadata.MetaDataException) Subspace(com.apple.foundationdb.subspace.Subspace) IndexScanType(com.apple.foundationdb.record.IndexScanType) Tuple(com.apple.foundationdb.tuple.Tuple) Range(com.apple.foundationdb.Range) KeyValueLogMessage(com.apple.foundationdb.record.logging.KeyValueLogMessage) TextTokenizerRegistryImpl(com.apple.foundationdb.record.provider.common.text.TextTokenizerRegistryImpl) Pair(org.apache.commons.lang3.tuple.Pair) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) PipelineOperation(com.apple.foundationdb.record.PipelineOperation) Map(java.util.Map) GroupingKeyExpression(com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression) QueryToKeyMatcher(com.apple.foundationdb.record.query.QueryToKeyMatcher) FDBIndexableRecord(com.apple.foundationdb.record.provider.foundationdb.FDBIndexableRecord) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) KeyValue(com.apple.foundationdb.KeyValue) IndexOptions(com.apple.foundationdb.record.metadata.IndexOptions) FDBStoreTimer(com.apple.foundationdb.record.provider.foundationdb.FDBStoreTimer) TextTokenizerRegistry(com.apple.foundationdb.record.provider.common.text.TextTokenizerRegistry) TupleRange(com.apple.foundationdb.record.TupleRange) TextTokenizer(com.apple.foundationdb.record.provider.common.text.TextTokenizer) List(java.util.List) CompletionStage(java.util.concurrent.CompletionStage) TupleHelpers(com.apple.foundationdb.tuple.TupleHelpers) API(com.apple.foundationdb.annotation.API) SpotBugsSuppressWarnings(com.apple.foundationdb.annotation.SpotBugsSuppressWarnings) CompletableFuture(java.util.concurrent.CompletableFuture) AsyncUtil(com.apple.foundationdb.async.AsyncUtil) Function(java.util.function.Function) Key(com.apple.foundationdb.record.metadata.Key) ExecuteProperties(com.apple.foundationdb.record.ExecuteProperties) BunchedMap(com.apple.foundationdb.map.BunchedMap) FDBRecordStore(com.apple.foundationdb.record.provider.foundationdb.FDBRecordStore) ByteScanLimiter(com.apple.foundationdb.record.ByteScanLimiter) ScanProperties(com.apple.foundationdb.record.ScanProperties) BunchedMapMultiIterator(com.apple.foundationdb.map.BunchedMapMultiIterator) Nonnull(javax.annotation.Nonnull) Nullable(javax.annotation.Nullable) ByteArrayUtil2(com.apple.foundationdb.tuple.ByteArrayUtil2) Logger(org.slf4j.Logger) Executor(java.util.concurrent.Executor) Consumer(java.util.function.Consumer) Index(com.apple.foundationdb.record.metadata.Index) Message(com.google.protobuf.Message) RecordCursor(com.apple.foundationdb.record.RecordCursor) QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Comparator(java.util.Comparator) Collections(java.util.Collections) KeyValue(com.apple.foundationdb.KeyValue) IndexEntry(com.apple.foundationdb.record.IndexEntry) Range(com.apple.foundationdb.Range) TupleRange(com.apple.foundationdb.record.TupleRange) ByteScanLimiter(com.apple.foundationdb.record.ByteScanLimiter) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) ExecuteProperties(com.apple.foundationdb.record.ExecuteProperties) ScanProperties(com.apple.foundationdb.record.ScanProperties) List(java.util.List) Tuple(com.apple.foundationdb.tuple.Tuple) Nonnull(javax.annotation.Nonnull) SpotBugsSuppressWarnings(com.apple.foundationdb.annotation.SpotBugsSuppressWarnings)

Aggregations

RecordCoreException (com.apple.foundationdb.record.RecordCoreException)121 Nonnull (javax.annotation.Nonnull)58 Test (org.junit.jupiter.api.Test)42 Index (com.apple.foundationdb.record.metadata.Index)37 List (java.util.List)35 Nullable (javax.annotation.Nullable)31 Tuple (com.apple.foundationdb.tuple.Tuple)29 ArrayList (java.util.ArrayList)27 KeyExpression (com.apple.foundationdb.record.metadata.expressions.KeyExpression)26 CompletableFuture (java.util.concurrent.CompletableFuture)25 Collectors (java.util.stream.Collectors)24 Collections (java.util.Collections)22 GroupingKeyExpression (com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression)19 Set (java.util.Set)19 Function (java.util.function.Function)19 IndexEntry (com.apple.foundationdb.record.IndexEntry)17 TupleRange (com.apple.foundationdb.record.TupleRange)17 IndexTypes (com.apple.foundationdb.record.metadata.IndexTypes)17 RecordCursor (com.apple.foundationdb.record.RecordCursor)16 AsyncUtil (com.apple.foundationdb.async.AsyncUtil)15