Search in sources :

Example 26 with FDBRecordContext

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

the class FDBAndQueryToIntersectionTest method sortedIntersectionBounded.

/**
 * Verify that a query with a sort by primary key and AND clause (with complex limits) is implemented as an
 * intersection of index scans, when the primary key is bounded.
 */
@ParameterizedTest
@BooleanSource
public void sortedIntersectionBounded(boolean shouldDeferFetch) throws Exception {
    RecordMetaDataHook hook = sortingShapesHook();
    setupEnumShapes(hook);
    RecordQuery query = RecordQuery.newBuilder().setRecordType("MyShapeRecord").setFilter(Query.and(Query.field("shape").equalsValue(TestRecordsEnumProto.MyShapeRecord.Shape.CIRCLE), Query.field("color").equalsValue(TestRecordsEnumProto.MyShapeRecord.Color.RED), Query.field("rec_no").greaterThanOrEquals(2), Query.field("rec_no").lessThanOrEquals(11))).setSort(field("rec_no")).build();
    setDeferFetchAfterUnionAndIntersection(shouldDeferFetch);
    // Fetch(Covering(Index(color [[10, 2],[10, 11]]) -> [color: KEY[0], rec_name: KEY[2], rec_no: KEY[1]]) ∩ Covering(Index(shape [[200, 2],[200, 11]]) -> [rec_name: KEY[2], rec_no: KEY[1], shape: KEY[0]]))
    // Fetch(Covering(Index(color [[10, 2],[10, 11]]) -> [color: KEY[0], rec_name: KEY[2], rec_no: KEY[1]]) ∩ Covering(Index(shape [[200, 2],[200, 11]]) -> [rec_name: KEY[2], rec_no: KEY[1], shape: KEY[0]]))
    RecordQueryPlan plan = planner.plan(query);
    if (shouldDeferFetch) {
        assertThat(plan, fetch(intersection(coveringIndexScan(indexScan(allOf(indexName("color"), bounds(hasTupleString("[[10, 2],[10, 11]]"))))), coveringIndexScan(indexScan(allOf(indexName("shape"), bounds(hasTupleString("[[200, 2],[200, 11]]"))))))));
        assertEquals(1992249868, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
        assertEquals(625673791, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
        assertEquals(-1309396162, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
    } else {
        assertThat(plan, intersection(indexScan(allOf(indexName("color"), bounds(hasTupleString("[[10, 2],[10, 11]]")))), indexScan(allOf(indexName("shape"), bounds(hasTupleString("[[200, 2],[200, 11]]"))))));
        assertEquals(-942526391, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
        assertEquals(-1527867032, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
        assertEquals(832030311, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
    }
    try (FDBRecordContext context = openContext()) {
        openEnumRecordStore(context, hook);
        int i = 0;
        try (RecordCursorIterator<FDBQueriedRecord<Message>> cursor = recordStore.executeQuery(plan).asIterator()) {
            while (cursor.hasNext()) {
                FDBQueriedRecord<Message> rec = cursor.next();
                TestRecordsEnumProto.MyShapeRecord.Builder shapeRec = TestRecordsEnumProto.MyShapeRecord.newBuilder();
                shapeRec.mergeFrom(rec.getRecord());
                assertThat(shapeRec.getRecName(), anyOf(is("SMALL-RED-CIRCLE"), is("MEDIUM-RED-CIRCLE")));
                assertThat(shapeRec.getShape(), equalTo(TestRecordsEnumProto.MyShapeRecord.Shape.CIRCLE));
                assertThat(shapeRec.getColor(), equalTo(TestRecordsEnumProto.MyShapeRecord.Color.RED));
                assertThat(shapeRec.getRecNo(), allOf(greaterThanOrEqualTo(2), lessThanOrEqualTo(11)));
                i++;
            }
        }
        assertEquals(2, i);
        assertDiscardedAtMost(4, context);
        if (shouldDeferFetch) {
            assertLoadRecord(2, context);
        }
    }
}
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) RecordQuery(com.apple.foundationdb.record.query.RecordQuery) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) BooleanSource(com.apple.test.BooleanSource)

Example 27 with FDBRecordContext

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

the class FDBAndQueryToIntersectionTest method sortedIntersectionUnbounded.

/**
 * Verify that a query with a sort by primary key and AND clause is implemented as an intersection of index scans,
 * when the primary key is unbounded.
 */
@ParameterizedTest
@BooleanSource
public void sortedIntersectionUnbounded(boolean shouldDeferFetch) throws Exception {
    RecordMetaDataHook hook = sortingShapesHook();
    setupEnumShapes(hook);
    RecordQuery query = RecordQuery.newBuilder().setRecordType("MyShapeRecord").setFilter(Query.and(Query.field("shape").equalsValue(TestRecordsEnumProto.MyShapeRecord.Shape.CIRCLE), Query.field("color").equalsValue(TestRecordsEnumProto.MyShapeRecord.Color.RED))).setSort(field("rec_no")).build();
    setDeferFetchAfterUnionAndIntersection(shouldDeferFetch);
    // Fetch(Covering(Index(color [[10],[10]]) -> [color: KEY[0], rec_name: KEY[2], rec_no: KEY[1]]) ∩ Covering(Index(shape [[200],[200]]) -> [rec_name: KEY[2], rec_no: KEY[1], shape: KEY[0]]))
    RecordQueryPlan plan = planner.plan(query);
    if (shouldDeferFetch) {
        assertThat(plan, fetch(intersection(coveringIndexScan(indexScan(allOf(indexName("color"), bounds(hasTupleString("[[10],[10]]"))))), coveringIndexScan(indexScan(allOf(indexName("shape"), bounds(hasTupleString("[[200],[200]]"))))))));
        assertEquals(-2072158516, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
        assertEquals(-1707812033, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
        assertEquals(1828796254, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
    } else {
        assertThat(plan, intersection(indexScan(allOf(indexName("color"), bounds(hasTupleString("[[10],[10]]")))), indexScan(allOf(indexName("shape"), bounds(hasTupleString("[[200],[200]]"))))));
        assertEquals(-296022647, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
        assertEquals(433614440, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
        assertEquals(-324744569, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
    }
    try (FDBRecordContext context = openContext()) {
        openEnumRecordStore(context, hook);
        int i = 0;
        try (RecordCursorIterator<FDBQueriedRecord<Message>> cursor = recordStore.executeQuery(plan).asIterator()) {
            while (cursor.hasNext()) {
                FDBQueriedRecord<Message> rec = cursor.next();
                TestRecordsEnumProto.MyShapeRecord.Builder shapeRec = TestRecordsEnumProto.MyShapeRecord.newBuilder();
                shapeRec.mergeFrom(rec.getRecord());
                assertThat(shapeRec.getRecName(), endsWith("-RED-CIRCLE"));
                assertThat(shapeRec.getShape(), equalTo(TestRecordsEnumProto.MyShapeRecord.Shape.CIRCLE));
                assertThat(shapeRec.getColor(), equalTo(TestRecordsEnumProto.MyShapeRecord.Color.RED));
                i++;
            }
        }
        assertEquals(3, i);
        assertDiscardedAtMost(10, context);
        if (shouldDeferFetch) {
            assertLoadRecord(3, context);
        }
    }
}
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) RecordQuery(com.apple.foundationdb.record.query.RecordQuery) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) BooleanSource(com.apple.test.BooleanSource)

Example 28 with FDBRecordContext

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

the class FDBCollateQueryTest method queryNames.

protected List<String> queryNames(RecordQuery query, RecordMetaDataHook hook, String... bindings) throws Exception {
    try (FDBRecordContext context = openContext()) {
        openSimpleRecordStore(context, hook);
        Bindings.Builder builder = Bindings.newBuilder();
        for (int i = 0; i < bindings.length; i += 2) {
            builder.set(bindings[i], bindings[i + 1]);
        }
        return recordStore.planQuery(query).execute(recordStore, EvaluationContext.forBindings(builder.build())).map(r -> {
            TestRecords1Proto.MySimpleRecord record = TestRecords1Proto.MySimpleRecord.newBuilder().mergeFrom(r.getRecord()).build();
            return record.getStrValueIndexed();
        }).asList().join();
    }
}
Also used : TestRecords1Proto(com.apple.foundationdb.record.TestRecords1Proto) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) Bindings(com.apple.foundationdb.record.Bindings)

Example 29 with FDBRecordContext

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

the class FDBCoveringIndexQueryTest method coveringOff.

/**
 * Verify that a covering index is used when possible.
 */
@SuppressWarnings("unchecked")
@DualPlannerTest
void coveringOff() throws Exception {
    complexQuerySetup(null);
    RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.field("num_value_unique").greaterThan(990)).setSort(field("num_value_unique")).setRequiredResults(Collections.singletonList(field("num_value_unique"))).build();
    // Covering(Index(MySimpleRecord$num_value_unique ([990],>) -> [num_value_unique: KEY[0], rec_no: KEY[1]])
    planner.setConfiguration(planner.getConfiguration().asBuilder().setDisabledTransformationRuleNames(ImmutableSet.of("PushFilterThroughFetchRule", "PushDistinctThroughFetchRule", "PushSetOperationThroughFetchRule", "MergeProjectionAndFetchRule"), PlannerRuleSet.DEFAULT).build());
    RecordQueryPlan plan = planner.plan(query);
    if (planner instanceof RecordQueryPlanner) {
        final BindingMatcher<? extends RecordQueryPlan> planMatcher = coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("MySimpleRecord$num_value_unique")).and(scanComparisons(range("([990],>")))));
        assertMatchesExactly(plan, planMatcher);
        assertEquals(-158312359, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
        assertEquals(-1293351441, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
        assertEquals(-1374755849, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
    } else {
        final BindingMatcher<? extends RecordQueryPlan> planMatcher = indexPlan().where(indexName("MySimpleRecord$num_value_unique")).and(scanComparisons(range("([990],>")));
        assertMatchesExactly(plan, planMatcher);
        assertEquals(-158312359, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
        assertEquals(594363437, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
        assertEquals(512959029, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
    }
    try (FDBRecordContext context = openContext()) {
        openSimpleRecordStore(context);
        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);
                i++;
            }
        }
        assertEquals(10, i);
        assertDiscardedNone(context);
    }
}
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) RecordQueryPlanner(com.apple.foundationdb.record.query.plan.RecordQueryPlanner) RecordQuery(com.apple.foundationdb.record.query.RecordQuery)

Example 30 with FDBRecordContext

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

the class FDBCoveringIndexQueryTest method coveringWithAdditionalNestedFilter.

/**
 * Verify that an extra covering filter can use a nested field.
 */
@DualPlannerTest
void coveringWithAdditionalNestedFilter() {
    try (FDBRecordContext context = openContext()) {
        RecordMetaDataBuilder builder = RecordMetaData.newBuilder().setRecords(TestRecordsWithHeaderProto.getDescriptor());
        builder.getRecordType("MyRecord").setPrimaryKey(field("header").nest(field("rec_no")));
        builder.addIndex("MyRecord", "multi", concat(field("str_value"), field("header").nest(concatenateFields("path", "num"))));
        RecordMetaData metaData = builder.getRecordMetaData();
        createOrOpenRecordStore(context, metaData);
        RecordQuery query = RecordQuery.newBuilder().setRecordType("MyRecord").setFilter(Query.and(Query.field("str_value").equalsValue("abc"), Query.field("header").matches(Query.field("num").equalsValue(1)))).build();
        // Fetch(Covering(Index(multi [[abc],[abc]]) -> [str_value: KEY[0], header: [num: KEY[2], path: KEY[1], rec_no: KEY[3]]]) | header/{num EQUALS 1})
        RecordQueryPlan plan = planner.plan(query);
        if (planner instanceof RecordQueryPlanner) {
            final BindingMatcher<? extends RecordQueryPlan> planMatcher = fetchFromPartialRecordPlan(filterPlan(coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("multi")).and(scanComparisons(range("[[abc],[abc]]")))))).where(queryComponents(exactly(equalsObject(Query.field("header").matches(Query.field("num").equalsValue(1)))))));
            assertMatchesExactly(plan, planMatcher);
            assertEquals(-1536005152, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
            assertEquals(1350035332, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
            assertEquals(-1843652335, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
        } else {
            final BindingMatcher<? extends RecordQueryPlan> planMatcher = fetchFromPartialRecordPlan(predicatesFilterPlan(coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("multi")).and(scanComparisons(range("[[abc],[abc]]")))))).where(predicates(only(valuePredicate(fieldValue("header.num"), new Comparisons.SimpleComparison(Comparisons.Type.EQUALS, 1))))));
            assertMatchesExactly(plan, planMatcher);
            assertEquals(1623341655, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
            assertEquals(2019556616, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
            assertEquals(-1174131051, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
        }
    }
}
Also used : RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) RecordMetaDataBuilder(com.apple.foundationdb.record.RecordMetaDataBuilder) RecordQueryPlanMatchers.scanComparisons(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.scanComparisons) Comparisons(com.apple.foundationdb.record.query.expressions.Comparisons) RecordQueryPlanner(com.apple.foundationdb.record.query.plan.RecordQueryPlanner) 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