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);
}
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)));
}
}
}
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()));
}
}
}
}
}
Aggregations