Search in sources :

Example 1 with ExpressionRef

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

the class OrderingProperty method evaluateAtRef.

@Nonnull
@Override
public Optional<Ordering> evaluateAtRef(@Nonnull ExpressionRef<? extends RelationalExpression> ref, @Nonnull List<Optional<Ordering>> orderingOptionals) {
    final Optional<SetMultimap<KeyExpression, Comparisons.Comparison>> commonEqualityBoundKeysMapOptional = Ordering.combineEqualityBoundKeys(orderingOptionals, Ordering::intersectEqualityBoundKeys);
    if (commonEqualityBoundKeysMapOptional.isEmpty()) {
        return Optional.empty();
    }
    final var commonEqualityBoundKeysMap = commonEqualityBoundKeysMapOptional.get();
    final Optional<List<KeyPart>> commonOrderingKeysOptional = Ordering.commonOrderingKeys(orderingOptionals, RequestedOrdering.preserve());
    if (commonOrderingKeysOptional.isEmpty()) {
        return Optional.empty();
    }
    final var commonOrderingKeys = commonOrderingKeysOptional.get().stream().filter(keyPart -> !commonEqualityBoundKeysMap.containsKey(keyPart.getNormalizedKeyExpression())).collect(ImmutableList.toImmutableList());
    final var allAreDistinct = orderingOptionals.stream().allMatch(orderingOptional -> orderingOptional.map(Ordering::isDistinct).orElse(false));
    return Optional.of(new Ordering(commonEqualityBoundKeysMap, commonOrderingKeys, allAreDistinct));
}
Also used : RecordQueryIntersectionPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryIntersectionPlan) PlannerProperty(com.apple.foundationdb.record.query.plan.temp.PlannerProperty) HashMultimap(com.google.common.collect.HashMultimap) Pair(org.apache.commons.lang3.tuple.Pair) RecordQueryScanPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryScanPlan) RecordQueryUnionPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryUnionPlan) RecordQueryUnorderedUnionPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryUnorderedUnionPlan) PrimaryScanExpression(com.apple.foundationdb.record.query.plan.temp.expressions.PrimaryScanExpression) ImmutableSetMultimap(com.google.common.collect.ImmutableSetMultimap) RequestedOrdering(com.apple.foundationdb.record.query.plan.temp.RequestedOrdering) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) ImmutableSet(com.google.common.collect.ImmutableSet) Collection(java.util.Collection) RecordQueryPredicatesFilterPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPredicatesFilterPlan) Collectors(java.util.stream.Collectors) BinaryOperator(java.util.function.BinaryOperator) RecordQueryCoveringIndexPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryCoveringIndexPlan) List(java.util.List) Stream(java.util.stream.Stream) RecordQueryInUnionPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryInUnionPlan) CorrelationIdentifier(com.apple.foundationdb.record.query.plan.temp.CorrelationIdentifier) RecordQueryInJoinPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryInJoinPlan) PlanContext(com.apple.foundationdb.record.query.plan.temp.PlanContext) Optional(java.util.Optional) API(com.apple.foundationdb.annotation.API) CORRELATION(com.apple.foundationdb.record.Bindings.Internal.CORRELATION) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) Iterables(com.google.common.collect.Iterables) ValuePredicate(com.apple.foundationdb.record.query.predicates.ValuePredicate) Quantifier(com.apple.foundationdb.record.query.plan.temp.Quantifier) Ordering(com.apple.foundationdb.record.query.plan.temp.Ordering) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) LogicalSortExpression(com.apple.foundationdb.record.query.plan.temp.expressions.LogicalSortExpression) Key(com.apple.foundationdb.record.metadata.Key) ImmutableList(com.google.common.collect.ImmutableList) ExpressionRef(com.apple.foundationdb.record.query.plan.temp.ExpressionRef) FieldValue(com.apple.foundationdb.record.query.predicates.FieldValue) Nonnull(javax.annotation.Nonnull) Nullable(javax.annotation.Nullable) RecordQueryIndexPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryIndexPlan) RecordQueryPlanWithIndex(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlanWithIndex) ScanComparisons(com.apple.foundationdb.record.query.plan.ScanComparisons) KeyPart(com.apple.foundationdb.record.query.plan.temp.KeyPart) SetMultimap(com.google.common.collect.SetMultimap) RelationalExpression(com.apple.foundationdb.record.query.plan.temp.RelationalExpression) ValueIndexExpansionVisitor(com.apple.foundationdb.record.query.plan.temp.ValueIndexExpansionVisitor) Comparisons(com.apple.foundationdb.record.query.expressions.Comparisons) RecordType(com.apple.foundationdb.record.metadata.RecordType) Index(com.apple.foundationdb.record.metadata.Index) ImmutableSetMultimap(com.google.common.collect.ImmutableSetMultimap) SetMultimap(com.google.common.collect.SetMultimap) ScanComparisons(com.apple.foundationdb.record.query.plan.ScanComparisons) Comparisons(com.apple.foundationdb.record.query.expressions.Comparisons) RequestedOrdering(com.apple.foundationdb.record.query.plan.temp.RequestedOrdering) Ordering(com.apple.foundationdb.record.query.plan.temp.Ordering) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) Nonnull(javax.annotation.Nonnull)

Example 2 with ExpressionRef

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

the class PlannerGraphProperty method show.

/**
 * Show the planner expression that and all the match candidates rendered in your default browser. This also
 * shows {@link PartialMatch}es between references if they exist.
 * @param renderSingleGroups iff true group references with just one member are not rendered
 * @param queryPlanRootReference the planner expression to be rendered.
 * @param matchCandidates a set of candidates for matching which should also be shown
 * @return the word "done" (IntelliJ really likes a return of String).
 */
@Nonnull
public static String show(final boolean renderSingleGroups, @Nonnull final GroupExpressionRef<? extends RelationalExpression> queryPlanRootReference, @Nonnull final Set<MatchCandidate> matchCandidates) {
    final PlannerGraph queryPlannerGraph = Objects.requireNonNull(queryPlanRootReference.acceptPropertyVisitor(forInternalShow(renderSingleGroups, true)));
    final PlannerGraph.InternalPlannerGraphBuilder graphBuilder = queryPlannerGraph.derived();
    final Map<MatchCandidate, PlannerGraph> matchCandidateMap = matchCandidates.stream().collect(ImmutableMap.toImmutableMap(Function.identity(), matchCandidate -> Objects.requireNonNull(matchCandidate.getTraversal().getRootReference().acceptPropertyVisitor(forInternalShow(renderSingleGroups)))));
    matchCandidateMap.forEach((matchCandidate, matchCandidateGraph) -> graphBuilder.addGraph(matchCandidateGraph));
    final ExpressionRefTraversal queryGraphTraversal = ExpressionRefTraversal.withRoot(queryPlanRootReference);
    final Set<ExpressionRef<? extends RelationalExpression>> queryGraphRefs = queryGraphTraversal.getRefs();
    queryGraphRefs.forEach(queryGraphRef -> {
        for (final MatchCandidate matchCandidate : Sets.intersection(matchCandidates, queryGraphRef.getMatchCandidates())) {
            final Set<PartialMatch> partialMatchesForCandidate = queryGraphRef.getPartialMatchesForCandidate(matchCandidate);
            final PlannerGraph matchCandidatePlannerGraph = Objects.requireNonNull(matchCandidateMap.get(matchCandidate));
            final Node queryRefNode = Objects.requireNonNull(queryPlannerGraph.getNodeForIdentity(queryGraphRef));
            for (final PartialMatch partialMatchForCandidate : partialMatchesForCandidate) {
                @Nullable final Node matchCandidateNode = matchCandidatePlannerGraph.getNodeForIdentity(partialMatchForCandidate.getCandidateRef());
                // should always be true but we don't want to bail out for corrupt graphs
                if (matchCandidateNode != null) {
                    graphBuilder.addEdge(queryRefNode, matchCandidateNode, new PartialMatchEdge());
                }
            }
        }
    });
    final String dotString = exportToDot(graphBuilder.build(), queryPlannerGraph.getNetwork().nodes(), nestedClusterProvider -> matchCandidateMap.entrySet().stream().map(entry -> new NamedCluster(entry.getKey().getName(), entry.getValue().getNetwork().nodes(), nestedClusterProvider)).collect(Collectors.toList()));
    return show(dotString);
}
Also used : ExpressionRefTraversal(com.apple.foundationdb.record.query.plan.temp.ExpressionRefTraversal) PartialMatchEdge(com.apple.foundationdb.record.query.plan.temp.explain.PlannerGraph.PartialMatchEdge) Iterables(com.google.common.collect.Iterables) GroupExpressionRef(com.apple.foundationdb.record.query.plan.temp.GroupExpressionRef) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) ComponentIdProvider(com.apple.foundationdb.record.query.plan.temp.explain.GraphExporter.ComponentIdProvider) Function(java.util.function.Function) PlannerProperty(com.apple.foundationdb.record.query.plan.temp.PlannerProperty) PartialMatch(com.apple.foundationdb.record.query.plan.temp.PartialMatch) ImmutableList(com.google.common.collect.ImmutableList) CharStreams(com.google.common.io.CharStreams) Map(java.util.Map) ImmutableNetwork(com.google.common.graph.ImmutableNetwork) MatchCandidate(com.apple.foundationdb.record.query.plan.temp.MatchCandidate) URI(java.net.URI) ExpressionRef(com.apple.foundationdb.record.query.plan.temp.ExpressionRef) Network(com.google.common.graph.Network) Edge(com.apple.foundationdb.record.query.plan.temp.explain.PlannerGraph.Edge) Nonnull(javax.annotation.Nonnull) Nullable(javax.annotation.Nullable) PrintWriter(java.io.PrintWriter) Desktop(java.awt.Desktop) Verify(com.google.common.base.Verify) ImmutableSet(com.google.common.collect.ImmutableSet) Cluster(com.apple.foundationdb.record.query.plan.temp.explain.GraphExporter.Cluster) ImmutableMap(com.google.common.collect.ImmutableMap) Node(com.apple.foundationdb.record.query.plan.temp.explain.PlannerGraph.Node) StringWriter(java.io.StringWriter) Collection(java.util.Collection) Debugger(com.apple.foundationdb.record.query.plan.temp.debug.Debugger) Throwables(com.google.common.base.Throwables) Set(java.util.Set) Maps(com.google.common.collect.Maps) InputStreamReader(java.io.InputStreamReader) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) File(java.io.File) StandardCharsets(java.nio.charset.StandardCharsets) RelationalExpression(com.apple.foundationdb.record.query.plan.temp.RelationalExpression) Objects(java.util.Objects) List(java.util.List) Writer(java.io.Writer) Optional(java.util.Optional) Preconditions(com.google.common.base.Preconditions) InputStream(java.io.InputStream) RelationalExpression(com.apple.foundationdb.record.query.plan.temp.RelationalExpression) PartialMatchEdge(com.apple.foundationdb.record.query.plan.temp.explain.PlannerGraph.PartialMatchEdge) ExpressionRefTraversal(com.apple.foundationdb.record.query.plan.temp.ExpressionRefTraversal) Node(com.apple.foundationdb.record.query.plan.temp.explain.PlannerGraph.Node) GroupExpressionRef(com.apple.foundationdb.record.query.plan.temp.GroupExpressionRef) ExpressionRef(com.apple.foundationdb.record.query.plan.temp.ExpressionRef) PartialMatch(com.apple.foundationdb.record.query.plan.temp.PartialMatch) MatchCandidate(com.apple.foundationdb.record.query.plan.temp.MatchCandidate) Nullable(javax.annotation.Nullable) Nonnull(javax.annotation.Nonnull)

Example 3 with ExpressionRef

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

the class OrToLogicalUnionRule method onMatch.

@Override
public void onMatch(@Nonnull PlannerRuleCall call) {
    final PlannerBindings bindings = call.getBindings();
    final SelectExpression selectExpression = bindings.get(root);
    final List<? extends Value> resultValues = selectExpression.getResultValues();
    final List<? extends Quantifier> quantifiers = bindings.getAll(qunMatcher);
    final List<? extends QueryPredicate> orTermPredicates = bindings.getAll(orTermPredicateMatcher);
    final List<ExpressionRef<RelationalExpression>> relationalExpressionRefs = new ArrayList<>(orTermPredicates.size());
    for (final QueryPredicate orTermPredicate : orTermPredicates) {
        relationalExpressionRefs.add(call.ref(new SelectExpression(resultValues, quantifiers, ImmutableList.of(orTermPredicate))));
    }
    call.yield(GroupExpressionRef.of(new LogicalUnionExpression(Quantifiers.forEachQuantifiers(relationalExpressionRefs))));
}
Also used : GroupExpressionRef(com.apple.foundationdb.record.query.plan.temp.GroupExpressionRef) ExpressionRef(com.apple.foundationdb.record.query.plan.temp.ExpressionRef) QueryPredicate(com.apple.foundationdb.record.query.predicates.QueryPredicate) PlannerBindings(com.apple.foundationdb.record.query.plan.temp.matchers.PlannerBindings) ArrayList(java.util.ArrayList) SelectExpression(com.apple.foundationdb.record.query.plan.temp.expressions.SelectExpression) LogicalUnionExpression(com.apple.foundationdb.record.query.plan.temp.expressions.LogicalUnionExpression)

Example 4 with ExpressionRef

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

the class PushDistinctBelowFilterRule method onMatch.

@Override
public void onMatch(@Nonnull PlannerRuleCall call) {
    final ExpressionRef<? extends RelationalExpression> inner = call.get(innerRefMatcher);
    final Quantifier.Physical qun = call.get(innerQuantifierMatcher);
    final RecordQueryPredicatesFilterPlan filterPlan = call.get(filterPlanMatcher);
    final RecordQueryUnorderedPrimaryKeyDistinctPlan newDistinctPlan = new RecordQueryUnorderedPrimaryKeyDistinctPlan(Quantifier.physical(inner));
    final Quantifier.Physical newQun = Quantifier.physical(call.ref(newDistinctPlan));
    final List<QueryPredicate> rebasedPredicates = filterPlan.getPredicates().stream().map(queryPredicate -> queryPredicate.rebase(Quantifiers.translate(qun, newQun))).collect(ImmutableList.toImmutableList());
    call.yield(call.ref(new RecordQueryPredicatesFilterPlan(newQun, rebasedPredicates)));
}
Also used : PlannerRuleCall(com.apple.foundationdb.record.query.plan.temp.PlannerRuleCall) PlannerRule(com.apple.foundationdb.record.query.plan.temp.PlannerRule) QuantifierMatchers.physicalQuantifier(com.apple.foundationdb.record.query.plan.temp.matchers.QuantifierMatchers.physicalQuantifier) Quantifier(com.apple.foundationdb.record.query.plan.temp.Quantifier) QueryPredicate(com.apple.foundationdb.record.query.predicates.QueryPredicate) Quantifiers(com.apple.foundationdb.record.query.plan.temp.Quantifiers) RecordQueryPredicatesFilterPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPredicatesFilterPlan) QuantifierMatchers.physicalQuantifierOverRef(com.apple.foundationdb.record.query.plan.temp.matchers.QuantifierMatchers.physicalQuantifierOverRef) RelationalExpression(com.apple.foundationdb.record.query.plan.temp.RelationalExpression) List(java.util.List) BindingMatcher(com.apple.foundationdb.record.query.plan.temp.matchers.BindingMatcher) ImmutableList(com.google.common.collect.ImmutableList) RecordQueryUnorderedPrimaryKeyDistinctPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryUnorderedPrimaryKeyDistinctPlan) ReferenceMatchers.anyRefOverOnlyPlans(com.apple.foundationdb.record.query.plan.temp.matchers.ReferenceMatchers.anyRefOverOnlyPlans) ExpressionRef(com.apple.foundationdb.record.query.plan.temp.ExpressionRef) ListMatcher.exactly(com.apple.foundationdb.record.query.plan.temp.matchers.ListMatcher.exactly) RecordQueryPlanMatchers(com.apple.foundationdb.record.query.plan.temp.matchers.RecordQueryPlanMatchers) Nonnull(javax.annotation.Nonnull) QueryPredicate(com.apple.foundationdb.record.query.predicates.QueryPredicate) RecordQueryPredicatesFilterPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPredicatesFilterPlan) QuantifierMatchers.physicalQuantifier(com.apple.foundationdb.record.query.plan.temp.matchers.QuantifierMatchers.physicalQuantifier) Quantifier(com.apple.foundationdb.record.query.plan.temp.Quantifier) RecordQueryUnorderedPrimaryKeyDistinctPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryUnorderedPrimaryKeyDistinctPlan)

Example 5 with ExpressionRef

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

the class AdjustMatchRule method onMatch.

@Override
@SuppressWarnings("java:S135")
public void onMatch(@Nonnull PlannerRuleCall call) {
    final PlannerBindings bindings = call.getBindings();
    final PartialMatch incompleteMatch = bindings.get(rootMatcher);
    final ExpressionRef<? extends RelationalExpression> queryReference = incompleteMatch.getQueryRef();
    final MatchCandidate matchCandidate = incompleteMatch.getMatchCandidate();
    final SetMultimap<ExpressionRef<? extends RelationalExpression>, RelationalExpression> refToExpressionMap = matchCandidate.findReferencingExpressions(ImmutableList.of(queryReference));
    for (final Map.Entry<ExpressionRef<? extends RelationalExpression>, RelationalExpression> entry : refToExpressionMap.entries()) {
        final ExpressionRef<? extends RelationalExpression> candidateReference = entry.getKey();
        final RelationalExpression candidateExpression = entry.getValue();
        matchWithCandidate(incompleteMatch, candidateExpression).ifPresent(matchInfo -> call.yieldPartialMatch(incompleteMatch.getBoundAliasMap(), matchCandidate, incompleteMatch.getQueryExpression(), candidateReference, matchInfo));
    }
}
Also used : RelationalExpression(com.apple.foundationdb.record.query.plan.temp.RelationalExpression) ExpressionRef(com.apple.foundationdb.record.query.plan.temp.ExpressionRef) PartialMatch(com.apple.foundationdb.record.query.plan.temp.PartialMatch) PlannerBindings(com.apple.foundationdb.record.query.plan.temp.matchers.PlannerBindings) MatchCandidate(com.apple.foundationdb.record.query.plan.temp.MatchCandidate) Map(java.util.Map)

Aggregations

ExpressionRef (com.apple.foundationdb.record.query.plan.temp.ExpressionRef)15 RelationalExpression (com.apple.foundationdb.record.query.plan.temp.RelationalExpression)12 List (java.util.List)10 Nonnull (javax.annotation.Nonnull)10 ImmutableList (com.google.common.collect.ImmutableList)9 GroupExpressionRef (com.apple.foundationdb.record.query.plan.temp.GroupExpressionRef)8 Quantifier (com.apple.foundationdb.record.query.plan.temp.Quantifier)8 PlannerBindings (com.apple.foundationdb.record.query.plan.temp.matchers.PlannerBindings)7 API (com.apple.foundationdb.annotation.API)6 MatchCandidate (com.apple.foundationdb.record.query.plan.temp.MatchCandidate)6 Set (java.util.Set)6 Nullable (javax.annotation.Nullable)6 RecordQueryPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan)5 PartialMatch (com.apple.foundationdb.record.query.plan.temp.PartialMatch)5 BindingMatcher (com.apple.foundationdb.record.query.plan.temp.matchers.BindingMatcher)5 QueryPredicate (com.apple.foundationdb.record.query.predicates.QueryPredicate)5 Iterables (com.google.common.collect.Iterables)5 Collection (java.util.Collection)5 Map (java.util.Map)5 PlannerRule (com.apple.foundationdb.record.query.plan.temp.PlannerRule)4