Search in sources :

Example 6 with KeyExpression

use of com.apple.foundationdb.record.metadata.expressions.KeyExpression in project fdb-record-layer by FoundationDB.

the class InExtractor method adjustOrdering.

/**
 * Adjust plan ordering for the result of handling these {@code IN} clauses.
 * @param ordering the base plan ordering
 * @param asPrefix {@code true} if the {@code IN} conditions become part of an equality prefix (because the elements are merged in order),
 * {@code false} if a separate ordering beforehand (because the elements are concatenated in turn)
 * @return a new plan ordering
 */
@Nullable
public PlanOrderingKey adjustOrdering(@Nullable PlanOrderingKey ordering, boolean asPrefix) {
    if (ordering == null || inClauses.isEmpty()) {
        return ordering;
    }
    // All the ordering keys from the IN joins look like non-prefix ordering and come before the others.
    final List<KeyExpression> keys = new ArrayList<>(ordering.getKeys());
    int prefixSize = ordering.getPrefixSize();
    final int primaryKeyStart = ordering.getPrimaryKeyStart();
    final int primaryKeyTailFromEnd = keys.size() - ordering.getPrimaryKeyTail();
    for (int i = 0; i < inClauses.size(); i++) {
        final KeyExpression inOrdering = inClauses.get(i).orderingKey;
        if (inOrdering == null) {
            return null;
        }
        final int position = keys.indexOf(inOrdering);
        if (position >= 0) {
            if (position < prefixSize) {
                // No longer an equality.
                prefixSize--;
            }
            keys.remove(position);
        }
        keys.add(prefixSize + i, inOrdering);
        if (asPrefix) {
            prefixSize++;
        }
    }
    return new PlanOrderingKey(keys, prefixSize, primaryKeyStart, keys.size() - primaryKeyTailFromEnd);
}
Also used : PlanOrderingKey(com.apple.foundationdb.record.query.plan.PlanOrderingKey) FieldKeyExpression(com.apple.foundationdb.record.metadata.expressions.FieldKeyExpression) NestingKeyExpression(com.apple.foundationdb.record.metadata.expressions.NestingKeyExpression) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) ArrayList(java.util.ArrayList) Nullable(javax.annotation.Nullable)

Example 7 with KeyExpression

use of com.apple.foundationdb.record.metadata.expressions.KeyExpression in project fdb-record-layer by FoundationDB.

the class AvailableFields method fromIndex.

@Nonnull
public static AvailableFields fromIndex(@Nonnull RecordType recordType, @Nonnull Index index, @Nonnull PlannableIndexTypes indexTypes, @Nullable KeyExpression commonPrimaryKey) {
    final KeyExpression rootExpression = index.getRootExpression();
    final List<KeyExpression> keyFields = new ArrayList<>();
    final List<KeyExpression> valueFields = new ArrayList<>();
    final List<KeyExpression> nonStoredLuceneExpressions = new ArrayList<>();
    if (indexTypes.getTextTypes().contains(index.getType())) {
        // Full text index entries have all of their fields except the tokenized one.
        keyFields.addAll(TextScanPlanner.getOtherFields(rootExpression));
    } else if (indexTypes.getValueTypes().contains(index.getType()) || indexTypes.getRankTypes().contains(index.getType())) {
        keyFields.addAll(KeyExpression.getKeyFields(rootExpression));
        valueFields.addAll(KeyExpression.getValueFields(rootExpression));
    } else if (indexTypes.getLuceneTypes().contains(index.getType())) {
        // Todo: this will not take into account stored non-primary-key fields.
        nonStoredLuceneExpressions.addAll(rootExpression.normalizeKeyForPositions());
        keyFields.addAll(rootExpression.normalizeKeyForPositions());
        nonStoredLuceneExpressions.removeAll(recordType.getPrimaryKey().normalizeKeyForPositions());
    } else {
        // Aggregate index
        if (rootExpression instanceof GroupingKeyExpression) {
            GroupingKeyExpression groupingKeyExpression = (GroupingKeyExpression) rootExpression;
            keyFields.addAll(groupingKeyExpression.getGroupingSubKey().normalizeKeyForPositions());
        }
    }
    // Like FDBRecordStoreBase.indexEntryKey(), but with key expressions instead of actual values.
    final List<KeyExpression> primaryKeys = new ArrayList<>(commonPrimaryKey == null ? Collections.emptyList() : commonPrimaryKey.normalizeKeyForPositions());
    index.trimPrimaryKey(primaryKeys);
    keyFields.addAll(primaryKeys);
    Map<KeyExpression, FieldData> fields = new HashMap<>();
    final IndexKeyValueToPartialRecord.Builder builder = IndexKeyValueToPartialRecord.newBuilder(recordType);
    for (int i = 0; i < keyFields.size(); i++) {
        KeyExpression keyField = keyFields.get(i);
        FieldData fieldData = FieldData.of(IndexKeyValueToPartialRecord.TupleSource.KEY, i);
        if (!nonStoredLuceneExpressions.contains(keyField) && !keyField.createsDuplicates() && addCoveringField(keyField, fieldData, builder)) {
            fields.put(keyField, fieldData);
        }
    }
    for (int i = 0; i < valueFields.size(); i++) {
        KeyExpression valueField = valueFields.get(i);
        FieldData fieldData = FieldData.of(IndexKeyValueToPartialRecord.TupleSource.VALUE, i);
        if (!nonStoredLuceneExpressions.contains(valueField) && !valueField.createsDuplicates() && addCoveringField(valueField, fieldData, builder)) {
            fields.put(valueField, fieldData);
        }
    }
    if (!builder.isValid()) {
        return NO_FIELDS;
    }
    return new AvailableFields(fields);
}
Also used : HashMap(java.util.HashMap) 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) ArrayList(java.util.ArrayList) Nonnull(javax.annotation.Nonnull)

Example 8 with KeyExpression

use of com.apple.foundationdb.record.metadata.expressions.KeyExpression in project fdb-record-layer by FoundationDB.

the class PlanOrderingKey method isOrderingCompatible.

/**
 * Is the given ordering key compatible with the candidate merge key?
 * A subkeys of the candidate key can appear in the equals part of the ordering in any order.
 * The remainder must match the ordering key after the equality.
 */
private static boolean isOrderingCompatible(@Nonnull PlanOrderingKey planOrderingKey, @Nonnull KeyExpression candidateKey) {
    int nextNonPrefix = planOrderingKey.prefixSize;
    for (KeyExpression component : candidateKey.normalizeKeyForPositions()) {
        int pos = planOrderingKey.keys.indexOf(component);
        if (pos < 0) {
            // Not present at all.
            return false;
        }
        if (pos < planOrderingKey.prefixSize) {
            // ordered by it.
            continue;
        }
        // Otherwise, components need to be in order.
        if (pos != nextNonPrefix) {
            return false;
        }
        nextNonPrefix++;
    }
    return true;
}
Also used : KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) ThenKeyExpression(com.apple.foundationdb.record.metadata.expressions.ThenKeyExpression)

Example 9 with KeyExpression

use of com.apple.foundationdb.record.metadata.expressions.KeyExpression in project fdb-record-layer by FoundationDB.

the class StandardIndexMaintainer method evaluateIndex.

/**
 * Apply the key and value expressions to a <code>record</code>.
 * @param <M> the message type of the record
 * @param record the record from which the index will extract its key and value
 * @return a list of index keys and values
 */
@Override
public <M extends Message> List<IndexEntry> evaluateIndex(@Nonnull FDBRecord<M> record) {
    final KeyExpression rootExpression = state.index.getRootExpression();
    final List<Key.Evaluated> indexKeys = rootExpression.evaluate(record);
    // so we have to tease them apart.
    if (rootExpression instanceof KeyWithValueExpression) {
        final KeyWithValueExpression keyWithValueExpression = (KeyWithValueExpression) rootExpression;
        return indexKeys.stream().map(key -> new IndexEntry(state.index, keyWithValueExpression.getKey(key), keyWithValueExpression.getValue(key))).collect(Collectors.toList());
    }
    return indexKeys.stream().map(key -> new IndexEntry(state.index, key)).collect(Collectors.toList());
}
Also used : IndexEntry(com.apple.foundationdb.record.IndexEntry) LogMessageKeys(com.apple.foundationdb.record.logging.LogMessageKeys) IndexMaintainerState(com.apple.foundationdb.record.provider.foundationdb.IndexMaintainerState) FDBRecord(com.apple.foundationdb.record.provider.foundationdb.FDBRecord) LoggerFactory(org.slf4j.LoggerFactory) Subspace(com.apple.foundationdb.subspace.Subspace) Transaction(com.apple.foundationdb.Transaction) IndexScanType(com.apple.foundationdb.record.IndexScanType) Tuple(com.apple.foundationdb.tuple.Tuple) Range(com.apple.foundationdb.Range) KeyValueLogMessage(com.apple.foundationdb.record.logging.KeyValueLogMessage) Pair(org.apache.commons.lang3.tuple.Pair) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) PipelineOperation(com.apple.foundationdb.record.PipelineOperation) RecordIndexUniquenessViolation(com.apple.foundationdb.record.RecordIndexUniquenessViolation) GroupingKeyExpression(com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression) FDBExceptions(com.apple.foundationdb.record.provider.foundationdb.FDBExceptions) FDBRecordStoreBase(com.apple.foundationdb.record.provider.foundationdb.FDBRecordStoreBase) QueryToKeyMatcher(com.apple.foundationdb.record.query.QueryToKeyMatcher) ByteArrayUtil(com.apple.foundationdb.tuple.ByteArrayUtil) FDBIndexableRecord(com.apple.foundationdb.record.provider.foundationdb.FDBIndexableRecord) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) KeyValue(com.apple.foundationdb.KeyValue) FDBStoreTimer(com.apple.foundationdb.record.provider.foundationdb.FDBStoreTimer) Collection(java.util.Collection) Collectors(java.util.stream.Collectors) TupleRange(com.apple.foundationdb.record.TupleRange) Objects(java.util.Objects) KeyValueCursor(com.apple.foundationdb.record.provider.foundationdb.KeyValueCursor) List(java.util.List) EvaluationContext(com.apple.foundationdb.record.EvaluationContext) TupleHelpers(com.apple.foundationdb.tuple.TupleHelpers) API(com.apple.foundationdb.annotation.API) SplitHelper.unpackKey(com.apple.foundationdb.record.provider.foundationdb.SplitHelper.unpackKey) IndexMaintainer(com.apple.foundationdb.record.provider.foundationdb.IndexMaintainer) IndexMaintenanceFilter(com.apple.foundationdb.record.provider.foundationdb.IndexMaintenanceFilter) IndexAggregateFunction(com.apple.foundationdb.record.metadata.IndexAggregateFunction) KeyWithValueExpression(com.apple.foundationdb.record.metadata.expressions.KeyWithValueExpression) IndexOperation(com.apple.foundationdb.record.provider.foundationdb.IndexOperation) CompletableFuture(java.util.concurrent.CompletableFuture) AsyncUtil(com.apple.foundationdb.async.AsyncUtil) RangeSet(com.apple.foundationdb.async.RangeSet) Function(java.util.function.Function) CursorStreamingMode(com.apple.foundationdb.record.CursorStreamingMode) ArrayList(java.util.ArrayList) Key(com.apple.foundationdb.record.metadata.Key) ExecuteProperties(com.apple.foundationdb.record.ExecuteProperties) ScanProperties(com.apple.foundationdb.record.ScanProperties) IndexRecordFunction(com.apple.foundationdb.record.metadata.IndexRecordFunction) Nonnull(javax.annotation.Nonnull) Nullable(javax.annotation.Nullable) IndexOperationResult(com.apple.foundationdb.record.provider.foundationdb.IndexOperationResult) MoreAsyncUtil(com.apple.foundationdb.async.MoreAsyncUtil) IsolationLevel(com.apple.foundationdb.record.IsolationLevel) Logger(org.slf4j.Logger) Executor(java.util.concurrent.Executor) RecordType(com.apple.foundationdb.record.metadata.RecordType) AsyncIterable(com.apple.foundationdb.async.AsyncIterable) Message(com.google.protobuf.Message) RecordCursor(com.apple.foundationdb.record.RecordCursor) Collections(java.util.Collections) GroupingKeyExpression(com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) IndexEntry(com.apple.foundationdb.record.IndexEntry) KeyWithValueExpression(com.apple.foundationdb.record.metadata.expressions.KeyWithValueExpression)

Example 10 with KeyExpression

use of com.apple.foundationdb.record.metadata.expressions.KeyExpression in project fdb-record-layer by FoundationDB.

the class ScalarTranslationVisitor method visitExpression.

@Nonnull
@Override
public Value visitExpression(@Nonnull final ThenKeyExpression thenKeyExpression) {
    if (thenKeyExpression.getColumnSize() > 1) {
        throw new RecordCoreException("cannot expand ThenKeyExpression in scalar expansion");
    }
    final ScalarVisitorState state = getCurrentState();
    final KeyExpression child = Iterables.getOnlyElement(thenKeyExpression.getChildren());
    return pop(child.expand(push(state)));
}
Also used : RecordCoreException(com.apple.foundationdb.record.RecordCoreException) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) FieldKeyExpression(com.apple.foundationdb.record.metadata.expressions.FieldKeyExpression) NestingKeyExpression(com.apple.foundationdb.record.metadata.expressions.NestingKeyExpression) ThenKeyExpression(com.apple.foundationdb.record.metadata.expressions.ThenKeyExpression) EmptyKeyExpression(com.apple.foundationdb.record.metadata.expressions.EmptyKeyExpression) Nonnull(javax.annotation.Nonnull)

Aggregations

KeyExpression (com.apple.foundationdb.record.metadata.expressions.KeyExpression)152 GroupingKeyExpression (com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression)85 Test (org.junit.jupiter.api.Test)63 FieldKeyExpression (com.apple.foundationdb.record.metadata.expressions.FieldKeyExpression)60 EmptyKeyExpression (com.apple.foundationdb.record.metadata.expressions.EmptyKeyExpression)56 NestingKeyExpression (com.apple.foundationdb.record.metadata.expressions.NestingKeyExpression)56 ThenKeyExpression (com.apple.foundationdb.record.metadata.expressions.ThenKeyExpression)52 Nonnull (javax.annotation.Nonnull)52 Index (com.apple.foundationdb.record.metadata.Index)37 List (java.util.List)36 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)35 Nullable (javax.annotation.Nullable)33 RecordQueryPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan)30 FunctionKeyExpression (com.apple.foundationdb.record.metadata.expressions.FunctionKeyExpression)28 Message (com.google.protobuf.Message)26 ArrayList (java.util.ArrayList)26 RecordMetaData (com.apple.foundationdb.record.RecordMetaData)25 QueryableKeyExpression (com.apple.foundationdb.record.metadata.expressions.QueryableKeyExpression)25 RecordCoreException (com.apple.foundationdb.record.RecordCoreException)24 ListKeyExpression (com.apple.foundationdb.record.metadata.expressions.ListKeyExpression)23