Search in sources :

Example 46 with BooleanSource

use of com.apple.test.BooleanSource in project fdb-record-layer by FoundationDB.

the class FDBOrQueryToUnionTest method testOrQuery4.

/**
 * Verify that queries with an OR of equality predicates on different fields are implemented using a union of indexes,
 * if all fields are indexed.
 */
@DualPlannerTest
@ParameterizedTest
@BooleanSource
void testOrQuery4(boolean shouldDeferFetch) throws Exception {
    RecordMetaDataHook hook = complexQuerySetupHook();
    complexQuerySetup(hook);
    RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.or(Query.field("str_value_indexed").equalsValue("even"), Query.field("num_value_3_indexed").equalsValue(1), Query.field("num_value_3_indexed").equalsValue(3))).build();
    setDeferFetchAfterUnionAndIntersection(shouldDeferFetch);
    // Fetch(Covering(Index(MySimpleRecord$str_value_indexed [[even],[even]]) -> [rec_no: KEY[1], str_value_indexed: KEY[0]]) ∪ Covering(Index(MySimpleRecord$num_value_3_indexed [[1],[1]]) -> [num_value_3_indexed: KEY[0], rec_no: KEY[1]]) ∪ Covering(Index(MySimpleRecord$num_value_3_indexed [[3],[3]]) -> [num_value_3_indexed: KEY[0], rec_no: KEY[1]]))
    RecordQueryPlan plan = planner.plan(query);
    if (shouldDeferFetch || planner instanceof CascadesPlanner) {
        final BindingMatcher<? extends RecordQueryPlan> planMatcher = fetchFromPartialRecordPlan(unionPlan(coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("MySimpleRecord$str_value_indexed")).and(scanComparisons(range("[[even],[even]]"))))), coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("MySimpleRecord$num_value_3_indexed")).and(scanComparisons(range("[[1],[1]]"))))), coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("MySimpleRecord$num_value_3_indexed")).and(scanComparisons(range("[[3],[3]]")))))).where(comparisonKey(primaryKey("MySimpleRecord"))));
        assertMatchesExactly(plan, planMatcher);
        assertEquals(-417814093, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
        assertEquals(-1082480572, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
        assertEquals(233155848, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
    } else {
        final BindingMatcher<? extends RecordQueryPlan> planMatcher = unionPlan(indexPlan().where(indexName("MySimpleRecord$str_value_indexed")).and(scanComparisons(range("[[even],[even]]"))), indexPlan().where(indexName("MySimpleRecord$num_value_3_indexed")).and(scanComparisons(range("[[1],[1]]"))), indexPlan().where(indexName("MySimpleRecord$num_value_3_indexed")).and(scanComparisons(range("[[3],[3]]")))).where(comparisonKey(primaryKey("MySimpleRecord")));
        assertMatchesExactly(plan, planMatcher);
        assertEquals(-673254486, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
        assertEquals(991016881, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
        assertEquals(-1988313995, 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.getStrValueIndexed().equals("even") || myrec.getNumValue3Indexed() == 1 || myrec.getNumValue3Indexed() == 3);
                i++;
            }
        }
        assertEquals(50 + 10 + 10, i);
        assertDiscardedAtMost(20, context);
        if (shouldDeferFetch) {
            assertLoadRecord(50 + 10 + 10, context);
        }
    }
}
Also used : RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) Message(com.google.protobuf.Message) FDBQueriedRecord(com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) RecordQuery(com.apple.foundationdb.record.query.RecordQuery) CascadesPlanner(com.apple.foundationdb.record.query.plan.temp.CascadesPlanner) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) BooleanSource(com.apple.test.BooleanSource)

Example 47 with BooleanSource

use of com.apple.test.BooleanSource in project fdb-record-layer by FoundationDB.

the class FDBAndQueryToIntersectionTest method testComplexQueryAndWithIncompatibleFilters.

/**
 * Verify that a complex query with an AND of fields that are _not_ compatibly ordered generates a plan without
 * an intersection (uses filter instead).
 */
@ParameterizedTest
@BooleanSource
public void testComplexQueryAndWithIncompatibleFilters(final boolean shouldOptimizeForIndexFilters) throws Exception {
    RecordMetaDataHook hook = complexQuerySetupHook();
    complexQuerySetup(hook);
    RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.and(Query.field("str_value_indexed").startsWith("e"), Query.field("num_value_3_indexed").equalsValue(3))).build();
    setOptimizeForIndexFilters(shouldOptimizeForIndexFilters);
    // Index(MySimpleRecord$str_value_indexed {[e],[e]}) | num_value_3_indexed EQUALS 3
    // Fetch(Covering(Index(multi_index {[e],[e]}) -> [num_value_2: KEY[1], num_value_3_indexed: KEY[2], rec_no: KEY[3], str_value_indexed: KEY[0]]) | num_value_3_indexed EQUALS 3)
    RecordQueryPlan plan = planner.plan(query);
    // Not an intersection plan, since not compatibly ordered.
    if (shouldOptimizeForIndexFilters) {
        assertThat(plan, allOf(hasNoDescendant(intersection(anything(), anything())), descendant(filter(Query.field("num_value_3_indexed").equalsValue(3), coveringIndexScan(indexScan(anyOf(indexName("multi_index"), bounds(hasTupleString("[[e],[e]]")))))))));
        assertFalse(plan.hasRecordScan(), "should not use record scan");
        assertEquals(-1810430840, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
        assertEquals(-1492232944, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
        assertEquals(-1442514296, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
    } else {
        assertThat(plan, allOf(hasNoDescendant(intersection(anything(), anything())), descendant(indexScan(anyOf(indexName("MySimpleRecord$str_value_indexed"), indexName("MySimpleRecord$num_value_3_indexed"))))));
        assertFalse(plan.hasRecordScan(), "should not use record scan");
        assertEquals(746853985, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
        assertEquals(312168193, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
        assertEquals(361886841, 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(40, context);
        assertLoadRecord(50, 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 48 with BooleanSource

use of com.apple.test.BooleanSource in project fdb-record-layer by FoundationDB.

the class FDBAndQueryToIntersectionTest method testComplexQueryAndWithTwoChildren.

/**
 * Verify that a complex query with an AND of fields with compatibly ordered indexes generates an intersection plan.
 */
@ParameterizedTest
@BooleanSource
public void testComplexQueryAndWithTwoChildren(boolean shouldDeferFetch) 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(shouldDeferFetch);
    // Index(MySimpleRecord$str_value_indexed [[even],[even]]) ∩ Index(MySimpleRecord$num_value_3_indexed [[3],[3]])
    // Fetch(Covering(Index(MySimpleRecord$str_value_indexed [[even],[even]]) -> [rec_no: KEY[1], str_value_indexed: KEY[0]]) ∩ Covering(Index(MySimpleRecord$num_value_3_indexed [[3],[3]]) -> [num_value_3_indexed: KEY[0], rec_no: KEY[1]]))
    RecordQueryPlan plan = planner.plan(query);
    if (shouldDeferFetch) {
        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")))));
        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 {
        assertThat(plan, intersection(indexScan(allOf(indexName("MySimpleRecord$str_value_indexed"), bounds(hasTupleString("[[even],[even]]")))), indexScan(allOf(indexName("MySimpleRecord$num_value_3_indexed"), bounds(hasTupleString("[[3],[3]]")))), equalTo(field("rec_no"))));
        assertEquals(-1973527173, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
        assertEquals(227253579, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
        assertEquals(1869819604, 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);
        if (shouldDeferFetch) {
            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) RecordQuery(com.apple.foundationdb.record.query.RecordQuery) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) BooleanSource(com.apple.test.BooleanSource)

Example 49 with BooleanSource

use of com.apple.test.BooleanSource in project fdb-record-layer by FoundationDB.

the class FDBAndQueryToIntersectionTest method testComplexQueryAndWithSomeIncompatibleFilters.

/**
 * Verify that a complex query with an AND of fields where some of them are compatibly ordered uses an intersection
 * for only those filters.
 */
@ParameterizedTest
@BooleanSource
public void testComplexQueryAndWithSomeIncompatibleFilters(boolean shouldDeferFetch) throws Exception {
    // Add an additional index to use for additional filtering
    RecordMetaDataHook hook = (metaDataBuilder) -> {
        complexQuerySetupHook().apply(metaDataBuilder);
        metaDataBuilder.removeIndex("multi_index");
        metaDataBuilder.addIndex("MySimpleRecord", "MySimpleRecord$num_value_2", field("num_value_2"));
    };
    complexQuerySetup(hook);
    RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.and(Query.field("str_value_indexed").startsWith("e"), Query.field("num_value_3_indexed").equalsValue(0), Query.field("num_value_2").equalsValue(2))).build();
    setDeferFetchAfterUnionAndIntersection(shouldDeferFetch);
    // Fetch(Covering(Index(MySimpleRecord$num_value_3_indexed [[0],[0]]) -> [num_value_3_indexed: KEY[0], rec_no: KEY[1]]) ∩ Covering(Index(MySimpleRecord$num_value_2 [[2],[2]]) -> [num_value_2: KEY[0], rec_no: KEY[1]])) | str_value_indexed STARTS_WITH e
    RecordQueryPlan plan = planner.plan(query);
    if (shouldDeferFetch) {
        assertThat(plan, filter(Query.field("str_value_indexed").startsWith("e"), fetch(intersection(coveringIndexScan(indexScan(allOf(indexName(equalTo("MySimpleRecord$num_value_3_indexed")), bounds(hasTupleString("[[0],[0]]"))))), coveringIndexScan(indexScan(allOf(indexName(equalTo("MySimpleRecord$num_value_2")), bounds(hasTupleString("[[2],[2]]"))))), equalTo(field("rec_no"))))));
        assertEquals(-1979861885, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
        assertEquals(-1271604119, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
        assertEquals(-1737180988, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
    } else {
        assertThat(plan, filter(Query.field("str_value_indexed").startsWith("e"), intersection(indexScan(allOf(indexName(equalTo("MySimpleRecord$num_value_3_indexed")), bounds(hasTupleString("[[0],[0]]")))), indexScan(allOf(indexName(equalTo("MySimpleRecord$num_value_2")), bounds(hasTupleString("[[2],[2]]")))), equalTo(field("rec_no")))));
        assertEquals(1095867174, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
        assertEquals(688107104, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
        assertEquals(222530235, 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());
                assertEquals(0, myrec.getNumValue3Indexed());
                assertEquals(2, myrec.getNumValue2());
                i++;
            }
        }
        assertEquals(3, i);
        assertDiscardedAtMost(42, context);
        if (shouldDeferFetch) {
            assertLoadRecord(7, context);
        }
    }
}
Also used : Arrays(java.util.Arrays) RecordQueryIntersectionPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryIntersectionPlan) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) RecordQueryPlanMatchers.predicates(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.predicates) PlanMatchers.bounds(com.apple.foundationdb.record.query.plan.match.PlanMatchers.bounds) RecordQueryPlanner(com.apple.foundationdb.record.query.plan.RecordQueryPlanner) Assertions.assertFalse(org.junit.jupiter.api.Assertions.assertFalse) Expressions.concatenateFields(com.apple.foundationdb.record.metadata.Key.Expressions.concatenateFields) Expressions.concat(com.apple.foundationdb.record.metadata.Key.Expressions.concat) Tag(org.junit.jupiter.api.Tag) PlanMatchers.coveringIndexScan(com.apple.foundationdb.record.query.plan.match.PlanMatchers.coveringIndexScan) RecordQueryPlanMatchers.selfOrDescendantPlans(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.selfOrDescendantPlans) Query(com.apple.foundationdb.record.query.expressions.Query) TestRecords1Proto(com.apple.foundationdb.record.TestRecords1Proto) PlanMatchers.intersection(com.apple.foundationdb.record.query.plan.match.PlanMatchers.intersection) Matchers.allOf(org.hamcrest.Matchers.allOf) Matchers.lessThanOrEqualTo(org.hamcrest.Matchers.lessThanOrEqualTo) Test(org.junit.jupiter.api.Test) PlanMatchers.hasTupleString(com.apple.foundationdb.record.query.plan.match.PlanMatchers.hasTupleString) ScanComparisons.range(com.apple.foundationdb.record.query.plan.ScanComparisons.range) PlanMatchers.indexName(com.apple.foundationdb.record.query.plan.match.PlanMatchers.indexName) FDBQueriedRecord(com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord) PlanMatchers.hasNoDescendant(com.apple.foundationdb.record.query.plan.match.PlanMatchers.hasNoDescendant) Matchers.equalTo(org.hamcrest.Matchers.equalTo) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) TestRecordsEnumProto(com.apple.foundationdb.record.TestRecordsEnumProto) IndexTypes(com.apple.foundationdb.record.metadata.IndexTypes) Matchers.is(org.hamcrest.Matchers.is) Matchers.anyOf(org.hamcrest.Matchers.anyOf) RecordQueryPlanMatchers(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers) RecordQueryPlanMatchers.predicatesFilterPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.predicatesFilterPlan) Matchers.endsWith(org.hamcrest.Matchers.endsWith) RecordQueryPlannerSubstitutionVisitor(com.apple.foundationdb.record.query.plan.visitor.RecordQueryPlannerSubstitutionVisitor) PlanMatchers.fetch(com.apple.foundationdb.record.query.plan.match.PlanMatchers.fetch) IndexScanParameters(com.apple.foundationdb.record.provider.foundationdb.IndexScanParameters) PlanMatchers.indexScan(com.apple.foundationdb.record.query.plan.match.PlanMatchers.indexScan) QueryPlanner(com.apple.foundationdb.record.query.plan.QueryPlanner) RecordQuery(com.apple.foundationdb.record.query.RecordQuery) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) ExecuteProperties.newBuilder(com.apple.foundationdb.record.ExecuteProperties.newBuilder) PlanHashable(com.apple.foundationdb.record.PlanHashable) PlanMatchers.filter(com.apple.foundationdb.record.query.plan.match.PlanMatchers.filter) TestHelpers.assertDiscardedExactly(com.apple.foundationdb.record.TestHelpers.assertDiscardedExactly) ImmutableList(com.google.common.collect.ImmutableList) RecordCursorIterator(com.apple.foundationdb.record.RecordCursorIterator) IndexScanComparisons(com.apple.foundationdb.record.provider.foundationdb.IndexScanComparisons) BooleanSource(com.apple.test.BooleanSource) 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) RecordQueryIndexPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryIndexPlan) Matchers.greaterThanOrEqualTo(org.hamcrest.Matchers.greaterThanOrEqualTo) RecordTypeBuilder(com.apple.foundationdb.record.metadata.RecordTypeBuilder) Tags(com.apple.test.Tags) TestHelpers.assertLoadRecord(com.apple.foundationdb.record.TestHelpers.assertLoadRecord) QueryPredicateMatchers.valuePredicate(com.apple.foundationdb.record.query.plan.temp.matchers.QueryPredicateMatchers.valuePredicate) PlannableIndexTypes(com.apple.foundationdb.record.query.plan.PlannableIndexTypes) Comparisons(com.apple.foundationdb.record.query.expressions.Comparisons) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) 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) PlanMatchers.descendant(com.apple.foundationdb.record.query.plan.match.PlanMatchers.descendant) RealAnythingMatcher.anything(com.apple.foundationdb.record.TestHelpers.RealAnythingMatcher.anything) ValueMatchers.fieldValue(com.apple.foundationdb.record.query.plan.temp.matchers.ValueMatchers.fieldValue) 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 BooleanSource

use of com.apple.test.BooleanSource in project fdb-record-layer by FoundationDB.

the class FDBFullTextQueryTest method delayFetchOnUnionOfFullTextScans.

@ParameterizedTest
@BooleanSource
public void delayFetchOnUnionOfFullTextScans(boolean shouldDeferFetch) throws Exception {
    final List<TestRecordsTextProto.SimpleDocument> documents = TextIndexTestUtils.toSimpleDocuments(Arrays.asList(TextSamples.ANGSTROM, TextSamples.AETHELRED, TextSamples.ROMEO_AND_JULIET_PROLOGUE, TextSamples.FRENCH));
    try (FDBRecordContext context = openContext()) {
        openRecordStore(context);
        documents.forEach(recordStore::saveRecord);
        commit(context);
    }
    try (FDBRecordContext context = openContext()) {
        openRecordStore(context);
        final QueryComponent filter1 = Query.field("text").text().containsPhrase("civil blood makes civil hands unclean");
        final Comparisons.Comparison comparison1 = new Comparisons.TextComparison(Comparisons.Type.TEXT_CONTAINS_PHRASE, "civil blood makes civil hands unclean", null, DefaultTextTokenizer.NAME);
        final QueryComponent filter2 = Query.field("text").text().containsPrefix("th");
        final Comparisons.Comparison comparison2 = new Comparisons.TextComparison(Comparisons.Type.TEXT_CONTAINS_PREFIX, Collections.singletonList("th"), null, DefaultTextTokenizer.NAME);
        // Query for full records
        RecordQuery query = RecordQuery.newBuilder().setRecordType(TextIndexTestUtils.SIMPLE_DOC).setFilter(Query.or(filter1, filter2)).build();
        setDeferFetchAfterUnionAndIntersection(shouldDeferFetch);
        // Unordered(TextIndex(SimpleDocument$text null, TEXT_CONTAINS_PHRASE civil blood makes civil hands unclean, null) ∪ TextIndex(SimpleDocument$text null, TEXT_CONTAINS_PREFIX [th], null) | UnorderedPrimaryKeyDistinct()) | UnorderedPrimaryKeyDistinct()
        // Fetch(Unordered(Covering(TextIndex(SimpleDocument$text null, TEXT_CONTAINS_PHRASE civil blood makes civil hands unclean, null) -> [doc_id: KEY[1]]) ∪ Covering(TextIndex(SimpleDocument$text null, TEXT_CONTAINS_PREFIX [th], null) -> [doc_id: KEY[1]]) | UnorderedPrimaryKeyDistinct()) | UnorderedPrimaryKeyDistinct())
        RecordQueryPlan plan = planner.plan(query);
        if (shouldDeferFetch) {
            assertThat(plan, fetch(primaryKeyDistinct(unorderedUnion(coveringIndexScan(textIndexScan(allOf(indexName(TextIndexTestUtils.SIMPLE_DEFAULT_NAME), textComparison(equalTo(comparison1))))), primaryKeyDistinct(coveringIndexScan(textIndexScan(allOf(indexName(TextIndexTestUtils.SIMPLE_DEFAULT_NAME), textComparison(equalTo(comparison2))))))))));
            assertEquals(-683922391, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
            assertEquals(-833837033, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
            assertEquals(-464003585, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
        } else {
            assertThat(plan, primaryKeyDistinct(unorderedUnion(textIndexScan(allOf(indexName(TextIndexTestUtils.SIMPLE_DEFAULT_NAME), textComparison(equalTo(comparison1)))), primaryKeyDistinct(textIndexScan(allOf(indexName(TextIndexTestUtils.SIMPLE_DEFAULT_NAME), textComparison(equalTo(comparison2))))))));
            assertEquals(515863556, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
            assertEquals(1307589440, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
            assertEquals(1677422888, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
        }
        List<Long> primaryKeys = recordStore.executeQuery(plan).map(FDBQueriedRecord::getPrimaryKey).map(t -> t.getLong(0)).asList().get();
        assertEquals(ImmutableSet.of(0L, 1L, 2L, 3L), ImmutableSet.copyOf(primaryKeys));
        if (shouldDeferFetch) {
            assertLoadRecord(4, context);
        } else {
            assertLoadRecord(8, context);
        }
    }
}
Also used : RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) Comparisons(com.apple.foundationdb.record.query.expressions.Comparisons) RecordQuery(com.apple.foundationdb.record.query.RecordQuery) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) BooleanSource(com.apple.test.BooleanSource)

Aggregations

BooleanSource (com.apple.test.BooleanSource)57 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)57 RecordQuery (com.apple.foundationdb.record.query.RecordQuery)37 RecordQueryPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan)37 FDBRecordContext (com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext)36 FDBQueriedRecord (com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord)24 Message (com.google.protobuf.Message)23 QueryComponent (com.apple.foundationdb.record.query.expressions.QueryComponent)14 RecordMetaDataBuilder (com.apple.foundationdb.record.RecordMetaDataBuilder)10 LuceneQueryComponent (com.apple.foundationdb.record.query.expressions.LuceneQueryComponent)10 RecordMetaData (com.apple.foundationdb.record.RecordMetaData)9 CascadesPlanner (com.apple.foundationdb.record.query.plan.temp.CascadesPlanner)9 MatcherAssert.assertThat (org.hamcrest.MatcherAssert.assertThat)9 Assertions.assertEquals (org.junit.jupiter.api.Assertions.assertEquals)9 Assertions.assertTrue (org.junit.jupiter.api.Assertions.assertTrue)9 Test (org.junit.jupiter.api.Test)9 TestRecords1Proto (com.apple.foundationdb.record.TestRecords1Proto)7 RecordCursorIterator (com.apple.foundationdb.record.RecordCursorIterator)6 Index (com.apple.foundationdb.record.metadata.Index)6 Tuple (com.apple.foundationdb.tuple.Tuple)6