use of com.apple.foundationdb.record.EvaluationContext in project fdb-record-layer by FoundationDB.
the class FDBInQueryTest method testOneOfThemInSorted.
/**
* Verify that one-of-them queries work with IN when sorted on the repeated field.
*/
@Test
void testOneOfThemInSorted() throws Exception {
RecordMetaDataHook recordMetaDataHook = metadata -> metadata.addIndex("MySimpleRecord", "ind", field("repeater", FanType.FanOut));
setupSimpleRecordStore(recordMetaDataHook, (i, builder) -> builder.setRecNo(i).addAllRepeater(Arrays.asList(10 + i % 4, 20 + i % 4)));
List<Integer> ls = Arrays.asList(13, 22);
List<Integer> reversed = new ArrayList<>(ls);
Collections.reverse(reversed);
RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.field("repeater").oneOfThem().in(reversed)).setSort(field("repeater", FanType.FanOut)).build();
RecordQueryPlan plan = planner.plan(query);
assertMatchesExactly(plan, inValuesJoinPlan(unorderedPrimaryKeyDistinctPlan(indexPlan().where(indexName("ind")).and(scanComparisons(range("[EQUALS $__in_repeater__0]"))))).where(inValuesList(equalsObject(ls))));
assertEquals(503365582, plan.planHash());
assertEquals(50, querySimpleRecordStore(recordMetaDataHook, plan, EvaluationContext::empty, record -> assertThat(record.getRecNo() % 4, anyOf(is(3L), is(2L))), TestHelpers::assertDiscardedNone));
}
use of com.apple.foundationdb.record.EvaluationContext in project fdb-record-layer by FoundationDB.
the class FDBInQueryTest method testInQueryOrOverlap.
/**
* Verify that IN queries can be planned using index scans, then used in a UNION to implement an OR with IN whose
* elements overlap, and that the union with that comparison key deduplicates the records in the overlap.
*/
@DualPlannerTest
void testInQueryOrOverlap() throws Exception {
complexQuerySetup(NO_HOOK);
RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.or(Query.field("num_value_unique").in(Arrays.asList(903, 905, 901)), Query.field("num_value_unique").in(Arrays.asList(906, 905, 904)))).build();
RecordQueryPlan plan = planner.plan(query);
if (planner instanceof RecordQueryPlanner) {
// Index(MySimpleRecord$num_value_unique [EQUALS $__in_num_value_unique__0]) WHERE __in_num_value_unique__0 IN [901, 903, 905] SORTED ∪[Field { 'num_value_unique' None}, Field { 'rec_no' None}] Index(MySimpleRecord$num_value_unique [EQUALS $__in_num_value_unique__0]) WHERE __in_num_value_unique__0 IN [904, 905, 906] SORTED
// Ordinary equality comparisons would be ordered just by the primary key so that would be the union comparison key.
// Must compare the IN field here; they are ordered, but not trivially (same value for each).
assertMatchesExactly(plan, unionPlan(inValuesJoinPlan(indexPlan().where(indexName("MySimpleRecord$num_value_unique")).and(scanComparisons(range("[EQUALS $__in_num_value_unique__0]")))).where(inValuesList(equalsObject(Arrays.asList(901, 903, 905)))), inValuesJoinPlan(indexPlan().where(indexName("MySimpleRecord$num_value_unique")).and(scanComparisons(range("[EQUALS $__in_num_value_unique__0]")))).where(inValuesList(equalsObject(Arrays.asList(904, 905, 906))))));
assertEquals(218263868, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(468995802, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(2098251608, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
} else {
assertMatchesExactly(plan, fetchFromPartialRecordPlan(unionPlan(inValuesJoinPlan(coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("MySimpleRecord$num_value_unique")).and(scanComparisons(equalities(exactly(anyParameterComparison()))))))).where(inValuesList(equalsObject(Arrays.asList(901, 903, 905)))), inValuesJoinPlan(coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("MySimpleRecord$num_value_unique")).and(scanComparisons(equalities(exactly(anyParameterComparison()))))))).where(inValuesList(equalsObject(Arrays.asList(904, 905, 906))))).where(comparisonKey(concat(field("num_value_unique"), primaryKey("MySimpleRecord"))))));
assertEquals(-1323754895, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(856768529, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-1700358353, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
}
Set<Long> dupes = new HashSet<>();
assertEquals(5, querySimpleRecordStore(NO_HOOK, plan, EvaluationContext::empty, record -> {
assertTrue(dupes.add(record.getRecNo()), "should not have duplicated records");
assertThat(record.getNumValueUnique(), anyOf(is(901), is(903), is(904), is(905), is(906)));
}, context -> TestHelpers.assertDiscardedAtMost(1, context)));
}
use of com.apple.foundationdb.record.EvaluationContext in project fdb-record-layer by FoundationDB.
the class FDBFilterCoalescingQueryTest method overlappingFilters.
/**
* TODO The planner does not currently coalesce the overlapping filters (>= 3 and > 0).
* TODO: Planner does not currently coalesce overlapping filters (https://github.com/FoundationDB/fdb-record-layer/issues/1)
*/
@Test
public void overlappingFilters() throws Exception {
RecordMetaDataHook hook = metaData -> {
metaData.addIndex("MySimpleRecord", new Index("multi_index", "str_value_indexed", "num_value_3_indexed"));
};
complexQuerySetup(hook);
RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.and(Query.field("str_value_indexed").equalsParameter("str"), Query.field("num_value_3_indexed").greaterThanOrEquals(3), Query.field("num_value_3_indexed").lessThanOrEquals(4), Query.field("num_value_3_indexed").greaterThan(0))).build();
// Index(multi_index [EQUALS $str, [GREATER_THAN_OR_EQUALS 3 && GREATER_THAN 0 && LESS_THAN_OR_EQUALS 4]])
RecordQueryPlan plan = planner.plan(query);
List<String> bounds = Arrays.asList("GREATER_THAN_OR_EQUALS 3", "LESS_THAN_OR_EQUALS 4", "GREATER_THAN 0");
Collection<List<String>> combinations = Collections2.permutations(bounds);
assertThat(plan, indexScan(allOf(indexName("multi_index"), bounds(anyOf(combinations.stream().map(ls -> hasTupleString("[EQUALS $str, [" + String.join(" && ", ls) + "]]")).collect(Collectors.toList()))))));
assertEquals(241654378, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(-81379784, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-1715241633, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
try (FDBRecordContext context = openContext()) {
openSimpleRecordStore(context, hook);
EvaluationContext boundContext = EvaluationContext.forBinding("str", "even");
int i = 0;
try (RecordCursorIterator<FDBQueriedRecord<Message>> cursor = plan.execute(recordStore, boundContext).asIterator()) {
while (cursor.hasNext()) {
FDBQueriedRecord<Message> rec = cursor.next();
TestRecords1Proto.MySimpleRecord.Builder myrec = TestRecords1Proto.MySimpleRecord.newBuilder();
myrec.mergeFrom(rec.getRecord());
assertEquals("even", myrec.getStrValueIndexed());
assertThat(myrec.getNumValue3Indexed(), allOf(greaterThanOrEqualTo(3), lessThanOrEqualTo(4)));
i++;
}
}
assertEquals(20, i);
assertDiscardedNone(context);
}
}
use of com.apple.foundationdb.record.EvaluationContext in project fdb-record-layer by FoundationDB.
the class FDBSelectorPlanTest method testTwoInnerPlan.
@DualPlannerTest
void testTwoInnerPlan() throws Exception {
complexQuerySetup(NO_HOOK);
RecordQuery query1 = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.field("num_value_2").equalsValue(1)).build();
RecordQuery query2 = RecordQuery.newBuilder().setRecordType("MySimpleRecord").build();
// This will always select plan1 for execution
RecordQueryPlan planUnderTest = RecordQuerySelectorPlan.from(plan(query1, query2), Arrays.asList(100, 0));
int count = querySimpleRecordStore(NO_HOOK, planUnderTest, EvaluationContext::empty, record -> assertThat(record.getNumValue2(), is(1)), context -> assertDiscardedAtMost(67, context));
assertEquals(33, count);
}
use of com.apple.foundationdb.record.EvaluationContext in project fdb-record-layer by FoundationDB.
the class FDBSelectorPlanTest method testOneInnerPlan.
@DualPlannerTest
void testOneInnerPlan() throws Exception {
complexQuerySetup(NO_HOOK);
RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.field("num_value_2").equalsValue(1)).build();
RecordQueryPlan planUnderTest = RecordQuerySelectorPlan.from(plan(query), Collections.singletonList(100));
int count = querySimpleRecordStore(NO_HOOK, planUnderTest, EvaluationContext::empty, record -> assertThat(record.getNumValue2(), is(1)), context -> assertDiscardedAtMost(67, context));
assertEquals(33, count);
}
Aggregations