use of com.apple.foundationdb.record.query.expressions.QueryRecordFunctionWithComparison in project fdb-record-layer by FoundationDB.
the class RecordQueryPlanner method planRankWithAnd.
@Nullable
private ScoredPlan planRankWithAnd(@Nonnull CandidateScan candidateScan, @Nonnull Index index, @Nonnull GroupingKeyExpression indexExpr, @Nonnull AndComponent and) {
final List<QueryComponent> filters = and.getChildren();
for (QueryComponent filter : filters) {
if (filter instanceof QueryRecordFunctionWithComparison) {
final QueryRecordFunctionWithComparison filterComparison = (QueryRecordFunctionWithComparison) filter;
final RankComparisons.RankComparison rankComparison = candidateScan.planContext.rankComparisons.getPlanComparison(filterComparison);
if (rankComparison != null && rankComparison.getIndex() == index && RankComparisons.matchesSort(indexExpr, candidateScan.planContext.query.getSort())) {
ScanComparisons scanComparisons = rankComparison.getScanComparisons();
final Set<RankComparisons.RankComparison> includedRankComparisons = new HashSet<>();
includedRankComparisons.add(rankComparison);
final List<QueryComponent> unsatisfiedFilters = new ArrayList<>(filters);
unsatisfiedFilters.remove(filter);
unsatisfiedFilters.removeAll(rankComparison.getGroupFilters());
for (int i = 0; i < unsatisfiedFilters.size(); i++) {
final QueryComponent otherFilter = unsatisfiedFilters.get(i);
if (otherFilter instanceof QueryRecordFunctionWithComparison) {
final QueryRecordFunctionWithComparison otherComparison = (QueryRecordFunctionWithComparison) otherFilter;
final RankComparisons.RankComparison otherRank = candidateScan.planContext.rankComparisons.getPlanComparison(otherComparison);
if (otherRank != null) {
ScanComparisons mergedScanComparisons = scanComparisons.merge(otherRank.getScanComparisons());
if (mergedScanComparisons != null) {
scanComparisons = mergedScanComparisons;
includedRankComparisons.add(otherRank);
unsatisfiedFilters.remove(i--);
}
}
}
}
final RecordQueryPlan scan = rankScan(candidateScan, filterComparison, scanComparisons);
final boolean createsDuplicates = RankComparisons.createsDuplicates(index, indexExpr);
return new ScoredPlan(scan, unsatisfiedFilters, Collections.emptyList(), indexExpr.getColumnSize(), createsDuplicates, includedRankComparisons);
}
}
}
return null;
}
use of com.apple.foundationdb.record.query.expressions.QueryRecordFunctionWithComparison in project fdb-record-layer by FoundationDB.
the class RecordQueryPlanner method planRank.
@Nullable
private ScoredPlan planRank(@Nonnull CandidateScan candidateScan, @Nonnull Index index, @Nonnull GroupingKeyExpression indexExpr, @Nonnull QueryComponent filter) {
if (filter instanceof QueryRecordFunctionWithComparison) {
final QueryRecordFunctionWithComparison filterComparison = (QueryRecordFunctionWithComparison) filter;
final RankComparisons.RankComparison rankComparison = candidateScan.planContext.rankComparisons.getPlanComparison(filterComparison);
if (rankComparison != null && rankComparison.getIndex() == index && RankComparisons.matchesSort(indexExpr, candidateScan.planContext.query.getSort())) {
final ScanComparisons scanComparisons = rankComparison.getScanComparisons();
final RecordQueryPlan scan = rankScan(candidateScan, filterComparison, scanComparisons);
final boolean createsDuplicates = RankComparisons.createsDuplicates(index, indexExpr);
return new ScoredPlan(scan, Collections.emptyList(), Collections.emptyList(), 1, createsDuplicates, Collections.singleton(rankComparison));
}
} else if (filter instanceof AndComponent) {
return planRankWithAnd(candidateScan, index, indexExpr, (AndComponent) filter);
}
return null;
}
use of com.apple.foundationdb.record.query.expressions.QueryRecordFunctionWithComparison in project fdb-record-layer by FoundationDB.
the class RankComparisons method findComparison.
private void findComparison(@Nonnull QueryRecordFunctionWithComparison comparison, @Nonnull List<Index> indexes, @Nonnull List<QueryComponent> potentialGroupFilters, @Nonnull AtomicInteger counter) {
RecordFunction<?> recordFunction = comparison.getFunction();
// TODO: Should share with indexMaintainerForAggregateFunction
// TODO: Move index-specific query planning behavior outside of planner (https://github.com/FoundationDB/fdb-record-layer/issues/17)
List<String> requiredIndexTypes;
if (recordFunction.getName().equals(FunctionNames.RANK)) {
requiredIndexTypes = Arrays.asList(IndexTypes.RANK, IndexTypes.TIME_WINDOW_LEADERBOARD);
} else if (recordFunction.getName().equals(FunctionNames.TIME_WINDOW_RANK)) {
requiredIndexTypes = Collections.singletonList(IndexTypes.TIME_WINDOW_LEADERBOARD);
} else {
requiredIndexTypes = null;
}
if (requiredIndexTypes != null) {
final GroupingKeyExpression operand = ((IndexRecordFunction) recordFunction).getOperand();
Optional<Index> matchingIndex = indexes.stream().filter(index -> requiredIndexTypes.contains(index.getType()) && index.getRootExpression().equals(operand)).min(Comparator.comparing(Index::getColumnSize));
if (matchingIndex.isPresent()) {
final KeyExpression groupBy = operand.getGroupingSubKey();
final List<QueryComponent> groupFilters = new ArrayList<>();
final List<Comparisons.Comparison> groupComparisons = new ArrayList<>();
if (!GroupingValidator.findGroupKeyFilters(potentialGroupFilters, groupBy, groupFilters, groupComparisons)) {
return;
}
QueryComponent substitute = null;
String bindingName = null;
final Comparisons.Type comparisonType = comparison.getComparison().getType();
if (!operand.createsDuplicates() && !comparisonType.isUnary()) {
bindingName = Bindings.Internal.RANK.bindingName(Integer.toString(counter.getAndIncrement()));
Comparisons.Comparison substituteComparison = new Comparisons.ParameterComparison(comparisonType, bindingName, Bindings.Internal.RANK);
final KeyExpression grouped = operand.getGroupedSubKey();
if (grouped instanceof FieldKeyExpression) {
substitute = new FieldWithComparison(((FieldKeyExpression) grouped).getFieldName(), substituteComparison);
} else if (grouped instanceof NestingKeyExpression) {
NestingKeyExpression nesting = (NestingKeyExpression) grouped;
if (nesting.getChild() instanceof FieldKeyExpression) {
substitute = new NestedField(nesting.getParent().getFieldName(), new FieldWithComparison(((FieldKeyExpression) nesting.getChild()).getFieldName(), substituteComparison));
}
}
if (substitute == null) {
bindingName = null;
}
}
comparisons.put(comparison, new RankComparison(comparison, matchingIndex.get(), groupFilters, groupComparisons, substitute, bindingName));
}
}
}
Aggregations