use of com.apple.foundationdb.record.query.plan.plans.RecordQueryUnorderedUnionPlan in project fdb-record-layer by FoundationDB.
the class RecordQueryPlanner method planUnorderedUnion.
@Nullable
private ScoredPlan planUnorderedUnion(@Nonnull PlanContext planContext, @Nonnull List<ScoredPlan> subplans) {
final KeyExpression sort = planContext.query.getSort();
if (sort != null) {
return null;
}
List<RecordQueryPlan> childPlans = new ArrayList<>(subplans.size());
Set<RankComparisons.RankComparison> includedRankComparisons = null;
for (ScoredPlan subplan : subplans) {
childPlans.add(subplan.plan);
includedRankComparisons = mergeRankComparisons(includedRankComparisons, subplan.includedRankComparisons);
}
final RecordQueryUnorderedUnionPlan unionPlan = RecordQueryUnorderedUnionPlan.from(childPlans);
if (unionPlan.getComplexity() > configuration.getComplexityThreshold()) {
throw new RecordQueryPlanComplexityException(unionPlan);
}
return new ScoredPlan(unionPlan, Collections.emptyList(), Collections.emptyList(), 1, true, includedRankComparisons);
}
use of com.apple.foundationdb.record.query.plan.plans.RecordQueryUnorderedUnionPlan in project fdb-record-layer by FoundationDB.
the class FDBOrQueryToUnionTest method testOrQuery5WithLimits.
@DualPlannerTest
@MethodSource("query5WithLimitsArgs")
@ParameterizedTest(name = "testOrQuery5WithLimits [limit = {0}, removesDuplicates = {1}]")
void testOrQuery5WithLimits(int limit, boolean removesDuplicates) throws Exception {
RecordMetaDataHook hook = complexQuerySetupHook();
complexQuerySetup(hook);
setDeferFetchAfterUnionAndIntersection(true);
RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.or(Query.field("str_value_indexed").lessThan("m"), Query.field("num_value_3_indexed").greaterThan(3))).setRemoveDuplicates(removesDuplicates).build();
// Unordered(Index(MySimpleRecord$str_value_indexed ([null],[m])) ∪ Index(MySimpleRecord$num_value_3_indexed ([3],>))
RecordQueryPlan plan = planner.plan(query);
final BindingMatcher<RecordQueryUnorderedUnionPlan> unionPlanBindingMatcher = unorderedUnionPlan(coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("MySimpleRecord$str_value_indexed")))), coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("MySimpleRecord$num_value_3_indexed")))));
final BindingMatcher<? extends RecordQueryPlan> planMatcher;
if (removesDuplicates) {
planMatcher = fetchFromPartialRecordPlan(unorderedPrimaryKeyDistinctPlan(unionPlanBindingMatcher));
} else {
planMatcher = fetchFromPartialRecordPlan(unionPlanBindingMatcher);
}
assertMatchesExactly(plan, planMatcher);
if (planner instanceof RecordQueryPlanner) {
assertEquals(removesDuplicates ? 1898767693 : 1898767686, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(removesDuplicates ? -583062018 : 212117636, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(removesDuplicates ? 1864525478 : -1635262164, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
} else {
assertEquals(removesDuplicates ? 1898767693 : 1898767686, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(removesDuplicates ? -583062018 : 212117636, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(removesDuplicates ? 1864525478 : -1635262164, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
}
try (FDBRecordContext context = openContext()) {
openSimpleRecordStore(context, hook);
boolean done = false;
byte[] continuation = null;
Set<Tuple> uniqueKeys = new HashSet<>();
int itr = 0;
while (!done) {
ExecuteProperties executeProperties = ExecuteProperties.newBuilder().setReturnedRowLimit(limit).build();
try (RecordCursorIterator<FDBQueriedRecord<Message>> cursor = recordStore.executeQuery(plan, continuation, executeProperties).asIterator()) {
int i = 0;
Set<Tuple> keysThisIteration = new HashSet<>();
while (cursor.hasNext()) {
FDBQueriedRecord<Message> rec = cursor.next();
TestRecords1Proto.MySimpleRecord.Builder myrec = TestRecords1Proto.MySimpleRecord.newBuilder();
myrec.mergeFrom(Objects.requireNonNull(rec).getRecord());
assertTrue(myrec.getStrValueIndexed().compareTo("m") < 0 || myrec.getNumValue3Indexed() > 3);
uniqueKeys.add(rec.getPrimaryKey());
if (removesDuplicates) {
assertThat(keysThisIteration.add(rec.getPrimaryKey()), is(true));
}
i++;
}
continuation = cursor.getContinuation();
done = cursor.getNoNextReason().isSourceExhausted();
if (!done) {
assertEquals(limit, i);
}
}
itr++;
assertThat("exceeded maximum iterations", itr, lessThan(500));
}
assertEquals(50 + 10, uniqueKeys.size());
}
}
Aggregations