Search in sources :

Example 46 with RecordQueryPlan

use of com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan in project fdb-record-layer by FoundationDB.

the class FDBInQueryTest method enumIn.

/**
 * Verify that enum field indexes are used to implement IN clauses.
 */
@DualPlannerTest
void enumIn() throws Exception {
    RecordMetaDataHook hook = metaData -> {
        final RecordTypeBuilder type = metaData.getRecordType("MyShapeRecord");
        metaData.addIndex(type, new Index("color", field("color")));
    };
    setupEnumShapes(hook);
    final var redBlue = asList(TestRecordsEnumProto.MyShapeRecord.Color.RED, TestRecordsEnumProto.MyShapeRecord.Color.BLUE);
    RecordQuery query = RecordQuery.newBuilder().setRecordType("MyShapeRecord").setFilter(Query.field("color").in(redBlue)).build();
    // Index(color [EQUALS $__in_color__0]) WHERE __in_color__0 IN [RED, BLUE]
    RecordQueryPlan plan = planner.plan(query);
    if (planner instanceof RecordQueryPlanner) {
        assertMatchesExactly(plan, descendantPlans(indexPlan().where(indexName("color"))));
        assertFalse(plan.hasRecordScan(), "should not use record scan");
        assertEquals(-520431454, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
        assertEquals(1447363737, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
        assertEquals(1442809521, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
    } else {
        assertMatchesExactly(plan, fetchFromPartialRecordPlan(inValuesJoinPlan(coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("color")).and(scanComparisons(equalities(exactly(anyParameterComparison()))))))).where(inValuesList(equalsObject(redBlue)))));
        assertFalse(plan.hasRecordScan(), "should not use record scan");
        assertEquals(1174038242, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
        assertEquals(-1089300981, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
        assertEquals(-1677589406, 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(Objects.requireNonNull(rec).getRecord());
                assertThat(shapeRec.getColor(), is(oneOf(TestRecordsEnumProto.MyShapeRecord.Color.RED, TestRecordsEnumProto.MyShapeRecord.Color.BLUE)));
                i++;
            }
        }
        assertEquals(18, i);
        TestHelpers.assertDiscardedNone(context);
    }
}
Also used : RecordQueryPlanMatchers.coveringIndexPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.coveringIndexPlan) Arrays(java.util.Arrays) RecordQueryPlanMatchers.inUnionPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.inUnionPlan) RecordQueryPlanMatchers.scanPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.scanPlan) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) RecordQueryPlanMatchers.predicates(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.predicates) RecordQueryPlanner(com.apple.foundationdb.record.query.plan.RecordQueryPlanner) RecordQueryPlanMatchers.fetchFromPartialRecordPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.fetchFromPartialRecordPlan) IndexScanType(com.apple.foundationdb.record.IndexScanType) RecordCursorResult(com.apple.foundationdb.record.RecordCursorResult) TestHelpers(com.apple.foundationdb.record.TestHelpers) ListMatcher.only(com.apple.foundationdb.record.query.plan.temp.matchers.ListMatcher.only) RecordQueryPlanMatchers.inValuesList(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.inValuesList) Assertions.assertFalse(org.junit.jupiter.api.Assertions.assertFalse) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) Arrays.asList(java.util.Arrays.asList) 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) RecordQueryPlanMatchers.selfOrDescendantPlans(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.selfOrDescendantPlans) Query(com.apple.foundationdb.record.query.expressions.Query) PrimitiveMatchers(com.apple.foundationdb.record.query.plan.temp.matchers.PrimitiveMatchers) RecordQueryPlannerConfiguration(com.apple.foundationdb.record.query.plan.RecordQueryPlannerConfiguration) RecordQueryPlanMatchers.inUnionValuesSources(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.inUnionValuesSources) Set(java.util.Set) FanType(com.apple.foundationdb.record.metadata.expressions.KeyExpression.FanType) RecordQueryPlanMatchers.inValuesJoinPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.inValuesJoinPlan) Test(org.junit.jupiter.api.Test) Objects(java.util.Objects) List(java.util.List) ScanComparisons.range(com.apple.foundationdb.record.query.plan.ScanComparisons.range) RecordQueryPlanMatchers.inParameterJoinPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.inParameterJoinPlan) RecordQueryPlanMatchers.comparisonKey(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.comparisonKey) RecordQueryPlanMatchers.inUnionInValues(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.inUnionInValues) EvaluationContext(com.apple.foundationdb.record.EvaluationContext) FDBQueriedRecord(com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) TestRecordsEnumProto(com.apple.foundationdb.record.TestRecordsEnumProto) 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.unionPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.unionPlan) Matchers.anyOf(org.hamcrest.Matchers.anyOf) RecordQueryPlanMatchers(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers) ScanComparisons.equalities(com.apple.foundationdb.record.query.plan.ScanComparisons.equalities) RecordQueryPlanMatchers.predicatesFilterPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.predicatesFilterPlan) Assertions.assertThrows(org.junit.jupiter.api.Assertions.assertThrows) Assertions.fail(org.junit.jupiter.api.Assertions.fail) RecordQueryPlanMatchers.indexPlanOf(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.indexPlanOf) EnumSource(org.junit.jupiter.params.provider.EnumSource) 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) HashSet(java.util.HashSet) RecordQueryPlanMatchers.descendantPlans(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.descendantPlans) ImmutableList(com.google.common.collect.ImmutableList) RecordCursorIterator(com.apple.foundationdb.record.RecordCursorIterator) Matchers.lessThan(org.hamcrest.Matchers.lessThan) RecordQueryPlanMatchers.inUnionComparisonKey(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.inUnionComparisonKey) RecordQueryPlanMatchers.scanComparisons(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.scanComparisons) RecordQueryPlanMatchers.unorderedPrimaryKeyDistinctPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.unorderedPrimaryKeyDistinctPlan) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) Expressions.field(com.apple.foundationdb.record.metadata.Key.Expressions.field) RecordQueryIndexPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryIndexPlan) Matchers.oneOf(org.hamcrest.Matchers.oneOf) RecordQueryPlanMatchers.inUnionBindingName(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.inUnionBindingName) Matchers.greaterThanOrEqualTo(org.hamcrest.Matchers.greaterThanOrEqualTo) ScanComparisons.unbounded(com.apple.foundationdb.record.query.plan.ScanComparisons.unbounded) RecordTypeBuilder(com.apple.foundationdb.record.metadata.RecordTypeBuilder) 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) RecordQueryPlanMatchers.inUnionInParameter(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.inUnionInParameter) ScanComparisons.anyParameterComparison(com.apple.foundationdb.record.query.plan.ScanComparisons.anyParameterComparison) Comparisons(com.apple.foundationdb.record.query.expressions.Comparisons) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) 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) TestHelpers.assertDiscardedAtMost(com.apple.foundationdb.record.TestHelpers.assertDiscardedAtMost) Message(com.google.protobuf.Message) QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) RecordQueryPlanMatchers.unorderedUnionPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.unorderedUnionPlan) 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) RecordTypeBuilder(com.apple.foundationdb.record.metadata.RecordTypeBuilder) FDBQueriedRecord(com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) RecordQueryPlanner(com.apple.foundationdb.record.query.plan.RecordQueryPlanner) RecordQuery(com.apple.foundationdb.record.query.RecordQuery)

Example 47 with RecordQueryPlan

use of com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan in project fdb-record-layer by FoundationDB.

the class FDBInQueryTest method testInQueryParameter2.

/**
 * Verify that an IN (with parameter) with an index is implemented as an index scan, with an IN union in the presence
 * of other equality-bound index parts.
 */
@DualPlannerTest
void testInQueryParameter2() throws Exception {
    RecordMetaDataHook hook = metaData -> {
        metaData.removeIndex("MySimpleRecord$num_value_3_indexed");
        metaData.removeIndex("MySimpleRecord$num_value_unique");
        metaData.addIndex("MySimpleRecord", new Index("multi_index", "num_value_3_indexed", "num_value_2", "num_value_unique"));
    };
    complexQuerySetup(hook);
    RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.and(Query.field("num_value_3_indexed").equalsParameter("p"), Query.field("num_value_2").in("valueThrees"))).setSort(Key.Expressions.field("num_value_unique")).build();
    planner.setConfiguration(InAsOrUnionMode.AS_UNION.configure(planner.getConfiguration().asBuilder()).build());
    RecordQueryPlan plan = planner.plan(query);
    if (planner instanceof RecordQueryPlanner) {
        assertMatchesExactly(plan, inUnionPlan(indexPlan().where(indexName("multi_index")).and(scanComparisons(range("[EQUALS $p, EQUALS $__in_num_value_2__0]")))).where(inUnionValuesSources(exactly(RecordQueryPlanMatchers.inUnionInParameter(equalsObject("valueThrees"))))));
        assertEquals(1360223246, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
        assertEquals(2045945193, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
        assertEquals(2045945193, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
    } else {
        assertMatchesExactly(plan, fetchFromPartialRecordPlan(inUnionPlan(coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("multi_index")).and(scanComparisons(equalities(exactly(anyParameterComparison(), anyParameterComparison()))))))).where(RecordQueryPlanMatchers.inUnionValuesSources(exactly(inUnionInParameter(equalsObject("valueThrees")))))));
        assertEquals(1947663752, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
        assertEquals(1788373323, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
        assertEquals(1788373323, 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) RecordQueryPlanMatchers.inUnionPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.inUnionPlan) RecordQueryPlanMatchers.scanPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.scanPlan) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) RecordQueryPlanMatchers.predicates(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.predicates) RecordQueryPlanner(com.apple.foundationdb.record.query.plan.RecordQueryPlanner) RecordQueryPlanMatchers.fetchFromPartialRecordPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.fetchFromPartialRecordPlan) IndexScanType(com.apple.foundationdb.record.IndexScanType) RecordCursorResult(com.apple.foundationdb.record.RecordCursorResult) TestHelpers(com.apple.foundationdb.record.TestHelpers) ListMatcher.only(com.apple.foundationdb.record.query.plan.temp.matchers.ListMatcher.only) RecordQueryPlanMatchers.inValuesList(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.inValuesList) Assertions.assertFalse(org.junit.jupiter.api.Assertions.assertFalse) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) Arrays.asList(java.util.Arrays.asList) 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) RecordQueryPlanMatchers.selfOrDescendantPlans(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.selfOrDescendantPlans) Query(com.apple.foundationdb.record.query.expressions.Query) PrimitiveMatchers(com.apple.foundationdb.record.query.plan.temp.matchers.PrimitiveMatchers) RecordQueryPlannerConfiguration(com.apple.foundationdb.record.query.plan.RecordQueryPlannerConfiguration) RecordQueryPlanMatchers.inUnionValuesSources(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.inUnionValuesSources) Set(java.util.Set) FanType(com.apple.foundationdb.record.metadata.expressions.KeyExpression.FanType) RecordQueryPlanMatchers.inValuesJoinPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.inValuesJoinPlan) Test(org.junit.jupiter.api.Test) Objects(java.util.Objects) List(java.util.List) ScanComparisons.range(com.apple.foundationdb.record.query.plan.ScanComparisons.range) RecordQueryPlanMatchers.inParameterJoinPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.inParameterJoinPlan) RecordQueryPlanMatchers.comparisonKey(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.comparisonKey) RecordQueryPlanMatchers.inUnionInValues(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.inUnionInValues) EvaluationContext(com.apple.foundationdb.record.EvaluationContext) FDBQueriedRecord(com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) TestRecordsEnumProto(com.apple.foundationdb.record.TestRecordsEnumProto) 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.unionPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.unionPlan) Matchers.anyOf(org.hamcrest.Matchers.anyOf) RecordQueryPlanMatchers(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers) ScanComparisons.equalities(com.apple.foundationdb.record.query.plan.ScanComparisons.equalities) RecordQueryPlanMatchers.predicatesFilterPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.predicatesFilterPlan) Assertions.assertThrows(org.junit.jupiter.api.Assertions.assertThrows) Assertions.fail(org.junit.jupiter.api.Assertions.fail) RecordQueryPlanMatchers.indexPlanOf(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.indexPlanOf) EnumSource(org.junit.jupiter.params.provider.EnumSource) 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) HashSet(java.util.HashSet) RecordQueryPlanMatchers.descendantPlans(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.descendantPlans) ImmutableList(com.google.common.collect.ImmutableList) RecordCursorIterator(com.apple.foundationdb.record.RecordCursorIterator) Matchers.lessThan(org.hamcrest.Matchers.lessThan) RecordQueryPlanMatchers.inUnionComparisonKey(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.inUnionComparisonKey) RecordQueryPlanMatchers.scanComparisons(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.scanComparisons) RecordQueryPlanMatchers.unorderedPrimaryKeyDistinctPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.unorderedPrimaryKeyDistinctPlan) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) Expressions.field(com.apple.foundationdb.record.metadata.Key.Expressions.field) RecordQueryIndexPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryIndexPlan) Matchers.oneOf(org.hamcrest.Matchers.oneOf) RecordQueryPlanMatchers.inUnionBindingName(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.inUnionBindingName) Matchers.greaterThanOrEqualTo(org.hamcrest.Matchers.greaterThanOrEqualTo) ScanComparisons.unbounded(com.apple.foundationdb.record.query.plan.ScanComparisons.unbounded) RecordTypeBuilder(com.apple.foundationdb.record.metadata.RecordTypeBuilder) 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) RecordQueryPlanMatchers.inUnionInParameter(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.inUnionInParameter) ScanComparisons.anyParameterComparison(com.apple.foundationdb.record.query.plan.ScanComparisons.anyParameterComparison) Comparisons(com.apple.foundationdb.record.query.expressions.Comparisons) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) 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) TestHelpers.assertDiscardedAtMost(com.apple.foundationdb.record.TestHelpers.assertDiscardedAtMost) Message(com.google.protobuf.Message) QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) RecordQueryPlanMatchers.unorderedUnionPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.unorderedUnionPlan) 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) Index(com.apple.foundationdb.record.metadata.Index) RecordQueryPlanner(com.apple.foundationdb.record.query.plan.RecordQueryPlanner) RecordQuery(com.apple.foundationdb.record.query.RecordQuery)

Example 48 with RecordQueryPlan

use of com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan in project fdb-record-layer by FoundationDB.

the class FDBAndQueryToIntersectionTest method testComplexQueryAndWithTwoChildren2.

/**
 * Verify that a complex query with an AND of fields with compatibly ordered indexes generates an intersection plan.
 */
@DualPlannerTest
public void testComplexQueryAndWithTwoChildren2() throws Exception {
    RecordMetaDataHook hook = complexQuerySetupHook();
    complexQuerySetup(hook);
    RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.and(Query.field("str_value_indexed").equalsValue("even"), Query.field("num_value_3_indexed").equalsValue(3))).build();
    setDeferFetchAfterUnionAndIntersection(true);
    RecordQueryPlan plan = planner.plan(query);
    assertThat(plan, fetch(intersection(coveringIndexScan(indexScan(allOf(indexName("MySimpleRecord$str_value_indexed"), bounds(hasTupleString("[[even],[even]]"))))), coveringIndexScan(indexScan(allOf(indexName("MySimpleRecord$num_value_3_indexed"), bounds(hasTupleString("[[3],[3]]"))))), equalTo(field("rec_no")))));
    if (planner instanceof RecordQueryPlanner) {
        assertEquals(-929788310, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
        assertEquals(-1914172894, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
        assertEquals(-271606869, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
    } else {
        assertEquals(-70465554, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
        assertEquals(2126183202, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
        assertEquals(-1157469383, 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(rec.getRecord());
                assertEquals("even", myrec.getStrValueIndexed());
                assertTrue((myrec.getNumValue3Indexed() % 5) == 3);
                i++;
            }
        }
        assertEquals(10, i);
        assertDiscardedExactly(50, context);
        assertLoadRecord(10, 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 49 with RecordQueryPlan

use of com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan 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 50 with RecordQueryPlan

use of com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan 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)

Aggregations

RecordQueryPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan)373 RecordQuery (com.apple.foundationdb.record.query.RecordQuery)265 FDBRecordContext (com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext)245 Test (org.junit.jupiter.api.Test)228 FDBQueriedRecord (com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord)174 Message (com.google.protobuf.Message)167 Query (com.apple.foundationdb.record.query.expressions.Query)123 Tags (com.apple.test.Tags)121 Tag (org.junit.jupiter.api.Tag)121 Index (com.apple.foundationdb.record.metadata.Index)119 RecordQueryPlanner (com.apple.foundationdb.record.query.plan.RecordQueryPlanner)118 Assertions.assertEquals (org.junit.jupiter.api.Assertions.assertEquals)118 QueryComponent (com.apple.foundationdb.record.query.expressions.QueryComponent)117 List (java.util.List)114 MatcherAssert.assertThat (org.hamcrest.MatcherAssert.assertThat)114 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)113 Expressions.field (com.apple.foundationdb.record.metadata.Key.Expressions.field)107 Arrays (java.util.Arrays)107 Collections (java.util.Collections)106 ArrayList (java.util.ArrayList)100