Search in sources :

Example 31 with FDBRecordContext

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

the class FDBCoveringIndexQueryTest method coveringWithHeader.

/**
 * Verify that an index can be covering if the required fields are in the primary key.
 */
@DualPlannerTest
void coveringWithHeader() throws Exception {
    RecordMetaDataHook hook = metaData -> {
        metaData.getRecordType("MyRecord").setPrimaryKey(field("header").nest(concatenateFields("path", "rec_no")));
        metaData.addIndex("MyRecord", "str_value");
    };
    try (FDBRecordContext context = openContext()) {
        openRecordWithHeader(context, hook);
        saveHeaderRecord(1, "a", 0, "lynx");
        saveHeaderRecord(2, "a", 1, "bobcat");
        saveHeaderRecord(3, "a", 2, "panther");
        saveHeaderRecord(1, "b", 3, "jaguar");
        saveHeaderRecord(2, "b", 4, "leopard");
        saveHeaderRecord(3, "b", 5, "lion");
        saveHeaderRecord(4, "b", 6, "tiger");
        context.commit();
    }
    RecordQuery query = RecordQuery.newBuilder().setRecordType("MyRecord").setFilter(Query.field("str_value").equalsValue("lion")).setRequiredResults(Collections.singletonList(field("header").nest("rec_no"))).build();
    // Covering(Index(MyRecord$str_value [[lion],[lion]]) -> [str_value: KEY[0], header: [path: KEY[1], rec_no: KEY[2]]])
    RecordQueryPlan plan = planner.plan(query);
    BindingMatcher<? extends RecordQueryPlan> planMatcher = coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("MyRecord$str_value")).and(scanComparisons(range("[[lion],[lion]]")))));
    assertMatchesExactly(plan, planMatcher);
    assertEquals(-629018945, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
    assertEquals(177826375, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
    assertEquals(344218219, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
    try (FDBRecordContext context = openContext()) {
        openRecordWithHeader(context, hook);
        try (RecordCursorIterator<FDBQueriedRecord<Message>> cursor = recordStore.executeQuery(plan).asIterator()) {
            while (cursor.hasNext()) {
                FDBQueriedRecord<Message> rec = cursor.next();
                TestRecordsWithHeaderProto.MyRecord.Builder myrec = TestRecordsWithHeaderProto.MyRecord.newBuilder();
                myrec.mergeFrom(Objects.requireNonNull(rec).getRecord());
                assertEquals(3, myrec.getHeader().getRecNo());
            }
        }
        context.commit();
        assertDiscardedNone(context);
    }
    query = RecordQuery.newBuilder().setRecordType("MyRecord").setFilter(Query.field("str_value").startsWith("l")).setRequiredResults(Arrays.asList(field("header").nest(concatenateFields("path", "rec_no")), field("str_value"))).build();
    // Covering(Index(MyRecord$str_value {[l],[l]}) -> [str_value: KEY[0], header: [path: KEY[1], rec_no: KEY[2]]])
    plan = planner.plan(query);
    planMatcher = coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("MyRecord$str_value")).and(scanComparisons(range("{[l],[l]}")))));
    assertMatchesExactly(plan, planMatcher);
    assertEquals(-1471907004, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
    assertEquals(-1581115138, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
    assertEquals(1123663700, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
    try (FDBRecordContext context = openContext()) {
        openRecordWithHeader(context, hook);
        List<Pair<String, Long>> results = new ArrayList<>();
        try (RecordCursorIterator<FDBQueriedRecord<Message>> cursor = recordStore.executeQuery(plan).asIterator()) {
            while (cursor.hasNext()) {
                FDBQueriedRecord<Message> rec = cursor.next();
                TestRecordsWithHeaderProto.MyRecord.Builder myrec = TestRecordsWithHeaderProto.MyRecord.newBuilder();
                myrec.mergeFrom(Objects.requireNonNull(rec).getRecord());
                assertThat(myrec.getStrValue(), startsWith("l"));
                assertThat(myrec.getHeader().hasPath(), is(true));
                assertThat(myrec.getHeader().hasRecNo(), is(true));
                results.add(Pair.of(myrec.getHeader().getPath(), myrec.getHeader().getRecNo()));
            }
        }
        assertEquals(Arrays.asList(Pair.of("b", 2L), Pair.of("b", 3L), Pair.of("a", 1L)), results);
        context.commit();
        assertDiscardedNone(context);
    }
}
Also used : RecordQueryPlanMatchers.coveringIndexPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.coveringIndexPlan) Arrays(java.util.Arrays) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) RecordQueryPlanMatchers.predicates(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.predicates) Disabled(org.junit.jupiter.api.Disabled) RecordQueryPlanner(com.apple.foundationdb.record.query.plan.RecordQueryPlanner) TestHelpers.assertDiscardedNone(com.apple.foundationdb.record.TestHelpers.assertDiscardedNone) RecordQueryPlanMatchers.fetchFromPartialRecordPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.fetchFromPartialRecordPlan) Pair(org.apache.commons.lang3.tuple.Pair) ListMatcher.only(com.apple.foundationdb.record.query.plan.temp.matchers.ListMatcher.only) Assertions.assertFalse(org.junit.jupiter.api.Assertions.assertFalse) Expressions.concatenateFields(com.apple.foundationdb.record.metadata.Key.Expressions.concatenateFields) RecordQueryPlanMatchers.indexName(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.indexName) Expressions.concat(com.apple.foundationdb.record.metadata.Key.Expressions.concat) Tag(org.junit.jupiter.api.Tag) Query(com.apple.foundationdb.record.query.expressions.Query) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) ImmutableSet(com.google.common.collect.ImmutableSet) TestRecords1Proto(com.apple.foundationdb.record.TestRecords1Proto) IndexOptions(com.apple.foundationdb.record.metadata.IndexOptions) Expressions.keyWithValue(com.apple.foundationdb.record.metadata.Key.Expressions.keyWithValue) Matchers.startsWith(org.hamcrest.Matchers.startsWith) Test(org.junit.jupiter.api.Test) Objects(java.util.Objects) List(java.util.List) ScanComparisons.range(com.apple.foundationdb.record.query.plan.ScanComparisons.range) FDBQueriedRecord(com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) IndexTypes(com.apple.foundationdb.record.metadata.IndexTypes) TestRecordsWithHeaderProto(com.apple.foundationdb.record.TestRecordsWithHeaderProto) Matchers.greaterThan(org.hamcrest.Matchers.greaterThan) Matchers.is(org.hamcrest.Matchers.is) RecordQueryPlanMatchers.predicatesFilterPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.predicatesFilterPlan) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) RecordQueryPlanMatchers.indexPlanOf(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.indexPlanOf) RecordQuery(com.apple.foundationdb.record.query.RecordQuery) PrimitiveMatchers.equalsObject(com.apple.foundationdb.record.query.plan.temp.matchers.PrimitiveMatchers.equalsObject) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) PlanHashable(com.apple.foundationdb.record.PlanHashable) ArrayList(java.util.ArrayList) Key(com.apple.foundationdb.record.metadata.Key) PlannerRuleSet(com.apple.foundationdb.record.query.plan.temp.PlannerRuleSet) ImmutableList(com.google.common.collect.ImmutableList) RecordCursorIterator(com.apple.foundationdb.record.RecordCursorIterator) Matchers.lessThan(org.hamcrest.Matchers.lessThan) RecordQueryPlanMatchers.scanComparisons(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.scanComparisons) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) Expressions.field(com.apple.foundationdb.record.metadata.Key.Expressions.field) ScanComparisons.unbounded(com.apple.foundationdb.record.query.plan.ScanComparisons.unbounded) RecordMetaDataBuilder(com.apple.foundationdb.record.RecordMetaDataBuilder) Tags(com.apple.test.Tags) QueryPredicateMatchers.valuePredicate(com.apple.foundationdb.record.query.plan.temp.matchers.QueryPredicateMatchers.valuePredicate) RecordQueryPlanMatchers.queryComponents(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.queryComponents) Comparisons(com.apple.foundationdb.record.query.expressions.Comparisons) RecordQueryPlanMatchers.filterPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.filterPlan) BindingMatcher(com.apple.foundationdb.record.query.plan.temp.matchers.BindingMatcher) Index(com.apple.foundationdb.record.metadata.Index) RecordQueryPlanMatchers.indexPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.indexPlan) Message(com.google.protobuf.Message) ListMatcher.exactly(com.apple.foundationdb.record.query.plan.temp.matchers.ListMatcher.exactly) Collections(java.util.Collections) ValueMatchers.fieldValue(com.apple.foundationdb.record.query.plan.temp.matchers.ValueMatchers.fieldValue) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) Message(com.google.protobuf.Message) ArrayList(java.util.ArrayList) FDBQueriedRecord(com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) RecordQuery(com.apple.foundationdb.record.query.RecordQuery) Pair(org.apache.commons.lang3.tuple.Pair)

Example 32 with FDBRecordContext

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

the class FDBCoveringIndexQueryTest method coveringMulti.

/**
 * Verify that an index can be covering if more than one field is required and they are in the key.
 */
@DualPlannerTest
void coveringMulti() throws Exception {
    RecordMetaDataHook hook = metaData -> {
        metaData.removeIndex("MySimpleRecord$num_value_unique");
        metaData.addIndex("MySimpleRecord", new Index("multi_index", "num_value_unique", "num_value_2"));
    };
    complexQuerySetup(hook);
    RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.field("num_value_unique").greaterThan(990)).setSort(field("num_value_unique")).setRequiredResults(Arrays.asList(field("num_value_unique"), field("num_value_2"))).build();
    // Covering(Index(multi_index ([990],>) -> [num_value_2: KEY[1], num_value_unique: KEY[0], rec_no: KEY[2]])
    RecordQueryPlan plan = planner.plan(query);
    final BindingMatcher<? extends RecordQueryPlan> planMatcher = coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("multi_index")).and(scanComparisons(range("([990],>")))));
    assertMatchesExactly(plan, planMatcher);
    assertEquals(291429560, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
    assertEquals(1065678, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
    assertEquals(-80338730, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
    try (FDBRecordContext context = openContext()) {
        openSimpleRecordStore(context, hook);
        int i = 0;
        try (RecordCursorIterator<FDBQueriedRecord<Message>> cursor = recordStore.executeQuery(plan).asIterator()) {
            while (cursor.hasNext()) {
                FDBQueriedRecord<Message> rec = cursor.next();
                TestRecords1Proto.MySimpleRecord.Builder myrec = TestRecords1Proto.MySimpleRecord.newBuilder();
                myrec.mergeFrom(Objects.requireNonNull(rec).getRecord());
                assertTrue(myrec.getNumValueUnique() > 990);
                assertEquals(myrec.getNumValue2(), (999 - i) % 3);
                i++;
            }
        }
        assertEquals(10, i);
        assertDiscardedNone(context);
    }
}
Also used : RecordQueryPlanMatchers.coveringIndexPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.coveringIndexPlan) Arrays(java.util.Arrays) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) RecordQueryPlanMatchers.predicates(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.predicates) Disabled(org.junit.jupiter.api.Disabled) RecordQueryPlanner(com.apple.foundationdb.record.query.plan.RecordQueryPlanner) TestHelpers.assertDiscardedNone(com.apple.foundationdb.record.TestHelpers.assertDiscardedNone) RecordQueryPlanMatchers.fetchFromPartialRecordPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.fetchFromPartialRecordPlan) Pair(org.apache.commons.lang3.tuple.Pair) ListMatcher.only(com.apple.foundationdb.record.query.plan.temp.matchers.ListMatcher.only) Assertions.assertFalse(org.junit.jupiter.api.Assertions.assertFalse) Expressions.concatenateFields(com.apple.foundationdb.record.metadata.Key.Expressions.concatenateFields) RecordQueryPlanMatchers.indexName(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.indexName) Expressions.concat(com.apple.foundationdb.record.metadata.Key.Expressions.concat) Tag(org.junit.jupiter.api.Tag) Query(com.apple.foundationdb.record.query.expressions.Query) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) ImmutableSet(com.google.common.collect.ImmutableSet) TestRecords1Proto(com.apple.foundationdb.record.TestRecords1Proto) IndexOptions(com.apple.foundationdb.record.metadata.IndexOptions) Expressions.keyWithValue(com.apple.foundationdb.record.metadata.Key.Expressions.keyWithValue) Matchers.startsWith(org.hamcrest.Matchers.startsWith) Test(org.junit.jupiter.api.Test) Objects(java.util.Objects) List(java.util.List) ScanComparisons.range(com.apple.foundationdb.record.query.plan.ScanComparisons.range) FDBQueriedRecord(com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) IndexTypes(com.apple.foundationdb.record.metadata.IndexTypes) TestRecordsWithHeaderProto(com.apple.foundationdb.record.TestRecordsWithHeaderProto) Matchers.greaterThan(org.hamcrest.Matchers.greaterThan) Matchers.is(org.hamcrest.Matchers.is) RecordQueryPlanMatchers.predicatesFilterPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.predicatesFilterPlan) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) RecordQueryPlanMatchers.indexPlanOf(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.indexPlanOf) RecordQuery(com.apple.foundationdb.record.query.RecordQuery) PrimitiveMatchers.equalsObject(com.apple.foundationdb.record.query.plan.temp.matchers.PrimitiveMatchers.equalsObject) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) PlanHashable(com.apple.foundationdb.record.PlanHashable) ArrayList(java.util.ArrayList) Key(com.apple.foundationdb.record.metadata.Key) PlannerRuleSet(com.apple.foundationdb.record.query.plan.temp.PlannerRuleSet) ImmutableList(com.google.common.collect.ImmutableList) RecordCursorIterator(com.apple.foundationdb.record.RecordCursorIterator) Matchers.lessThan(org.hamcrest.Matchers.lessThan) RecordQueryPlanMatchers.scanComparisons(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.scanComparisons) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) Expressions.field(com.apple.foundationdb.record.metadata.Key.Expressions.field) ScanComparisons.unbounded(com.apple.foundationdb.record.query.plan.ScanComparisons.unbounded) RecordMetaDataBuilder(com.apple.foundationdb.record.RecordMetaDataBuilder) Tags(com.apple.test.Tags) QueryPredicateMatchers.valuePredicate(com.apple.foundationdb.record.query.plan.temp.matchers.QueryPredicateMatchers.valuePredicate) RecordQueryPlanMatchers.queryComponents(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.queryComponents) Comparisons(com.apple.foundationdb.record.query.expressions.Comparisons) RecordQueryPlanMatchers.filterPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.filterPlan) BindingMatcher(com.apple.foundationdb.record.query.plan.temp.matchers.BindingMatcher) Index(com.apple.foundationdb.record.metadata.Index) RecordQueryPlanMatchers.indexPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.indexPlan) Message(com.google.protobuf.Message) ListMatcher.exactly(com.apple.foundationdb.record.query.plan.temp.matchers.ListMatcher.exactly) Collections(java.util.Collections) ValueMatchers.fieldValue(com.apple.foundationdb.record.query.plan.temp.matchers.ValueMatchers.fieldValue) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) Message(com.google.protobuf.Message) Index(com.apple.foundationdb.record.metadata.Index) FDBQueriedRecord(com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) RecordQuery(com.apple.foundationdb.record.query.RecordQuery)

Example 33 with FDBRecordContext

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

the class FDBCoveringIndexQueryTest method coveringWithHeaderValue.

/**
 * Verify that an index can be covering for nested fields if the field is in the value of the index.
 */
@DualPlannerTest
void coveringWithHeaderValue() throws Exception {
    RecordMetaDataHook hook = metaData -> {
        metaData.getRecordType("MyRecord").setPrimaryKey(field("header").nest(field("rec_no")));
        metaData.addIndex("MyRecord", new Index("MyRecord$str_value", field("str_value"), field("header").nest(field("path")), IndexTypes.VALUE, Collections.emptyMap()));
    };
    try (FDBRecordContext context = openContext()) {
        openRecordWithHeader(context, hook);
    }
    RecordQuery query = RecordQuery.newBuilder().setRecordType("MyRecord").setFilter(Query.field("str_value").equalsValue("lion")).setRequiredResults(Collections.singletonList(field("header").nest("path"))).build();
    // Covering(Index(MyRecord$str_value [[lion],[lion]]) -> [str_value: KEY[0], header: [path: VALUE[0], rec_no: KEY[1]]])
    RecordQueryPlan plan = planner.plan(query);
    final BindingMatcher<? extends RecordQueryPlan> planMatcher = coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("MyRecord$str_value")).and(scanComparisons(range("[[lion],[lion]]")))));
    assertMatchesExactly(plan, planMatcher);
    assertEquals(-629018945, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
    assertEquals(177826375, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
    assertEquals(344218219, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
}
Also used : RecordQueryPlanMatchers.coveringIndexPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.coveringIndexPlan) Arrays(java.util.Arrays) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) RecordQueryPlanMatchers.predicates(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.predicates) Disabled(org.junit.jupiter.api.Disabled) RecordQueryPlanner(com.apple.foundationdb.record.query.plan.RecordQueryPlanner) TestHelpers.assertDiscardedNone(com.apple.foundationdb.record.TestHelpers.assertDiscardedNone) RecordQueryPlanMatchers.fetchFromPartialRecordPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.fetchFromPartialRecordPlan) Pair(org.apache.commons.lang3.tuple.Pair) ListMatcher.only(com.apple.foundationdb.record.query.plan.temp.matchers.ListMatcher.only) Assertions.assertFalse(org.junit.jupiter.api.Assertions.assertFalse) Expressions.concatenateFields(com.apple.foundationdb.record.metadata.Key.Expressions.concatenateFields) RecordQueryPlanMatchers.indexName(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.indexName) Expressions.concat(com.apple.foundationdb.record.metadata.Key.Expressions.concat) Tag(org.junit.jupiter.api.Tag) Query(com.apple.foundationdb.record.query.expressions.Query) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) ImmutableSet(com.google.common.collect.ImmutableSet) TestRecords1Proto(com.apple.foundationdb.record.TestRecords1Proto) IndexOptions(com.apple.foundationdb.record.metadata.IndexOptions) Expressions.keyWithValue(com.apple.foundationdb.record.metadata.Key.Expressions.keyWithValue) Matchers.startsWith(org.hamcrest.Matchers.startsWith) Test(org.junit.jupiter.api.Test) Objects(java.util.Objects) List(java.util.List) ScanComparisons.range(com.apple.foundationdb.record.query.plan.ScanComparisons.range) FDBQueriedRecord(com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) IndexTypes(com.apple.foundationdb.record.metadata.IndexTypes) TestRecordsWithHeaderProto(com.apple.foundationdb.record.TestRecordsWithHeaderProto) Matchers.greaterThan(org.hamcrest.Matchers.greaterThan) Matchers.is(org.hamcrest.Matchers.is) RecordQueryPlanMatchers.predicatesFilterPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.predicatesFilterPlan) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) RecordQueryPlanMatchers.indexPlanOf(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.indexPlanOf) RecordQuery(com.apple.foundationdb.record.query.RecordQuery) PrimitiveMatchers.equalsObject(com.apple.foundationdb.record.query.plan.temp.matchers.PrimitiveMatchers.equalsObject) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) PlanHashable(com.apple.foundationdb.record.PlanHashable) ArrayList(java.util.ArrayList) Key(com.apple.foundationdb.record.metadata.Key) PlannerRuleSet(com.apple.foundationdb.record.query.plan.temp.PlannerRuleSet) ImmutableList(com.google.common.collect.ImmutableList) RecordCursorIterator(com.apple.foundationdb.record.RecordCursorIterator) Matchers.lessThan(org.hamcrest.Matchers.lessThan) RecordQueryPlanMatchers.scanComparisons(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.scanComparisons) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) Expressions.field(com.apple.foundationdb.record.metadata.Key.Expressions.field) ScanComparisons.unbounded(com.apple.foundationdb.record.query.plan.ScanComparisons.unbounded) RecordMetaDataBuilder(com.apple.foundationdb.record.RecordMetaDataBuilder) Tags(com.apple.test.Tags) QueryPredicateMatchers.valuePredicate(com.apple.foundationdb.record.query.plan.temp.matchers.QueryPredicateMatchers.valuePredicate) RecordQueryPlanMatchers.queryComponents(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.queryComponents) Comparisons(com.apple.foundationdb.record.query.expressions.Comparisons) RecordQueryPlanMatchers.filterPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.filterPlan) BindingMatcher(com.apple.foundationdb.record.query.plan.temp.matchers.BindingMatcher) Index(com.apple.foundationdb.record.metadata.Index) RecordQueryPlanMatchers.indexPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.indexPlan) Message(com.google.protobuf.Message) ListMatcher.exactly(com.apple.foundationdb.record.query.plan.temp.matchers.ListMatcher.exactly) Collections(java.util.Collections) ValueMatchers.fieldValue(com.apple.foundationdb.record.query.plan.temp.matchers.ValueMatchers.fieldValue) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) Index(com.apple.foundationdb.record.metadata.Index) RecordQuery(com.apple.foundationdb.record.query.RecordQuery)

Example 34 with FDBRecordContext

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

the class FDBCoveringIndexQueryTest method coveringWithHeaderConcatenatedValue.

/**
 * Verify that an index can be covering for concatenated nested fields in the value of the index.
 */
@DualPlannerTest
void coveringWithHeaderConcatenatedValue() throws Exception {
    RecordMetaDataHook hook = metaData -> {
        metaData.getRecordType("MyRecord").setPrimaryKey(field("header").nest(field("rec_no")));
        metaData.addIndex("MyRecord", new Index("MyRecord$str_value", field("str_value"), field("header").nest(concatenateFields("path", "num")), IndexTypes.VALUE, Collections.emptyMap()));
    };
    try (FDBRecordContext context = openContext()) {
        openRecordWithHeader(context, hook);
    }
    RecordQuery query = RecordQuery.newBuilder().setRecordType("MyRecord").setFilter(Query.field("str_value").equalsValue("leopard")).setRequiredResults(Collections.singletonList(field("header").nest(concatenateFields("num", "path")))).build();
    // Covering(Index(MyRecord$str_value [[leopard],[leopard]]) -> [str_value: KEY[0], header: [num: VALUE[1], path: VALUE[0], rec_no: KEY[1]]])
    RecordQueryPlan plan = planner.plan(query);
    final BindingMatcher<? extends RecordQueryPlan> planMatcher = coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("MyRecord$str_value")).and(scanComparisons(range("[[leopard],[leopard]]")))));
    assertMatchesExactly(plan, planMatcher);
    assertEquals(-568702564, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
    assertEquals(1766803018, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
    assertEquals(344218219, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
}
Also used : RecordQueryPlanMatchers.coveringIndexPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.coveringIndexPlan) Arrays(java.util.Arrays) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) RecordQueryPlanMatchers.predicates(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.predicates) Disabled(org.junit.jupiter.api.Disabled) RecordQueryPlanner(com.apple.foundationdb.record.query.plan.RecordQueryPlanner) TestHelpers.assertDiscardedNone(com.apple.foundationdb.record.TestHelpers.assertDiscardedNone) RecordQueryPlanMatchers.fetchFromPartialRecordPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.fetchFromPartialRecordPlan) Pair(org.apache.commons.lang3.tuple.Pair) ListMatcher.only(com.apple.foundationdb.record.query.plan.temp.matchers.ListMatcher.only) Assertions.assertFalse(org.junit.jupiter.api.Assertions.assertFalse) Expressions.concatenateFields(com.apple.foundationdb.record.metadata.Key.Expressions.concatenateFields) RecordQueryPlanMatchers.indexName(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.indexName) Expressions.concat(com.apple.foundationdb.record.metadata.Key.Expressions.concat) Tag(org.junit.jupiter.api.Tag) Query(com.apple.foundationdb.record.query.expressions.Query) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) ImmutableSet(com.google.common.collect.ImmutableSet) TestRecords1Proto(com.apple.foundationdb.record.TestRecords1Proto) IndexOptions(com.apple.foundationdb.record.metadata.IndexOptions) Expressions.keyWithValue(com.apple.foundationdb.record.metadata.Key.Expressions.keyWithValue) Matchers.startsWith(org.hamcrest.Matchers.startsWith) Test(org.junit.jupiter.api.Test) Objects(java.util.Objects) List(java.util.List) ScanComparisons.range(com.apple.foundationdb.record.query.plan.ScanComparisons.range) FDBQueriedRecord(com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) IndexTypes(com.apple.foundationdb.record.metadata.IndexTypes) TestRecordsWithHeaderProto(com.apple.foundationdb.record.TestRecordsWithHeaderProto) Matchers.greaterThan(org.hamcrest.Matchers.greaterThan) Matchers.is(org.hamcrest.Matchers.is) RecordQueryPlanMatchers.predicatesFilterPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.predicatesFilterPlan) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) RecordQueryPlanMatchers.indexPlanOf(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.indexPlanOf) RecordQuery(com.apple.foundationdb.record.query.RecordQuery) PrimitiveMatchers.equalsObject(com.apple.foundationdb.record.query.plan.temp.matchers.PrimitiveMatchers.equalsObject) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) PlanHashable(com.apple.foundationdb.record.PlanHashable) ArrayList(java.util.ArrayList) Key(com.apple.foundationdb.record.metadata.Key) PlannerRuleSet(com.apple.foundationdb.record.query.plan.temp.PlannerRuleSet) ImmutableList(com.google.common.collect.ImmutableList) RecordCursorIterator(com.apple.foundationdb.record.RecordCursorIterator) Matchers.lessThan(org.hamcrest.Matchers.lessThan) RecordQueryPlanMatchers.scanComparisons(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.scanComparisons) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) Expressions.field(com.apple.foundationdb.record.metadata.Key.Expressions.field) ScanComparisons.unbounded(com.apple.foundationdb.record.query.plan.ScanComparisons.unbounded) RecordMetaDataBuilder(com.apple.foundationdb.record.RecordMetaDataBuilder) Tags(com.apple.test.Tags) QueryPredicateMatchers.valuePredicate(com.apple.foundationdb.record.query.plan.temp.matchers.QueryPredicateMatchers.valuePredicate) RecordQueryPlanMatchers.queryComponents(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.queryComponents) Comparisons(com.apple.foundationdb.record.query.expressions.Comparisons) RecordQueryPlanMatchers.filterPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.filterPlan) BindingMatcher(com.apple.foundationdb.record.query.plan.temp.matchers.BindingMatcher) Index(com.apple.foundationdb.record.metadata.Index) RecordQueryPlanMatchers.indexPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.indexPlan) Message(com.google.protobuf.Message) ListMatcher.exactly(com.apple.foundationdb.record.query.plan.temp.matchers.ListMatcher.exactly) Collections(java.util.Collections) ValueMatchers.fieldValue(com.apple.foundationdb.record.query.plan.temp.matchers.ValueMatchers.fieldValue) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) Index(com.apple.foundationdb.record.metadata.Index) RecordQuery(com.apple.foundationdb.record.query.RecordQuery)

Example 35 with FDBRecordContext

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

the class FDBCrossRecordQueryTest method testCrossRecordTypeQuery.

/**
 * Verify that sorting by a common field on a universal index returns all types of records in an index scan.
 */
@DualPlannerTest
public void testCrossRecordTypeQuery() throws Exception {
    try (FDBRecordContext context = openContext()) {
        openUnionRecordStore(context);
        saveSimpleRecord(100, "first", 1);
        saveSimpleRecord(110, "second", 2);
        saveSimpleRecord2("third", 3);
        saveSimpleRecord2("fourth", 4);
        saveSimpleRecord(80, "fifth", 5);
        saveSimpleRecord2("sixth", 6);
        saveSimpleRecord2("seventh", 7);
        saveSimpleRecord(60, "seventh", 7);
        saveSimpleRecord2("seventh again", 7);
        saveSimpleRecord3("eighth", 8);
        commit(context);
    }
    RecordQuery query = RecordQuery.newBuilder().setSort(field("etag")).build();
    // Index(versions <,>)
    RecordQueryPlan plan = planner.plan(query);
    MatcherAssert.assertThat(plan, indexScan(allOf(indexName("versions"), unbounded())));
    assertEquals(1555932709, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
    assertEquals(155792354, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
    assertEquals(155792354, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
    List<String> names = new ArrayList<>();
    List<Integer> etags = new ArrayList<>();
    try (FDBRecordContext context = openContext()) {
        openUnionRecordStore(context);
        try (RecordCursorIterator<FDBQueriedRecord<Message>> cursor = recordStore.executeQuery(plan).asIterator()) {
            while (cursor.hasNext()) {
                final Message record = cursor.next().getRecord();
                names.add((String) record.getField(record.getDescriptorForType().findFieldByName("str_value_indexed")));
                etags.add((int) record.getField(record.getDescriptorForType().findFieldByName("etag")));
            }
        }
        assertDiscardedNone(context);
    }
    assertEquals(Arrays.asList("first", "second", "third", "fourth", "fifth", "sixth"), names.subList(0, 6));
    assertThat(names.subList(6, 9), containsInAnyOrder("seventh", "seventh", "seventh again"));
    assertEquals(1555932709, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
    assertEquals(155792354, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
    assertEquals(155792354, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
    assertEquals("eighth", names.get(9));
    assertEquals(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 7, 7, 8), etags);
}
Also used : RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) FDBQueriedRecord(com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord) Message(com.google.protobuf.Message) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) ArrayList(java.util.ArrayList) PlanMatchers.hasTupleString(com.apple.foundationdb.record.query.plan.match.PlanMatchers.hasTupleString) RecordQuery(com.apple.foundationdb.record.query.RecordQuery)

Aggregations

FDBRecordContext (com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext)542 Test (org.junit.jupiter.api.Test)365 RecordQueryPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan)226 RecordQuery (com.apple.foundationdb.record.query.RecordQuery)215 Message (com.google.protobuf.Message)187 FDBQueriedRecord (com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord)170 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)165 Tuple (com.apple.foundationdb.tuple.Tuple)147 Tag (org.junit.jupiter.api.Tag)136 Tags (com.apple.test.Tags)129 Assertions.assertEquals (org.junit.jupiter.api.Assertions.assertEquals)123 List (java.util.List)121 Index (com.apple.foundationdb.record.metadata.Index)119 MatcherAssert.assertThat (org.hamcrest.MatcherAssert.assertThat)114 ArrayList (java.util.ArrayList)112 Collections (java.util.Collections)100 Query (com.apple.foundationdb.record.query.expressions.Query)97 RecordQueryPlanner (com.apple.foundationdb.record.query.plan.RecordQueryPlanner)96 Arrays (java.util.Arrays)94 ExecuteProperties (com.apple.foundationdb.record.ExecuteProperties)93