use of com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan in project fdb-record-layer by FoundationDB.
the class FDBRecordStoreQueryTest method query.
@DualPlannerTest
void query() throws Exception {
try (FDBRecordContext context = openContext()) {
openSimpleRecordStore(context);
for (int i = 0; i < 100; i++) {
TestRecords1Proto.MySimpleRecord.Builder recBuilder = TestRecords1Proto.MySimpleRecord.newBuilder();
recBuilder.setRecNo(i);
recBuilder.setStrValueIndexed((i & 1) == 1 ? "odd" : "even");
recBuilder.setNumValueUnique(i + 1000);
recordStore.saveRecord(recBuilder.build());
}
commit(context);
}
RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.field("str_value_indexed").equalsValue("even")).build();
RecordQueryPlan plan = planner.plan(query);
try (FDBRecordContext context = openContext()) {
openSimpleRecordStore(context);
int i = 0;
try (RecordCursorIterator<FDBQueriedRecord<Message>> cursor = recordStore.executeQuery(plan).asIterator()) {
while (cursor.hasNext()) {
FDBQueriedRecord<Message> rec = Objects.requireNonNull(cursor.next());
TestRecords1Proto.MySimpleRecord.Builder myrec = TestRecords1Proto.MySimpleRecord.newBuilder();
myrec.mergeFrom(rec.getRecord());
assertEquals(0, myrec.getNumValueUnique() % 2);
i++;
}
}
assertEquals(50, i);
assertDiscardedNone(context);
}
}
use of com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan in project fdb-record-layer by FoundationDB.
the class FDBRecordStoreQueryTest method doesNotNormalizeLargeCnf.
/**
* Check that a query with a CNF filter predicate that would be very large in disjunctive normal form does not get
* normalized. For now, the predicate should be left alone as a filter.
* @see com.apple.foundationdb.record.query.plan.planning.BooleanNormalizer
*/
@Test
void doesNotNormalizeLargeCnf() throws Exception {
RecordMetaDataHook hook = complexQuerySetupHook();
complexQuerySetup(hook);
final QueryComponent cnf = Query.and(IntStream.rangeClosed(1, 9).boxed().map(i -> Query.or(IntStream.rangeClosed(1, 9).boxed().map(j -> Query.field("num_value_3_indexed").equalsValue(i * 9 + j)).collect(Collectors.toList()))).collect(Collectors.toList()));
final RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(cnf).build();
RecordQueryPlan plan = planner.plan(query);
assertMatchesExactly(plan, filterPlan(RecordQueryPlanMatchers.anyPlan()).where(queryComponents(only(equalsObject(cnf)))));
}
use of com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan in project fdb-record-layer by FoundationDB.
the class FDBRecordStoreQueryTest method doesNotNormalizeBigExpression.
/**
* Check that a query with a non-CNF filter predicate that would be very large in disjunctive normal form does not
* get normalized. For now, the predicate should be left alone as a filter.
* @see com.apple.foundationdb.record.query.plan.planning.BooleanNormalizer
*/
@Test
void doesNotNormalizeBigExpression() throws Exception {
RecordMetaDataHook hook = complexQuerySetupHook();
complexQuerySetup(hook);
final QueryComponent cnf = Query.and(IntStream.rangeClosed(1, 9).boxed().map(i -> Query.or(IntStream.rangeClosed(1, 9).boxed().map(j -> Query.and(Query.field("num_value_3_indexed").equalsValue(i * 9 + j), Query.field("str_value_indexed").equalsValue("foo"))).collect(Collectors.toList()))).collect(Collectors.toList()));
final RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(cnf).build();
RecordQueryPlan plan = planner.plan(query);
assertMatchesExactly(plan, filterPlan(RecordQueryPlanMatchers.anyPlan()).where(queryComponents(only(equalsObject(cnf)))));
}
use of com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan in project fdb-record-layer by FoundationDB.
the class FDBRecordStoreQueryTest method queryWithContinuation.
/**
* Verify that simple queries execute properly with continuations.
*/
@DualPlannerTest
void queryWithContinuation() throws Exception {
setupSimpleRecordStore(null, (i, builder) -> {
builder.setRecNo(i);
builder.setNumValue2(i % 2);
builder.setStrValueIndexed((i % 2 == 0) ? "even" : "odd");
});
try (FDBRecordContext context = openContext()) {
openSimpleRecordStore(context, null);
RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setAllowedIndexes(Collections.emptyList()).build();
// Scan(<,>) | [MySimpleRecord]
RecordQueryPlan plan = planner.plan(query);
assertMatchesExactly(plan, typeFilterPlan(scanPlan().where(scanComparisons(unbounded()))).where(recordTypes(containsAll(ImmutableSet.of("MySimpleRecord")))));
assertEquals(1623132336, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(1955010341, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(1955010341, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
byte[] continuation = null;
List<TestRecords1Proto.MySimpleRecord> retrieved = new ArrayList<>(100);
while (true) {
RecordCursor<TestRecords1Proto.MySimpleRecord> cursor = recordStore.executeQuery(plan, continuation, ExecuteProperties.newBuilder().setReturnedRowLimit(10).build()).map(rec -> TestRecords1Proto.MySimpleRecord.newBuilder().mergeFrom(rec.getRecord()).build());
List<TestRecords1Proto.MySimpleRecord> list = cursor.asList().get();
assertEquals(Math.min(10, 100 - retrieved.size()), list.size());
for (int i = 0; i < list.size(); i++) {
assertEquals(retrieved.size() + i, list.get(i).getRecNo());
}
assertDiscardedNone(context);
retrieved.addAll(list);
if (retrieved.size() > 100) {
fail("added more records than were present");
}
continuation = cursor.getNext().getContinuation().toBytes();
if (continuation == null) {
break;
}
}
query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.field("str_value_indexed").equalsValue("odd")).build();
// Index(MySimpleRecord$str_value_indexed [[odd],[odd]])
plan = planner.plan(query);
assertMatchesExactly(plan, indexPlan().where(indexName("MySimpleRecord$str_value_indexed")).and(scanComparisons(range("[[odd],[odd]]"))));
assertEquals(-1917280682, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(-1357054180, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(9136435, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
continuation = null;
retrieved = new ArrayList<>(50);
while (true) {
RecordCursor<TestRecords1Proto.MySimpleRecord> cursor = recordStore.executeQuery(plan, continuation, ExecuteProperties.newBuilder().setReturnedRowLimit(5).build()).map(rec -> TestRecords1Proto.MySimpleRecord.newBuilder().mergeFrom(rec.getRecord()).build());
List<TestRecords1Proto.MySimpleRecord> list = cursor.asList().get();
assertEquals(Math.min(5, 50 - retrieved.size()), list.size());
for (int i = 0; i < list.size(); i++) {
assertEquals(2 * (retrieved.size() + i) + 1, list.get(i).getRecNo());
}
assertDiscardedNone(context);
retrieved.addAll(list);
if (retrieved.size() > 50) {
fail("added more records than met filter");
}
continuation = cursor.getNext().getContinuation().toBytes();
if (continuation == null) {
break;
}
}
clearStoreCounter(context);
final QueryComponent filter = Query.field("num_value_2").equalsValue(0);
query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(filter).build();
plan = planner.plan(query);
if (planner instanceof RecordQueryPlanner) {
assertMatchesExactly(plan, filterPlan(typeFilterPlan(scanPlan().where(scanComparisons(unbounded())))).where(queryComponents(exactly(equalsObject(filter)))));
assertEquals(913370522, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
// TODO: https://github.com/FoundationDB/fdb-record-layer/issues/1074
// assertEquals(389700036, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
} else {
assertMatchesExactly(plan, predicatesFilterPlan(typeFilterPlan(scanPlan().where(scanComparisons(unbounded())))).where(predicates(only(valuePredicate(fieldValue(anyValue(), "num_value_2"), new Comparisons.SimpleComparison(Comparisons.Type.EQUALS, 0))))));
assertEquals(-1244637277, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
}
continuation = null;
retrieved = new ArrayList<>(50);
while (true) {
RecordCursor<TestRecords1Proto.MySimpleRecord> cursor = recordStore.executeQuery(plan, continuation, ExecuteProperties.newBuilder().setReturnedRowLimit(15).build()).map(rec -> TestRecords1Proto.MySimpleRecord.newBuilder().mergeFrom(rec.getRecord()).build());
List<TestRecords1Proto.MySimpleRecord> list = cursor.asList().get();
assertEquals(Math.min(15, 50 - retrieved.size()), list.size());
for (int i = 0; i < list.size(); i++) {
assertEquals(2 * (retrieved.size() + i), list.get(i).getRecNo());
}
retrieved.addAll(list);
if (retrieved.size() > 50) {
fail("added more records than met filter");
}
continuation = cursor.getNext().getContinuation().toBytes();
if (continuation == null) {
break;
}
}
assertDiscardedAtMost(51, context);
}
}
use of com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan in project fdb-record-layer by FoundationDB.
the class FDBInQueryTest method testRecordFunctionInGrouped.
/**
* Verify that IN works with grouped rank indexes.
*/
@Test
void testRecordFunctionInGrouped() throws Exception {
RecordMetaDataHook recordMetaDataHook = metadata -> metadata.addIndex("MySimpleRecord", new Index("rank_by_string", field("num_value_2").groupBy(field("str_value_indexed")), IndexTypes.RANK));
setupSimpleRecordStore(recordMetaDataHook, (i, builder) -> builder.setRecNo(i).setStrValueIndexed("str" + i % 4).setNumValue2(i + 100));
List<Long> ls = Arrays.asList(1L, 3L, 5L);
RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.and(Query.field("str_value_indexed").equalsValue("str0"), Query.rank(Key.Expressions.field("num_value_2").groupBy(Key.Expressions.field("str_value_indexed"))).in(ls))).build();
// Index(rank_by_string [EQUALS str0, EQUALS $__in_rank([Field { 'str_value_indexed' None}, Field { 'num_value_2' None}] group 1)__0] BY_RANK) WHERE __in_rank([Field { 'str_value_indexed' None}, Field { 'num_value_2' None}] group 1)__0 IN [1, 3, 5]
RecordQueryPlan plan = planner.plan(query);
assertMatchesExactly(plan, inValuesJoinPlan(indexPlan().where(indexName("rank_by_string")).and(RecordQueryPlanMatchers.indexScanType(IndexScanType.BY_RANK))).where(inValuesList(equalsObject(ls))));
assertEquals(-778840248, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(-1474202802, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(2030164999, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
List<Long> recNos = new ArrayList<>();
querySimpleRecordStore(recordMetaDataHook, plan, EvaluationContext::empty, record -> recNos.add(record.getRecNo()), TestHelpers::assertDiscardedNone);
assertEquals(Arrays.asList(4L, 12L, 20L), recNos);
}
Aggregations