use of com.apple.foundationdb.record.query.plan.planning.InExtractor in project fdb-record-layer by FoundationDB.
the class RecordQueryPlanner method planFilter.
/**
* Plan the given filter, which can be the whole query or a branch of an {@code OR}.
* @param planContext the plan context for the query
* @param filter the filter to plan
* @param needOrdering whether to populate {@link ScoredPlan#planOrderingKey} to facilitate combining sub-plans
* @return the best plan or {@code null} if no suitable index exists
*/
@Nullable
private ScoredPlan planFilter(@Nonnull PlanContext planContext, @Nonnull QueryComponent filter, boolean needOrdering) {
final InExtractor inExtractor = new InExtractor(filter);
ScoredPlan withInAsOrUnion = null;
if (planContext.query.getSort() != null) {
final InExtractor savedExtractor = new InExtractor(inExtractor);
boolean canSort = inExtractor.setSort(planContext.query.getSort(), planContext.query.isSortReverse());
if (!canSort) {
if (getConfiguration().shouldAttemptFailedInJoinAsUnion()) {
withInAsOrUnion = planFilterWithInUnion(planContext, savedExtractor);
} else if (getConfiguration().shouldAttemptFailedInJoinAsOr()) {
// Can't implement as an IN join because of the sort order. Try as an OR instead.
QueryComponent asOr = normalizeAndOrForInAsOr(inExtractor.asOr());
if (!filter.equals(asOr)) {
withInAsOrUnion = planFilter(planContext, asOr);
}
}
}
} else if (needOrdering) {
inExtractor.sortByClauses();
}
final ScoredPlan withInJoin = planFilterWithInJoin(planContext, inExtractor, needOrdering);
if (withInAsOrUnion != null) {
if (withInJoin == null || withInAsOrUnion.score > withInJoin.score || FieldWithComparisonCountProperty.evaluate(withInAsOrUnion.plan) < FieldWithComparisonCountProperty.evaluate(withInJoin.plan)) {
return withInAsOrUnion;
}
}
return withInJoin;
}
Aggregations