Search in sources :

Example 1 with AndComponent

use of com.apple.foundationdb.record.query.expressions.AndComponent in project fdb-record-layer by FoundationDB.

the class RecordQueryPlanner method normalizeAndOrForInAsOr.

private QueryComponent normalizeAndOrForInAsOr(@Nonnull QueryComponent component) {
    if (!(component instanceof AndComponent)) {
        return component;
    }
    final AndComponent and = (AndComponent) component;
    OrComponent singleOrChild = null;
    final List<QueryComponent> otherChildren = new ArrayList<>();
    for (QueryComponent child : and.getChildren()) {
        if (child instanceof OrComponent) {
            if (singleOrChild == null) {
                singleOrChild = (OrComponent) child;
            } else {
                return and;
            }
        } else if (Query.isSingleFieldComparison(child)) {
            otherChildren.add(child);
        } else {
            return and;
        }
    }
    if (singleOrChild == null) {
        return and;
    }
    // We have exactly one OR child and the others are single field comparisons
    return OrComponent.from(distributeAnd(otherChildren, singleOrChild.getChildren()));
}
Also used : QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) OrComponent(com.apple.foundationdb.record.query.expressions.OrComponent) AndComponent(com.apple.foundationdb.record.query.expressions.AndComponent) ArrayList(java.util.ArrayList)

Example 2 with AndComponent

use of com.apple.foundationdb.record.query.expressions.AndComponent in project fdb-record-layer by FoundationDB.

the class RecordQueryPlanner method planIndex.

@Nullable
private ScoredPlan planIndex(@Nonnull PlanContext planContext, @Nonnull QueryComponent filter, @Nullable Index index, @Nonnull KeyExpression indexExpr, @Nonnull List<ScoredPlan> intersectionCandidates) {
    final KeyExpression sort = planContext.query.getSort();
    final boolean sortReverse = planContext.query.isSortReverse();
    final CandidateScan candidateScan = new CandidateScan(planContext, index, sortReverse);
    ScoredPlan p = null;
    if (index != null) {
        if (indexTypes.getRankTypes().contains(index.getType())) {
            GroupingKeyExpression grouping = (GroupingKeyExpression) indexExpr;
            p = planRank(candidateScan, index, grouping, filter);
            // Plan as just value index.
            indexExpr = grouping.getWholeKey();
        } else if (indexTypes.getTextTypes().contains(index.getType())) {
            p = planText(candidateScan, index, filter, sort);
            if (p != null) {
                p = planRemoveDuplicates(planContext, p);
            }
            if (p != null) {
                p = computeIndexFilters(planContext, p);
            }
            return p;
        } else if (indexTypes.getLuceneTypes().contains(index.getType())) {
            p = planLucene(candidateScan, index, filter, sort);
            if (p != null) {
                p = planRemoveDuplicates(planContext, p);
            }
            if (p != null) {
                p = computeIndexFilters(planContext, p);
            }
            return p;
        } else if (!indexTypes.getValueTypes().contains(index.getType())) {
            return null;
        }
    }
    if (p == null) {
        p = planCandidateScan(candidateScan, indexExpr, filter, sort);
    }
    if (p == null) {
        // we can't match the filter, but maybe the sort
        p = planSortOnly(candidateScan, indexExpr, sort);
        if (p != null) {
            final List<QueryComponent> unsatisfiedFilters = filter instanceof AndComponent ? ((AndComponent) filter).getChildren() : Collections.singletonList(filter);
            p = new ScoredPlan(0, p.plan, unsatisfiedFilters, p.createsDuplicates);
        }
    }
    if (p != null) {
        if (getConfiguration().shouldOptimizeForIndexFilters()) {
            // partition index filters
            if (index == null) {
                // if we scan without an index all filters become index filters as we don't need a fetch
                // to evaluate these filters
                p = p.withFilters(p.combineNonSargables(), Collections.emptyList());
            } else {
                p = computeIndexFilters(planContext, p);
            }
        }
    }
    if (p != null) {
        p = planRemoveDuplicates(planContext, p);
        if (p != null && p.getNumNonSargables() > 0) {
            PlanOrderingKey planOrderingKey = PlanOrderingKey.forPlan(metaData, p.plan, planContext.commonPrimaryKey);
            if (planOrderingKey != null && (sort != null || planOrderingKey.isPrimaryKeyOrdered())) {
                // If there is a sort, all chosen plans should be ordered by it and so compatible.
                // Otherwise, by requiring pkey order, we miss out on the possible intersection of
                // X < 10 AND X < 5, which should have been handled already. We gain simplicity
                // in not trying X < 10 AND Y = 5 AND Z = 'foo', where we would need to throw
                // some out as we fail to align them all.
                p.planOrderingKey = planOrderingKey;
                intersectionCandidates.add(p);
            }
        }
    }
    return p;
}
Also used : QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) GroupingKeyExpression(com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression) AndComponent(com.apple.foundationdb.record.query.expressions.AndComponent) RecordTypeKeyExpression(com.apple.foundationdb.record.metadata.expressions.RecordTypeKeyExpression) VersionKeyExpression(com.apple.foundationdb.record.metadata.expressions.VersionKeyExpression) GroupingKeyExpression(com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) FieldKeyExpression(com.apple.foundationdb.record.metadata.expressions.FieldKeyExpression) NestingKeyExpression(com.apple.foundationdb.record.metadata.expressions.NestingKeyExpression) EmptyKeyExpression(com.apple.foundationdb.record.metadata.expressions.EmptyKeyExpression) ThenKeyExpression(com.apple.foundationdb.record.metadata.expressions.ThenKeyExpression) Nullable(javax.annotation.Nullable)

Example 3 with AndComponent

use of com.apple.foundationdb.record.query.expressions.AndComponent in project fdb-record-layer by FoundationDB.

the class FDBRecordStore method mergeRecordTypeAndComponent.

@Nonnull
protected static QueryComponent mergeRecordTypeAndComponent(@Nonnull String recordType, @Nullable QueryComponent component) {
    if (component == null) {
        return new RecordTypeKeyComparison(recordType);
    }
    List<QueryComponent> components = new ArrayList<>();
    components.add(new RecordTypeKeyComparison(recordType));
    if (component instanceof AndComponent) {
        components.addAll(((AndComponent) component).getChildren());
    } else {
        components.add(component);
    }
    return Query.and(components);
}
Also used : QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) AndComponent(com.apple.foundationdb.record.query.expressions.AndComponent) ArrayList(java.util.ArrayList) RecordTypeKeyComparison(com.apple.foundationdb.record.query.expressions.RecordTypeKeyComparison) Nonnull(javax.annotation.Nonnull)

Example 4 with AndComponent

use of com.apple.foundationdb.record.query.expressions.AndComponent in project fdb-record-layer by FoundationDB.

the class IndexAggregateFunctionCall method extractFieldPaths.

/**
 * Helper method to extract a set of key expressions that are bound through some comparison in the
 * query component passed in.
 * @param queryComponent the query component
 * @param predicate a predicate used for filtering each encountered {@link FieldWithComparison}
 * @return a set of {@link KeyExpression}s where each element is a key expression of a field (i.e. a
 * {@link com.apple.foundationdb.record.metadata.expressions.FieldKeyExpression}) or a simple nesting field
 * (i.e. a {@link com.apple.foundationdb.record.metadata.expressions.NestingKeyExpression}) that is bound
 * through some comparison
 */
@Nonnull
public static Set<KeyExpression> extractFieldPaths(@Nonnull QueryComponent queryComponent, @Nonnull final Predicate<FieldWithComparison> predicate) {
    if (queryComponent instanceof BaseField) {
        final BaseField baseField = (BaseField) queryComponent;
        if (baseField instanceof NestedField) {
            final NestedField nestedField = (NestedField) baseField;
            final Set<KeyExpression> nestedExpressions = extractFieldPaths(nestedField.getChild(), predicate);
            return nestedExpressions.stream().map(nestedExpression -> Key.Expressions.field(nestedField.getFieldName()).nest(nestedExpression)).collect(ImmutableSet.toImmutableSet());
        }
        if (baseField instanceof FieldWithComparison) {
            final FieldWithComparison fieldWithComparison = (FieldWithComparison) baseField;
            if (predicate.test(fieldWithComparison)) {
                return ImmutableSet.of(Key.Expressions.field(fieldWithComparison.getFieldName()));
            }
        }
        return ImmutableSet.of();
    } else if (queryComponent instanceof AndComponent) {
        final Set<KeyExpression> boundFields = Sets.newHashSet();
        final AndComponent andComponent = (AndComponent) queryComponent;
        andComponent.getChildren().forEach(child -> boundFields.addAll(extractEqualityBoundFields(child)));
        return boundFields;
    }
    return ImmutableSet.of();
}
Also used : NestedField(com.apple.foundationdb.record.query.expressions.NestedField) FieldWithComparison(com.apple.foundationdb.record.query.expressions.FieldWithComparison) Iterables(com.google.common.collect.Iterables) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) ImmutableSet(com.google.common.collect.ImmutableSet) Predicate(java.util.function.Predicate) Set(java.util.Set) EnumeratingIterable(com.apple.foundationdb.record.query.combinatorics.EnumeratingIterable) AndComponent(com.apple.foundationdb.record.query.expressions.AndComponent) Sets(com.google.common.collect.Sets) Comparisons(com.apple.foundationdb.record.query.expressions.Comparisons) List(java.util.List) NestedField(com.apple.foundationdb.record.query.expressions.NestedField) Stream(java.util.stream.Stream) BaseField(com.apple.foundationdb.record.query.expressions.BaseField) QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) GroupingKeyExpression(com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression) StreamSupport(java.util.stream.StreamSupport) API(com.apple.foundationdb.annotation.API) Objects(com.google.common.base.Objects) Nonnull(javax.annotation.Nonnull) EmptyKeyExpression(com.apple.foundationdb.record.metadata.expressions.EmptyKeyExpression) TopologicalSort(com.apple.foundationdb.record.query.combinatorics.TopologicalSort) Nullable(javax.annotation.Nullable) BaseField(com.apple.foundationdb.record.query.expressions.BaseField) ImmutableSet(com.google.common.collect.ImmutableSet) Set(java.util.Set) AndComponent(com.apple.foundationdb.record.query.expressions.AndComponent) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) GroupingKeyExpression(com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression) EmptyKeyExpression(com.apple.foundationdb.record.metadata.expressions.EmptyKeyExpression) FieldWithComparison(com.apple.foundationdb.record.query.expressions.FieldWithComparison) Nonnull(javax.annotation.Nonnull)

Example 5 with AndComponent

use of com.apple.foundationdb.record.query.expressions.AndComponent 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)

Aggregations

AndComponent (com.apple.foundationdb.record.query.expressions.AndComponent)6 QueryComponent (com.apple.foundationdb.record.query.expressions.QueryComponent)5 ArrayList (java.util.ArrayList)3 Nullable (javax.annotation.Nullable)3 EmptyKeyExpression (com.apple.foundationdb.record.metadata.expressions.EmptyKeyExpression)2 GroupingKeyExpression (com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression)2 KeyExpression (com.apple.foundationdb.record.metadata.expressions.KeyExpression)2 Nonnull (javax.annotation.Nonnull)2 API (com.apple.foundationdb.annotation.API)1 FieldKeyExpression (com.apple.foundationdb.record.metadata.expressions.FieldKeyExpression)1 NestingKeyExpression (com.apple.foundationdb.record.metadata.expressions.NestingKeyExpression)1 RecordTypeKeyExpression (com.apple.foundationdb.record.metadata.expressions.RecordTypeKeyExpression)1 ThenKeyExpression (com.apple.foundationdb.record.metadata.expressions.ThenKeyExpression)1 VersionKeyExpression (com.apple.foundationdb.record.metadata.expressions.VersionKeyExpression)1 IndexScanComparisons (com.apple.foundationdb.record.provider.foundationdb.IndexScanComparisons)1 TimeWindowScanComparisons (com.apple.foundationdb.record.provider.foundationdb.leaderboard.TimeWindowScanComparisons)1 EnumeratingIterable (com.apple.foundationdb.record.query.combinatorics.EnumeratingIterable)1 TopologicalSort (com.apple.foundationdb.record.query.combinatorics.TopologicalSort)1 BaseField (com.apple.foundationdb.record.query.expressions.BaseField)1 Comparisons (com.apple.foundationdb.record.query.expressions.Comparisons)1