Search in sources :

Example 1 with PlanContext

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

the class TestRuleExecution method applyRule.

public static TestRuleExecution applyRule(@Nonnull PlanContext context, @Nonnull PlannerRule<? extends RelationalExpression> rule, @Nonnull GroupExpressionRef<RelationalExpression> group) {
    boolean ruleMatched = false;
    for (RelationalExpression expression : group.getMembers()) {
        final Iterator<CascadesRuleCall> ruleCalls = rule.getMatcher().bindMatches(PlannerBindings.empty(), expression).map(bindings -> new CascadesRuleCall(context, rule, group, Quantifiers.AliasResolver.withRoot(group), bindings)).iterator();
        while (ruleCalls.hasNext()) {
            ruleCalls.next().run();
            ruleMatched = true;
        }
    }
    return new TestRuleExecution(ruleMatched, group);
}
Also used : RelationalExpression(com.apple.foundationdb.record.query.plan.temp.RelationalExpression) Iterator(java.util.Iterator) PlannerRule(com.apple.foundationdb.record.query.plan.temp.PlannerRule) PlanContext(com.apple.foundationdb.record.query.plan.temp.PlanContext) PlannerBindings(com.apple.foundationdb.record.query.plan.temp.matchers.PlannerBindings) Quantifiers(com.apple.foundationdb.record.query.plan.temp.Quantifiers) GroupExpressionRef(com.apple.foundationdb.record.query.plan.temp.GroupExpressionRef) Nonnull(javax.annotation.Nonnull) Nullable(javax.annotation.Nullable) CascadesRuleCall(com.apple.foundationdb.record.query.plan.temp.CascadesRuleCall) RelationalExpression(com.apple.foundationdb.record.query.plan.temp.RelationalExpression) CascadesRuleCall(com.apple.foundationdb.record.query.plan.temp.CascadesRuleCall)

Example 2 with PlanContext

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

the class ImplementDistinctUnionRule method onMatch.

@Override
@SuppressWarnings("java:S135")
public void onMatch(@Nonnull PlannerRuleCall call) {
    final PlanContext context = call.getContext();
    final Optional<Set<RequestedOrdering>> requiredOrderingsOptional = call.getInterestingProperty(OrderingAttribute.ORDERING);
    if (requiredOrderingsOptional.isEmpty()) {
        return;
    }
    final Set<RequestedOrdering> requestedOrderings = requiredOrderingsOptional.get();
    final KeyExpression commonPrimaryKey = context.getCommonPrimaryKey();
    if (commonPrimaryKey == null) {
        return;
    }
    final List<KeyExpression> commonPrimaryKeyParts = commonPrimaryKey.normalizeKeyForPositions();
    final PlannerBindings bindings = call.getBindings();
    final Quantifier.ForEach unionForEachQuantifier = bindings.get(unionForEachQuantifierMatcher);
    final List<? extends Collection<? extends RecordQueryPlan>> plansByQuantifier = bindings.getAll(unionLegPlansMatcher);
    // group each leg's plans by their provided ordering
    final ImmutableList<Set<Map.Entry<Ordering, ImmutableList<RecordQueryPlan>>>> plansByQuantifierOrdering = plansByQuantifier.stream().map(plansForQuantifier -> {
        final Map<Ordering, ImmutableList<RecordQueryPlan>> groupedBySortedness = plansForQuantifier.stream().flatMap(plan -> {
            final Optional<Ordering> orderingForLegOptional = OrderingProperty.evaluate(plan, context);
            return orderingForLegOptional.stream().map(ordering -> Pair.of(ordering, plan));
        }).collect(Collectors.groupingBy(Pair::getLeft, Collectors.mapping(Pair::getRight, ImmutableList.toImmutableList())));
        return groupedBySortedness.entrySet();
    }).collect(ImmutableList.toImmutableList());
    for (final List<Map.Entry<Ordering, ImmutableList<RecordQueryPlan>>> entries : CrossProduct.crossProduct(plansByQuantifierOrdering)) {
        final ImmutableList<Optional<Ordering>> orderingOptionals = entries.stream().map(entry -> Optional.of(entry.getKey())).collect(ImmutableList.toImmutableList());
        for (final RequestedOrdering requestedOrdering : requestedOrderings) {
            final Optional<Ordering> combinedOrderingOptional = OrderingProperty.deriveForUnionFromOrderings(orderingOptionals, requestedOrdering, Ordering::intersectEqualityBoundKeys);
            pushInterestingOrders(call, unionForEachQuantifier, orderingOptionals, requestedOrdering);
            if (combinedOrderingOptional.isEmpty()) {
                // 
                continue;
            }
            final Ordering ordering = combinedOrderingOptional.get();
            final Set<KeyExpression> equalityBoundKeys = ordering.getEqualityBoundKeys();
            final List<KeyPart> orderingKeyParts = ordering.getOrderingKeyParts();
            final List<KeyExpression> orderingKeys = orderingKeyParts.stream().map(KeyPart::getNormalizedKeyExpression).collect(ImmutableList.toImmutableList());
            // make sure the common primary key parts are either bound through equality or they are part of the ordering
            if (!isPrimaryKeyCompatibleWithOrdering(commonPrimaryKeyParts, orderingKeys, equalityBoundKeys)) {
                continue;
            }
            // 
            // At this point we know we can implement the distinct union over the partitions of compatibly ordered plans
            // 
            final KeyExpression comparisonKey = orderingKeys.size() == 1 ? Iterables.getOnlyElement(orderingKeys) : Key.Expressions.concat(orderingKeys);
            // 
            // create new references
            // 
            final ImmutableList<Quantifier.Physical> newQuantifiers = entries.stream().map(Map.Entry::getValue).map(GroupExpressionRef::from).map(Quantifier::physical).collect(ImmutableList.toImmutableList());
            call.yield(call.ref(RecordQueryUnionPlan.fromQuantifiers(newQuantifiers, comparisonKey, true)));
        }
    }
}
Also used : PlannerRuleCall(com.apple.foundationdb.record.query.plan.temp.PlannerRuleCall) ReferenceMatchers.references(com.apple.foundationdb.record.query.plan.temp.matchers.ReferenceMatchers.references) OrderingAttribute(com.apple.foundationdb.record.query.plan.temp.OrderingAttribute) 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) GroupExpressionRef(com.apple.foundationdb.record.query.plan.temp.GroupExpressionRef) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) Key(com.apple.foundationdb.record.metadata.Key) ImmutableList(com.google.common.collect.ImmutableList) Pair(org.apache.commons.lang3.tuple.Pair) Map(java.util.Map) MultiMatcher.some(com.apple.foundationdb.record.query.plan.temp.matchers.MultiMatcher.some) RecordQueryUnionPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryUnionPlan) Nonnull(javax.annotation.Nonnull) RequestedOrdering(com.apple.foundationdb.record.query.plan.temp.RequestedOrdering) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) ImmutableSet(com.google.common.collect.ImmutableSet) LogicalDistinctExpression(com.apple.foundationdb.record.query.plan.temp.expressions.LogicalDistinctExpression) Collection(java.util.Collection) Set(java.util.Set) MultiMatcher.all(com.apple.foundationdb.record.query.plan.temp.matchers.MultiMatcher.all) PlannerBindings(com.apple.foundationdb.record.query.plan.temp.matchers.PlannerBindings) KeyPart(com.apple.foundationdb.record.query.plan.temp.KeyPart) RelationalExpressionMatchers.logicalUnionExpression(com.apple.foundationdb.record.query.plan.temp.matchers.RelationalExpressionMatchers.logicalUnionExpression) Collectors(java.util.stream.Collectors) LogicalUnionExpression(com.apple.foundationdb.record.query.plan.temp.expressions.LogicalUnionExpression) List(java.util.List) BindingMatcher(com.apple.foundationdb.record.query.plan.temp.matchers.BindingMatcher) CrossProduct(com.apple.foundationdb.record.query.combinatorics.CrossProduct) OrderingProperty(com.apple.foundationdb.record.query.plan.temp.properties.OrderingProperty) PlanContext(com.apple.foundationdb.record.query.plan.temp.PlanContext) Optional(java.util.Optional) RelationalExpressionMatchers.logicalDistinctExpression(com.apple.foundationdb.record.query.plan.temp.matchers.RelationalExpressionMatchers.logicalDistinctExpression) API(com.apple.foundationdb.annotation.API) QuantifierMatchers.forEachQuantifierOverRef(com.apple.foundationdb.record.query.plan.temp.matchers.QuantifierMatchers.forEachQuantifierOverRef) ListMatcher.exactly(com.apple.foundationdb.record.query.plan.temp.matchers.ListMatcher.exactly) QuantifierMatchers.forEachQuantifier(com.apple.foundationdb.record.query.plan.temp.matchers.QuantifierMatchers.forEachQuantifier) RecordQueryPlanMatchers(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers) ImmutableSet(com.google.common.collect.ImmutableSet) Set(java.util.Set) ImmutableList(com.google.common.collect.ImmutableList) KeyPart(com.apple.foundationdb.record.query.plan.temp.KeyPart) PlannerBindings(com.apple.foundationdb.record.query.plan.temp.matchers.PlannerBindings) Ordering(com.apple.foundationdb.record.query.plan.temp.Ordering) RequestedOrdering(com.apple.foundationdb.record.query.plan.temp.RequestedOrdering) Pair(org.apache.commons.lang3.tuple.Pair) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) Optional(java.util.Optional) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) RequestedOrdering(com.apple.foundationdb.record.query.plan.temp.RequestedOrdering) GroupExpressionRef(com.apple.foundationdb.record.query.plan.temp.GroupExpressionRef) PlanContext(com.apple.foundationdb.record.query.plan.temp.PlanContext) Quantifier(com.apple.foundationdb.record.query.plan.temp.Quantifier) QuantifierMatchers.forEachQuantifier(com.apple.foundationdb.record.query.plan.temp.matchers.QuantifierMatchers.forEachQuantifier) Map(java.util.Map)

Example 3 with PlanContext

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

the class MatchLeafRule method onMatch.

@Override
public void onMatch(@Nonnull PlannerRuleCall call) {
    final PlanContext context = call.getContext();
    final RelationalExpression expression = call.get(root);
    // iterate through all candidates known to the context
    for (final MatchCandidate matchCandidate : context.getMatchCandidates()) {
        final ExpressionRefTraversal traversal = matchCandidate.getTraversal();
        final Set<ExpressionRef<? extends RelationalExpression>> leafRefs = traversal.getLeafReferences();
        // iterate through all leaf references in all
        for (final ExpressionRef<? extends RelationalExpression> leafRef : leafRefs) {
            for (final RelationalExpression leafMember : leafRef.getMembers()) {
                // expressions.
                if (leafMember.getQuantifiers().isEmpty()) {
                    final Iterable<BoundMatch<MatchInfo>> boundMatchInfos = matchWithCandidate(expression, leafMember);
                    // yield any match to the planner
                    boundMatchInfos.forEach(boundMatchInfo -> call.yieldPartialMatch(boundMatchInfo.getAliasMap(), matchCandidate, expression, leafRef, boundMatchInfo.getMatchResult()));
                }
            }
        }
    }
}
Also used : RelationalExpression(com.apple.foundationdb.record.query.plan.temp.RelationalExpression) ExpressionRefTraversal(com.apple.foundationdb.record.query.plan.temp.ExpressionRefTraversal) ExpressionRef(com.apple.foundationdb.record.query.plan.temp.ExpressionRef) PlanContext(com.apple.foundationdb.record.query.plan.temp.PlanContext) BoundMatch(com.apple.foundationdb.record.query.plan.temp.matching.BoundMatch) MatchCandidate(com.apple.foundationdb.record.query.plan.temp.MatchCandidate)

Aggregations

PlanContext (com.apple.foundationdb.record.query.plan.temp.PlanContext)3 GroupExpressionRef (com.apple.foundationdb.record.query.plan.temp.GroupExpressionRef)2 PlannerRule (com.apple.foundationdb.record.query.plan.temp.PlannerRule)2 RelationalExpression (com.apple.foundationdb.record.query.plan.temp.RelationalExpression)2 PlannerBindings (com.apple.foundationdb.record.query.plan.temp.matchers.PlannerBindings)2 API (com.apple.foundationdb.annotation.API)1 Key (com.apple.foundationdb.record.metadata.Key)1 KeyExpression (com.apple.foundationdb.record.metadata.expressions.KeyExpression)1 CrossProduct (com.apple.foundationdb.record.query.combinatorics.CrossProduct)1 RecordQueryPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan)1 RecordQueryUnionPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryUnionPlan)1 CascadesRuleCall (com.apple.foundationdb.record.query.plan.temp.CascadesRuleCall)1 ExpressionRef (com.apple.foundationdb.record.query.plan.temp.ExpressionRef)1 ExpressionRefTraversal (com.apple.foundationdb.record.query.plan.temp.ExpressionRefTraversal)1 KeyPart (com.apple.foundationdb.record.query.plan.temp.KeyPart)1 MatchCandidate (com.apple.foundationdb.record.query.plan.temp.MatchCandidate)1 Ordering (com.apple.foundationdb.record.query.plan.temp.Ordering)1 OrderingAttribute (com.apple.foundationdb.record.query.plan.temp.OrderingAttribute)1 PlannerRuleCall (com.apple.foundationdb.record.query.plan.temp.PlannerRuleCall)1 Quantifier (com.apple.foundationdb.record.query.plan.temp.Quantifier)1