Search in sources :

Example 1 with QueryRecordFunctionWithComparison

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;
}
Also used : RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) QueryRecordFunctionWithComparison(com.apple.foundationdb.record.query.expressions.QueryRecordFunctionWithComparison) RankComparisons(com.apple.foundationdb.record.query.plan.planning.RankComparisons) ArrayList(java.util.ArrayList) TimeWindowScanComparisons(com.apple.foundationdb.record.provider.foundationdb.leaderboard.TimeWindowScanComparisons) IndexScanComparisons(com.apple.foundationdb.record.provider.foundationdb.IndexScanComparisons) HashSet(java.util.HashSet) Nullable(javax.annotation.Nullable)

Example 2 with QueryRecordFunctionWithComparison

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;
}
Also used : RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) QueryRecordFunctionWithComparison(com.apple.foundationdb.record.query.expressions.QueryRecordFunctionWithComparison) TimeWindowScanComparisons(com.apple.foundationdb.record.provider.foundationdb.leaderboard.TimeWindowScanComparisons) IndexScanComparisons(com.apple.foundationdb.record.provider.foundationdb.IndexScanComparisons) RankComparisons(com.apple.foundationdb.record.query.plan.planning.RankComparisons) AndComponent(com.apple.foundationdb.record.query.expressions.AndComponent) Nullable(javax.annotation.Nullable)

Example 3 with QueryRecordFunctionWithComparison

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));
        }
    }
}
Also used : FunctionNames(com.apple.foundationdb.record.FunctionNames) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) Arrays(java.util.Arrays) IndexAggregateFunction(com.apple.foundationdb.record.metadata.IndexAggregateFunction) Bindings(com.apple.foundationdb.record.Bindings) HashMap(java.util.HashMap) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) Function(java.util.function.Function) ArrayList(java.util.ArrayList) FieldKeyExpression(com.apple.foundationdb.record.metadata.expressions.FieldKeyExpression) Tuple(com.apple.foundationdb.tuple.Tuple) QueryRecordFunctionWithComparison(com.apple.foundationdb.record.query.expressions.QueryRecordFunctionWithComparison) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) NestingKeyExpression(com.apple.foundationdb.record.metadata.expressions.NestingKeyExpression) Map(java.util.Map) GroupingKeyExpression(com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression) IndexRecordFunction(com.apple.foundationdb.record.metadata.IndexRecordFunction) Nonnull(javax.annotation.Nonnull) Nullable(javax.annotation.Nullable) FieldWithComparison(com.apple.foundationdb.record.query.expressions.FieldWithComparison) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) Set(java.util.Set) ScanComparisons(com.apple.foundationdb.record.query.plan.ScanComparisons) RecordQueryScoreForRankPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryScoreForRankPlan) AndComponent(com.apple.foundationdb.record.query.expressions.AndComponent) Collectors(java.util.stream.Collectors) AndOrComponent(com.apple.foundationdb.record.query.expressions.AndOrComponent) Comparisons(com.apple.foundationdb.record.query.expressions.Comparisons) List(java.util.List) NestedField(com.apple.foundationdb.record.query.expressions.NestedField) Index(com.apple.foundationdb.record.metadata.Index) IndexTypes(com.apple.foundationdb.record.metadata.IndexTypes) QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) Optional(java.util.Optional) API(com.apple.foundationdb.annotation.API) RecordFunction(com.apple.foundationdb.record.RecordFunction) Comparator(java.util.Comparator) ComponentWithChildren(com.apple.foundationdb.record.query.expressions.ComponentWithChildren) Collections(java.util.Collections) QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) IndexRecordFunction(com.apple.foundationdb.record.metadata.IndexRecordFunction) GroupingKeyExpression(com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression) FieldKeyExpression(com.apple.foundationdb.record.metadata.expressions.FieldKeyExpression) NestingKeyExpression(com.apple.foundationdb.record.metadata.expressions.NestingKeyExpression) GroupingKeyExpression(com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) ArrayList(java.util.ArrayList) Index(com.apple.foundationdb.record.metadata.Index) NestedField(com.apple.foundationdb.record.query.expressions.NestedField) FieldKeyExpression(com.apple.foundationdb.record.metadata.expressions.FieldKeyExpression) NestingKeyExpression(com.apple.foundationdb.record.metadata.expressions.NestingKeyExpression) QueryRecordFunctionWithComparison(com.apple.foundationdb.record.query.expressions.QueryRecordFunctionWithComparison) FieldWithComparison(com.apple.foundationdb.record.query.expressions.FieldWithComparison) ScanComparisons(com.apple.foundationdb.record.query.plan.ScanComparisons) Comparisons(com.apple.foundationdb.record.query.expressions.Comparisons) FieldWithComparison(com.apple.foundationdb.record.query.expressions.FieldWithComparison)

Aggregations

QueryRecordFunctionWithComparison (com.apple.foundationdb.record.query.expressions.QueryRecordFunctionWithComparison)3 RecordQueryPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan)3 Nullable (javax.annotation.Nullable)3 IndexScanComparisons (com.apple.foundationdb.record.provider.foundationdb.IndexScanComparisons)2 TimeWindowScanComparisons (com.apple.foundationdb.record.provider.foundationdb.leaderboard.TimeWindowScanComparisons)2 AndComponent (com.apple.foundationdb.record.query.expressions.AndComponent)2 QueryComponent (com.apple.foundationdb.record.query.expressions.QueryComponent)2 RankComparisons (com.apple.foundationdb.record.query.plan.planning.RankComparisons)2 ArrayList (java.util.ArrayList)2 API (com.apple.foundationdb.annotation.API)1 Bindings (com.apple.foundationdb.record.Bindings)1 FunctionNames (com.apple.foundationdb.record.FunctionNames)1 RecordCoreException (com.apple.foundationdb.record.RecordCoreException)1 RecordFunction (com.apple.foundationdb.record.RecordFunction)1 RecordMetaData (com.apple.foundationdb.record.RecordMetaData)1 Index (com.apple.foundationdb.record.metadata.Index)1 IndexAggregateFunction (com.apple.foundationdb.record.metadata.IndexAggregateFunction)1 IndexRecordFunction (com.apple.foundationdb.record.metadata.IndexRecordFunction)1 IndexTypes (com.apple.foundationdb.record.metadata.IndexTypes)1 FieldKeyExpression (com.apple.foundationdb.record.metadata.expressions.FieldKeyExpression)1