Search in sources :

Example 66 with KeyExpression

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

the class LuceneIndexMaintainer method update.

@Nonnull
@Override
public <M extends Message> CompletableFuture<Void> update(@Nullable FDBIndexableRecord<M> oldRecord, @Nullable FDBIndexableRecord<M> newRecord) {
    LOG.trace("update oldRecord={}, newRecord={}", oldRecord, newRecord);
    // Extract information for grouping from old and new records
    final KeyExpression root = state.index.getRootExpression();
    final Map<Tuple, List<LuceneDocumentFromRecord.DocumentField>> oldRecordFields = LuceneDocumentFromRecord.getRecordFields(root, oldRecord);
    final Map<Tuple, List<LuceneDocumentFromRecord.DocumentField>> newRecordFields = LuceneDocumentFromRecord.getRecordFields(root, newRecord);
    final Set<Tuple> unchanged = new HashSet<>();
    for (Map.Entry<Tuple, List<LuceneDocumentFromRecord.DocumentField>> entry : oldRecordFields.entrySet()) {
        if (entry.getValue().equals(newRecordFields.get(entry.getKey()))) {
            unchanged.add(entry.getKey());
        }
    }
    for (Tuple t : unchanged) {
        newRecordFields.remove(t);
        oldRecordFields.remove(t);
    }
    LOG.trace("update oldFields={}, newFields{}", oldRecordFields, newRecordFields);
    // delete old
    try {
        for (Tuple t : oldRecordFields.keySet()) {
            deleteDocument(t, oldRecord.getPrimaryKey().pack());
        }
    } catch (IOException e) {
        throw new RecordCoreException("Issue deleting old index keys", "oldRecord", oldRecord, e);
    }
    // There's actually no possibility of a NPE here. (line 304/306)
    if (newRecord == null) {
        return AsyncUtil.DONE;
    }
    // update new
    try {
        for (Map.Entry<Tuple, List<LuceneDocumentFromRecord.DocumentField>> entry : newRecordFields.entrySet()) {
            writeDocument(entry.getValue(), entry.getKey(), newRecord.getPrimaryKey().pack());
        }
    } catch (IOException e) {
        throw new RecordCoreException("Issue updating new index keys", e).addLogInfo("newRecord", newRecord);
    }
    return AsyncUtil.DONE;
}
Also used : RecordCoreException(com.apple.foundationdb.record.RecordCoreException) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) List(java.util.List) IOException(java.io.IOException) Map(java.util.Map) Tuple(com.apple.foundationdb.tuple.Tuple) HashSet(java.util.HashSet) Nonnull(javax.annotation.Nonnull)

Example 67 with KeyExpression

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

the class FDBComparatorPlanTest method testRepeatedKeyFails.

@DualPlannerTest
void testRepeatedKeyFails() throws Exception {
    // Test when the comparison key is a repeated field
    complexQuerySetup(NO_HOOK);
    RecordQuery query1 = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.field("num_value_2").equalsValue(1)).build();
    RecordQuery query2 = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.field("num_value_2").equalsValue(1)).build();
    Descriptors.FieldDescriptor comparisonKey = recordStore.getRecordMetaData().getRecordType("MySimpleRecord").getDescriptor().findFieldByName("repeater");
    KeyExpression keyExpression = Key.Expressions.fromDescriptor(comparisonKey);
    RecordQueryPlan planUnderTest = RecordQueryComparatorPlan.from(plan(query1, query2), keyExpression, 0, abortOnComparisonFailure);
    // Repeated keys will fail the comparison since they are not supported
    assertDifferentPlans(planUnderTest, 1, 134, 33);
}
Also used : KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) Descriptors(com.google.protobuf.Descriptors) RecordQuery(com.apple.foundationdb.record.query.RecordQuery) DualPlannerTest(com.apple.foundationdb.record.provider.foundationdb.query.DualPlannerTest)

Example 68 with KeyExpression

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

the class RemoveSortRule method onMatch.

@Override
public void onMatch(@Nonnull PlannerRuleCall call) {
    final LogicalSortExpression sortExpression = call.get(root);
    final RecordQueryPlan innerPlan = call.get(innerPlanMatcher);
    final KeyExpression sortKeyExpression = sortExpression.getSort();
    if (sortKeyExpression == null) {
        call.yield(call.ref(innerPlan));
        return;
    }
    final Optional<Ordering> orderingOptional = OrderingProperty.evaluate(innerPlan, call.getContext());
    if (orderingOptional.isEmpty()) {
        return;
    }
    final Ordering ordering = orderingOptional.get();
    final Set<KeyExpression> equalityBoundKeys = ordering.getEqualityBoundKeys();
    int equalityBoundUnsorted = equalityBoundKeys.size();
    final List<KeyPart> orderingKeys = ordering.getOrderingKeyParts();
    final Iterator<KeyPart> orderingKeysIterator = orderingKeys.iterator();
    final List<KeyExpression> normalizedSortExpressions = sortKeyExpression.normalizeKeyForPositions();
    for (final KeyExpression normalizedSortExpression : normalizedSortExpressions) {
        if (equalityBoundKeys.contains(normalizedSortExpression)) {
            equalityBoundUnsorted--;
            continue;
        }
        if (!orderingKeysIterator.hasNext()) {
            return;
        }
        final KeyPart currentOrderingKeyPart = orderingKeysIterator.next();
        if (!normalizedSortExpression.equals(currentOrderingKeyPart.getNormalizedKeyExpression())) {
            return;
        }
    }
    final boolean strictOrdered = // If we have exhausted the ordering info's keys, too, then its constituents are strictly ordered.
    !orderingKeysIterator.hasNext() || // Also a unique index if have gone through declared fields.
    strictlyOrderedIfUnique(innerPlan, call.getContext()::getIndexByName, normalizedSortExpressions.size() + equalityBoundUnsorted);
    call.yield(call.ref(strictOrdered ? innerPlan.strictlySorted() : innerPlan));
}
Also used : RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) Ordering(com.apple.foundationdb.record.query.plan.temp.Ordering) KeyPart(com.apple.foundationdb.record.query.plan.temp.KeyPart) LogicalSortExpression(com.apple.foundationdb.record.query.plan.temp.expressions.LogicalSortExpression)

Example 69 with KeyExpression

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

the class FilterVisitor method postVisit.

@Nonnull
@Override
public RecordQueryPlan postVisit(@Nonnull RecordQueryPlan recordQueryPlan) {
    if (recordQueryPlan instanceof RecordQueryFilterPlan) {
        final RecordQueryFilterPlan filterPlan = (RecordQueryFilterPlan) recordQueryPlan;
        final List<QueryComponent> filters = filterPlan.getFilters();
        final AvailableFields availableFields = availableFields(((RecordQueryFilterPlan) recordQueryPlan).getInnerPlan());
        // Partition the filters according to whether they can be evaluated using just the fields from the index or
        // if they need a full record.
        final List<QueryComponent> indexFilters = Lists.newArrayListWithCapacity(filters.size());
        final List<QueryComponent> residualFilters = Lists.newArrayListWithCapacity(filters.size());
        final Set<KeyExpression> allReferencedFields = new HashSet<>();
        partitionFilters(filters, availableFields, indexFilters, residualFilters, allReferencedFields);
        Verify.verify(indexFilters.size() + residualFilters.size() == filters.size());
        if (indexFilters.isEmpty()) {
            return recordQueryPlan;
        }
        @Nullable RecordQueryPlan removedFetchPlan = removeIndexFetch(filterPlan.getChild(), allReferencedFields);
        if (removedFetchPlan == null) {
            return recordQueryPlan;
        }
        recordQueryPlan = new RecordQueryFetchFromPartialRecordPlan(new RecordQueryFilterPlan(removedFetchPlan, indexFilters), TranslateValueFunction.unableToTranslate());
        if (!residualFilters.isEmpty()) {
            recordQueryPlan = new RecordQueryFilterPlan(recordQueryPlan, residualFilters);
        }
    }
    return recordQueryPlan;
}
Also used : RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) AvailableFields(com.apple.foundationdb.record.query.plan.AvailableFields) RecordQueryFilterPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryFilterPlan) RecordQueryFetchFromPartialRecordPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryFetchFromPartialRecordPlan) FunctionKeyExpression(com.apple.foundationdb.record.metadata.expressions.FunctionKeyExpression) LiteralKeyExpression(com.apple.foundationdb.record.metadata.expressions.LiteralKeyExpression) FieldKeyExpression(com.apple.foundationdb.record.metadata.expressions.FieldKeyExpression) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) QueryableKeyExpression(com.apple.foundationdb.record.metadata.expressions.QueryableKeyExpression) ThenKeyExpression(com.apple.foundationdb.record.metadata.expressions.ThenKeyExpression) Nullable(javax.annotation.Nullable) HashSet(java.util.HashSet) Nonnull(javax.annotation.Nonnull)

Example 70 with KeyExpression

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

the class IntersectionVisitor method postVisit.

@Nonnull
@Override
public RecordQueryPlan postVisit(@Nonnull final RecordQueryPlan recordQueryPlan) {
    if (recordQueryPlan instanceof RecordQueryIntersectionPlan) {
        RecordQueryIntersectionPlan intersectionPlan = (RecordQueryIntersectionPlan) recordQueryPlan;
        Set<KeyExpression> requiredFields = intersectionPlan.getRequiredFields();
        List<RecordQueryPlan> newChildren = new ArrayList<>(intersectionPlan.getChildren().size());
        for (RecordQueryPlan plan : intersectionPlan.getChildren()) {
            @Nullable RecordQueryPlan newPlan = removeIndexFetch(plan, requiredFields);
            if (newPlan == null) {
                // can't remove index fetch, so give up
                return recordQueryPlan;
            }
            newChildren.add(newPlan);
        }
        return new RecordQueryFetchFromPartialRecordPlan(RecordQueryIntersectionPlan.from(newChildren, intersectionPlan.getComparisonKey()), TranslateValueFunction.unableToTranslate());
    }
    return recordQueryPlan;
}
Also used : RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) RecordQueryFetchFromPartialRecordPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryFetchFromPartialRecordPlan) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) ArrayList(java.util.ArrayList) Nullable(javax.annotation.Nullable) RecordQueryIntersectionPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryIntersectionPlan) 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