use of com.apple.foundationdb.record.query.plan.planning.RankComparisons in project fdb-record-layer by FoundationDB.
the class RecordQueryPlanner method planFilterForInJoin.
private ScoredPlan planFilterForInJoin(@Nonnull PlanContext planContext, @Nonnull QueryComponent filter, boolean needOrdering) {
planContext.rankComparisons = new RankComparisons(filter, planContext.indexes);
List<ScoredPlan> intersectionCandidates = new ArrayList<>();
ScoredPlan bestPlan = null;
Index bestIndex = null;
if (planContext.commonPrimaryKey != null) {
bestPlan = planIndex(planContext, filter, null, planContext.commonPrimaryKey, intersectionCandidates);
}
for (Index index : planContext.indexes) {
KeyExpression indexKeyExpression = indexKeyExpressionForPlan(planContext.commonPrimaryKey, index);
ScoredPlan p = planIndex(planContext, filter, index, indexKeyExpression, intersectionCandidates);
if (p != null) {
// * need for type filtering if row scan with multiple types.
if (isBetterThanOther(planContext, p, index, bestPlan, bestIndex)) {
bestPlan = p;
bestIndex = index;
}
}
}
if (bestPlan != null) {
if (bestPlan.getNumNonSargables() > 0) {
bestPlan = handleNonSargables(bestPlan, intersectionCandidates, planContext);
}
if (needOrdering) {
bestPlan.planOrderingKey = PlanOrderingKey.forPlan(metaData, bestPlan.plan, planContext.commonPrimaryKey);
}
}
return bestPlan;
}
use of com.apple.foundationdb.record.query.plan.planning.RankComparisons in project fdb-record-layer by FoundationDB.
the class RecordQueryPlanner method planCoveringAggregateIndex.
@Nullable
public RecordQueryCoveringIndexPlan planCoveringAggregateIndex(@Nonnull RecordQuery query, @Nonnull Index index, @Nonnull KeyExpression indexExpr) {
final Collection<RecordType> recordTypes = metaData.recordTypesForIndex(index);
if (recordTypes.size() != 1) {
// Unfortunately, since we materialize partial records, we need a unique type for them.
return null;
}
final RecordType recordType = recordTypes.iterator().next();
final PlanContext planContext = getPlanContext(query);
planContext.rankComparisons = new RankComparisons(query.getFilter(), planContext.indexes);
// Repeated fields will be scanned one at a time by covering aggregate, so there is no issue with fan out.
planContext.allowDuplicates = true;
final CandidateScan candidateScan = new CandidateScan(planContext, index, query.isSortReverse());
final ScoredPlan scoredPlan = planCandidateScan(candidateScan, indexExpr, BooleanNormalizer.forConfiguration(configuration).normalizeIfPossible(query.getFilter()), query.getSort());
// It would be possible to handle unsatisfiedFilters if they, too, only involved group key (covering) fields.
if (scoredPlan == null || !scoredPlan.unsatisfiedFilters.isEmpty() || !(scoredPlan.plan instanceof RecordQueryIndexPlan)) {
return null;
}
final IndexKeyValueToPartialRecord.Builder builder = IndexKeyValueToPartialRecord.newBuilder(recordType);
final List<KeyExpression> keyFields = index.getRootExpression().normalizeKeyForPositions();
final List<KeyExpression> valueFields = Collections.emptyList();
for (KeyExpression resultField : query.getRequiredResults()) {
if (!addCoveringField(resultField, builder, keyFields, valueFields)) {
return null;
}
}
builder.addRequiredMessageFields();
if (!builder.isValid(true)) {
return null;
}
RecordQueryIndexPlan plan = (RecordQueryIndexPlan) scoredPlan.plan;
IndexScanParameters scanParameters = new IndexScanComparisons(IndexScanType.BY_GROUP, plan.getComparisons());
plan = new RecordQueryIndexPlan(plan.getIndexName(), scanParameters, plan.isReverse());
return new RecordQueryCoveringIndexPlan(plan, recordType.getName(), AvailableFields.NO_FIELDS, builder.build());
}
Aggregations