Search in sources :

Example 1 with Tags

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

the class FDBNestedFieldQueryTest method nested.

/**
 * Verify that nested field comparisons with fanout can scan indexes.
 */
@DualPlannerTest
public void nested() throws Exception {
    try (FDBRecordContext context = openContext()) {
        openNestedRecordStore(context);
        TestRecords4Proto.RestaurantReviewer.Builder reviewerBuilder = TestRecords4Proto.RestaurantReviewer.newBuilder();
        reviewerBuilder.setId(1);
        reviewerBuilder.setName("Lemuel");
        recordStore.saveRecord(reviewerBuilder.build());
        reviewerBuilder.setId(2);
        reviewerBuilder.setName("Gulliver");
        recordStore.saveRecord(reviewerBuilder.build());
        TestRecords4Proto.RestaurantRecord.Builder recBuilder = TestRecords4Proto.RestaurantRecord.newBuilder();
        recBuilder.setRestNo(101);
        recBuilder.setName("The Emperor's Three Tables");
        TestRecords4Proto.RestaurantReview.Builder reviewBuilder = recBuilder.addReviewsBuilder();
        reviewBuilder.setReviewer(1);
        reviewBuilder.setRating(10);
        reviewBuilder = recBuilder.addReviewsBuilder();
        reviewBuilder.setReviewer(2);
        reviewBuilder.setRating(3);
        TestRecords4Proto.RestaurantTag.Builder tagBuilder = recBuilder.addTagsBuilder();
        tagBuilder.setValue("Lilliput");
        tagBuilder.setWeight(5);
        recordStore.saveRecord(recBuilder.build());
        recBuilder = TestRecords4Proto.RestaurantRecord.newBuilder();
        recBuilder.setRestNo(102);
        recBuilder.setName("Small Fry's Fried Victuals");
        reviewBuilder = recBuilder.addReviewsBuilder();
        reviewBuilder.setReviewer(1);
        reviewBuilder.setRating(5);
        reviewBuilder = recBuilder.addReviewsBuilder();
        reviewBuilder.setReviewer(2);
        reviewBuilder.setRating(5);
        tagBuilder = recBuilder.addTagsBuilder();
        tagBuilder.setValue("Lilliput");
        tagBuilder.setWeight(1);
        recordStore.saveRecord(recBuilder.build());
        commit(context);
    }
    // TODO this was originally:
    // QueryExpression.field("reviews").matches(QueryExpression.field("rating").greaterThan(5)),
    // which should have failed validate
    RecordQuery query = RecordQuery.newBuilder().setRecordType("RestaurantRecord").setFilter(Query.field("reviews").oneOfThem().matches(Query.field("rating").greaterThan(5))).build();
    // Index(review_rating ([5],>) | UnorderedPrimaryKeyDistinct()
    RecordQueryPlan plan = planner.plan(query);
    if (planner instanceof RecordQueryPlanner) {
        assertThat(plan, primaryKeyDistinct(indexScan(allOf(indexName("review_rating"), bounds(hasTupleString("([5],>"))))));
        assertEquals(1378568952, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
        assertEquals(-2085209333, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
        assertEquals(2129300140, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
    } else {
        assertThat(plan, fetch(primaryKeyDistinct(coveringIndexScan(indexScan(allOf(indexName("review_rating"), bounds(hasTupleString("([5],>"))))))));
        assertEquals(1060048085, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
        assertEquals(-1589243362, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
        assertEquals(-1669701185, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
    }
    assertEquals(Arrays.asList(101L), fetchResultValues(plan, TestRecords4Proto.RestaurantRecord.REST_NO_FIELD_NUMBER, this::openNestedRecordStore, TestHelpers::assertDiscardedNone));
    query = RecordQuery.newBuilder().setRecordType("RestaurantRecord").setFilter(Query.field("tags").oneOfThem().matches(Query.and(Query.field("value").equalsValue("Lilliput"), Query.field("weight").greaterThanOrEquals(5)))).build();
    // Index(tag [[Lilliput, 5],[Lilliput]]) | UnorderedPrimaryKeyDistinct()
    plan = planner.plan(query);
    if (planner instanceof RecordQueryPlanner) {
        assertThat(plan, primaryKeyDistinct(indexScan(allOf(indexName("tag"), bounds(hasTupleString("[[Lilliput, 5],[Lilliput]]"))))));
        assertEquals(-1197819382, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
        assertEquals(1570485504, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
        assertEquals(1584619812, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
    } else {
        assertThat(plan, fetch(primaryKeyDistinct(coveringIndexScan(indexScan(allOf(indexName("tag"), bounds(hasTupleString("[[Lilliput, 5],[Lilliput]]"))))))));
        assertEquals(205198931, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
        assertEquals(2066451475, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
        assertEquals(2080585783, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
    }
    assertEquals(Collections.singletonList(101L), fetchResultValues(plan, TestRecords4Proto.RestaurantRecord.REST_NO_FIELD_NUMBER, this::openNestedRecordStore, TestHelpers::assertDiscardedNone));
    QueryComponent reviewFilter = Query.field("reviews").oneOfThem().matches(Query.and(Query.field("rating").equalsValue(5), Query.field("reviewer").equalsValue(1L)));
    query = RecordQuery.newBuilder().setRecordType("RestaurantRecord").setFilter(reviewFilter).build();
    plan = planner.plan(query);
    if (planner instanceof RecordQueryPlanner) {
        assertThat(plan, filter(reviewFilter, primaryKeyDistinct(indexScan(allOf(indexName("review_rating"), bounds(hasTupleString("[[5],[5]]")))))));
        assertEquals(1252155441, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
        assertEquals(-2056078191, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
        assertEquals(-1471222808, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
        assertEquals(Collections.singletonList(102L), fetchResultValues(plan, TestRecords4Proto.RestaurantRecord.REST_NO_FIELD_NUMBER, this::openNestedRecordStore, TestHelpers::assertDiscardedNone));
    } else {
        assertThat(plan, filter(reviewFilter, primaryKeyDistinct(indexScan(allOf(indexName("review_rating"), bounds(hasTupleString("[[5],[5]]")))))));
        assertEquals(1252155441, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
        assertEquals(1947915247, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
        assertEquals(-1762196666, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
        assertEquals(Collections.singletonList(102L), fetchResultValues(plan, TestRecords4Proto.RestaurantRecord.REST_NO_FIELD_NUMBER, this::openNestedRecordStore, context -> TestHelpers.assertDiscardedAtMost(3, context)));
    }
}
Also used : RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) Arrays(java.util.Arrays) TestRecords3Proto(com.apple.foundationdb.record.TestRecords3Proto) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) PlanMatchers.bounds(com.apple.foundationdb.record.query.plan.match.PlanMatchers.bounds) RecordQueryPlanner(com.apple.foundationdb.record.query.plan.RecordQueryPlanner) IndexScanType(com.apple.foundationdb.record.IndexScanType) Tuple(com.apple.foundationdb.tuple.Tuple) RecordCursorResult(com.apple.foundationdb.record.RecordCursorResult) TestHelpers(com.apple.foundationdb.record.TestHelpers) 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) GroupingKeyExpression(com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression) Tag(org.junit.jupiter.api.Tag) PlanMatchers.coveringIndexScan(com.apple.foundationdb.record.query.plan.match.PlanMatchers.coveringIndexScan) PlanMatchers.indexScanType(com.apple.foundationdb.record.query.plan.match.PlanMatchers.indexScanType) TestRecords4Proto(com.apple.foundationdb.record.TestRecords4Proto) Query(com.apple.foundationdb.record.query.expressions.Query) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) Matchers.allOf(org.hamcrest.Matchers.allOf) Test(org.junit.jupiter.api.Test) PlanMatchers.hasTupleString(com.apple.foundationdb.record.query.plan.match.PlanMatchers.hasTupleString) PlanMatchers.indexName(com.apple.foundationdb.record.query.plan.match.PlanMatchers.indexName) EvaluationContext(com.apple.foundationdb.record.EvaluationContext) FDBQueriedRecord(com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) IndexTypes(com.apple.foundationdb.record.metadata.IndexTypes) TestRecordsWithHeaderProto(com.apple.foundationdb.record.TestRecordsWithHeaderProto) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) Assertions.assertNotNull(org.junit.jupiter.api.Assertions.assertNotNull) PlanMatchers.fetch(com.apple.foundationdb.record.query.plan.match.PlanMatchers.fetch) QueryRecordFunction(com.apple.foundationdb.record.query.expressions.QueryRecordFunction) PlanMatchers.primaryKeyDistinct(com.apple.foundationdb.record.query.plan.match.PlanMatchers.primaryKeyDistinct) PlanMatchers.indexScan(com.apple.foundationdb.record.query.plan.match.PlanMatchers.indexScan) PlanMatchers.queryPredicateDescendant(com.apple.foundationdb.record.query.plan.match.PlanMatchers.queryPredicateDescendant) RecordQuery(com.apple.foundationdb.record.query.RecordQuery) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) TestRecordsNestedMapProto(com.apple.foundationdb.record.TestRecordsNestedMapProto) PlanHashable(com.apple.foundationdb.record.PlanHashable) PlanMatchers.filter(com.apple.foundationdb.record.query.plan.match.PlanMatchers.filter) Key(com.apple.foundationdb.record.metadata.Key) PlanMatchers.scan(com.apple.foundationdb.record.query.plan.match.PlanMatchers.scan) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) Expressions.field(com.apple.foundationdb.record.metadata.Key.Expressions.field) FDBStoredRecord(com.apple.foundationdb.record.provider.foundationdb.FDBStoredRecord) RecordMetaDataBuilder(com.apple.foundationdb.record.RecordMetaDataBuilder) Tags(com.apple.test.Tags) PredicateMatchers(com.apple.foundationdb.record.query.predicates.match.PredicateMatchers) TestRecords5Proto(com.apple.foundationdb.record.TestRecords5Proto) Index(com.apple.foundationdb.record.metadata.Index) Message(com.google.protobuf.Message) RecordCursor(com.apple.foundationdb.record.RecordCursor) QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) Collections(java.util.Collections) QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) RecordQueryPlanner(com.apple.foundationdb.record.query.plan.RecordQueryPlanner) RecordQuery(com.apple.foundationdb.record.query.RecordQuery)

Aggregations

EvaluationContext (com.apple.foundationdb.record.EvaluationContext)1 IndexScanType (com.apple.foundationdb.record.IndexScanType)1 PlanHashable (com.apple.foundationdb.record.PlanHashable)1 RecordCursor (com.apple.foundationdb.record.RecordCursor)1 RecordCursorResult (com.apple.foundationdb.record.RecordCursorResult)1 RecordMetaData (com.apple.foundationdb.record.RecordMetaData)1 RecordMetaDataBuilder (com.apple.foundationdb.record.RecordMetaDataBuilder)1 TestHelpers (com.apple.foundationdb.record.TestHelpers)1 TestRecords3Proto (com.apple.foundationdb.record.TestRecords3Proto)1 TestRecords4Proto (com.apple.foundationdb.record.TestRecords4Proto)1 TestRecords5Proto (com.apple.foundationdb.record.TestRecords5Proto)1 TestRecordsNestedMapProto (com.apple.foundationdb.record.TestRecordsNestedMapProto)1 TestRecordsWithHeaderProto (com.apple.foundationdb.record.TestRecordsWithHeaderProto)1 Index (com.apple.foundationdb.record.metadata.Index)1 IndexTypes (com.apple.foundationdb.record.metadata.IndexTypes)1 Key (com.apple.foundationdb.record.metadata.Key)1 Expressions.concat (com.apple.foundationdb.record.metadata.Key.Expressions.concat)1 Expressions.concatenateFields (com.apple.foundationdb.record.metadata.Key.Expressions.concatenateFields)1 Expressions.field (com.apple.foundationdb.record.metadata.Key.Expressions.field)1 GroupingKeyExpression (com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression)1