use of com.apple.foundationdb.record.query.IndexQueryabilityFilter in project fdb-record-layer by FoundationDB.
the class FDBRecordStore method getSnapshotRecordCount.
@Override
public CompletableFuture<Long> getSnapshotRecordCount(@Nonnull KeyExpression key, @Nonnull Key.Evaluated value, @Nonnull IndexQueryabilityFilter indexQueryabilityFilter) {
if (getRecordMetaData().getRecordCountKey() != null) {
if (key.getColumnSize() != value.size()) {
throw recordCoreException("key and value are not the same size");
}
final ReadTransaction tr = context.readTransaction(true);
final Tuple subkey = Tuple.from(RECORD_COUNT_KEY).addAll(value.toTupleAppropriateList());
if (getRecordMetaData().getRecordCountKey().equals(key)) {
return tr.get(getSubspace().pack(subkey)).thenApply(FDBRecordStore::decodeRecordCount);
} else if (key.isPrefixKey(getRecordMetaData().getRecordCountKey())) {
AsyncIterable<KeyValue> kvs = tr.getRange(getSubspace().range(Tuple.from(RECORD_COUNT_KEY)));
return MoreAsyncUtil.reduce(getExecutor(), kvs.iterator(), 0L, (count, kv) -> count + decodeRecordCount(kv.getValue()));
}
}
return evaluateAggregateFunction(Collections.emptyList(), IndexFunctionHelper.count(key), TupleRange.allOf(value.toTuple()), IsolationLevel.SNAPSHOT, indexQueryabilityFilter).thenApply(tuple -> tuple.getLong(0));
}
use of com.apple.foundationdb.record.query.IndexQueryabilityFilter in project fdb-record-layer by FoundationDB.
the class FDBRestrictedIndexQueryTest method indexQueryabilityFilter.
/**
* Verify that the query planner uses the specified {@link com.apple.foundationdb.record.query.IndexQueryabilityFilter}.
* If both allowed indexes and a queryability filter are set, verify that the planner uses the allowed indexes.
*/
@DualPlannerTest
void indexQueryabilityFilter() {
RecordMetaDataHook hook = metaData -> {
metaData.removeIndex("MySimpleRecord$str_value_indexed");
metaData.addIndex("MySimpleRecord", new Index("limited_str_value_index", field("str_value_indexed"), Index.EMPTY_VALUE, IndexTypes.VALUE, IndexOptions.NOT_ALLOWED_FOR_QUERY_OPTIONS));
};
try (FDBRecordContext context = openContext()) {
openSimpleRecordStore(context, hook);
recordStore.deleteAllRecords();
commit(context);
}
RecordQuery query1 = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.field("str_value_indexed").equalsValue("abc")).build();
// Scan(<,>) | [MySimpleRecord] | str_value_indexed EQUALS abc
// Scan(<,>) | [MySimpleRecord] | $5eb5afb5-7c31-4fa4-bd7a-cec3027b6ade/str_value_indexed EQUALS abc
RecordQueryPlan plan1 = planner.plan(query1);
assertThat("should not use prohibited index", plan1, hasNoDescendant(indexScan("limited_str_value_index")));
assertTrue(plan1.hasFullRecordScan(), "should use full record scan");
if (planner instanceof RecordQueryPlanner) {
assertEquals(-223683738, plan1.planHash(PlanHashable.PlanHashKind.LEGACY));
// TODO: Issue https://github.com/FoundationDB/fdb-record-layer/issues/1074
// assertEquals(-1148834070, plan1.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
} else {
assertEquals(-2136471589, plan1.planHash(PlanHashable.PlanHashKind.LEGACY));
}
RecordQuery query2 = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.field("str_value_indexed").equalsValue("abc")).setIndexQueryabilityFilter(IndexQueryabilityFilter.TRUE).build();
// Index(limited_str_value_index [[abc],[abc]])
RecordQueryPlan plan2 = planner.plan(query2);
assertThat("explicitly use any index", plan2, descendant(indexScan("limited_str_value_index")));
assertFalse(plan2.hasRecordScan(), "should not use record scan");
assertEquals(-1573180774, plan2.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(994464666, plan2.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-1531627068, plan2.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
RecordQuery query3 = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.field("str_value_indexed").equalsValue("abc")).setIndexQueryabilityFilter(IndexQueryabilityFilter.FALSE).setAllowedIndex("limited_str_value_index").build();
// Index(limited_str_value_index [[abc],[abc]])
RecordQueryPlan plan3 = planner.plan(query3);
assertThat("should use allowed index despite index queryability filter", plan3, descendant(indexScan("limited_str_value_index")));
assertFalse(plan3.hasRecordScan(), "should not use record scan");
assertEquals(-1573180774, plan2.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(994464666, plan2.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-1531627068, plan2.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
}
Aggregations