Search in sources :

Example 6 with AliasMap

use of com.apple.foundationdb.record.query.plan.temp.AliasMap in project fdb-record-layer by FoundationDB.

the class PushFilterThroughFetchRule method onMatch.

@Override
public void onMatch(@Nonnull PlannerRuleCall call) {
    final PlannerBindings bindings = call.getBindings();
    final RecordQueryPredicatesFilterPlan filterPlan = bindings.get(root);
    final RecordQueryFetchFromPartialRecordPlan fetchPlan = bindings.get(fetchPlanMatcher);
    final Quantifier.Physical quantifierOverFetch = bindings.get(quantifierOverFetchMatcher);
    final RecordQueryPlan innerPlan = bindings.get(innerPlanMatcher);
    final List<? extends QueryPredicate> queryPredicates = filterPlan.getPredicates();
    final ImmutableList.Builder<QueryPredicate> pushedPredicatesBuilder = ImmutableList.builder();
    final ImmutableList.Builder<QueryPredicate> residualPredicatesBuilder = ImmutableList.builder();
    final CorrelationIdentifier newInnerAlias = CorrelationIdentifier.uniqueID();
    for (final QueryPredicate queryPredicate : queryPredicates) {
        final Optional<QueryPredicate> pushedPredicateOptional = queryPredicate.replaceLeavesMaybe(leafPredicate -> pushLeafPredicate(fetchPlan, newInnerAlias, leafPredicate));
        if (pushedPredicateOptional.isPresent()) {
            pushedPredicatesBuilder.add(pushedPredicateOptional.get());
        } else {
            residualPredicatesBuilder.add(queryPredicate);
        }
    }
    final ImmutableList<QueryPredicate> pushedPredicates = pushedPredicatesBuilder.build();
    final ImmutableList<QueryPredicate> residualPredicates = residualPredicatesBuilder.build();
    Verify.verify(pushedPredicates.size() + residualPredicates.size() == queryPredicates.size());
    // case 1
    if (pushedPredicates.isEmpty()) {
        return;
    }
    // for case 2 and case 3 we can at least build a FILTER(inner, pushedPredicates) as that is
    // required both for case 2 nd 3
    final Quantifier.Physical newInnerQuantifier = Quantifier.physical(GroupExpressionRef.of(innerPlan), newInnerAlias);
    final RecordQueryPredicatesFilterPlan pushedFilterPlan = new RecordQueryPredicatesFilterPlan(newInnerQuantifier, pushedPredicates);
    final RecordQueryFetchFromPartialRecordPlan newFetchPlan = new RecordQueryFetchFromPartialRecordPlan(pushedFilterPlan, fetchPlan.getPushValueFunction());
    if (residualPredicates.isEmpty()) {
        // case 2
        call.yield(call.ref(newFetchPlan));
    } else {
        // case 3
        // create yet another physical quantifier on top of the fetch
        final Quantifier.Physical newQuantifierOverFetch = Quantifier.physical(GroupExpressionRef.of(newFetchPlan));
        final AliasMap translationMap = AliasMap.of(quantifierOverFetch.getAlias(), newQuantifierOverFetch.getAlias());
        // rebase all residual predicates to use that quantifier's alias
        final ImmutableList<QueryPredicate> rebasedResidualPredicates = residualPredicates.stream().map(residualPredicate -> residualPredicate.rebase(translationMap)).collect(ImmutableList.toImmutableList());
        call.yield(GroupExpressionRef.of(new RecordQueryPredicatesFilterPlan(newQuantifierOverFetch, rebasedResidualPredicates)));
    }
}
Also used : RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) TranslateValueFunction(com.apple.foundationdb.record.query.plan.plans.TranslateValueFunction) PlannerRuleCall(com.apple.foundationdb.record.query.plan.temp.PlannerRuleCall) RecordQueryFetchFromPartialRecordPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryFetchFromPartialRecordPlan) PlannerRule(com.apple.foundationdb.record.query.plan.temp.PlannerRule) Quantifier(com.apple.foundationdb.record.query.plan.temp.Quantifier) RecordQueryPlanMatchers.anyPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.anyPlan) PredicateWithValue(com.apple.foundationdb.record.query.predicates.PredicateWithValue) GroupExpressionRef(com.apple.foundationdb.record.query.plan.temp.GroupExpressionRef) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) RecordQueryPlanMatchers.predicatesFilter(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.predicatesFilter) ImmutableList(com.google.common.collect.ImmutableList) AliasMap(com.apple.foundationdb.record.query.plan.temp.AliasMap) Nonnull(javax.annotation.Nonnull) Nullable(javax.annotation.Nullable) Verify(com.google.common.base.Verify) QuantifierMatchers.physicalQuantifier(com.apple.foundationdb.record.query.plan.temp.matchers.QuantifierMatchers.physicalQuantifier) PlannerBindings(com.apple.foundationdb.record.query.plan.temp.matchers.PlannerBindings) QueryPredicate(com.apple.foundationdb.record.query.predicates.QueryPredicate) RecordQueryPredicatesFilterPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPredicatesFilterPlan) QueryComponentPredicate(com.apple.foundationdb.record.query.predicates.QueryComponentPredicate) Value(com.apple.foundationdb.record.query.predicates.Value) List(java.util.List) BindingMatcher(com.apple.foundationdb.record.query.plan.temp.matchers.BindingMatcher) CorrelationIdentifier(com.apple.foundationdb.record.query.plan.temp.CorrelationIdentifier) Optional(java.util.Optional) API(com.apple.foundationdb.annotation.API) RecordQueryPlanMatchers(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers) QueryPredicate(com.apple.foundationdb.record.query.predicates.QueryPredicate) ImmutableList(com.google.common.collect.ImmutableList) AliasMap(com.apple.foundationdb.record.query.plan.temp.AliasMap) RecordQueryFetchFromPartialRecordPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryFetchFromPartialRecordPlan) RecordQueryPredicatesFilterPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPredicatesFilterPlan) CorrelationIdentifier(com.apple.foundationdb.record.query.plan.temp.CorrelationIdentifier) PlannerBindings(com.apple.foundationdb.record.query.plan.temp.matchers.PlannerBindings) Quantifier(com.apple.foundationdb.record.query.plan.temp.Quantifier) QuantifierMatchers.physicalQuantifier(com.apple.foundationdb.record.query.plan.temp.matchers.QuantifierMatchers.physicalQuantifier)

Example 7 with AliasMap

use of com.apple.foundationdb.record.query.plan.temp.AliasMap in project fdb-record-layer by FoundationDB.

the class ComputingMatcher method enumerate.

/**
 * Method to enumerate the permutations on this side against the permutation of the other side in order
 * to form matches (bijective mappings between the permutations). The match function is called for each pair of
 * elements (for a match attempt). If the match function returns a non-empty {@link Iterable} the pair is recorded
 * as a matching pair. We attempt to find a matching pair (one from this side; one from the other side) for each
 * element identified by {@link #getAliases()}. For each individual new such pair that is found,
 * the method {@link MatchAccumulator#accumulate} is called. Once a set of bindings is established for all aliases
 * in {@link #getAliases} this method then calls {@link MatchAccumulator#finish} to produce an iterable of type
 * {@code R}.
 * @param iterator an enumerating iterable for the permutations on this side
 * @param otherPermutation one permutation (that is not violating dependencies, constraints, etc.) of the other side
 * @return an {@link Iterator} of match results (of type {@code BoundMatch<R>})
 */
@SuppressWarnings("java:S135")
@Nonnull
public Iterator<BoundMatch<R>> enumerate(@Nonnull final EnumeratingIterator<CorrelationIdentifier> iterator, @Nonnull final List<CorrelationIdentifier> otherPermutation) {
    final Set<CorrelationIdentifier> aliases = getAliases();
    final AliasMap boundAliasesMap = getBoundAliasesMap();
    if (otherPermutation.isEmpty()) {
        return ImmutableList.of(BoundMatch.<R>withAliasMap(boundAliasesMap)).iterator();
    }
    final int size = otherPermutation.size();
    return new AbstractIterator<BoundMatch<R>>() {

        @Override
        protected BoundMatch<R> computeNext() {
            while (iterator.hasNext()) {
                final List<CorrelationIdentifier> permutation = iterator.next();
                final AliasMap.Builder aliasMapBuilder = AliasMap.builder(aliases.size());
                final MatchAccumulator<M, R> accumulatedMatchResult = matchAccumulatorSupplier.get();
                int i;
                for (i = 0; i < size; i++) {
                    final AliasMap aliasMap = aliasMapBuilder.build();
                    final CorrelationIdentifier alias = permutation.get(i);
                    final CorrelationIdentifier otherAlias = otherPermutation.get(i);
                    final Optional<AliasMap> locallyBoundMapOptional = mapDependenciesToOther(aliasMap, alias, otherAlias);
                    if (!locallyBoundMapOptional.isPresent()) {
                        break;
                    }
                    final AliasMap locallyBoundMap = locallyBoundMapOptional.get();
                    final T entity = Objects.requireNonNull(getAliasToElementMap().get(alias));
                    final T otherEntity = Objects.requireNonNull(getOtherAliasToElementMap().get(otherAlias));
                    final Iterable<M> matchResults = matchFunction.apply(entity, otherEntity, boundAliasesMap.combine(locallyBoundMap));
                    if (Iterables.isEmpty(matchResults)) {
                        break;
                    }
                    accumulatedMatchResult.accumulate(matchResults);
                    // We now amend the equivalences passed in by adding the already known bound aliases left
                    // of i and make them equivalent as well
                    aliasMapBuilder.put(alias, otherAlias);
                }
                final R result = accumulatedMatchResult.finish();
                if (i == size) {
                    iterator.skip(i - 1);
                    return BoundMatch.withAliasMapAndMatchResult(boundAliasesMap.combine(aliasMapBuilder.build()), result);
                } else {
                    iterator.skip(i);
                }
            }
            return endOfData();
        }
    };
}
Also used : AliasMap(com.apple.foundationdb.record.query.plan.temp.AliasMap) CorrelationIdentifier(com.apple.foundationdb.record.query.plan.temp.CorrelationIdentifier) AbstractIterator(com.google.common.collect.AbstractIterator) Nonnull(javax.annotation.Nonnull)

Aggregations

AliasMap (com.apple.foundationdb.record.query.plan.temp.AliasMap)7 CorrelationIdentifier (com.apple.foundationdb.record.query.plan.temp.CorrelationIdentifier)6 Nonnull (javax.annotation.Nonnull)6 Quantifier (com.apple.foundationdb.record.query.plan.temp.Quantifier)5 API (com.apple.foundationdb.annotation.API)4 Value (com.apple.foundationdb.record.query.predicates.Value)4 RelationalExpression (com.apple.foundationdb.record.query.plan.temp.RelationalExpression)3 PredicateWithValue (com.apple.foundationdb.record.query.predicates.PredicateWithValue)3 QueryPredicate (com.apple.foundationdb.record.query.predicates.QueryPredicate)3 Verify (com.google.common.base.Verify)3 ImmutableList (com.google.common.collect.ImmutableList)3 CrossProduct (com.apple.foundationdb.record.query.combinatorics.CrossProduct)2 EnumeratingIterable (com.apple.foundationdb.record.query.combinatorics.EnumeratingIterable)2 Comparisons (com.apple.foundationdb.record.query.expressions.Comparisons)2 ComparisonRange (com.apple.foundationdb.record.query.plan.temp.ComparisonRange)2 Compensation (com.apple.foundationdb.record.query.plan.temp.Compensation)2 IdentityBiMap (com.apple.foundationdb.record.query.plan.temp.IdentityBiMap)2 IterableHelpers (com.apple.foundationdb.record.query.plan.temp.IterableHelpers)2 MatchInfo (com.apple.foundationdb.record.query.plan.temp.MatchInfo)2 PartialMatch (com.apple.foundationdb.record.query.plan.temp.PartialMatch)2