Search in sources :

Example 21 with CorrelationIdentifier

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

the class TopologicalSortTest method testTopologicalSortSingle.

@Test
public void testTopologicalSortSingle() {
    final CorrelationIdentifier a = CorrelationIdentifier.of("a");
    final EnumeratingIterable<CorrelationIdentifier> topologicalPermutationIterable = TopologicalSort.topologicalOrderPermutations(ImmutableSet.of(a), id -> ImmutableSet.of());
    final ImmutableList<List<CorrelationIdentifier>> topologicalPermutations = ImmutableList.copyOf(topologicalPermutationIterable);
    assertEquals(1, topologicalPermutations.size());
}
Also used : CorrelationIdentifier(com.apple.foundationdb.record.query.plan.temp.CorrelationIdentifier) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) Test(org.junit.jupiter.api.Test)

Example 22 with CorrelationIdentifier

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

the class ImplementInJoinRule method getInSourcesForRequestedOrdering.

@Nonnull
@SuppressWarnings("unchecked")
private ImmutableList<InSource> getInSourcesForRequestedOrdering(@Nonnull final Map<CorrelationIdentifier, Quantifier> explodeAliasToQuantifierMap, @Nonnull final Set<CorrelationIdentifier> explodeAliases, @Nonnull final IdentityBiMap<Quantifier.ForEach, ExplodeExpression> quantifierToExplodeBiMap, @Nonnull final Ordering providedInnerOrdering, @Nonnull final RequestedOrdering requestedOrdering) {
    final var availableExplodeAliases = Sets.newLinkedHashSet(explodeAliases);
    final var requestedOrderingKeyParts = requestedOrdering.getOrderingKeyParts();
    final var sourcesBuilder = ImmutableList.<InSource>builder();
    final var resultOrderingKeyPartsBuilder = ImmutableList.<KeyPart>builder();
    final var innerOrderingKeyParts = providedInnerOrdering.getOrderingKeyParts();
    final var innerEqualityBoundKeyMap = providedInnerOrdering.getEqualityBoundKeyMap();
    final var resultOrderingEqualityBoundKeyMap = HashMultimap.create(innerEqualityBoundKeyMap);
    for (var i = 0; i < requestedOrderingKeyParts.size() && !availableExplodeAliases.isEmpty(); i++) {
        final var requestedOrderingKeyPart = requestedOrderingKeyParts.get(i);
        final var comparisons = innerEqualityBoundKeyMap.get(requestedOrderingKeyPart.getNormalizedKeyExpression());
        if (comparisons.isEmpty()) {
            return ImmutableList.of();
        }
        final var comparisonsCorrelatedTo = comparisons.stream().flatMap(comparison -> comparison.getCorrelatedTo().stream()).collect(ImmutableSet.toImmutableSet());
        if (comparisonsCorrelatedTo.size() > 1) {
            return ImmutableList.of();
        }
        if (Sets.intersection(comparisonsCorrelatedTo, explodeAliases).isEmpty()) {
            // 
            continue;
        }
        final var explodeAlias = Iterables.getOnlyElement(comparisonsCorrelatedTo);
        // 
        if (!availableExplodeAliases.contains(explodeAlias)) {
            return ImmutableList.of();
        }
        // 
        // We need to find the one quantifier over an explode expression that we can use to establish
        // the requested order.
        // 
        final var explodeQuantifier = Objects.requireNonNull(explodeAliasToQuantifierMap.get(explodeAlias));
        final var explodeExpression = Objects.requireNonNull(quantifierToExplodeBiMap.getUnwrapped(explodeQuantifier));
        // 
        // At this point we have a bound key expression that matches the requested order at this position,
        // and we have our hands on a particular explode expression leading us directly do the in source.
        // 
        final var explodeResultValues = explodeExpression.getResultValues();
        if (explodeResultValues.size() != 1) {
            return ImmutableList.of();
        }
        final var explodeValue = Iterables.getOnlyElement(explodeResultValues);
        final InSource inSource;
        if (explodeValue instanceof LiteralValue<?>) {
            final Object literalValue = ((LiteralValue<?>) explodeValue).getLiteralValue();
            if (literalValue instanceof List<?>) {
                inSource = new SortedInValuesSource(CORRELATION.bindingName(explodeQuantifier.getAlias().getId()), (List<Object>) literalValue, requestedOrderingKeyPart.isReverse());
            } else {
                return ImmutableList.of();
            }
        } else if (explodeValue instanceof QuantifiedColumnValue) {
            inSource = new SortedInParameterSource(CORRELATION.bindingName(explodeQuantifier.getAlias().getId()), ((QuantifiedColumnValue) explodeValue).getAlias().getId(), requestedOrderingKeyPart.isReverse());
        } else {
            return ImmutableList.of();
        }
        availableExplodeAliases.remove(explodeAlias);
        sourcesBuilder.add(inSource);
        resultOrderingEqualityBoundKeyMap.removeAll(requestedOrderingKeyPart.getNormalizedKeyExpression());
        resultOrderingKeyPartsBuilder.add(requestedOrderingKeyPart);
    }
    if (availableExplodeAliases.isEmpty()) {
        // 
        // All available explode aliases have been depleted. Create an ordering and check against the requested
        // ordering.
        // 
        resultOrderingKeyPartsBuilder.addAll(innerOrderingKeyParts);
        final var resultOrdering = new Ordering(resultOrderingEqualityBoundKeyMap, resultOrderingKeyPartsBuilder.build(), providedInnerOrdering.isDistinct());
        return Ordering.satisfiesRequestedOrdering(resultOrdering, requestedOrdering) ? sourcesBuilder.build() : ImmutableList.of();
    } else {
        // 
        for (final var explodeAlias : availableExplodeAliases) {
            final var explodeQuantifier = Objects.requireNonNull(explodeAliasToQuantifierMap.get(explodeAlias));
            final var explodeExpression = Objects.requireNonNull(quantifierToExplodeBiMap.getUnwrapped(explodeQuantifier));
            final var explodeResultValues = explodeExpression.getResultValues();
            if (explodeResultValues.size() != 1) {
                return ImmutableList.of();
            }
            final var explodeValue = Iterables.getOnlyElement(explodeResultValues);
            final InSource inSource;
            if (explodeValue instanceof LiteralValue<?>) {
                final Object literalValue = ((LiteralValue<?>) explodeValue).getLiteralValue();
                if (literalValue instanceof List<?>) {
                    inSource = new InValuesSource(CORRELATION.bindingName(explodeQuantifier.getAlias().getId()), (List<Object>) literalValue);
                } else {
                    return ImmutableList.of();
                }
            } else if (explodeValue instanceof QuantifiedColumnValue) {
                inSource = new InParameterSource(CORRELATION.bindingName(explodeQuantifier.getAlias().getId()), ((QuantifiedColumnValue) explodeValue).getAlias().getId());
            } else {
                return ImmutableList.of();
            }
            sourcesBuilder.add(inSource);
        }
    }
    // 
    return sourcesBuilder.build();
}
Also used : PlannerRuleCall(com.apple.foundationdb.record.query.plan.temp.PlannerRuleCall) OrderingAttribute(com.apple.foundationdb.record.query.plan.temp.OrderingAttribute) LinkedIdentitySet(com.apple.foundationdb.record.query.plan.temp.LinkedIdentitySet) GroupExpressionRef(com.apple.foundationdb.record.query.plan.temp.GroupExpressionRef) HashMultimap(com.google.common.collect.HashMultimap) Pair(org.apache.commons.lang3.tuple.Pair) RelationalExpressionMatchers.selectExpression(com.apple.foundationdb.record.query.plan.temp.matchers.RelationalExpressionMatchers.selectExpression) Map(java.util.Map) RequestedOrdering(com.apple.foundationdb.record.query.plan.temp.RequestedOrdering) ImmutableSet(com.google.common.collect.ImmutableSet) Collection(java.util.Collection) Set(java.util.Set) SelectExpression(com.apple.foundationdb.record.query.plan.temp.expressions.SelectExpression) LiteralValue(com.apple.foundationdb.record.query.predicates.LiteralValue) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) Objects(java.util.Objects) Value(com.apple.foundationdb.record.query.predicates.Value) List(java.util.List) RecordQueryInUnionPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryInUnionPlan) CorrelationIdentifier(com.apple.foundationdb.record.query.plan.temp.CorrelationIdentifier) OrderingProperty(com.apple.foundationdb.record.query.plan.temp.properties.OrderingProperty) Optional(java.util.Optional) API(com.apple.foundationdb.annotation.API) InParameterSource(com.apple.foundationdb.record.query.plan.plans.InParameterSource) CORRELATION(com.apple.foundationdb.record.Bindings.Internal.CORRELATION) Iterables(com.google.common.collect.Iterables) PlannerRule(com.apple.foundationdb.record.query.plan.temp.PlannerRule) Quantifier(com.apple.foundationdb.record.query.plan.temp.Quantifier) CollectionMatcher(com.apple.foundationdb.record.query.plan.temp.matchers.CollectionMatcher) Ordering(com.apple.foundationdb.record.query.plan.temp.Ordering) Quantifiers(com.apple.foundationdb.record.query.plan.temp.Quantifiers) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) RelationalExpressionMatchers.explodeExpression(com.apple.foundationdb.record.query.plan.temp.matchers.RelationalExpressionMatchers.explodeExpression) Lists(com.google.common.collect.Lists) ImmutableList(com.google.common.collect.ImmutableList) IdentityBiMap(com.apple.foundationdb.record.query.plan.temp.IdentityBiMap) PushInterestingOrderingThroughInLikeSelectRule.findInnerQuantifier(com.apple.foundationdb.record.query.plan.temp.rules.PushInterestingOrderingThroughInLikeSelectRule.findInnerQuantifier) InSource(com.apple.foundationdb.record.query.plan.plans.InSource) InValuesSource(com.apple.foundationdb.record.query.plan.plans.InValuesSource) MultiMatcher.some(com.apple.foundationdb.record.query.plan.temp.matchers.MultiMatcher.some) Nonnull(javax.annotation.Nonnull) SortedInValuesSource(com.apple.foundationdb.record.query.plan.plans.SortedInValuesSource) KeyPart(com.apple.foundationdb.record.query.plan.temp.KeyPart) SortedInParameterSource(com.apple.foundationdb.record.query.plan.plans.SortedInParameterSource) BindingMatcher(com.apple.foundationdb.record.query.plan.temp.matchers.BindingMatcher) QuantifierMatchers.forEachQuantifier(com.apple.foundationdb.record.query.plan.temp.matchers.QuantifierMatchers.forEachQuantifier) QuantifiedColumnValue(com.apple.foundationdb.record.query.predicates.QuantifiedColumnValue) ExplodeExpression(com.apple.foundationdb.record.query.plan.temp.expressions.ExplodeExpression) SortedInParameterSource(com.apple.foundationdb.record.query.plan.plans.SortedInParameterSource) KeyPart(com.apple.foundationdb.record.query.plan.temp.KeyPart) LiteralValue(com.apple.foundationdb.record.query.predicates.LiteralValue) InParameterSource(com.apple.foundationdb.record.query.plan.plans.InParameterSource) SortedInParameterSource(com.apple.foundationdb.record.query.plan.plans.SortedInParameterSource) QuantifiedColumnValue(com.apple.foundationdb.record.query.predicates.QuantifiedColumnValue) InSource(com.apple.foundationdb.record.query.plan.plans.InSource) RequestedOrdering(com.apple.foundationdb.record.query.plan.temp.RequestedOrdering) Ordering(com.apple.foundationdb.record.query.plan.temp.Ordering) InValuesSource(com.apple.foundationdb.record.query.plan.plans.InValuesSource) SortedInValuesSource(com.apple.foundationdb.record.query.plan.plans.SortedInValuesSource) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) SortedInValuesSource(com.apple.foundationdb.record.query.plan.plans.SortedInValuesSource) Nonnull(javax.annotation.Nonnull)

Example 23 with CorrelationIdentifier

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

the class AbstractDataAccessRule method computeBoundKeyPartMap.

@Nonnull
private static Map<QueryPredicate, BoundKeyPart> computeBoundKeyPartMap(final PartialMatch partialMatch) {
    final MatchInfo matchInfo = partialMatch.getMatchInfo();
    final Map<CorrelationIdentifier, ComparisonRange> boundParameterPrefixMap = partialMatch.getBoundParameterPrefixMap();
    return matchInfo.getBoundKeyParts().stream().filter(boundKeyPart -> {
        // make sure that matching actually bound the part and that it can be used in a scan
        return matchInfo.getParameterAliasForBoundKeyPart(boundKeyPart).map(boundParameterPrefixMap::containsKey).orElse(false);
    }).peek(// make sure we got a predicate mapping
    boundKeyPart -> Objects.requireNonNull(boundKeyPart.getQueryPredicate())).collect(Collectors.toMap(BoundKeyPart::getQueryPredicate, Function.identity(), (a, b) -> {
        if (matchInfo.getCandidatePredicateForBoundKeyPart(a) == matchInfo.getCandidatePredicateForBoundKeyPart(b) && a.getComparisonRangeType() == b.getComparisonRangeType()) {
            return a;
        }
        throw new RecordCoreException("merge conflict");
    }, Maps::newIdentityHashMap));
}
Also used : PlannerRuleCall(com.apple.foundationdb.record.query.plan.temp.PlannerRuleCall) OrderingAttribute(com.apple.foundationdb.record.query.plan.temp.OrderingAttribute) CascadesPlanner(com.apple.foundationdb.record.query.plan.temp.CascadesPlanner) LinkedIdentitySet(com.apple.foundationdb.record.query.plan.temp.LinkedIdentitySet) GroupExpressionRef(com.apple.foundationdb.record.query.plan.temp.GroupExpressionRef) PartialMatch(com.apple.foundationdb.record.query.plan.temp.PartialMatch) Pair(org.apache.commons.lang3.tuple.Pair) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) ComparisonRange(com.apple.foundationdb.record.query.plan.temp.ComparisonRange) Map(java.util.Map) IndexScanExpression(com.apple.foundationdb.record.query.plan.temp.expressions.IndexScanExpression) MatchCandidate(com.apple.foundationdb.record.query.plan.temp.MatchCandidate) PrimaryScanExpression(com.apple.foundationdb.record.query.plan.temp.expressions.PrimaryScanExpression) RequestedOrdering(com.apple.foundationdb.record.query.plan.temp.RequestedOrdering) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) ImmutableSet(com.google.common.collect.ImmutableSet) ImmutableMap(com.google.common.collect.ImmutableMap) Collection(java.util.Collection) MatchPartition(com.apple.foundationdb.record.query.plan.temp.MatchPartition) Set(java.util.Set) PlannerBindings(com.apple.foundationdb.record.query.plan.temp.matchers.PlannerBindings) ReferencedFieldsAttribute(com.apple.foundationdb.record.query.plan.temp.ReferencedFieldsAttribute) Collectors(java.util.stream.Collectors) Objects(java.util.Objects) BoundKeyPart(com.apple.foundationdb.record.query.plan.temp.BoundKeyPart) List(java.util.List) Stream(java.util.stream.Stream) CorrelationIdentifier(com.apple.foundationdb.record.query.plan.temp.CorrelationIdentifier) MatchInfo(com.apple.foundationdb.record.query.plan.temp.MatchInfo) Optional(java.util.Optional) API(com.apple.foundationdb.annotation.API) IntStream(java.util.stream.IntStream) Iterables(com.google.common.collect.Iterables) PlannerRule(com.apple.foundationdb.record.query.plan.temp.PlannerRule) Quantifier(com.apple.foundationdb.record.query.plan.temp.Quantifier) Ordering(com.apple.foundationdb.record.query.plan.temp.Ordering) Function(java.util.function.Function) Key(com.apple.foundationdb.record.metadata.Key) LinkedHashMap(java.util.LinkedHashMap) Lists(com.google.common.collect.Lists) ImmutableList(com.google.common.collect.ImmutableList) Compensation(com.apple.foundationdb.record.query.plan.temp.Compensation) StreamSupport(java.util.stream.StreamSupport) ExpressionRef(com.apple.foundationdb.record.query.plan.temp.ExpressionRef) Nonnull(javax.annotation.Nonnull) Nullable(javax.annotation.Nullable) ChooseK(com.apple.foundationdb.record.query.combinatorics.ChooseK) LogicalIntersectionExpression(com.apple.foundationdb.record.query.plan.temp.expressions.LogicalIntersectionExpression) Iterator(java.util.Iterator) LogicalDistinctExpression(com.apple.foundationdb.record.query.plan.temp.expressions.LogicalDistinctExpression) PartialOrder(com.apple.foundationdb.record.query.combinatorics.PartialOrder) QueryPredicate(com.apple.foundationdb.record.query.predicates.QueryPredicate) KeyPart(com.apple.foundationdb.record.query.plan.temp.KeyPart) Maps(com.google.common.collect.Maps) RelationalExpression(com.apple.foundationdb.record.query.plan.temp.RelationalExpression) BindingMatcher(com.apple.foundationdb.record.query.plan.temp.matchers.BindingMatcher) PrimaryScanMatchCandidate(com.apple.foundationdb.record.query.plan.temp.PrimaryScanMatchCandidate) Comparator(java.util.Comparator) ValueIndexScanMatchCandidate(com.apple.foundationdb.record.query.plan.temp.ValueIndexScanMatchCandidate) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) MatchInfo(com.apple.foundationdb.record.query.plan.temp.MatchInfo) CorrelationIdentifier(com.apple.foundationdb.record.query.plan.temp.CorrelationIdentifier) ComparisonRange(com.apple.foundationdb.record.query.plan.temp.ComparisonRange) Nonnull(javax.annotation.Nonnull)

Example 24 with CorrelationIdentifier

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

the class PushSetOperationThroughFetchRule method onMatch.

@Override
@SuppressWarnings("java:S1905")
public void onMatch(@Nonnull PlannerRuleCall call) {
    final PlannerBindings bindings = call.getBindings();
    final RecordQuerySetPlan setOperationPlan = bindings.get(getMatcher());
    final List<? extends Quantifier.Physical> quantifiersOverFetches = bindings.getAll(quantifierOverFetchMatcher);
    // if set operation is dynamic all quantifiers must have fetches
    if (setOperationPlan.isDynamic()) {
        if (quantifiersOverFetches.size() < setOperationPlan.getQuantifiers().size()) {
            return;
        }
    } else {
        if (quantifiersOverFetches.size() <= 1) {
            // pulling up the fetch is meaningless in this case
            return;
        }
    }
    final List<? extends RecordQueryFetchFromPartialRecordPlan> fetchPlans = bindings.getAll(fetchPlanMatcher);
    final ImmutableList<TranslateValueFunction> dependentFunctions = fetchPlans.stream().map(RecordQueryFetchFromPartialRecordPlan::getPushValueFunction).collect(ImmutableList.toImmutableList());
    Verify.verify(quantifiersOverFetches.size() == fetchPlans.size());
    Verify.verify(fetchPlans.size() == dependentFunctions.size());
    final List<? extends Value> requiredValues = setOperationPlan.getRequiredValues(CorrelationIdentifier.uniqueID());
    final Set<CorrelationIdentifier> pushableAliases = setOperationPlan.tryPushValues(dependentFunctions, quantifiersOverFetches, requiredValues);
    // if set operation is dynamic all aliases must be pushable
    if (setOperationPlan.isDynamic()) {
        if (pushableAliases.size() < setOperationPlan.getQuantifiers().size()) {
            return;
        }
    } else {
        if (pushableAliases.size() <= 1) {
            // pulling up the fetch is meaningless in this case
            return;
        }
    }
    final ImmutableList.Builder<Quantifier.Physical> pushableQuantifiersBuilder = ImmutableList.builder();
    final ImmutableList.Builder<RecordQueryFetchFromPartialRecordPlan> pushableFetchPlansBuilder = ImmutableList.builder();
    final ImmutableList.Builder<TranslateValueFunction> pushableDependentFunctionsBuilder = ImmutableList.builder();
    for (int i = 0; i < quantifiersOverFetches.size(); i++) {
        final Quantifier.Physical quantifier = quantifiersOverFetches.get(i);
        if (pushableAliases.contains(quantifier.getAlias())) {
            pushableQuantifiersBuilder.add(quantifier);
            pushableFetchPlansBuilder.add(fetchPlans.get(i));
            pushableDependentFunctionsBuilder.add(dependentFunctions.get(i));
        }
    }
    final ImmutableList<Quantifier.Physical> pushableQuantifiers = pushableQuantifiersBuilder.build();
    final ImmutableList<RecordQueryFetchFromPartialRecordPlan> pushableFetchPlans = pushableFetchPlansBuilder.build();
    final ImmutableList<TranslateValueFunction> pushableDependentFunctions = pushableDependentFunctionsBuilder.build();
    final ImmutableList<Quantifier.Physical> nonPushableQuantifiers = setOperationPlan.getQuantifiers().stream().map(quantifier -> (Quantifier.Physical) quantifier).filter(quantifier -> !pushableAliases.contains(quantifier.getAlias())).collect(ImmutableList.toImmutableList());
    final List<? extends ExpressionRef<RecordQueryPlan>> newPushedInnerPlans = pushableFetchPlans.stream().map(RecordQueryFetchFromPartialRecordPlan::getChild).map(GroupExpressionRef::of).collect(ImmutableList.toImmutableList());
    Verify.verify(pushableQuantifiers.size() + nonPushableQuantifiers.size() == setOperationPlan.getQuantifiers().size());
    final TranslateValueFunction combinedTranslateValueFunction = setOperationPlan.pushValueFunction(pushableDependentFunctions);
    final RecordQuerySetPlan newSetOperationPlan = setOperationPlan.withChildrenReferences(newPushedInnerPlans);
    final RecordQueryFetchFromPartialRecordPlan newFetchPlan = new RecordQueryFetchFromPartialRecordPlan(newSetOperationPlan, combinedTranslateValueFunction);
    if (nonPushableQuantifiers.isEmpty()) {
        call.yield(GroupExpressionRef.of(newFetchPlan));
    } else {
        final List<ExpressionRef<? extends RecordQueryPlan>> newFetchPlanAndResidualInners = Streams.concat(Stream.of(GroupExpressionRef.of(newFetchPlan)), nonPushableQuantifiers.stream().map(Quantifier.Physical::getRangesOver).map(RecordQueryPlan::narrowReference)).collect(ImmutableList.toImmutableList());
        call.yield(GroupExpressionRef.of(setOperationPlan.withChildrenReferences(newFetchPlanAndResidualInners)));
    }
}
Also used : 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) GroupExpressionRef(com.apple.foundationdb.record.query.plan.temp.GroupExpressionRef) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) RecordQueryPlanMatchers.fetchFromPartialRecordPlan(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers.fetchFromPartialRecordPlan) ImmutableList(com.google.common.collect.ImmutableList) RelationalExpressionMatchers.ofTypeOwning(com.apple.foundationdb.record.query.plan.temp.matchers.RelationalExpressionMatchers.ofTypeOwning) ExpressionRef(com.apple.foundationdb.record.query.plan.temp.ExpressionRef) MultiMatcher.some(com.apple.foundationdb.record.query.plan.temp.matchers.MultiMatcher.some) Nonnull(javax.annotation.Nonnull) Verify(com.google.common.base.Verify) RecordQuerySetPlan(com.apple.foundationdb.record.query.plan.plans.RecordQuerySetPlan) QuantifierMatchers.physicalQuantifier(com.apple.foundationdb.record.query.plan.temp.matchers.QuantifierMatchers.physicalQuantifier) Set(java.util.Set) PlannerBindings(com.apple.foundationdb.record.query.plan.temp.matchers.PlannerBindings) Streams(com.google.common.collect.Streams) Value(com.apple.foundationdb.record.query.predicates.Value) List(java.util.List) BindingMatcher(com.apple.foundationdb.record.query.plan.temp.matchers.BindingMatcher) Stream(java.util.stream.Stream) CorrelationIdentifier(com.apple.foundationdb.record.query.plan.temp.CorrelationIdentifier) API(com.apple.foundationdb.annotation.API) ImmutableList(com.google.common.collect.ImmutableList) GroupExpressionRef(com.apple.foundationdb.record.query.plan.temp.GroupExpressionRef) ExpressionRef(com.apple.foundationdb.record.query.plan.temp.ExpressionRef) PlannerBindings(com.apple.foundationdb.record.query.plan.temp.matchers.PlannerBindings) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) TranslateValueFunction(com.apple.foundationdb.record.query.plan.plans.TranslateValueFunction) RecordQueryFetchFromPartialRecordPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryFetchFromPartialRecordPlan) RecordQuerySetPlan(com.apple.foundationdb.record.query.plan.plans.RecordQuerySetPlan) CorrelationIdentifier(com.apple.foundationdb.record.query.plan.temp.CorrelationIdentifier) Quantifier(com.apple.foundationdb.record.query.plan.temp.Quantifier) QuantifierMatchers.physicalQuantifier(com.apple.foundationdb.record.query.plan.temp.matchers.QuantifierMatchers.physicalQuantifier)

Example 25 with CorrelationIdentifier

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

the class MatchableSortExpression method forPartialMatch.

/**
 * This synthesizes a list of {@link BoundKeyPart}s from the current partial match and the ordering information
 * contained in this expression. Using the list of parameter ids, each {@link BoundKeyPart} links together the
 * (1) normalized key expression that originally produced the key (from index, or common primary key)
 * (2) a comparison range for this parameter which is contained in the already existent partial match
 * (3) the predicate on the query part that participated and bound this parameter (and implicitly was used to
 *     synthesize the comparison range in (2)
 * (4) the candidate predicate on the candidate side that is the {@link Placeholder} for the parameter
 * @param partialMatch the pre-existing partial match on {@code (expression, this)} that the caller wants to adjust.
 * @return a list of bound key parts that express the order of the outgoing data stream and their respective mappings
 *         between query and match candidate
 */
@Nonnull
private List<BoundKeyPart> forPartialMatch(@Nonnull PartialMatch partialMatch) {
    final MatchCandidate matchCandidate = partialMatch.getMatchCandidate();
    final MatchInfo matchInfo = partialMatch.getMatchInfo();
    final Map<CorrelationIdentifier, ComparisonRange> parameterBindingMap = matchInfo.getParameterBindingMap();
    final PredicateMap accumulatedPredicateMap = matchInfo.getAccumulatedPredicateMap();
    final ImmutableMap<CorrelationIdentifier, QueryPredicate> parameterBindingPredicateMap = accumulatedPredicateMap.entries().stream().filter(entry -> {
        final PredicateMapping predicateMapping = entry.getValue();
        return predicateMapping.getParameterAliasOptional().isPresent();
    }).collect(ImmutableMap.toImmutableMap(entry -> {
        final PredicateMapping predicateMapping = entry.getValue();
        return Objects.requireNonNull(predicateMapping.getParameterAliasOptional().orElseThrow(() -> new RecordCoreException("parameter alias should have been set")));
    }, entry -> Objects.requireNonNull(entry.getKey())));
    final List<KeyExpression> normalizedKeys = matchCandidate.getAlternativeKeyExpression().normalizeKeyForPositions();
    final ImmutableList.Builder<BoundKeyPart> builder = ImmutableList.builder();
    final List<CorrelationIdentifier> candidateParameterIds = matchCandidate.getParameters();
    for (final CorrelationIdentifier parameterId : sortParameterIds) {
        final int ordinalInCandidate = candidateParameterIds.indexOf(parameterId);
        Verify.verify(ordinalInCandidate >= 0);
        final KeyExpression normalizedKey = normalizedKeys.get(ordinalInCandidate);
        Objects.requireNonNull(parameterId);
        Objects.requireNonNull(normalizedKey);
        @Nullable final ComparisonRange comparisonRange = parameterBindingMap.get(parameterId);
        @Nullable final QueryPredicate queryPredicate = parameterBindingPredicateMap.get(parameterId);
        Verify.verify(comparisonRange == null || comparisonRange.getRangeType() == ComparisonRange.Type.EMPTY || queryPredicate != null);
        builder.add(BoundKeyPart.of(normalizedKey, comparisonRange == null ? ComparisonRange.Type.EMPTY : comparisonRange.getRangeType(), queryPredicate, isReverse));
    }
    return builder.build();
}
Also used : Iterables(com.google.common.collect.Iterables) Quantifier(com.apple.foundationdb.record.query.plan.temp.Quantifier) GroupExpressionRef(com.apple.foundationdb.record.query.plan.temp.GroupExpressionRef) Supplier(java.util.function.Supplier) PredicateMap(com.apple.foundationdb.record.query.plan.temp.PredicateMap) PartialMatch(com.apple.foundationdb.record.query.plan.temp.PartialMatch) ImmutableList(com.google.common.collect.ImmutableList) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) ComparisonRange(com.apple.foundationdb.record.query.plan.temp.ComparisonRange) Attribute(com.apple.foundationdb.record.query.plan.temp.explain.Attribute) Map(java.util.Map) MatchCandidate(com.apple.foundationdb.record.query.plan.temp.MatchCandidate) Placeholder(com.apple.foundationdb.record.query.predicates.ValueComparisonRangePredicate.Placeholder) AliasMap(com.apple.foundationdb.record.query.plan.temp.AliasMap) Nonnull(javax.annotation.Nonnull) Nullable(javax.annotation.Nullable) PredicateMapping(com.apple.foundationdb.record.query.plan.temp.PredicateMultiMap.PredicateMapping) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) AdjustMatchRule(com.apple.foundationdb.record.query.plan.temp.rules.AdjustMatchRule) Verify(com.google.common.base.Verify) ImmutableSet(com.google.common.collect.ImmutableSet) ImmutableMap(com.google.common.collect.ImmutableMap) Set(java.util.Set) InternalPlannerGraphRewritable(com.apple.foundationdb.record.query.plan.temp.explain.InternalPlannerGraphRewritable) QueryPredicate(com.apple.foundationdb.record.query.predicates.QueryPredicate) RelationalExpression(com.apple.foundationdb.record.query.plan.temp.RelationalExpression) Objects(java.util.Objects) BoundKeyPart(com.apple.foundationdb.record.query.plan.temp.BoundKeyPart) Value(com.apple.foundationdb.record.query.predicates.Value) List(java.util.List) CorrelationIdentifier(com.apple.foundationdb.record.query.plan.temp.CorrelationIdentifier) MatchInfo(com.apple.foundationdb.record.query.plan.temp.MatchInfo) Optional(java.util.Optional) RemoveSortRule(com.apple.foundationdb.record.query.plan.temp.rules.RemoveSortRule) API(com.apple.foundationdb.annotation.API) PlannerGraph(com.apple.foundationdb.record.query.plan.temp.explain.PlannerGraph) NodeInfo(com.apple.foundationdb.record.query.plan.temp.explain.NodeInfo) QueryPredicate(com.apple.foundationdb.record.query.predicates.QueryPredicate) ImmutableList(com.google.common.collect.ImmutableList) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) PredicateMap(com.apple.foundationdb.record.query.plan.temp.PredicateMap) BoundKeyPart(com.apple.foundationdb.record.query.plan.temp.BoundKeyPart) PredicateMapping(com.apple.foundationdb.record.query.plan.temp.PredicateMultiMap.PredicateMapping) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) MatchInfo(com.apple.foundationdb.record.query.plan.temp.MatchInfo) CorrelationIdentifier(com.apple.foundationdb.record.query.plan.temp.CorrelationIdentifier) MatchCandidate(com.apple.foundationdb.record.query.plan.temp.MatchCandidate) ComparisonRange(com.apple.foundationdb.record.query.plan.temp.ComparisonRange) Nullable(javax.annotation.Nullable) Nonnull(javax.annotation.Nonnull)

Aggregations

CorrelationIdentifier (com.apple.foundationdb.record.query.plan.temp.CorrelationIdentifier)31 Set (java.util.Set)19 ImmutableSet (com.google.common.collect.ImmutableSet)18 Test (org.junit.jupiter.api.Test)17 List (java.util.List)15 ImmutableList (com.google.common.collect.ImmutableList)14 Nonnull (javax.annotation.Nonnull)11 Quantifier (com.apple.foundationdb.record.query.plan.temp.Quantifier)10 API (com.apple.foundationdb.annotation.API)8 AliasMap (com.apple.foundationdb.record.query.plan.temp.AliasMap)8 Value (com.apple.foundationdb.record.query.predicates.Value)7 GroupExpressionRef (com.apple.foundationdb.record.query.plan.temp.GroupExpressionRef)5 MatchInfo (com.apple.foundationdb.record.query.plan.temp.MatchInfo)5 PartialMatch (com.apple.foundationdb.record.query.plan.temp.PartialMatch)5 RelationalExpression (com.apple.foundationdb.record.query.plan.temp.RelationalExpression)5 QueryPredicate (com.apple.foundationdb.record.query.predicates.QueryPredicate)5 Verify (com.google.common.base.Verify)5 Optional (java.util.Optional)5 RecordQueryFetchFromPartialRecordPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryFetchFromPartialRecordPlan)4 RecordQueryPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan)4