use of com.apple.foundationdb.record.RecordMetaDataBuilder in project fdb-record-layer by FoundationDB.
the class FDBRecordStoreNullQueryTest method proto3ScalarNotNullMetaData.
protected static RecordMetaData proto3ScalarNotNullMetaData() {
RecordMetaDataBuilder metaData = RecordMetaData.newBuilder().setRecords(TestRecordsNulls3Proto.getDescriptor());
metaData.addIndex("MyNullRecord", "MyNullRecord$int_value", Key.Expressions.field("int_value", KeyExpression.FanType.None, Key.Evaluated.NullStandin.NOT_NULL));
metaData.addIndex("MyNullRecord", "MyNullRecord$string_value", Key.Expressions.field("string_value", KeyExpression.FanType.None, Key.Evaluated.NullStandin.NOT_NULL));
return metaData.getRecordMetaData();
}
use of com.apple.foundationdb.record.RecordMetaDataBuilder in project fdb-record-layer by FoundationDB.
the class FDBNestedFieldQueryTest method nestedRankMap.
/**
* Verify that a rank index on a map-like repeated nested message can be scanned for rank comparisons.
*/
@Test
public void nestedRankMap() throws Exception {
final GroupingKeyExpression rankGroup = new GroupingKeyExpression(concat(field("other_id"), field("map").nest(field("entry", KeyExpression.FanType.FanOut).nest(concatenateFields("key", "value")))), 1);
final RecordMetaDataBuilder metaDataBuilder = RecordMetaData.newBuilder().setRecords(TestRecordsNestedMapProto.getDescriptor());
metaDataBuilder.addIndex("OuterRecord", new Index("rank_value_by_key", rankGroup, IndexTypes.RANK));
// TODO: This is not a very obvious way to specify this. But we don't have correlation names.
final QueryComponent keyCondition = Query.field("map").matches(Query.field("entry").oneOfThem().matches(Query.field("key").equalsValue("alpha")));
final QueryRecordFunction<Long> rank = Query.rank(rankGroup).withAdditionalCondition(keyCondition);
try (FDBRecordContext context = openContext()) {
createOrOpenRecordStore(context, metaDataBuilder.getRecordMetaData());
TestRecordsNestedMapProto.OuterRecord.Builder builder = TestRecordsNestedMapProto.OuterRecord.newBuilder().setOtherId(1);
TestRecordsNestedMapProto.MapRecord.Builder mapBuilder = builder.getMapBuilder();
builder.setRecId(1);
mapBuilder.addEntryBuilder().setKey("alpha").setValue("abc");
mapBuilder.addEntryBuilder().setKey("beta").setValue("bcd");
recordStore.saveRecord(builder.build());
builder.setRecId(2);
mapBuilder.clear();
mapBuilder.addEntryBuilder().setKey("alpha").setValue("aaa");
mapBuilder.addEntryBuilder().setKey("beta").setValue("bbb");
recordStore.saveRecord(builder.build());
commit(context);
}
RecordQuery query = RecordQuery.newBuilder().setRecordType("OuterRecord").setFilter(Query.and(Query.field("other_id").equalsValue(1L), Query.rank(rankGroup).lessThan(10L), keyCondition)).build();
RecordQueryPlan plan = planner.plan(query);
assertThat(plan, primaryKeyDistinct(indexScan(allOf(indexName("rank_value_by_key"), indexScanType(IndexScanType.BY_RANK), bounds(hasTupleString("([1, alpha, null],[1, alpha, 10])"))))));
assertEquals(1307013946, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(-1725407749, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(825274646, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
try (FDBRecordContext context = openContext()) {
createOrOpenRecordStore(context, metaDataBuilder.getRecordMetaData());
try (RecordCursor<FDBQueriedRecord<Message>> cursor = recordStore.executeQuery(plan)) {
RecordCursorResult<FDBQueriedRecord<Message>> result = cursor.getNext();
assertTrue(result.hasNext());
assertEquals(Tuple.from(2), result.get().getPrimaryKey());
result = cursor.getNext();
assertTrue(result.hasNext());
assertEquals(Tuple.from(1), result.get().getPrimaryKey());
assertEquals(1, rank.eval(recordStore, EvaluationContext.EMPTY, result.get().getStoredRecord()).get());
result = cursor.getNext();
assertFalse(result.hasNext());
}
}
}
use of com.apple.foundationdb.record.RecordMetaDataBuilder in project fdb-record-layer by FoundationDB.
the class FDBCoveringIndexQueryTest method coveringWithAdditionalNestedFilter.
/**
* Verify that an extra covering filter can use a nested field.
*/
@DualPlannerTest
void coveringWithAdditionalNestedFilter() {
try (FDBRecordContext context = openContext()) {
RecordMetaDataBuilder builder = RecordMetaData.newBuilder().setRecords(TestRecordsWithHeaderProto.getDescriptor());
builder.getRecordType("MyRecord").setPrimaryKey(field("header").nest(field("rec_no")));
builder.addIndex("MyRecord", "multi", concat(field("str_value"), field("header").nest(concatenateFields("path", "num"))));
RecordMetaData metaData = builder.getRecordMetaData();
createOrOpenRecordStore(context, metaData);
RecordQuery query = RecordQuery.newBuilder().setRecordType("MyRecord").setFilter(Query.and(Query.field("str_value").equalsValue("abc"), Query.field("header").matches(Query.field("num").equalsValue(1)))).build();
// Fetch(Covering(Index(multi [[abc],[abc]]) -> [str_value: KEY[0], header: [num: KEY[2], path: KEY[1], rec_no: KEY[3]]]) | header/{num EQUALS 1})
RecordQueryPlan plan = planner.plan(query);
if (planner instanceof RecordQueryPlanner) {
final BindingMatcher<? extends RecordQueryPlan> planMatcher = fetchFromPartialRecordPlan(filterPlan(coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("multi")).and(scanComparisons(range("[[abc],[abc]]")))))).where(queryComponents(exactly(equalsObject(Query.field("header").matches(Query.field("num").equalsValue(1)))))));
assertMatchesExactly(plan, planMatcher);
assertEquals(-1536005152, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(1350035332, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-1843652335, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
} else {
final BindingMatcher<? extends RecordQueryPlan> planMatcher = fetchFromPartialRecordPlan(predicatesFilterPlan(coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("multi")).and(scanComparisons(range("[[abc],[abc]]")))))).where(predicates(only(valuePredicate(fieldValue("header.num"), new Comparisons.SimpleComparison(Comparisons.Type.EQUALS, 1))))));
assertMatchesExactly(plan, planMatcher);
assertEquals(1623341655, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(2019556616, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-1174131051, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
}
}
}
use of com.apple.foundationdb.record.RecordMetaDataBuilder in project fdb-record-layer by FoundationDB.
the class FDBNestedFieldQueryTest method nestedAndOnNestedMap.
/**
* Verify that an AND query on a nested record store that can be mostly implemented by a scan of a concatenated index
* still filters on predicates that are not satisfied by scanning that index.
* Specifically, verify that an AND query with a predicate on an outer record and a predicate on an inner, map-like
* record that can be satisfied by scanning a particular index, and a predicate on the inner record that cannot be
* satisfied by scanning that index, is planned as an index scan followed by a filter with the unsatisfied predicate.
*/
@DualPlannerTest
public void nestedAndOnNestedMap() throws Exception {
try (FDBRecordContext context = openContext()) {
RecordMetaDataBuilder metaDataBuilder = RecordMetaData.newBuilder().setRecords(TestRecordsNestedMapProto.getDescriptor());
metaDataBuilder.addIndex("OuterRecord", "key_index", concat(field("other_id"), field("map").nest(field("entry", KeyExpression.FanType.FanOut).nest("key"))));
createOrOpenRecordStore(context, metaDataBuilder.getRecordMetaData());
commit(context);
}
RecordQuery query = RecordQuery.newBuilder().setRecordType("OuterRecord").setFilter(Query.and(Query.field("other_id").equalsValue(1L), Query.field("map").matches(Query.field("entry").oneOfThem().matches(Query.and(Query.field("key").equalsValue("alpha"), Query.field("value").notEquals("test")))))).build();
// Index(key_index [[1, alpha],[1, alpha]]) | UnorderedPrimaryKeyDistinct() | map/{one of entry/{And([key EQUALS alpha, value NOT_EQUALS test])}}
RecordQueryPlan plan = planner.plan(query);
// verify that the value filter that can't be satisfied by the index isn't dropped from the filter expression
assertThat(plan, filter(Query.field("map").matches(Query.field("entry").oneOfThem().matches(Query.and(Query.field("key").equalsValue("alpha"), Query.field("value").notEquals("test")))), primaryKeyDistinct(indexScan(allOf(indexName("key_index"), bounds(hasTupleString("[[1, alpha],[1, alpha]]")))))));
if (planner instanceof RecordQueryPlanner) {
assertEquals(-1406660101, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(-16989308, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-1707510741, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
} else {
assertEquals(-1406660101, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(-307963352, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-1998484785, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
}
}
use of com.apple.foundationdb.record.RecordMetaDataBuilder in project fdb-record-layer by FoundationDB.
the class FDBRecordStoreIndexTest method noMaintenanceFilteredOnIndex.
@Test
public void noMaintenanceFilteredOnIndex() throws Exception {
try (FDBRecordContext context = openContext()) {
openAnyRecordStore(TestRecordsIndexFilteringProto.getDescriptor(), context);
TestRecordsIndexFilteringProto.MyBasicRecord recordA = TestRecordsIndexFilteringProto.MyBasicRecord.newBuilder().setRecNo(1001).setNumValue2(101).build();
recordStore.saveRecord(recordA);
context.commit();
Collection<StoreTimer.Event> events = context.getTimer().getEvents();
assertFalse(events.contains(FDBStoreTimer.Events.SAVE_INDEX_ENTRY));
assertFalse(events.contains(FDBStoreTimer.Events.SKIP_INDEX_RECORD));
}
// add index
RecordMetaDataHook hook = metaDataBuilder -> {
metaDataBuilder.setVersion(metaDataBuilder.getVersion() + 1);
metaDataBuilder.addIndex("MyBasicRecord", "value2$filtered", field("num_value_2"));
};
// rebuild the index so that it is in a READABLE state
try (FDBRecordContext context = openContext()) {
openAnyRecordStore(TestRecordsIndexFilteringProto.getDescriptor(), context, hook);
try (OnlineIndexer indexer = OnlineIndexer.forRecordStoreAndIndex(recordStore, "value2$filtered")) {
indexer.buildIndex();
}
}
try (FDBRecordContext context = openContext()) {
openAnyRecordStore(TestRecordsIndexFilteringProto.getDescriptor(), context, hook);
context.getTimer().reset();
TestRecordsIndexFilteringProto.MyBasicRecord recordA = TestRecordsIndexFilteringProto.MyBasicRecord.newBuilder().setRecNo(1002).setNumValue2(102).build();
recordStore.saveRecord(recordA);
context.commit();
Collection<StoreTimer.Event> events = context.getTimer().getEvents();
assertTrue(events.contains(FDBStoreTimer.Events.SAVE_INDEX_ENTRY));
assertFalse(events.contains(FDBStoreTimer.Events.SKIP_INDEX_RECORD));
}
try (FDBRecordContext context = openContext()) {
RecordMetaDataBuilder metaData = RecordMetaData.newBuilder().setRecords(TestRecordsIndexFilteringProto.getDescriptor());
hook.apply(metaData);
IndexMaintenanceFilter noneFilter = (i, r) -> IndexMaintenanceFilter.IndexValues.NONE;
recordStore = getStoreBuilder(context, metaData.getRecordMetaData()).setIndexMaintenanceFilter(noneFilter).createOrOpen();
setupPlanner(null);
context.getTimer().reset();
TestRecordsIndexFilteringProto.MyBasicRecord recordB = TestRecordsIndexFilteringProto.MyBasicRecord.newBuilder().setRecNo(1003).setNumValue2(103).build();
recordStore.saveRecord(recordB);
context.commit();
Collection<StoreTimer.Event> events = context.getTimer().getEvents();
assertFalse(events.contains(FDBStoreTimer.Events.SAVE_INDEX_ENTRY));
assertTrue(events.contains(FDBStoreTimer.Events.SKIP_INDEX_RECORD));
}
}
Aggregations