Search in sources :

Example 41 with QueryComponent

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

the class FunctionKeyIndexTest method testQueryFunctionIndex.

private void testQueryFunctionIndex(boolean functionQuery) throws Exception {
    Index funcIndex = new Index("substr_index", function("substr", concat(field("str_value"), value(0), value(3))), IndexTypes.VALUE);
    Index normalIndex = new Index("normal_index", field("str_value"), IndexTypes.VALUE);
    Records records = Records.create();
    for (int i = 0; i < 10; i++) {
        String strValue = "ab" + Character.toString((char) ('c' + i)) + "_" + i;
        records.add(i, strValue);
    }
    saveRecords(records, funcIndex, normalIndex);
    QueryComponent filter;
    if (functionQuery) {
        filter = Query.and(Query.keyExpression(funcIndex.getRootExpression()).greaterThanOrEquals("abd"), Query.keyExpression(funcIndex.getRootExpression()).lessThanOrEquals("abg"));
    } else {
        filter = Query.and(Query.field("str_value").greaterThanOrEquals("abd"), Query.field("str_value").lessThanOrEquals("abg"));
    }
    RecordQuery query = RecordQuery.newBuilder().setRecordType("TypesRecord").setFilter(filter).build();
    // Index(substr_index [[abd],[abg]])
    RecordQueryPlan plan = planner.plan(query);
    if (functionQuery) {
        assertThat(plan, indexScan(allOf(indexName(funcIndex.getName()), bounds(hasTupleString("[[abd],[abg]]")))));
        assertEquals(316561162, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
        assertEquals(1660925199, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
        assertEquals(33212272, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
    } else {
        // Here I'm really just making sure that (a) the substr_index is not selected, because the
        // function call doesn't appear in the query anyway and (b) that the planner doesn't throw
        // an exception or do something wonky as a result of the presence of this index.
        assertThat(plan, indexScan(allOf(indexName(normalIndex.getName()), bounds(hasTupleString("[[abd],[abg]]")))));
        assertEquals(1189784448, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
        assertEquals(1463869061, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
        assertEquals(-163843866, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
    }
    try (FDBRecordContext context = openContext()) {
        openRecordStore(context, funcIndex, normalIndex);
        int count = 0;
        try (RecordCursorIterator<FDBQueriedRecord<Message>> cursor = recordStore.executeQuery(plan).asIterator()) {
            while (cursor.hasNext()) {
                FDBQueriedRecord<Message> queriedRecord = cursor.next();
                TypesRecord record = fromMessage(queriedRecord.getRecord());
                assertTrue(records.contains(record));
                String str = functionQuery ? record.getStrValue().substring(0, 3) : record.getStrValue();
                assertThat(str, greaterThanOrEqualTo("abd"));
                assertThat(str, lessThanOrEqualTo("abg"));
                ++count;
            }
        }
        assertEquals(functionQuery ? 4 : 3, count);
        assertDiscardedNone(context);
    }
}
Also used : RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) Message(com.google.protobuf.Message) Index(com.apple.foundationdb.record.metadata.Index) TypesRecord(com.apple.foundationdb.record.TestDataTypesProto.TypesRecord) PlanMatchers.hasTupleString(com.apple.foundationdb.record.query.plan.match.PlanMatchers.hasTupleString) Matchers.containsString(org.hamcrest.Matchers.containsString) RecordQuery(com.apple.foundationdb.record.query.RecordQuery)

Example 42 with QueryComponent

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

the class LucenePlanner method getScanForOrLucene.

private LuceneIndexQueryPlan getScanForOrLucene(@Nonnull Index index, final String parentFieldName, final OrComponent filter, final FilterSatisfiedMask filterMask, final ScanComparisons groupingComparisons) {
    final Iterator<FilterSatisfiedMask> subFilterMasks = filterMask != null ? filterMask.getChildren().iterator() : null;
    final List<QueryComponent> filters = filter.getChildren();
    LuceneIndexQueryPlan combinedComparison = null;
    for (QueryComponent subFilter : filters) {
        final FilterSatisfiedMask childMask = subFilterMasks != null ? subFilterMasks.next() : null;
        LuceneIndexQueryPlan childComparison = getComparisonsForLuceneFilter(index, parentFieldName, subFilter, childMask, groupingComparisons);
        if (childComparison != null && childMask != null) {
            childMask.setSatisfied(true);
            combinedComparison = combinedComparison == null ? childComparison : LuceneIndexQueryPlan.merge(childComparison, combinedComparison, "OR");
        }
    }
    if (filterMask != null && filterMask.getUnsatisfiedFilters().isEmpty()) {
        filterMask.setSatisfied(true);
    }
    return combinedComparison;
}
Also used : QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) LuceneQueryComponent(com.apple.foundationdb.record.query.expressions.LuceneQueryComponent) FilterSatisfiedMask(com.apple.foundationdb.record.query.plan.planning.FilterSatisfiedMask)

Example 43 with QueryComponent

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

the class CombineFilterRuleTest method combineFilter.

@Test
public void combineFilter() {
    for (RecordQueryPlan basePlan : basePlans) {
        QueryComponent filter1 = Query.field("testField").equalsValue(5);
        QueryComponent filter2 = Query.field("testField2").equalsValue(10);
        GroupExpressionRef<RelationalExpression> root = GroupExpressionRef.of(buildLogicalFilter(filter1, buildLogicalFilter(filter2, basePlan)));
        TestRuleExecution execution = TestRuleExecution.applyRule(blankContext, rule, root);
        assertTrue(execution.isRuleMatched());
        assertTrue(execution.getResult().containsInMemo(buildLogicalFilter(Query.and(filter1, filter2), basePlan)));
    }
}
Also used : RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) RelationalExpression(com.apple.foundationdb.record.query.plan.temp.RelationalExpression) Test(org.junit.jupiter.api.Test)

Example 44 with QueryComponent

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

the class CombineFilterRuleTest method doesNotCoalesce.

@Test
public void doesNotCoalesce() {
    for (RecordQueryPlan basePlan : basePlans) {
        QueryComponent filter1 = Query.field("testField").equalsValue(5);
        GroupExpressionRef<RelationalExpression> root = GroupExpressionRef.of(buildLogicalFilter(filter1, buildLogicalFilter(filter1, basePlan)));
        TestRuleExecution execution = TestRuleExecution.applyRule(blankContext, rule, root);
        assertTrue(execution.isRuleMatched());
        // this rule should not try to coalesce the two filters
        assertTrue(root.containsInMemo(buildLogicalFilter(Query.and(filter1, filter1), basePlan)));
        assertFalse(root.containsInMemo(buildLogicalFilter(filter1, basePlan)));
    }
}
Also used : RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) RelationalExpression(com.apple.foundationdb.record.query.plan.temp.RelationalExpression) Test(org.junit.jupiter.api.Test)

Example 45 with QueryComponent

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

the class BooleanNormalizerTest method assertExpectedNormalization.

protected static void assertExpectedNormalization(@Nonnull final BooleanNormalizer normalizer, @Nonnull final QueryComponent expected, @Nonnull final QueryComponent given) {
    final QueryComponent normalized = normalizer.normalize(given);
    assertFilterEquals(expected, normalized);
    if (!normalizer.isCheckForDuplicateConditions()) {
        assertEquals(numberOfTerms(expected), normalizer.getNormalizedSize(given));
    }
    assertEquals(normalized, normalizer.normalize(normalized), "Normalized form should be stable");
}
Also used : QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent)

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