Search in sources :

Example 61 with RecordQuery

use of com.apple.foundationdb.record.query.RecordQuery in project fdb-record-layer by FoundationDB.

the class FDBOrQueryToUnionTest method testOrQuery2.

/**
 * Verify that queries with an OR of a mix of equality and inequality predicates on the same field are implemented
 * using a union of indexes.
 */
@DualPlannerTest
@ParameterizedTest
@BooleanSource
void testOrQuery2(boolean shouldDeferFetch) throws Exception {
    RecordMetaDataHook hook = complexQuerySetupHook();
    complexQuerySetup(hook);
    RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.or(Query.field("num_value_3_indexed").equalsValue(1), Query.field("num_value_3_indexed").equalsValue(2), Query.field("num_value_3_indexed").greaterThan(3))).build();
    setDeferFetchAfterUnionAndIntersection(shouldDeferFetch);
    // Fetch(Covering(Index(MySimpleRecord$num_value_3_indexed [[1],[1]]) -> [num_value_3_indexed: KEY[0], rec_no: KEY[1]]) ∪[Field { 'num_value_3_indexed' None}, Field { 'rec_no' None}] Covering(Index(MySimpleRecord$num_value_3_indexed [[2],[2]]) -> [num_value_3_indexed: KEY[0], rec_no: KEY[1]]) ∪[Field { 'num_value_3_indexed' None}, Field { 'rec_no' None}] Covering(Index(MySimpleRecord$num_value_3_indexed ([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$num_value_3_indexed")).and(scanComparisons(range("[[1],[1]]"))))), coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("MySimpleRecord$num_value_3_indexed")).and(scanComparisons(range("[[2],[2]]"))))), coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("MySimpleRecord$num_value_3_indexed")).and(scanComparisons(range("([3],>")))))).where(comparisonKey(concat(field("num_value_3_indexed"), primaryKey("MySimpleRecord")))));
        assertMatchesExactly(plan, planMatcher);
        assertEquals(504228282, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
        assertEquals(1520996708, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
        assertEquals(2080970598, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
    } else {
        final BindingMatcher<? extends RecordQueryPlan> planMatcher = unionPlan(indexPlan().where(indexName("MySimpleRecord$num_value_3_indexed")).and(scanComparisons(range("[[1],[1]]"))), indexPlan().where(indexName("MySimpleRecord$num_value_3_indexed")).and(scanComparisons(range("[[2],[2]]"))), indexPlan().where(indexName("MySimpleRecord$num_value_3_indexed")).and(scanComparisons(range("([3],>")))).where(comparisonKey(concat(field("num_value_3_indexed"), primaryKey("MySimpleRecord"))));
        assertMatchesExactly(plan, planMatcher);
        assertEquals(1299166123, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
        assertEquals(-700473135, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
        assertEquals(-140499245, 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.getNumValue3Indexed() == 1 || myrec.getNumValue3Indexed() == 2 || myrec.getNumValue3Indexed() > 3);
                i++;
            }
        }
        assertEquals(20 + 20 + 20, i);
        assertDiscardedNone(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 62 with RecordQuery

use of com.apple.foundationdb.record.query.RecordQuery in project fdb-record-layer by FoundationDB.

the class FDBOrQueryToUnionTest method testOrQuery5.

/**
 * Verify that an OR of inequalities on different fields uses an unordered union, since there is no compatible ordering.
 */
@DualPlannerTest
@ParameterizedTest(name = "testOrQuery5 [removesDuplicates = {0}]")
@BooleanSource
void testOrQuery5(boolean removesDuplicates) throws Exception {
    RecordMetaDataHook hook = complexQuerySetupHook();
    complexQuerySetup(hook);
    RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.or(Query.field("str_value_indexed").lessThan("m"), Query.field("num_value_3_indexed").greaterThan(3))).setRemoveDuplicates(removesDuplicates).build();
    // Unordered(Index(MySimpleRecord$str_value_indexed ([null],[m])) ∪ Index(MySimpleRecord$num_value_3_indexed ([3],>))
    RecordQueryPlan plan = planner.plan(query);
    if (planner instanceof CascadesPlanner) {
        BindingMatcher<? extends RecordQueryPlan> planMatcher = unorderedUnionPlan(coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("MySimpleRecord$str_value_indexed")).and(scanComparisons(range("([null],[m])"))))), coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("MySimpleRecord$num_value_3_indexed")).and(scanComparisons(range("([3],>"))))));
        if (removesDuplicates) {
            planMatcher = fetchFromPartialRecordPlan(unorderedPrimaryKeyDistinctPlan(planMatcher));
        } else {
            planMatcher = fetchFromPartialRecordPlan(planMatcher);
        }
        assertMatchesExactly(plan, planMatcher);
        assertEquals(removesDuplicates ? 1898767693 : 1898767686, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
        assertEquals(removesDuplicates ? -583062018 : 212117636, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
        assertEquals(removesDuplicates ? 1864525478 : -1635262164, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
    } else {
        BindingMatcher<? extends RecordQueryPlan> planMatcher = unorderedUnionPlan(indexPlan().where(indexName("MySimpleRecord$str_value_indexed")).and(scanComparisons(range("([null],[m])"))), indexPlan().where(indexName("MySimpleRecord$num_value_3_indexed")).and(scanComparisons(range("([3],>"))));
        if (removesDuplicates) {
            planMatcher = unorderedPrimaryKeyDistinctPlan(planMatcher);
        }
        assertMatchesExactly(plan, planMatcher);
        assertEquals(removesDuplicates ? -1569447744 : -1569447745, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
        assertEquals(removesDuplicates ? 1558364455 : -1941423187, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
        assertEquals(removesDuplicates ? -289015345 : 506164309, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
    }
    try (FDBRecordContext context = openContext()) {
        Objects.requireNonNull(context.getTimer()).reset();
        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().compareTo("m") < 0 || myrec.getNumValue3Indexed() > 3);
                i++;
            }
        }
        if (removesDuplicates) {
            assertEquals(50 + 10, i);
            assertDiscardedAtMost(10, context);
        } else {
            assertEquals(70, i);
            assertDiscardedNone(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 63 with RecordQuery

use of com.apple.foundationdb.record.query.RecordQuery in project fdb-record-layer by FoundationDB.

the class FDBQueryCompatibilityTest method testQueryCompatibilityConstraintComplex.

@Test
void testQueryCompatibilityConstraintComplex() throws Exception {
    RecordMetaDataHook hook = complexQuerySetupHook();
    complexQuerySetup(hook);
    final RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.and(Query.field("str_value_indexed").equalsParameter("p1"), Query.field("str_value_indexed").equalsParameter("p2"), Query.field("str_value_indexed").equalsParameter("p3"), Query.field("str_value_indexed").equalsParameter("p4"), Query.field("str_value_indexed").equalsParameter("p5"), Query.field("str_value_indexed").equalsParameter("p6"), Query.field("str_value_indexed").equalsParameter("p7"), Query.field("str_value_indexed").equalsParameter("p8"), Query.field("num_value_3_indexed").equalsParameter("p9"), Query.field("num_value_2").equalsParameter("p10"))).build();
    BoundRecordQuery boundQuery = query.bind(recordStore, Bindings.newBuilder().set("p1", "even").set("p2", "even").set("p3", "even").set("p4", "even").set("p5", "even").set("p6", "even").set("p7", "even").set("p8", "even").set("p9", 3).set("p10", 0).build());
    BoundRecordQuery boundQuery2 = query.bind(recordStore, Bindings.newBuilder().set("p1", "even").set("p2", "even").set("p3", "even").set("p4", "odd").set("p5", "odd").set("p6", "even").set("p7", "even").set("p8", "even").set("p9", 3).set("p10", 0).build());
    assertNotEquals(boundQuery.hashCode(), boundQuery2.hashCode());
    assertNotEquals(boundQuery2, boundQuery);
    boundQuery2 = query.bind(recordStore, Bindings.newBuilder().set("p1", "odd").set("p2", "odd").set("p3", "odd").set("p4", "odd").set("p5", "odd").set("p6", "odd").set("p7", "odd").set("p8", "odd").set("p9", 3).set("p10", 0).build());
    assertEquals(boundQuery.hashCode(), boundQuery2.hashCode());
    assertEquals(boundQuery2, boundQuery);
}
Also used : BoundRecordQuery(com.apple.foundationdb.record.query.BoundRecordQuery) BoundRecordQuery(com.apple.foundationdb.record.query.BoundRecordQuery) RecordQuery(com.apple.foundationdb.record.query.RecordQuery) Test(org.junit.jupiter.api.Test)

Example 64 with RecordQuery

use of com.apple.foundationdb.record.query.RecordQuery in project fdb-record-layer by FoundationDB.

the class FDBQueryCompatibilityTest method testQueryCompatibilityConstraintSimple.

@Test
void testQueryCompatibilityConstraintSimple() throws Exception {
    RecordMetaDataHook hook = complexQuerySetupHook();
    complexQuerySetup(hook);
    final RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.and(Query.field("str_value_indexed").equalsParameter("p1"), Query.field("str_value_indexed").equalsParameter("p2"), Query.field("num_value_3_indexed").equalsParameter("p3"), Query.field("num_value_2").equalsParameter("p4"))).build();
    BoundRecordQuery boundQuery = query.bind(recordStore, Bindings.newBuilder().set("p1", "even").set("p2", "even").set("p3", 3).set("p4", 0).build());
    BoundRecordQuery boundQuery2 = query.bind(recordStore, Bindings.newBuilder().set("p1", "even").set("p2", "even").set("p3", 3).set("p4", 0).build());
    assertEquals(boundQuery.hashCode(), boundQuery2.hashCode());
    assertEquals(boundQuery2, boundQuery);
    boundQuery2 = query.bind(recordStore, Bindings.newBuilder().set("p1", "even").set("p2", "odd").set("p3", 3).set("p4", 0).build());
    assertNotEquals(boundQuery.hashCode(), boundQuery2.hashCode());
    assertNotEquals(boundQuery2, boundQuery);
    boundQuery2 = query.bind(recordStore, Bindings.newBuilder().set("p1", "odd").set("p2", "odd").set("p3", 3).set("p4", 0).build());
    assertEquals(boundQuery.hashCode(), boundQuery2.hashCode());
    assertEquals(boundQuery2, boundQuery);
}
Also used : BoundRecordQuery(com.apple.foundationdb.record.query.BoundRecordQuery) BoundRecordQuery(com.apple.foundationdb.record.query.BoundRecordQuery) RecordQuery(com.apple.foundationdb.record.query.RecordQuery) Test(org.junit.jupiter.api.Test)

Example 65 with RecordQuery

use of com.apple.foundationdb.record.query.RecordQuery in project fdb-record-layer by FoundationDB.

the class FDBRecordStoreIndexScanPreferenceTest method noIndexes.

@Test
public void noIndexes() throws Exception {
    try (FDBRecordContext context = openContext()) {
        openAnyRecordStore(TestNoIndexesProto.getDescriptor(), context);
    }
    RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").build();
    for (QueryPlanner.IndexScanPreference indexScanPreference : QueryPlanner.IndexScanPreference.values()) {
        planner.setIndexScanPreference(indexScanPreference);
        RecordQueryPlan plan = planner.plan(query);
        assertThat(plan, scan(unbounded()));
    }
}
Also used : RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) RecordQuery(com.apple.foundationdb.record.query.RecordQuery) QueryPlanner(com.apple.foundationdb.record.query.plan.QueryPlanner) Test(org.junit.jupiter.api.Test)

Aggregations

RecordQuery (com.apple.foundationdb.record.query.RecordQuery)334 RecordQueryPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan)250 FDBRecordContext (com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext)222 Test (org.junit.jupiter.api.Test)205 Message (com.google.protobuf.Message)166 FDBQueriedRecord (com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord)163 Index (com.apple.foundationdb.record.metadata.Index)114 Query (com.apple.foundationdb.record.query.expressions.Query)114 Tags (com.apple.test.Tags)112 Tag (org.junit.jupiter.api.Tag)112 Assertions.assertEquals (org.junit.jupiter.api.Assertions.assertEquals)108 RecordQueryPlanner (com.apple.foundationdb.record.query.plan.RecordQueryPlanner)107 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)106 MatcherAssert.assertThat (org.hamcrest.MatcherAssert.assertThat)102 Arrays (java.util.Arrays)99 Expressions.field (com.apple.foundationdb.record.metadata.Key.Expressions.field)98 Collections (java.util.Collections)97 List (java.util.List)96 QueryComponent (com.apple.foundationdb.record.query.expressions.QueryComponent)95 Assertions.assertTrue (org.junit.jupiter.api.Assertions.assertTrue)93