Search in sources :

Example 21 with QueryComponent

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

the class TextIndexTest method queryMapDocumentsWithIndex.

@Nonnull
private List<Long> queryMapDocumentsWithIndex(@Nonnull String key, @Nonnull QueryComponent textFilter, int planHash, boolean isCoveringIndexExpected) throws InterruptedException, ExecutionException {
    if (!(textFilter instanceof ComponentWithComparison)) {
        throw new RecordCoreArgumentException("filter without comparison provided as text filter");
    }
    final QueryComponent filter = Query.field("entry").oneOfThem().matches(Query.and(Query.field("key").equalsValue(key), textFilter));
    Matcher<RecordQueryPlan> indexMatcher = textIndexScan(allOf(indexName(MAP_ON_VALUE_INDEX.getName()), groupingBounds(allOf(notNullValue(), hasTupleString("[[" + key + "],[" + key + "]]"))), textComparison(equalTo(((ComponentWithComparison) textFilter).getComparison()))));
    if (isCoveringIndexExpected) {
        indexMatcher = coveringIndexScan(indexMatcher);
    }
    final Matcher<RecordQueryPlan> planMatcher = descendant(indexMatcher);
    return queryDocuments(Collections.singletonList(MAP_DOC), Collections.singletonList(field("doc_id")), filter, planHash, planMatcher).map(t -> t.getLong(0)).asList().get();
}
Also used : RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) ComponentWithComparison(com.apple.foundationdb.record.query.expressions.ComponentWithComparison) RecordCoreArgumentException(com.apple.foundationdb.record.RecordCoreArgumentException) Nonnull(javax.annotation.Nonnull)

Example 22 with QueryComponent

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

the class TextIndexTest method queryMapDocumentsWithGroupedIndex.

@Nonnull
private List<Long> queryMapDocumentsWithGroupedIndex(@Nonnull String key, @Nonnull QueryComponent textFilter, long group, int planHash) throws InterruptedException, ExecutionException {
    if (!(textFilter instanceof ComponentWithComparison)) {
        throw new RecordCoreArgumentException("filter without comparison provided as text filter");
    }
    final QueryComponent filter = Query.and(Query.field("group").equalsValue(group), Query.field("entry").oneOfThem().matches(Query.and(Query.field("key").equalsValue(key), textFilter)));
    final Matcher<RecordQueryPlan> planMatcher = descendant(coveringIndexScan(textIndexScan(allOf(indexName(MAP_ON_VALUE_GROUPED_INDEX.getName()), groupingBounds(allOf(notNullValue(), hasTupleString("[[" + group + ", " + key + "],[" + group + ", " + key + "]]"))), textComparison(equalTo(((ComponentWithComparison) textFilter).getComparison()))))));
    return queryDocuments(Collections.singletonList(MAP_DOC), Collections.singletonList(field("doc_id")), filter, planHash, planMatcher).map(t -> t.getLong(0)).asList().get();
}
Also used : RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) ComponentWithComparison(com.apple.foundationdb.record.query.expressions.ComponentWithComparison) RecordCoreArgumentException(com.apple.foundationdb.record.RecordCoreArgumentException) Nonnull(javax.annotation.Nonnull)

Example 23 with QueryComponent

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

the class TextIndexTest method queryComplexDocumentsWithIndex.

@Nonnull
private List<Tuple> queryComplexDocumentsWithIndex(@Nonnull QueryComponent textFilter, @Nullable QueryComponent additionalFilter, boolean skipFilterCheck, long group, int planHash) throws InterruptedException, ExecutionException {
    if (!(textFilter instanceof ComponentWithComparison)) {
        throw new RecordCoreArgumentException("filter without comparison provided as text filter");
    }
    final Matcher<RecordQueryPlan> textScanMatcher = textIndexScan(allOf(indexName(COMPLEX_TEXT_BY_GROUP.getName()), groupingBounds(allOf(notNullValue(), hasTupleString("[[" + group + "],[" + group + "]]"))), textComparison(equalTo(((ComponentWithComparison) textFilter).getComparison()))));
    // Don't care whether it's covering or not
    final Matcher<RecordQueryPlan> textPlanMatcher = anyOf(textScanMatcher, coveringIndexScan(textScanMatcher));
    final Matcher<RecordQueryPlan> planMatcher;
    final QueryComponent filter;
    if (additionalFilter != null) {
        if (skipFilterCheck) {
            planMatcher = descendant(textPlanMatcher);
        } else {
            planMatcher = descendant(filter(additionalFilter, descendant(textPlanMatcher)));
        }
        filter = Query.and(textFilter, additionalFilter, Query.field("group").equalsValue(group));
    } else {
        planMatcher = descendant(textPlanMatcher);
        filter = Query.and(textFilter, Query.field("group").equalsValue(group));
    }
    return queryComplexDocumentsWithPlan(filter, planHash, planMatcher);
}
Also used : RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) ComponentWithComparison(com.apple.foundationdb.record.query.expressions.ComponentWithComparison) RecordCoreArgumentException(com.apple.foundationdb.record.RecordCoreArgumentException) Nonnull(javax.annotation.Nonnull)

Example 24 with QueryComponent

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

the class QueryPlanCursorTest method filterKeyCount.

private void filterKeyCount(int amount) throws Exception {
    final QueryComponent filter = Query.field("str_value_indexed").equalsValue("even");
    try (FDBRecordContext context = openContext()) {
        openSimpleRecordStore(context);
        recordStore.getTimer().reset();
        final RecordQueryPlan plan = indexPlanEquals("MySimpleRecord$num_value_3_indexed", 2);
        byte[] continuation = null;
        int unfilteredCount = 0;
        // Read with no filter.
        do {
            RecordCursor<FDBQueriedRecord<Message>> cursor = recordStore.executeQuery(plan, continuation, ExecuteProperties.SERIAL_EXECUTE).limitRowsTo(amount);
            int count = cursor.getCount().get();
            assertThat(count, lessThanOrEqualTo(amount));
            unfilteredCount += count;
            continuation = cursor.getNext().getContinuation().toBytes();
        } while (continuation != null);
        recordStore.getTimer().reset();
        // Read with a filter.
        continuation = null;
        int filteredCount = 0;
        do {
            RecordCursor<FDBQueriedRecord<Message>> cursor = recordStore.executeQuery(plan, continuation, ExecuteProperties.SERIAL_EXECUTE).limitRowsTo(amount).filterInstrumented(rec -> filter.eval(recordStore, EvaluationContext.EMPTY, rec), recordStore.getTimer(), Collections.singleton(FDBStoreTimer.Counts.QUERY_FILTER_PLAN_GIVEN), Collections.emptySet(), Collections.singleton(FDBStoreTimer.Counts.QUERY_FILTER_PLAN_PASSED), Collections.emptySet());
            int count = cursor.getCount().get();
            assertThat(count, lessThanOrEqualTo(amount));
            filteredCount += count;
            continuation = cursor.getNext().getContinuation().toBytes();
        } while (continuation != null);
        int filteredGiven = recordStore.getTimer().getCount(FDBStoreTimer.Counts.QUERY_FILTER_PLAN_GIVEN);
        int filteredPassed = recordStore.getTimer().getCount(FDBStoreTimer.Counts.QUERY_FILTER_PLAN_PASSED);
        // We should have passed as many keys through our filter as there are records returned.
        assertEquals(filteredCount, filteredPassed);
        // We should read the same amount of data whether we are filtering or not.
        assertEquals(unfilteredCount, filteredGiven);
    }
}
Also used : RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent)

Example 25 with QueryComponent

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

the class FDBReturnedRecordLimitQueryTest method testComplexLimits2.

/**
 * Verify that a returned record limit works properly against a query with a filter on one field and a sort on another,
 * when the filter field is un-indexed and the sort is in reverse order.
 */
@ParameterizedTest
@BooleanSource
void testComplexLimits2(final boolean shouldOptimizeForIndexFilters) throws Exception {
    RecordMetaDataHook hook = complexQuerySetupHook();
    complexQuerySetup(hook);
    final QueryComponent filter = Query.field("num_value_2").equalsValue(0);
    RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(filter).setSort(field("str_value_indexed"), true).build();
    setOptimizeForIndexFilters(shouldOptimizeForIndexFilters);
    // Index(MySimpleRecord$str_value_indexed <,> REVERSE) | num_value_2 EQUALS 0
    // Fetch(Covering(Index(multi_index <,> REVERSE) -> [num_value_2: KEY[1], num_value_3_indexed: KEY[2], rec_no: KEY[3], str_value_indexed: KEY[0]]) | num_value_2 EQUALS 0)
    RecordQueryPlan plan = planner.plan(query);
    if (shouldOptimizeForIndexFilters) {
        assertThat(plan, fetch(filter(filter, coveringIndexScan(indexScan(allOf(indexName("multi_index"), unbounded()))))));
        assertTrue(plan.isReverse());
        assertEquals(-1143466156, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
        assertEquals(915163788, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
        assertEquals(-1279091452, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
    } else {
        assertThat(plan, filter(filter, indexScan(allOf(indexName("MySimpleRecord$str_value_indexed"), unbounded()))));
        assertTrue(plan.isReverse());
        assertEquals(-384998859, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
        assertEquals(-1575402371, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
        assertEquals(525309685, 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, null, ExecuteProperties.newBuilder().setReturnedRowLimit(10).build()).asIterator()) {
            while (cursor.hasNext()) {
                FDBQueriedRecord<Message> rec = cursor.next();
                TestRecords1Proto.MySimpleRecord.Builder myrec = TestRecords1Proto.MySimpleRecord.newBuilder();
                myrec.mergeFrom(Objects.requireNonNull(rec).getRecord());
                assertEquals(0, myrec.getNumValue2());
                assertEquals("odd", myrec.getStrValueIndexed());
                i += 1;
            }
        }
        assertEquals(10, i);
        assertDiscardedAtMost(34, context);
    }
}
Also used : RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) 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

QueryComponent (com.apple.foundationdb.record.query.expressions.QueryComponent)96 RecordQueryPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan)58 RecordQuery (com.apple.foundationdb.record.query.RecordQuery)44 Test (org.junit.jupiter.api.Test)41 FDBRecordContext (com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext)37 ArrayList (java.util.ArrayList)30 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)29 FDBQueriedRecord (com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord)25 Index (com.apple.foundationdb.record.metadata.Index)24 Nonnull (javax.annotation.Nonnull)23 Comparisons (com.apple.foundationdb.record.query.expressions.Comparisons)22 Message (com.google.protobuf.Message)22 Query (com.apple.foundationdb.record.query.expressions.Query)20 RecordQueryPlanner (com.apple.foundationdb.record.query.plan.RecordQueryPlanner)20 List (java.util.List)20 Collections (java.util.Collections)19 Nullable (javax.annotation.Nullable)18 Assertions.assertEquals (org.junit.jupiter.api.Assertions.assertEquals)18 PlanHashable (com.apple.foundationdb.record.PlanHashable)17 Expressions.field (com.apple.foundationdb.record.metadata.Key.Expressions.field)17