use of com.apple.foundationdb.record.EvaluationContext in project fdb-record-layer by FoundationDB.
the class RecordQueryInUnionPlan method executePlan.
@Nonnull
@Override
public <M extends Message> RecordCursor<QueryResult> executePlan(@Nonnull final FDBRecordStoreBase<M> store, @Nonnull final EvaluationContext context, @Nullable final byte[] continuation, @Nonnull final ExecuteProperties executeProperties) {
int size = getValuesSize(context);
if (size > maxNumberOfValuesAllowed) {
throw new RecordCoreException("too many IN values").addLogInfo("size", size);
}
if (size == 0) {
return RecordCursor.empty();
}
final RecordQueryPlan childPlan = getInnerPlan();
if (size == 1) {
final EvaluationContext childContext = getValuesContexts(context).get(0);
return childPlan.executePlan(store, childContext, continuation, executeProperties);
}
final ExecuteProperties childExecuteProperties;
// Can pass the limit down to all sides, since that is the most we'll take total.
if (executeProperties.getSkip() > 0) {
childExecuteProperties = executeProperties.clearSkipAndAdjustLimit();
} else {
childExecuteProperties = executeProperties;
}
final List<Function<byte[], RecordCursor<FDBQueriedRecord<M>>>> childCursorFunctions = getValuesContexts(context).stream().map(childContext -> (Function<byte[], RecordCursor<FDBQueriedRecord<M>>>) childContinuation -> childPlan.execute(store, childContext, childContinuation, childExecuteProperties)).collect(Collectors.toList());
return UnionCursor.create(store, comparisonKey, reverse, childCursorFunctions, continuation).skipThenLimit(executeProperties.getSkip(), executeProperties.getReturnedRowLimit()).map(QueryResult::of);
}
use of com.apple.foundationdb.record.EvaluationContext in project fdb-record-layer by FoundationDB.
the class RecordQueryInUnionPlan method getValuesContexts.
@Nonnull
protected List<EvaluationContext> getValuesContexts(@Nonnull EvaluationContext context) {
List<EvaluationContext> parents = Collections.singletonList(context);
for (InSource values : valuesSources) {
final List<EvaluationContext> children = new ArrayList<>();
for (EvaluationContext parent : parents) {
for (Object value : values.getValues(parent)) {
children.add(parent.withBinding(values.getBindingName(), value));
}
}
parents = children;
}
return parents;
}
use of com.apple.foundationdb.record.EvaluationContext in project fdb-record-layer by FoundationDB.
the class FDBInQueryTest method testInQueryIndex.
/**
* Verify that an IN with an index is implemented as an index scan, with an IN join.
*/
@DualPlannerTest
void testInQueryIndex() throws Exception {
complexQuerySetup(NO_HOOK);
List<Integer> ls = asList(1, 2, 4);
RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.field("num_value_3_indexed").in(ls)).setSort(field("num_value_3_indexed")).build();
planner.setConfiguration(InAsOrUnionMode.AS_UNION.configure(planner.getConfiguration().asBuilder()).build());
RecordQueryPlan plan = planner.plan(query);
if (planner instanceof RecordQueryPlanner) {
// Index(MySimpleRecord$num_value_3_indexed [EQUALS $__in_num_value_3_indexed__0]) WHERE __in_num_value_3_indexed__0 IN [1, 2, 4]
assertMatchesExactly(plan, inValuesJoinPlan(indexPlan().where(indexName("MySimpleRecord$num_value_3_indexed")).and(scanComparisons(range("[EQUALS $__in_num_value_3_indexed__0]")))).where(inValuesList(equalsObject(ls))));
assertEquals(-2004060309, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(571226247, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(571195399, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
} else {
assertMatchesExactly(plan, fetchFromPartialRecordPlan(inValuesJoinPlan(coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("MySimpleRecord$num_value_3_indexed")).and(scanComparisons(equalities(only(anyParameterComparison()))))))).where(inValuesList(equalsObject(ls)))));
assertEquals(-2068499040, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(-992959779, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-1998042418, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
}
assertEquals(60, querySimpleRecordStore(NO_HOOK, plan, EvaluationContext::empty, record -> assertThat(record.getNumValue3Indexed(), anyOf(is(1), is(2), is(4))), TestHelpers::assertDiscardedNone));
}
use of com.apple.foundationdb.record.EvaluationContext in project fdb-record-layer by FoundationDB.
the class FDBInQueryTest method testInQueryNoIndex.
/**
* Verify that an IN without an index is implemented as a filter on a scan, as opposed to a loop of a filter on a scan.
*/
@DualPlannerTest
void testInQueryNoIndex() throws Exception {
complexQuerySetup(NO_HOOK);
final QueryComponent filter = Query.field("num_value_2").in(asList(0, 2));
RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(filter).build();
// Scan(<,>) | [MySimpleRecord] | num_value_2 IN [0, 2]
RecordQueryPlan plan = planner.plan(query);
if (planner instanceof RecordQueryPlanner) {
assertMatchesExactly(plan, filterPlan(descendantPlans(scanPlan().where(scanComparisons(unbounded())))).where(queryComponents(exactly(equalsObject(filter)))));
assertEquals(-1139367278, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(-1907300063, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-1694772440, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
} else {
assertMatchesExactly(plan, predicatesFilterPlan(descendantPlans(scanPlan().where(scanComparisons(unbounded())))).where(predicates(valuePredicate(fieldValue("num_value_2"), new Comparisons.ListComparison(Comparisons.Type.IN, ImmutableList.of(0, 2))))));
assertEquals(997592219, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(-1107686929, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-895159306, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
}
assertEquals(67, querySimpleRecordStore(NO_HOOK, plan, EvaluationContext::empty, record -> assertThat(record.getNumValue2(), anyOf(is(0), is(2))), context -> assertDiscardedAtMost(33, context)));
}
use of com.apple.foundationdb.record.EvaluationContext 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