Search in sources :

Example 36 with IndexAggregateFunction

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

the class FDBRestrictedIndexQueryTest method queryAggregateWithWriteOnly.

/**
 * Verify that write-only aggregate indexes are not used by the planner.
 * Verify that re-allowing reads to those indexes allows the planner to use them.
 * TODO: Abstract out common code in queryWithWriteOnly, queryWithDisabled, queryAggregateWithWriteOnly and queryAggregateWithDisabled (https://github.com/FoundationDB/fdb-record-layer/issues/4)
 */
@Test
void queryAggregateWithWriteOnly() throws Exception {
    Index sumIndex = new Index("value3sum", field("num_value_3_indexed").ungrouped(), IndexTypes.SUM);
    Index maxIndex = new Index("value3max", field("num_value_3_indexed").ungrouped(), IndexTypes.MAX_EVER_TUPLE);
    RecordMetaDataHook hook = metaData -> {
        metaData.addIndex("MySimpleRecord", sumIndex);
        metaData.addIndex("MySimpleRecord", maxIndex);
    };
    try (FDBRecordContext context = openContext()) {
        openSimpleRecordStore(context, hook);
        recordStore.deleteAllRecords();
        recordStore.clearAndMarkIndexWriteOnly("value3sum").join();
        recordStore.clearAndMarkIndexWriteOnly("value3max").join();
        RangeSet rangeSet = new RangeSet(recordStore.indexRangeSubspace(sumIndex));
        rangeSet.insertRange(context.ensureActive(), Tuple.from(1000).pack(), Tuple.from(1500).pack(), true).get();
        saveSimpleRecord(1066, 42);
        saveSimpleRecord(1776, 100);
        assertThrowsAggregateFunctionNotSupported(() -> recordStore.evaluateAggregateFunction(Collections.singletonList("MySimpleRecord"), new IndexAggregateFunction(FunctionNames.SUM, sumIndex.getRootExpression(), sumIndex.getName()), TupleRange.ALL, IsolationLevel.SERIALIZABLE).get(), "value3sum.sum(Field { 'num_value_3_indexed' None} group 1)");
        assertThrowsAggregateFunctionNotSupported(() -> recordStore.evaluateAggregateFunction(Collections.singletonList("MySimpleRecord"), new IndexAggregateFunction(FunctionNames.MAX_EVER, maxIndex.getRootExpression(), maxIndex.getName()), TupleRange.ALL, IsolationLevel.SERIALIZABLE).get(), "value3max.max_ever(Field { 'num_value_3_indexed' None} group 1)");
        commit(context);
    }
    try (FDBRecordContext context = openContext()) {
        openSimpleRecordStore(context, hook);
        recordStore.uncheckedMarkIndexReadable("value3sum").join();
        recordStore.uncheckedMarkIndexReadable("value3max").join();
        // Unsafe: made readable without building indexes, which is why sum gets wrong answer.
        assertEquals(42L, recordStore.evaluateAggregateFunction(Collections.singletonList("MySimpleRecord"), new IndexAggregateFunction(FunctionNames.SUM, sumIndex.getRootExpression(), sumIndex.getName()), TupleRange.ALL, IsolationLevel.SERIALIZABLE).get().getLong(0));
        assertEquals(100L, recordStore.evaluateAggregateFunction(Collections.singletonList("MySimpleRecord"), new IndexAggregateFunction(FunctionNames.MAX_EVER, maxIndex.getRootExpression(), maxIndex.getName()), TupleRange.ALL, IsolationLevel.SERIALIZABLE).get().getLong(0));
        recordStore.rebuildAllIndexes().get();
        assertEquals(142L, recordStore.evaluateAggregateFunction(Collections.singletonList("MySimpleRecord"), new IndexAggregateFunction(FunctionNames.SUM, sumIndex.getRootExpression(), sumIndex.getName()), TupleRange.ALL, IsolationLevel.SERIALIZABLE).get().getLong(0));
        assertEquals(100L, recordStore.evaluateAggregateFunction(Collections.singletonList("MySimpleRecord"), new IndexAggregateFunction(FunctionNames.MAX_EVER, maxIndex.getRootExpression(), maxIndex.getName()), TupleRange.ALL, IsolationLevel.SERIALIZABLE).get().getLong(0));
    }
}
Also used : LogMessageKeys(com.apple.foundationdb.record.logging.LogMessageKeys) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) PlanMatchers.bounds(com.apple.foundationdb.record.query.plan.match.PlanMatchers.bounds) RecordQueryPlanner(com.apple.foundationdb.record.query.plan.RecordQueryPlanner) Tuple(com.apple.foundationdb.tuple.Tuple) TestHelpers(com.apple.foundationdb.record.TestHelpers) Assertions.assertFalse(org.junit.jupiter.api.Assertions.assertFalse) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) GroupingKeyExpression(com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression) Tag(org.junit.jupiter.api.Tag) Query(com.apple.foundationdb.record.query.expressions.Query) TestRecords1Proto(com.apple.foundationdb.record.TestRecords1Proto) IndexOptions(com.apple.foundationdb.record.metadata.IndexOptions) Predicate(java.util.function.Predicate) Matchers.allOf(org.hamcrest.Matchers.allOf) IndexQueryabilityFilter(com.apple.foundationdb.record.query.IndexQueryabilityFilter) TupleRange(com.apple.foundationdb.record.TupleRange) Test(org.junit.jupiter.api.Test) Objects(java.util.Objects) PlanMatchers.hasTupleString(com.apple.foundationdb.record.query.plan.match.PlanMatchers.hasTupleString) List(java.util.List) PlanMatchers.indexName(com.apple.foundationdb.record.query.plan.match.PlanMatchers.indexName) RecordStoreState(com.apple.foundationdb.record.RecordStoreState) FDBQueriedRecord(com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord) PlanMatchers.hasNoDescendant(com.apple.foundationdb.record.query.plan.match.PlanMatchers.hasNoDescendant) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) AggregateFunctionNotSupportedException(com.apple.foundationdb.record.AggregateFunctionNotSupportedException) IndexTypes(com.apple.foundationdb.record.metadata.IndexTypes) Matchers.containsString(org.hamcrest.Matchers.containsString) Assertions.assertThrows(org.junit.jupiter.api.Assertions.assertThrows) FunctionNames(com.apple.foundationdb.record.FunctionNames) IndexAggregateFunction(com.apple.foundationdb.record.metadata.IndexAggregateFunction) PlanMatchers.indexScan(com.apple.foundationdb.record.query.plan.match.PlanMatchers.indexScan) Assertions.assertNull(org.junit.jupiter.api.Assertions.assertNull) CompletableFuture(java.util.concurrent.CompletableFuture) RecordQuery(com.apple.foundationdb.record.query.RecordQuery) RangeSet(com.apple.foundationdb.async.RangeSet) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) Function(java.util.function.Function) PlanHashable(com.apple.foundationdb.record.PlanHashable) Key(com.apple.foundationdb.record.metadata.Key) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) Nonnull(javax.annotation.Nonnull) Expressions.field(com.apple.foundationdb.record.metadata.Key.Expressions.field) EmptyKeyExpression(com.apple.foundationdb.record.metadata.expressions.EmptyKeyExpression) IsolationLevel(com.apple.foundationdb.record.IsolationLevel) Tags(com.apple.test.Tags) Index(com.apple.foundationdb.record.metadata.Index) Executable(org.junit.jupiter.api.function.Executable) Message(com.google.protobuf.Message) RecordCursor(com.apple.foundationdb.record.RecordCursor) PlanMatchers.descendant(com.apple.foundationdb.record.query.plan.match.PlanMatchers.descendant) Collections(java.util.Collections) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) RangeSet(com.apple.foundationdb.async.RangeSet) Index(com.apple.foundationdb.record.metadata.Index) IndexAggregateFunction(com.apple.foundationdb.record.metadata.IndexAggregateFunction) Test(org.junit.jupiter.api.Test)

Example 37 with IndexAggregateFunction

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

the class FDBRestrictedIndexQueryTest method queryAggregateWithFilteredIndex.

/**
 * Verify that disabled aggregate indexes are not used by the planner.
 * Verify that re-enabling those indexes allows the planner to use them.
 * TODO: Abstract out common code in queryWithWriteOnly, queryWithDisabled, queryAggregateWithWriteOnly and queryAggregateWithDisabled (https://github.com/FoundationDB/fdb-record-layer/issues/4)
 */
@Test
void queryAggregateWithFilteredIndex() throws Exception {
    Index sumIndex = new Index("value3sum", field("num_value_3_indexed").ungrouped(), IndexTypes.SUM);
    Index maxIndex = new Index("value3max", field("num_value_3_indexed").ungrouped(), IndexTypes.MAX_EVER_TUPLE);
    RecordMetaDataHook hook = metaData -> {
        metaData.addIndex("MySimpleRecord", sumIndex);
        metaData.addIndex("MySimpleRecord", maxIndex);
    };
    try (FDBRecordContext context = openContext()) {
        // test filtered
        openSimpleRecordStore(context, hook);
        recordStore.deleteAllRecords();
        saveSimpleRecord(1066, 42);
        saveSimpleRecord(1776, 100);
        assertThrowsAggregateFunctionNotSupported(() -> recordStore.evaluateAggregateFunction(Collections.singletonList("MySimpleRecord"), new IndexAggregateFunction(FunctionNames.SUM, sumIndex.getRootExpression(), null), TupleRange.ALL, IsolationLevel.SERIALIZABLE, IndexQueryabilityFilter.FALSE).get(), "sum(Field { 'num_value_3_indexed' None} group 1)");
        assertThrowsAggregateFunctionNotSupported(() -> recordStore.evaluateAggregateFunction(Collections.singletonList("MySimpleRecord"), new IndexAggregateFunction(FunctionNames.MAX_EVER, maxIndex.getRootExpression(), null), TupleRange.ALL, IsolationLevel.SERIALIZABLE, IndexQueryabilityFilter.FALSE).get(), "max_ever(Field { 'num_value_3_indexed' None} group 1)");
        commit(context);
    }
    try (FDBRecordContext context = openContext()) {
        // test unfiltered
        openSimpleRecordStore(context, hook);
        assertEquals(142L, recordStore.evaluateAggregateFunction(Collections.singletonList("MySimpleRecord"), new IndexAggregateFunction(FunctionNames.SUM, sumIndex.getRootExpression(), null), TupleRange.ALL, IsolationLevel.SERIALIZABLE).get().getLong(0));
        assertEquals(100L, recordStore.evaluateAggregateFunction(Collections.singletonList("MySimpleRecord"), new IndexAggregateFunction(FunctionNames.MAX_EVER, maxIndex.getRootExpression(), null), TupleRange.ALL, IsolationLevel.SERIALIZABLE).get().getLong(0));
        assertEquals(142L, recordStore.evaluateAggregateFunction(Collections.singletonList("MySimpleRecord"), new IndexAggregateFunction(FunctionNames.SUM, sumIndex.getRootExpression(), null), TupleRange.ALL, IsolationLevel.SERIALIZABLE, IndexQueryabilityFilter.TRUE).get().getLong(0));
        assertEquals(100L, recordStore.evaluateAggregateFunction(Collections.singletonList("MySimpleRecord"), new IndexAggregateFunction(FunctionNames.MAX_EVER, maxIndex.getRootExpression(), null), TupleRange.ALL, IsolationLevel.SERIALIZABLE, IndexQueryabilityFilter.TRUE).get().getLong(0));
    }
}
Also used : LogMessageKeys(com.apple.foundationdb.record.logging.LogMessageKeys) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) PlanMatchers.bounds(com.apple.foundationdb.record.query.plan.match.PlanMatchers.bounds) RecordQueryPlanner(com.apple.foundationdb.record.query.plan.RecordQueryPlanner) Tuple(com.apple.foundationdb.tuple.Tuple) TestHelpers(com.apple.foundationdb.record.TestHelpers) Assertions.assertFalse(org.junit.jupiter.api.Assertions.assertFalse) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) GroupingKeyExpression(com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression) Tag(org.junit.jupiter.api.Tag) Query(com.apple.foundationdb.record.query.expressions.Query) TestRecords1Proto(com.apple.foundationdb.record.TestRecords1Proto) IndexOptions(com.apple.foundationdb.record.metadata.IndexOptions) Predicate(java.util.function.Predicate) Matchers.allOf(org.hamcrest.Matchers.allOf) IndexQueryabilityFilter(com.apple.foundationdb.record.query.IndexQueryabilityFilter) TupleRange(com.apple.foundationdb.record.TupleRange) Test(org.junit.jupiter.api.Test) Objects(java.util.Objects) PlanMatchers.hasTupleString(com.apple.foundationdb.record.query.plan.match.PlanMatchers.hasTupleString) List(java.util.List) PlanMatchers.indexName(com.apple.foundationdb.record.query.plan.match.PlanMatchers.indexName) RecordStoreState(com.apple.foundationdb.record.RecordStoreState) FDBQueriedRecord(com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord) PlanMatchers.hasNoDescendant(com.apple.foundationdb.record.query.plan.match.PlanMatchers.hasNoDescendant) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) AggregateFunctionNotSupportedException(com.apple.foundationdb.record.AggregateFunctionNotSupportedException) IndexTypes(com.apple.foundationdb.record.metadata.IndexTypes) Matchers.containsString(org.hamcrest.Matchers.containsString) Assertions.assertThrows(org.junit.jupiter.api.Assertions.assertThrows) FunctionNames(com.apple.foundationdb.record.FunctionNames) IndexAggregateFunction(com.apple.foundationdb.record.metadata.IndexAggregateFunction) PlanMatchers.indexScan(com.apple.foundationdb.record.query.plan.match.PlanMatchers.indexScan) Assertions.assertNull(org.junit.jupiter.api.Assertions.assertNull) CompletableFuture(java.util.concurrent.CompletableFuture) RecordQuery(com.apple.foundationdb.record.query.RecordQuery) RangeSet(com.apple.foundationdb.async.RangeSet) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) Function(java.util.function.Function) PlanHashable(com.apple.foundationdb.record.PlanHashable) Key(com.apple.foundationdb.record.metadata.Key) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) Nonnull(javax.annotation.Nonnull) Expressions.field(com.apple.foundationdb.record.metadata.Key.Expressions.field) EmptyKeyExpression(com.apple.foundationdb.record.metadata.expressions.EmptyKeyExpression) IsolationLevel(com.apple.foundationdb.record.IsolationLevel) Tags(com.apple.test.Tags) Index(com.apple.foundationdb.record.metadata.Index) Executable(org.junit.jupiter.api.function.Executable) Message(com.google.protobuf.Message) RecordCursor(com.apple.foundationdb.record.RecordCursor) PlanMatchers.descendant(com.apple.foundationdb.record.query.plan.match.PlanMatchers.descendant) Collections(java.util.Collections) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) Index(com.apple.foundationdb.record.metadata.Index) IndexAggregateFunction(com.apple.foundationdb.record.metadata.IndexAggregateFunction) Test(org.junit.jupiter.api.Test)

Example 38 with IndexAggregateFunction

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

the class FDBRecordStore method getSnapshotRecordCountForRecordType.

@Override
public CompletableFuture<Long> getSnapshotRecordCountForRecordType(@Nonnull String recordTypeName, @Nonnull IndexQueryabilityFilter indexQueryabilityFilter) {
    // A COUNT index on this record type.
    IndexAggregateFunction aggregateFunction = IndexFunctionHelper.count(EmptyKeyExpression.EMPTY);
    Optional<IndexMaintainer> indexMaintainer = IndexFunctionHelper.indexMaintainerForAggregateFunction(this, aggregateFunction, Collections.singletonList(recordTypeName), indexQueryabilityFilter);
    if (indexMaintainer.isPresent()) {
        return indexMaintainer.get().evaluateAggregateFunction(aggregateFunction, TupleRange.ALL, IsolationLevel.SNAPSHOT).thenApply(tuple -> tuple.getLong(0));
    }
    // A universal COUNT index by record type.
    // In fact, any COUNT index by record type that applied to this record type would work, no matter what other
    // types it applied to.
    aggregateFunction = IndexFunctionHelper.count(Key.Expressions.recordType());
    indexMaintainer = IndexFunctionHelper.indexMaintainerForAggregateFunction(this, aggregateFunction, Collections.emptyList(), indexQueryabilityFilter);
    if (indexMaintainer.isPresent()) {
        RecordType recordType = getRecordMetaData().getRecordType(recordTypeName);
        return indexMaintainer.get().evaluateAggregateFunction(aggregateFunction, TupleRange.allOf(recordType.getRecordTypeKeyTuple()), IsolationLevel.SNAPSHOT).thenApply(tuple -> tuple.getLong(0));
    }
    throw recordCoreException("Require a COUNT index on " + recordTypeName);
}
Also used : SyntheticRecordType(com.apple.foundationdb.record.metadata.SyntheticRecordType) RecordType(com.apple.foundationdb.record.metadata.RecordType) IndexAggregateFunction(com.apple.foundationdb.record.metadata.IndexAggregateFunction)

Example 39 with IndexAggregateFunction

use of com.apple.foundationdb.record.metadata.IndexAggregateFunction in project lionrock by panghy.

the class RemoteRecordLayerTests method testRichIndex_getNumberOfCustomersWhoHaveBooksListedAsPreferenceTags.

@Test
public void testRichIndex_getNumberOfCustomersWhoHaveBooksListedAsPreferenceTags() {
    Long bookPreferenceCount = fdb.runAsync((FDBRecordContext cx) -> recordStoreBuilder.copyBuilder().setContext(cx).openAsync().thenCompose(store -> {
        Index index = store.getRecordMetaData().getIndex("preference_tag_count");
        IndexAggregateFunction function = new IndexAggregateFunction(FunctionNames.COUNT, index.getRootExpression(), index.getName());
        return store.evaluateAggregateFunction(Collections.singletonList("Customer"), function, Key.Evaluated.scalar("books"), IsolationLevel.SERIALIZABLE).thenApply(tuple -> tuple.getLong(0));
    })).join();
    assertEquals(2, bookPreferenceCount);
}
Also used : Index(com.apple.foundationdb.record.metadata.Index) IndexAggregateFunction(com.apple.foundationdb.record.metadata.IndexAggregateFunction) Test(org.junit.jupiter.api.Test) AbstractGrpcTest(io.github.panghy.lionrock.foundationdb.AbstractGrpcTest)

Aggregations

IndexAggregateFunction (com.apple.foundationdb.record.metadata.IndexAggregateFunction)39 Test (org.junit.jupiter.api.Test)35 Index (com.apple.foundationdb.record.metadata.Index)33 List (java.util.List)30 TupleRange (com.apple.foundationdb.record.TupleRange)29 IndexTypes (com.apple.foundationdb.record.metadata.IndexTypes)29 FunctionNames (com.apple.foundationdb.record.FunctionNames)28 IsolationLevel (com.apple.foundationdb.record.IsolationLevel)28 Expressions.field (com.apple.foundationdb.record.metadata.Key.Expressions.field)28 Tuple (com.apple.foundationdb.tuple.Tuple)28 Assertions.assertEquals (org.junit.jupiter.api.Assertions.assertEquals)28 Collections (java.util.Collections)27 Nonnull (javax.annotation.Nonnull)27 RecordCoreException (com.apple.foundationdb.record.RecordCoreException)25 LogMessageKeys (com.apple.foundationdb.record.logging.LogMessageKeys)25 Key (com.apple.foundationdb.record.metadata.Key)25 MatcherAssert.assertThat (org.hamcrest.MatcherAssert.assertThat)25 Assertions.assertThrows (org.junit.jupiter.api.Assertions.assertThrows)25 TestRecords1Proto (com.apple.foundationdb.record.TestRecords1Proto)24 CompletableFuture (java.util.concurrent.CompletableFuture)24