Search in sources :

Example 6 with GroupExpressionRef

use of com.apple.foundationdb.record.query.plan.temp.GroupExpressionRef 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 7 with GroupExpressionRef

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

the class ImplementUnorderedUnionRule method onMatch.

@Override
public void onMatch(@Nonnull PlannerRuleCall call) {
    final PlannerBindings bindings = call.getBindings();
    final List<? extends Collection<? extends RecordQueryPlan>> groupedPlansByLeg = bindings.getAll(unionLegPlansMatcher);
    final ImmutableList<Quantifier.Physical> quantifiers = groupedPlansByLeg.stream().map(GroupExpressionRef::from).map(Quantifier::physical).collect(ImmutableList.toImmutableList());
    call.yield(call.ref(RecordQueryUnorderedUnionPlan.fromQuantifiers(quantifiers)));
}
Also used : PlannerBindings(com.apple.foundationdb.record.query.plan.temp.matchers.PlannerBindings) GroupExpressionRef(com.apple.foundationdb.record.query.plan.temp.GroupExpressionRef)

Aggregations

GroupExpressionRef (com.apple.foundationdb.record.query.plan.temp.GroupExpressionRef)7 Nonnull (javax.annotation.Nonnull)6 RecordQueryPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan)5 PlannerRule (com.apple.foundationdb.record.query.plan.temp.PlannerRule)5 ImmutableList (com.google.common.collect.ImmutableList)5 List (java.util.List)5 Set (java.util.Set)5 API (com.apple.foundationdb.annotation.API)4 PlannerRuleCall (com.apple.foundationdb.record.query.plan.temp.PlannerRuleCall)4 Quantifier (com.apple.foundationdb.record.query.plan.temp.Quantifier)4 BindingMatcher (com.apple.foundationdb.record.query.plan.temp.matchers.BindingMatcher)4 MultiMatcher.some (com.apple.foundationdb.record.query.plan.temp.matchers.MultiMatcher.some)4 KeyPart (com.apple.foundationdb.record.query.plan.temp.KeyPart)3 Ordering (com.apple.foundationdb.record.query.plan.temp.Ordering)3 OrderingAttribute (com.apple.foundationdb.record.query.plan.temp.OrderingAttribute)3 Quantifiers (com.apple.foundationdb.record.query.plan.temp.Quantifiers)3 RequestedOrdering (com.apple.foundationdb.record.query.plan.temp.RequestedOrdering)3 CollectionMatcher (com.apple.foundationdb.record.query.plan.temp.matchers.CollectionMatcher)3 PlannerBindings (com.apple.foundationdb.record.query.plan.temp.matchers.PlannerBindings)3 QuantifierMatchers.forEachQuantifier (com.apple.foundationdb.record.query.plan.temp.matchers.QuantifierMatchers.forEachQuantifier)3