Search in sources :

Example 16 with FieldKeyExpression

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

the class FDBRecordStoreIndexTest method minMaxIndex.

@ParameterizedTest(name = "minMaxIndex({0})")
@EnumSource(MinMaxIndexTypes.class)
public void minMaxIndex(MinMaxIndexTypes indexTypes) throws Exception {
    final FieldKeyExpression recno = field("rec_no");
    final GroupingKeyExpression byKey = recno.groupBy(field("num_value_3_indexed"));
    final RecordMetaDataHook hook = md -> {
        RecordTypeBuilder type = md.getRecordType("MySimpleRecord");
        md.addIndex(type, new Index("min", byKey, indexTypes.min()));
        md.addIndex(type, new Index("max", byKey, indexTypes.max()));
    };
    final IndexAggregateFunction minOverall = new IndexAggregateFunction(FunctionNames.MIN_EVER, recno, null);
    final IndexAggregateFunction maxOverall = new IndexAggregateFunction(FunctionNames.MAX_EVER, recno, null);
    final IndexAggregateFunction minByKey = new IndexAggregateFunction(FunctionNames.MIN_EVER, byKey, null);
    final IndexAggregateFunction maxByKey = new IndexAggregateFunction(FunctionNames.MAX_EVER, byKey, null);
    List<String> types = Collections.singletonList("MySimpleRecord");
    try (FDBRecordContext context = openContext()) {
        openSimpleRecordStore(context, hook);
        assertNull(recordStore.evaluateAggregateFunction(types, minOverall, Key.Evaluated.EMPTY, IsolationLevel.SNAPSHOT).join());
        assertNull(recordStore.evaluateAggregateFunction(types, maxOverall, Key.Evaluated.EMPTY, IsolationLevel.SNAPSHOT).join());
        assertNull(recordStore.evaluateAggregateFunction(types, minByKey, Key.Evaluated.scalar(1), IsolationLevel.SNAPSHOT).join());
        assertNull(recordStore.evaluateAggregateFunction(types, maxByKey, Key.Evaluated.scalar(1), IsolationLevel.SNAPSHOT).join());
        for (int i = 0; i < 100; i++) {
            TestRecords1Proto.MySimpleRecord.Builder recBuilder = TestRecords1Proto.MySimpleRecord.newBuilder();
            recBuilder.setRecNo(i);
            recBuilder.setNumValue3Indexed(i % 5);
            recordStore.saveRecord(recBuilder.build());
        }
        commit(context);
    }
    try (FDBRecordContext context = openContext()) {
        openSimpleRecordStore(context, hook);
        assertEquals(0, recordStore.evaluateAggregateFunction(types, minOverall, Key.Evaluated.EMPTY, IsolationLevel.SNAPSHOT).join().getLong(0));
        assertEquals(99, recordStore.evaluateAggregateFunction(types, maxOverall, Key.Evaluated.EMPTY, IsolationLevel.SNAPSHOT).join().getLong(0));
        assertEquals(1, recordStore.evaluateAggregateFunction(types, minByKey, Key.Evaluated.scalar(1), IsolationLevel.SNAPSHOT).join().getLong(0));
        assertEquals(96, recordStore.evaluateAggregateFunction(types, maxByKey, Key.Evaluated.scalar(1), IsolationLevel.SNAPSHOT).join().getLong(0));
        commit(context);
    }
    try (FDBRecordContext context = openContext()) {
        openSimpleRecordStore(context, hook);
        recordStore.deleteRecord(Tuple.from(0));
        recordStore.deleteRecord(Tuple.from(99));
        assertEquals(0, recordStore.evaluateAggregateFunction(types, minOverall, Key.Evaluated.EMPTY, IsolationLevel.SNAPSHOT).join().getLong(0));
        assertEquals(99, recordStore.evaluateAggregateFunction(types, maxOverall, Key.Evaluated.EMPTY, IsolationLevel.SNAPSHOT).join().getLong(0));
        commit(context);
    }
    // verify that negatives do not appear in min/max
    try (FDBRecordContext context = openContext()) {
        openSimpleRecordStore(context, hook);
        TestRecords1Proto.MySimpleRecord.Builder recBuilder = TestRecords1Proto.MySimpleRecord.newBuilder();
        recBuilder.setRecNo(-1);
        recBuilder.setNumValue3Indexed(1);
        recordStore.saveRecord(recBuilder.build());
        if (!indexTypes.shouldAllowNegative()) {
            fail("should have thrown exception");
        }
    } catch (RecordCoreException e) {
        if (indexTypes.shouldAllowNegative()) {
            throw e;
        }
        assertEquals(e.getMessage(), "Attempted update of MAX_EVER_LONG or MIN_EVER_LONG index with negative value");
    }
}
Also used : BeforeEach(org.junit.jupiter.api.BeforeEach) Arrays(java.util.Arrays) LogMessageKeys(com.apple.foundationdb.record.logging.LogMessageKeys) MetaDataException(com.apple.foundationdb.record.metadata.MetaDataException) IndexScanType(com.apple.foundationdb.record.IndexScanType) Pair(org.apache.commons.lang3.tuple.Pair) FDBError(com.apple.foundationdb.FDBError) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) RecordIndexUniquenessViolation(com.apple.foundationdb.record.RecordIndexUniquenessViolation) Expressions.concat(com.apple.foundationdb.record.metadata.Key.Expressions.concat) GroupingKeyExpression(com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression) Tag(org.junit.jupiter.api.Tag) Query(com.apple.foundationdb.record.query.expressions.Query) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) IndexOptions(com.apple.foundationdb.record.metadata.IndexOptions) Set(java.util.Set) FanType(com.apple.foundationdb.record.metadata.expressions.KeyExpression.FanType) TupleRange(com.apple.foundationdb.record.TupleRange) Matchers.instanceOf(org.hamcrest.Matchers.instanceOf) RecordMetaDataProvider(com.apple.foundationdb.record.RecordMetaDataProvider) RecordStoreState(com.apple.foundationdb.record.RecordStoreState) TupleHelpers(com.apple.foundationdb.tuple.TupleHelpers) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) InvalidIndexEntry(com.apple.foundationdb.record.provider.foundationdb.indexes.InvalidIndexEntry) AutoContinuingCursor(com.apple.foundationdb.record.cursors.AutoContinuingCursor) Matchers.is(org.hamcrest.Matchers.is) Assertions.assertThrows(org.junit.jupiter.api.Assertions.assertThrows) Assertions.fail(org.junit.jupiter.api.Assertions.fail) FunctionNames(com.apple.foundationdb.record.FunctionNames) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) Assertions.assertNotNull(org.junit.jupiter.api.Assertions.assertNotNull) IndexAggregateFunction(com.apple.foundationdb.record.metadata.IndexAggregateFunction) Assertions.assertNull(org.junit.jupiter.api.Assertions.assertNull) AsyncUtil(com.apple.foundationdb.async.AsyncUtil) ArrayList(java.util.ArrayList) Strings(com.google.common.base.Strings) CloseableAsyncIterator(com.apple.foundationdb.async.CloseableAsyncIterator) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) FDBRecordStoreBase.indexEntryKey(com.apple.foundationdb.record.provider.foundationdb.FDBRecordStoreBase.indexEntryKey) Nullable(javax.annotation.Nullable) Matchers.greaterThanOrEqualTo(org.hamcrest.Matchers.greaterThanOrEqualTo) IsolationLevel(com.apple.foundationdb.record.IsolationLevel) Tags(com.apple.test.Tags) TestRecords1EvolvedProto(com.apple.foundationdb.record.TestRecords1EvolvedProto) ExecutionException(java.util.concurrent.ExecutionException) Assertions.assertArrayEquals(org.junit.jupiter.api.Assertions.assertArrayEquals) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) Index(com.apple.foundationdb.record.metadata.Index) FDBException(com.apple.foundationdb.FDBException) ThenKeyExpression(com.apple.foundationdb.record.metadata.expressions.ThenKeyExpression) IndexEntry(com.apple.foundationdb.record.IndexEntry) StoreTimer(com.apple.foundationdb.record.provider.common.StoreTimer) LoggerFactory(org.slf4j.LoggerFactory) Assertions.assertNotEquals(org.junit.jupiter.api.Assertions.assertNotEquals) Random(java.util.Random) Tuple(com.apple.foundationdb.tuple.Tuple) Range(com.apple.foundationdb.Range) Assertions.assertFalse(org.junit.jupiter.api.Assertions.assertFalse) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Expressions.concatenateFields(com.apple.foundationdb.record.metadata.Key.Expressions.concatenateFields) ImmutableSet(com.google.common.collect.ImmutableSet) TestRecords1Proto(com.apple.foundationdb.record.TestRecords1Proto) ImmutableMap(com.google.common.collect.ImmutableMap) Matchers.lessThanOrEqualTo(org.hamcrest.Matchers.lessThanOrEqualTo) Collection(java.util.Collection) CompletionException(java.util.concurrent.CompletionException) IndexQueryabilityFilter(com.apple.foundationdb.record.query.IndexQueryabilityFilter) TypeSafeMatcher(org.hamcrest.TypeSafeMatcher) Collectors(java.util.stream.Collectors) Test(org.junit.jupiter.api.Test) List(java.util.List) EvaluationContext(com.apple.foundationdb.record.EvaluationContext) Matchers.equalTo(org.hamcrest.Matchers.equalTo) IndexTypes(com.apple.foundationdb.record.metadata.IndexTypes) Optional(java.util.Optional) TestNoIndexesProto(com.apple.foundationdb.record.TestNoIndexesProto) LazyCursor(com.apple.foundationdb.record.cursors.LazyCursor) EnumSource(org.junit.jupiter.params.provider.EnumSource) CompletableFuture(java.util.concurrent.CompletableFuture) Iterators(com.google.common.collect.Iterators) Key(com.apple.foundationdb.record.metadata.Key) FieldKeyExpression(com.apple.foundationdb.record.metadata.expressions.FieldKeyExpression) HashSet(java.util.HashSet) ExecuteProperties(com.apple.foundationdb.record.ExecuteProperties) ScanProperties(com.apple.foundationdb.record.ScanProperties) RecordCursorIterator(com.apple.foundationdb.record.RecordCursorIterator) BooleanSource(com.apple.test.BooleanSource) Nonnull(javax.annotation.Nonnull) Expressions.field(com.apple.foundationdb.record.metadata.Key.Expressions.field) EmptyKeyExpression(com.apple.foundationdb.record.metadata.expressions.EmptyKeyExpression) Matchers.hasEntry(org.hamcrest.Matchers.hasEntry) Description(org.hamcrest.Description) Matchers.oneOf(org.hamcrest.Matchers.oneOf) Logger(org.slf4j.Logger) RecordMetaDataBuilder(com.apple.foundationdb.record.RecordMetaDataBuilder) RecordTypeBuilder(com.apple.foundationdb.record.metadata.RecordTypeBuilder) IndexState(com.apple.foundationdb.record.IndexState) TestRecordsIndexFilteringProto(com.apple.foundationdb.record.TestRecordsIndexFilteringProto) Message(com.google.protobuf.Message) Collections(java.util.Collections) GroupingKeyExpression(com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression) Index(com.apple.foundationdb.record.metadata.Index) IndexAggregateFunction(com.apple.foundationdb.record.metadata.IndexAggregateFunction) RecordTypeBuilder(com.apple.foundationdb.record.metadata.RecordTypeBuilder) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) FieldKeyExpression(com.apple.foundationdb.record.metadata.expressions.FieldKeyExpression) EnumSource(org.junit.jupiter.params.provider.EnumSource) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 17 with FieldKeyExpression

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

the class LuceneIndexExpressions method getFieldsRecursively.

@SuppressWarnings("squid:S3776")
public static <T extends RecordSource<T>> void getFieldsRecursively(@Nonnull KeyExpression expression, @Nonnull T source, @Nonnull DocumentDestination<T> destination, @Nullable String fieldNamePrefix, int keyIndex, int groupingCount, @Nonnull List<Integer> overriddenKeyRanges) {
    if (expression instanceof ThenKeyExpression) {
        int count = 0;
        for (KeyExpression child : ((ThenKeyExpression) expression).getChildren()) {
            getFieldsRecursively(child, source, destination, fieldNamePrefix, keyIndex + count, groupingCount, overriddenKeyRanges);
            count += child.getColumnSize();
        }
        return;
    }
    String fieldNameSuffix = null;
    boolean suffixOverride = false;
    if (expression instanceof LuceneFunctionKeyExpression.LuceneFieldName) {
        LuceneFunctionKeyExpression.LuceneFieldName fieldNameExpression = (LuceneFunctionKeyExpression.LuceneFieldName) expression;
        KeyExpression nameExpression = fieldNameExpression.getNameExpression();
        if (nameExpression instanceof LiteralKeyExpression) {
            fieldNameSuffix = (String) ((LiteralKeyExpression<?>) nameExpression).getValue();
        } else if (nameExpression instanceof FieldKeyExpression) {
            Iterator<Object> names = source.getValues((FieldKeyExpression) nameExpression).iterator();
            if (names.hasNext()) {
                fieldNameSuffix = (String) names.next();
                if (names.hasNext()) {
                    throw new RecordCoreException("Lucene field name override should evaluate to single value");
                }
            }
        } else {
            throw new RecordCoreException("Lucene field name override should be a literal or a field");
        }
        suffixOverride = true;
        expression = fieldNameExpression.getNamedExpression();
    }
    if (expression instanceof NestingKeyExpression) {
        NestingKeyExpression nestingExpression = (NestingKeyExpression) expression;
        FieldKeyExpression parentExpression = nestingExpression.getParent();
        KeyExpression child = nestingExpression.getChild();
        if (!suffixOverride) {
            fieldNameSuffix = parentExpression.getFieldName();
        } else {
            addOverriddenKeyRange(overriddenKeyRanges, fieldNamePrefix, fieldNameSuffix);
        }
        String fieldName = appendFieldName(fieldNamePrefix, fieldNameSuffix);
        for (T subsource : source.getChildren(parentExpression)) {
            getFieldsRecursively(child, subsource, destination, fieldName, keyIndex, groupingCount, overriddenKeyRanges);
        }
        if (suffixOverride) {
            // Remove the last 2 numbers added above
            removedLastOverriddenKeyRange(overriddenKeyRanges);
        }
        return;
    }
    boolean fieldStored = false;
    boolean fieldText = false;
    while (true) {
        if (expression instanceof LuceneFunctionKeyExpression.LuceneStored) {
            LuceneFunctionKeyExpression.LuceneStored storedExpression = (LuceneFunctionKeyExpression.LuceneStored) expression;
            fieldStored = true;
            expression = storedExpression.getStoredExpression();
        } else if (expression instanceof LuceneFunctionKeyExpression.LuceneText) {
            LuceneFunctionKeyExpression.LuceneText textExpression = (LuceneFunctionKeyExpression.LuceneText) expression;
            fieldText = true;
            expression = textExpression.getFieldExpression();
        } else {
            // TODO: More text options.
            break;
        }
    }
    if (expression instanceof FieldKeyExpression) {
        FieldKeyExpression fieldExpression = (FieldKeyExpression) expression;
        if (!suffixOverride) {
            fieldNameSuffix = fieldExpression.getFieldName();
        } else {
            addOverriddenKeyRange(overriddenKeyRanges, fieldNamePrefix, fieldNameSuffix);
        }
        String fieldName = appendFieldName(fieldNamePrefix, fieldNameSuffix);
        if (fieldName == null) {
            fieldName = "_";
        }
        Descriptors.Descriptor recordDescriptor = source.getDescriptor();
        Descriptors.FieldDescriptor fieldDescriptor = recordDescriptor.findFieldByName(fieldExpression.getFieldName());
        DocumentFieldType fieldType;
        if (fieldText) {
            switch(fieldDescriptor.getJavaType()) {
                case STRING:
                    fieldType = DocumentFieldType.TEXT;
                    break;
                default:
                    throw new RecordCoreException("Unknown Lucene text field type");
            }
        } else {
            switch(fieldDescriptor.getJavaType()) {
                case STRING:
                    fieldType = DocumentFieldType.STRING;
                    break;
                case INT:
                    fieldType = DocumentFieldType.INT;
                    break;
                case LONG:
                    fieldType = DocumentFieldType.LONG;
                    break;
                case DOUBLE:
                    fieldType = DocumentFieldType.DOUBLE;
                    break;
                case BOOLEAN:
                    fieldType = DocumentFieldType.BOOLEAN;
                    break;
                default:
                    throw new RecordCoreException("Unknown Lucene field type");
            }
        }
        for (Object value : source.getValues(fieldExpression)) {
            destination.addField(source, fieldName, value, fieldType, fieldStored, overriddenKeyRanges, keyIndex < groupingCount ? keyIndex : -1);
        }
        if (suffixOverride) {
            // Remove the last 2 numbers added above
            removedLastOverriddenKeyRange(overriddenKeyRanges);
        }
        return;
    }
    throw new RecordCoreException("Unknown Lucene field key expression");
}
Also used : ThenKeyExpression(com.apple.foundationdb.record.metadata.expressions.ThenKeyExpression) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) LiteralKeyExpression(com.apple.foundationdb.record.metadata.expressions.LiteralKeyExpression) FieldKeyExpression(com.apple.foundationdb.record.metadata.expressions.FieldKeyExpression) NestingKeyExpression(com.apple.foundationdb.record.metadata.expressions.NestingKeyExpression) GroupingKeyExpression(com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression) ThenKeyExpression(com.apple.foundationdb.record.metadata.expressions.ThenKeyExpression) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) FieldKeyExpression(com.apple.foundationdb.record.metadata.expressions.FieldKeyExpression) NestingKeyExpression(com.apple.foundationdb.record.metadata.expressions.NestingKeyExpression) Iterator(java.util.Iterator) Descriptors(com.google.protobuf.Descriptors) LiteralKeyExpression(com.apple.foundationdb.record.metadata.expressions.LiteralKeyExpression)

Example 18 with FieldKeyExpression

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

the class RecordMetaDataBuilder method protoFieldOptions.

@SuppressWarnings("deprecation")
private void protoFieldOptions(RecordTypeBuilder recordType, Descriptors.FieldDescriptor fieldDescriptor, RecordMetaDataOptionsProto.FieldOptions fieldOptions) {
    Descriptors.Descriptor descriptor = recordType.getDescriptor();
    if (fieldOptions.hasIndex() || fieldOptions.hasIndexed()) {
        String type;
        Map<String, String> options;
        if (fieldOptions.hasIndex()) {
            RecordMetaDataOptionsProto.FieldOptions.IndexOption indexOption = fieldOptions.getIndex();
            type = indexOption.getType();
            options = Index.buildOptions(indexOption.getOptionsList(), indexOption.getUnique());
        } else {
            type = Index.indexTypeToType(fieldOptions.getIndexed());
            options = Index.indexTypeToOptions(fieldOptions.getIndexed());
        }
        final FieldKeyExpression field = Key.Expressions.fromDescriptor(fieldDescriptor);
        final KeyExpression expr;
        if (type.equals(IndexTypes.RANK)) {
            expr = field.ungrouped();
        } else {
            expr = field;
        }
        final Index index = new Index(descriptor.getName() + "$" + fieldDescriptor.getName(), expr, Index.EMPTY_VALUE, type, options);
        addIndex(recordType, index);
    } else if (fieldOptions.getPrimaryKey()) {
        if (recordType.getPrimaryKey() != null) {
            throw new MetaDataException("Only one primary key per record type is allowed have: " + recordType.getPrimaryKey() + "; adding on " + fieldDescriptor.getName());
        } else {
            if (fieldDescriptor.isRepeated()) {
                // TODO maybe default to concatenate for this.
                throw new MetaDataException("Primary key cannot be set on a repeated field");
            } else {
                recordType.setPrimaryKey(Key.Expressions.fromDescriptor(fieldDescriptor));
            }
        }
    }
}
Also used : FieldKeyExpression(com.apple.foundationdb.record.metadata.expressions.FieldKeyExpression) LiteralKeyExpression(com.apple.foundationdb.record.metadata.expressions.LiteralKeyExpression) FieldKeyExpression(com.apple.foundationdb.record.metadata.expressions.FieldKeyExpression) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) FormerIndex(com.apple.foundationdb.record.metadata.FormerIndex) Index(com.apple.foundationdb.record.metadata.Index) Descriptors(com.google.protobuf.Descriptors) MetaDataException(com.apple.foundationdb.record.metadata.MetaDataException)

Example 19 with FieldKeyExpression

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

the class RecordQueryPlanner method planOneOfThemWithComparison.

@Nullable
private ScoredPlan planOneOfThemWithComparison(@Nonnull CandidateScan candidateScan, @Nonnull KeyExpression indexExpr, @Nonnull OneOfThemWithComparison oneOfThemWithComparison, @Nullable KeyExpression sort) {
    final Comparisons.Comparison comparison = oneOfThemWithComparison.getComparison();
    final ScanComparisons scanComparisons = ScanComparisons.from(comparison);
    if (scanComparisons == null) {
        final ScoredPlan sortOnlyPlan = planSortOnly(candidateScan, indexExpr, sort);
        if (sortOnlyPlan != null) {
            return new ScoredPlan(0, sortOnlyPlan.plan, Collections.<QueryComponent>singletonList(oneOfThemWithComparison), sortOnlyPlan.createsDuplicates);
        } else {
            return null;
        }
    }
    if (indexExpr instanceof FieldKeyExpression) {
        FieldKeyExpression field = (FieldKeyExpression) indexExpr;
        if (Objects.equals(oneOfThemWithComparison.getFieldName(), field.getFieldName()) && field.getFanType() == FanType.FanOut) {
            if (sort != null) {
                if (sort instanceof FieldKeyExpression) {
                    FieldKeyExpression sortField = (FieldKeyExpression) sort;
                    if (Objects.equals(sortField.getFieldName(), field.getFieldName())) {
                        // everything matches, yay!! Hopefully that comparison can be for tuples
                        return new ScoredPlan(1, valueScan(candidateScan, scanComparisons, true), Collections.<QueryComponent>emptyList(), true);
                    }
                }
            } else {
                return new ScoredPlan(1, valueScan(candidateScan, scanComparisons, false), Collections.<QueryComponent>emptyList(), true);
            }
        }
        return null;
    } else if (indexExpr instanceof ThenKeyExpression) {
        // May need second column to do sort, so handle like And, which does such cases.
        ThenKeyExpression then = (ThenKeyExpression) indexExpr;
        return new AndWithThenPlanner(candidateScan, then, Collections.singletonList(oneOfThemWithComparison), sort).plan();
    } else if (indexExpr instanceof NestingKeyExpression) {
        return null;
    }
    return null;
}
Also used : ThenKeyExpression(com.apple.foundationdb.record.metadata.expressions.ThenKeyExpression) TimeWindowScanComparisons(com.apple.foundationdb.record.provider.foundationdb.leaderboard.TimeWindowScanComparisons) IndexScanComparisons(com.apple.foundationdb.record.provider.foundationdb.IndexScanComparisons) FieldKeyExpression(com.apple.foundationdb.record.metadata.expressions.FieldKeyExpression) NestingKeyExpression(com.apple.foundationdb.record.metadata.expressions.NestingKeyExpression) TimeWindowScanComparisons(com.apple.foundationdb.record.provider.foundationdb.leaderboard.TimeWindowScanComparisons) IndexScanComparisons(com.apple.foundationdb.record.provider.foundationdb.IndexScanComparisons) RankComparisons(com.apple.foundationdb.record.query.plan.planning.RankComparisons) Comparisons(com.apple.foundationdb.record.query.expressions.Comparisons) Nullable(javax.annotation.Nullable)

Example 20 with FieldKeyExpression

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

the class RecordQueryPlanner method planOneOfThemWithComponent.

@Nullable
private ScoredPlan planOneOfThemWithComponent(@Nonnull CandidateScan candidateScan, @Nonnull KeyExpression indexExpr, @Nonnull OneOfThemWithComponent filter, @Nullable KeyExpression sort) {
    if (indexExpr instanceof FieldKeyExpression) {
        return null;
    } else if (indexExpr instanceof ThenKeyExpression) {
        ThenKeyExpression then = (ThenKeyExpression) indexExpr;
        return planOneOfThemWithComponent(candidateScan, then.getChildren().get(0), filter, sort);
    } else if (indexExpr instanceof NestingKeyExpression) {
        NestingKeyExpression indexNesting = (NestingKeyExpression) indexExpr;
        ScoredPlan plan = null;
        if (sort == null) {
            plan = planNesting(candidateScan, indexNesting, filter, null);
        } else if (sort instanceof FieldKeyExpression) {
            plan = null;
        } else if (sort instanceof ThenKeyExpression) {
            plan = null;
        } else if (sort instanceof NestingKeyExpression) {
            NestingKeyExpression sortNesting = (NestingKeyExpression) sort;
            plan = planNesting(candidateScan, indexNesting, filter, sortNesting);
        }
        if (plan != null) {
            List<QueryComponent> unsatisfied;
            if (!plan.unsatisfiedFilters.isEmpty()) {
                unsatisfied = Collections.singletonList(filter);
            } else {
                unsatisfied = Collections.emptyList();
            }
            // Right now it marks the whole nesting as unsatisfied, in theory there could be plans that handle that
            plan = new ScoredPlan(plan.score, plan.plan, unsatisfied, true);
        }
        return plan;
    }
    return null;
}
Also used : ThenKeyExpression(com.apple.foundationdb.record.metadata.expressions.ThenKeyExpression) QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) FieldKeyExpression(com.apple.foundationdb.record.metadata.expressions.FieldKeyExpression) NestingKeyExpression(com.apple.foundationdb.record.metadata.expressions.NestingKeyExpression) Nullable(javax.annotation.Nullable)

Aggregations

FieldKeyExpression (com.apple.foundationdb.record.metadata.expressions.FieldKeyExpression)24 KeyExpression (com.apple.foundationdb.record.metadata.expressions.KeyExpression)17 ThenKeyExpression (com.apple.foundationdb.record.metadata.expressions.ThenKeyExpression)16 Nullable (javax.annotation.Nullable)15 Nonnull (javax.annotation.Nonnull)14 RecordCoreException (com.apple.foundationdb.record.RecordCoreException)13 ArrayList (java.util.ArrayList)13 EmptyKeyExpression (com.apple.foundationdb.record.metadata.expressions.EmptyKeyExpression)12 List (java.util.List)12 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)12 Collections (java.util.Collections)11 Collectors (java.util.stream.Collectors)11 FunctionNames (com.apple.foundationdb.record.FunctionNames)10 RecordMetaData (com.apple.foundationdb.record.RecordMetaData)10 FDBError (com.apple.foundationdb.FDBError)9 FDBException (com.apple.foundationdb.FDBException)9 Range (com.apple.foundationdb.Range)9 AsyncUtil (com.apple.foundationdb.async.AsyncUtil)9 CloseableAsyncIterator (com.apple.foundationdb.async.CloseableAsyncIterator)9 EvaluationContext (com.apple.foundationdb.record.EvaluationContext)9