use of com.apple.foundationdb.record.query.expressions.QueryComponent in project fdb-record-layer by FoundationDB.
the class FDBRecordStoreLimitTestBase method plans.
public Stream<Arguments> plans(boolean fail) {
RecordQueryPlan scanPlan = new RecordQueryScanPlan(ScanComparisons.EMPTY, false);
IndexScanParameters fullValueScan = IndexScanComparisons.byValue();
RecordQueryPlan indexPlan = new RecordQueryIndexPlan("MySimpleRecord$str_value_indexed", fullValueScan, false);
QueryComponent filter = Query.field("str_value_indexed").equalsValue("odd");
QueryComponent middleFilter = Query.and(Query.field("rec_no").greaterThan(24L), Query.field("rec_no").lessThan(60L));
RecordQueryPlan firstChild = indexPlanEquals("MySimpleRecord$str_value_indexed", "even");
RecordQueryPlan secondChild = indexPlanEquals("MySimpleRecord$num_value_3_indexed", 0);
return Stream.of(Arguments.of("full record scan", fail, scanPlan), Arguments.of("simple index scan", fail, indexPlan), Arguments.of("reverse index scan", fail, new RecordQueryIndexPlan("MySimpleRecord$str_value_indexed", fullValueScan, true)), Arguments.of("filter on scan plan", fail, new RecordQueryFilterPlan(scanPlan, filter)), Arguments.of("filter on index plan", fail, new RecordQueryFilterPlan(indexPlan, filter)), Arguments.of("type filter on scan plan", fail, new RecordQueryTypeFilterPlan(scanPlan, Collections.singletonList("MySimpleRecord"))), Arguments.of("type filter on index plan", fail, new RecordQueryTypeFilterPlan(indexPlan, Collections.singletonList("MySimpleRecord"))), Arguments.of("disjoint union", fail, RecordQueryUnionPlan.from(indexPlanEquals("MySimpleRecord$str_value_indexed", "odd"), indexPlanEquals("MySimpleRecord$str_value_indexed", "even"), primaryKey(), false)), Arguments.of("overlapping union", fail, RecordQueryUnionPlan.from(firstChild, secondChild, primaryKey(), false)), Arguments.of("overlapping union (swapped args)", fail, RecordQueryUnionPlan.from(secondChild, firstChild, primaryKey(), false)), Arguments.of("overlapping intersection", fail, RecordQueryIntersectionPlan.from(firstChild, secondChild, primaryKey())), Arguments.of("overlapping intersection", fail, RecordQueryIntersectionPlan.from(secondChild, firstChild, primaryKey())), Arguments.of("union with inner filter", fail, RecordQueryUnionPlan.from(new RecordQueryFilterPlan(firstChild, middleFilter), secondChild, primaryKey(), false)), Arguments.of("union with two inner filters", fail, RecordQueryUnionPlan.from(new RecordQueryFilterPlan(firstChild, middleFilter), new RecordQueryFilterPlan(secondChild, Query.field("rec_no").lessThan(55L)), primaryKey(), false)), Arguments.of("intersection with inner filter", fail, RecordQueryIntersectionPlan.from(new RecordQueryFilterPlan(firstChild, middleFilter), secondChild, primaryKey())), Arguments.of("intersection with two inner filters", fail, RecordQueryIntersectionPlan.from(new RecordQueryFilterPlan(firstChild, middleFilter), new RecordQueryFilterPlan(secondChild, Query.field("rec_no").lessThan(55L)), primaryKey())));
}
use of com.apple.foundationdb.record.query.expressions.QueryComponent in project fdb-record-layer by FoundationDB.
the class FDBInQueryTest method cnfAsInQuery.
/**
* Verify that an IN predicate that, when converted to an OR of equality predicates, would lead to a very large DNF
* gets planned as a normal IN query rather than throwing an exception.
*/
@Test
void cnfAsInQuery() throws Exception {
RecordMetaDataHook hook = metaData -> metaData.addIndex("MySimpleRecord", "compoundIndex", concat(field("num_value_3_indexed"), field("str_value_indexed")));
complexQuerySetup(hook);
// A CNF whose DNF size doesn't fit in an int, expressed with IN predicates.
List<QueryComponent> conjuncts = new ArrayList<>();
for (int i = 0; i < 32; i++) {
conjuncts.add(Query.field("num_value_3_indexed").in(ImmutableList.of(i * 100, i * 100 + 1)));
}
final QueryComponent filter = Query.and(conjuncts);
RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(filter).setSort(field("str_value_indexed")).build();
RecordQueryPlan plan = planner.plan(query);
// Did not throw an exception
assertMatchesExactly(plan, filterPlan(indexPlan().where(indexName("MySimpleRecord$str_value_indexed")).and(scanComparisons(unbounded()))).where(queryComponents(exactly(conjuncts.stream().map(PrimitiveMatchers::equalsObject).collect(ImmutableList.toImmutableList())))));
}
use of com.apple.foundationdb.record.query.expressions.QueryComponent in project fdb-record-layer by FoundationDB.
the class FDBInQueryTest method testInQueryEmptyList.
/**
* Verify that an IN with an empty list returns nothing.
*/
@DualPlannerTest
void testInQueryEmptyList() throws Exception {
complexQuerySetup(NO_HOOK);
List<Integer> ls = Collections.emptyList();
final QueryComponent filter = Query.field("num_value_2").in(ls);
RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(filter).build();
// Scan(<,>) | [MySimpleRecord] | num_value_2 IN []
RecordQueryPlan plan = planner.plan(query);
if (planner instanceof RecordQueryPlanner) {
assertMatchesExactly(plan, filterPlan(selfOrDescendantPlans(scanPlan().where(scanComparisons(unbounded())))).where(queryComponents(only(equalsObject(filter)))));
assertEquals(-1139440895, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(-1907402540, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-1694845095, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
} else {
assertMatchesExactly(plan, predicatesFilterPlan(selfOrDescendantPlans(scanPlan().and(scanComparisons(unbounded())))).where(predicates(valuePredicate(fieldValue("num_value_2"), new Comparisons.ListComparison(Comparisons.Type.IN, ImmutableList.of())))));
assertEquals(997518602, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(-1107789406, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-895231961, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
}
assertEquals(0, querySimpleRecordStore(NO_HOOK, plan, EvaluationContext::empty, (rec) -> {
}));
}
use of com.apple.foundationdb.record.query.expressions.QueryComponent in project fdb-record-layer by FoundationDB.
the class FDBOrQueryToUnionTest method testOrQueryNoIndex.
/**
* Verify that queries with an OR of predicates with a common scan and different filters does not bother with a Union.
*/
@DualPlannerTest
void testOrQueryNoIndex() throws Exception {
RecordMetaDataHook hook = metadata -> metadata.removeIndex("MySimpleRecord$num_value_3_indexed");
complexQuerySetup(hook);
QueryComponent orComponent = Query.or(Query.field("num_value_3_indexed").equalsValue(1), Query.field("num_value_3_indexed").equalsValue(2), Query.field("num_value_3_indexed").equalsValue(4));
RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.and(Query.field("str_value_indexed").equalsValue("even"), orComponent)).build();
// Index(MySimpleRecord$str_value_indexed [[even],[even]]) | Or([num_value_3_indexed EQUALS 1, num_value_3_indexed EQUALS 2, num_value_3_indexed EQUALS 4])
RecordQueryPlan plan = planner.plan(query);
if (planner instanceof RecordQueryPlanner) {
final BindingMatcher<? extends RecordQueryPlan> planMatcher = filterPlan(indexPlan().where(indexName("MySimpleRecord$str_value_indexed")).and(scanComparisons(range("[[even],[even]]")))).where(queryComponents(exactly(equalsObject(orComponent))));
assertMatchesExactly(plan, planMatcher);
assertEquals(-1553701984, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(1108620348, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(1573180943, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
} else {
final BindingMatcher<? extends RecordQueryPlan> planMatcher = predicatesFilterPlan(indexPlan().where(indexName("MySimpleRecord$str_value_indexed")).and(scanComparisons(range("[[even],[even]]")))).where(predicates(only(orPredicate(exactly(valuePredicate(fieldValue("num_value_3_indexed"), new Comparisons.SimpleComparison(Comparisons.Type.EQUALS, 1)), valuePredicate(fieldValue("num_value_3_indexed"), new Comparisons.SimpleComparison(Comparisons.Type.EQUALS, 2)), valuePredicate(fieldValue("num_value_3_indexed"), new Comparisons.SimpleComparison(Comparisons.Type.EQUALS, 4)))))));
assertMatchesExactly(plan, planMatcher);
assertEquals(-1029166388, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(1957223857, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-1873182844, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
}
try (FDBRecordContext context = openContext()) {
openSimpleRecordStore(context, hook);
int i = 0;
try (RecordCursorIterator<FDBQueriedRecord<Message>> cursor = recordStore.executeQuery(plan).asIterator()) {
while (cursor.hasNext()) {
FDBQueriedRecord<Message> rec = cursor.next();
TestRecords1Proto.MySimpleRecord.Builder myrec = TestRecords1Proto.MySimpleRecord.newBuilder();
myrec.mergeFrom(Objects.requireNonNull(rec).getRecord());
assertEquals("even", myrec.getStrValueIndexed());
assertTrue(myrec.getNumValue3Indexed() == 1 || myrec.getNumValue3Indexed() == 2 || myrec.getNumValue3Indexed() == 4);
i++;
}
}
assertEquals(10 + 10 + 10, i);
assertDiscardedExactly(10 + 10, context);
}
}
use of com.apple.foundationdb.record.query.expressions.QueryComponent in project fdb-record-layer by FoundationDB.
the class FDBInQueryTest method testInQueryNoIndexWithParameter.
/**
* Verify that an IN (with parameter) without an index is implemented as a filter on a scan.
*/
@Test
void testInQueryNoIndexWithParameter() throws Exception {
complexQuerySetup(NO_HOOK);
final QueryComponent filter = Query.field("num_value_2").in("valuesThree");
RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(// num_value_2 is i%3
filter).build();
// Scan(<,>) | [MySimpleRecord] | num_value_2 IN $valuesThree
RecordQueryPlan plan = planner.plan(query);
assertMatchesExactly(plan, filterPlan(descendantPlans(scanPlan().where(scanComparisons(unbounded())))).where(queryComponents(exactly(equalsObject(filter)))));
assertEquals(-1677754212, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(-192829430, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-192829430, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
assertEquals(33, querySimpleRecordStore(NO_HOOK, plan, () -> EvaluationContext.forBinding("valuesThree", asList(1, 3)), record -> assertThat(record.getNumValue2(), anyOf(is(1), is(3))), context -> assertDiscardedAtMost(67, context)));
}
Aggregations