Skip to content

Commit 6e98b4c

Browse files
committed
pullng up unmatched values
1 parent 4c2603f commit 6e98b4c

File tree

25 files changed

+466
-284
lines changed

25 files changed

+466
-284
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* AggregateMappings.java
3+
*
4+
* This source file is part of the FoundationDB open source project
5+
*
6+
* Copyright 2015-2025 Apple Inc. and the FoundationDB project authors
7+
*
8+
* Licensed under the Apache License, Version 2.0 (the "License");
9+
* you may not use this file except in compliance with the License.
10+
* You may obtain a copy of the License at
11+
*
12+
* http://www.apache.org/licenses/LICENSE-2.0
13+
*
14+
* Unless required by applicable law or agreed to in writing, software
15+
* distributed under the License is distributed on an "AS IS" BASIS,
16+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+
* See the License for the specific language governing permissions and
18+
* limitations under the License.
19+
*/
20+
21+
package com.apple.foundationdb.record.query.plan.cascades;
22+
23+
import com.apple.foundationdb.record.query.plan.cascades.values.Value;
24+
import com.google.common.collect.BiMap;
25+
import com.google.common.collect.ImmutableBiMap;
26+
import com.google.common.collect.ImmutableMap;
27+
28+
import javax.annotation.Nonnull;
29+
import java.util.Map;
30+
31+
public class AggregateMappings {
32+
@Nonnull
33+
private final Map<Value, Value> matchedAggregateMap;
34+
35+
@Nonnull
36+
private final BiMap<CorrelationIdentifier, Value> unmatchedAggregateMap;
37+
38+
private AggregateMappings(@Nonnull final Map<Value, Value> matchedAggregateMap, @Nonnull final BiMap<CorrelationIdentifier, Value> unmatchedAggregateMap) {
39+
this.matchedAggregateMap = matchedAggregateMap;
40+
this.unmatchedAggregateMap = unmatchedAggregateMap;
41+
}
42+
43+
@Nonnull
44+
public Map<Value, Value> getMatchedAggregateMap() {
45+
return matchedAggregateMap;
46+
}
47+
48+
@Nonnull
49+
public BiMap<CorrelationIdentifier, Value> getUnmatchedAggregateMap() {
50+
return unmatchedAggregateMap;
51+
}
52+
53+
public static AggregateMappings empty() {
54+
return of(ImmutableBiMap.of(), ImmutableBiMap.of());
55+
}
56+
57+
@Nonnull
58+
public static AggregateMappings of(@Nonnull final BiMap<Value, Value> matchedAggregateMap,
59+
@Nonnull final BiMap<CorrelationIdentifier, Value> unmatchedAggregateMap) {
60+
return new AggregateMappings(ImmutableMap.copyOf(matchedAggregateMap), ImmutableBiMap.copyOf(unmatchedAggregateMap));
61+
}
62+
}

fdb-record-layer-core/src/main/java/com/apple/foundationdb/record/query/plan/cascades/Compensation.java

Lines changed: 34 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
import com.apple.foundationdb.record.query.plan.cascades.expressions.RelationalExpression;
2828
import com.apple.foundationdb.record.query.plan.cascades.predicates.QueryPredicate;
2929
import com.apple.foundationdb.record.query.plan.cascades.rules.DataAccessRule;
30-
import com.apple.foundationdb.record.query.plan.cascades.values.Value;
3130
import com.google.common.base.Suppliers;
3231
import com.google.common.base.Verify;
3332
import com.google.common.collect.ImmutableList;
@@ -392,7 +391,7 @@ default ForMatch derived(final boolean isImpossible,
392391
@Nonnull final Set<? extends Quantifier> unmatchedQuantifiers,
393392
@Nonnull final Set<CorrelationIdentifier> compensatedAliases,
394393
@Nonnull final ResultCompensationFunction resultCompensationFunction,
395-
@Nonnull final Map<Value, Value> matchedAggregateValueMap) {
394+
@Nonnull final AggregateMappings aggregateMappings) {
396395
//
397396
// At least one of these conditions must be true:
398397
// - it is an impossible compensation (in which case the predicate compensation map may be empty)
@@ -405,7 +404,7 @@ default ForMatch derived(final boolean isImpossible,
405404
!predicateCompensationMap.isEmpty() || resultCompensationFunction.isNeeded() || isNeededForFiltering());
406405

407406
return new ForMatch(isImpossible, this, predicateCompensationMap, matchedQuantifiers,
408-
unmatchedQuantifiers, compensatedAliases, resultCompensationFunction, matchedAggregateValueMap);
407+
unmatchedQuantifiers, compensatedAliases, resultCompensationFunction, aggregateMappings);
409408
}
410409

411410
/**
@@ -456,7 +455,7 @@ default boolean isFinalNeeded() {
456455
ResultCompensationFunction getResultCompensationFunction();
457456

458457
@Nonnull
459-
Map<Value, Value> getMatchedAggregateValueMap();
458+
AggregateMappings getAggregateMappings();
460459

461460
/**
462461
* Specific implementation of union-ing two compensations both of type {@link WithSelectCompensation}.
@@ -495,6 +494,11 @@ default Compensation union(@Nonnull Compensation otherCompensation) {
495494
return impossibleCompensation();
496495
}
497496

497+
final Compensation unionedChildCompensation = getChildCompensation().union(otherWithSelectCompensation.getChildCompensation());
498+
if (unionedChildCompensation.isImpossible() || !unionedChildCompensation.canBeDeferred()) {
499+
return Compensation.impossibleCompensation();
500+
}
501+
498502
final ResultCompensationFunction newResultResultCompensationFunction;
499503
final var resultCompensationFunction = getResultCompensationFunction();
500504
final var otherResultCompensationFunction = otherWithSelectCompensation.getResultCompensationFunction();
@@ -508,7 +512,8 @@ default Compensation union(@Nonnull Compensation otherCompensation) {
508512
newResultResultCompensationFunction = resultCompensationFunction;
509513
}
510514

511-
final var otherCompensationMap = otherWithSelectCompensation.getPredicateCompensationMap();
515+
final var otherCompensationMap =
516+
otherWithSelectCompensation.getPredicateCompensationMap();
512517
final var combinedPredicateMap = new LinkedIdentityMap<QueryPredicate, PredicateCompensationFunction>();
513518

514519
combinedPredicateMap.putAll(getPredicateCompensationMap());
@@ -531,11 +536,6 @@ default Compensation union(@Nonnull Compensation otherCompensation) {
531536
combinedPredicateMap.put(otherEntry.getKey(), otherEntry.getValue());
532537
}
533538

534-
final Compensation unionedChildCompensation = getChildCompensation().union(otherWithSelectCompensation.getChildCompensation());
535-
if (unionedChildCompensation.isImpossible() || !unionedChildCompensation.canBeDeferred()) {
536-
return Compensation.impossibleCompensation();
537-
}
538-
539539
if (!unionedChildCompensation.isNeededForFiltering() &&
540540
!newResultResultCompensationFunction.isNeeded() && combinedPredicateMap.isEmpty()) {
541541
return Compensation.noCompensation();
@@ -551,7 +551,7 @@ default Compensation union(@Nonnull Compensation otherCompensation) {
551551
ImmutableSet.of(),
552552
Sets.union(getCompensatedAliases(), otherWithSelectCompensation.getCompensatedAliases()),
553553
newResultResultCompensationFunction,
554-
ImmutableMap.of());
554+
AggregateMappings.empty());
555555
}
556556

557557
/**
@@ -572,6 +572,23 @@ default Compensation intersect(@Nonnull Compensation otherCompensation) {
572572
}
573573
final var otherWithSelectCompensation = (WithSelectCompensation)otherCompensation;
574574

575+
final Compensation childCompensation = getChildCompensation();
576+
Verify.verify(!(childCompensation instanceof WithSelectCompensation) ||
577+
((WithSelectCompensation)childCompensation).getUnmatchedForEachQuantifiers().isEmpty());
578+
579+
final Compensation intersectedChildCompensation =
580+
childCompensation.intersect(otherWithSelectCompensation.getChildCompensation());
581+
if (intersectedChildCompensation.isImpossible() || !intersectedChildCompensation.canBeDeferred()) {
582+
return Compensation.impossibleCompensation();
583+
}
584+
585+
final var newMatchedAggregateMap =
586+
Stream.concat(getAggregateMappings().getMatchedAggregateMap().entrySet().stream(),
587+
otherWithSelectCompensation.getAggregateMappings().getMatchedAggregateMap().entrySet().stream())
588+
.collect(ImmutableMap.toImmutableMap(Map.Entry::getKey,
589+
Map.Entry::getValue,
590+
(l, r) -> l));
591+
575592
final ResultCompensationFunction newResultResultCompensationFunction;
576593
final var resultCompensationFunction = getResultCompensationFunction();
577594
final var otherResultCompensationFunction = otherWithSelectCompensation.getResultCompensationFunction();
@@ -600,16 +617,6 @@ default Compensation intersect(@Nonnull Compensation otherCompensation) {
600617
}
601618
}
602619

603-
final Compensation childCompensation = getChildCompensation();
604-
Verify.verify(!(childCompensation instanceof WithSelectCompensation) ||
605-
((WithSelectCompensation)childCompensation).getUnmatchedForEachQuantifiers().isEmpty());
606-
607-
final Compensation intersectedChildCompensation =
608-
childCompensation.intersect(otherWithSelectCompensation.getChildCompensation());
609-
if (intersectedChildCompensation.isImpossible() || !intersectedChildCompensation.canBeDeferred()) {
610-
return Compensation.impossibleCompensation();
611-
}
612-
613620
if (!intersectedChildCompensation.isNeededForFiltering() &&
614621
!newResultResultCompensationFunction.isNeeded() && combinedPredicateMap.isEmpty()) {
615622
return Compensation.noCompensation();
@@ -619,13 +626,6 @@ default Compensation intersect(@Nonnull Compensation otherCompensation) {
619626
return intersectedChildCompensation;
620627
}
621628

622-
final var newMatchedAggregateValueMap =
623-
Stream.concat(getMatchedAggregateValueMap().entrySet().stream(),
624-
otherWithSelectCompensation.getMatchedAggregateValueMap().entrySet().stream())
625-
.collect(ImmutableMap.toImmutableMap(Map.Entry::getKey,
626-
Map.Entry::getValue,
627-
(l, r) -> l));
628-
629629
// Note that at the current time each side can only contribute at most one foreach quantifier, thus the
630630
// intersection should also only contain at most one for each quantifier.
631631
final Sets.SetView<Quantifier> intersectedMatchedQuantifiers =
@@ -647,7 +647,7 @@ default Compensation intersect(@Nonnull Compensation otherCompensation) {
647647
intersectedUnmatchedQuantifiers,
648648
getCompensatedAliases(), // both compensated aliases must be identical, but too expensive to check
649649
newResultResultCompensationFunction,
650-
newMatchedAggregateValueMap);
650+
AggregateMappings.empty());
651651
}
652652
}
653653

@@ -677,7 +677,7 @@ class ForMatch implements WithSelectCompensation {
677677
@Nonnull
678678
private final ResultCompensationFunction resultCompensationFunction;
679679
@Nonnull
680-
private final Map<Value, Value> matchedAggregateValueMap;
680+
private final AggregateMappings aggregateMappings;
681681

682682
@Nonnull
683683
private final Supplier<Set<Quantifier>> unmatchedForEachQuantifiersSupplier;
@@ -689,7 +689,7 @@ private ForMatch(final boolean isImpossible,
689689
@Nonnull final Collection<? extends Quantifier> unmatchedQuantifiers,
690690
@Nonnull final Set<CorrelationIdentifier> compensatedAliases,
691691
@Nonnull final ResultCompensationFunction resultCompensationFunction,
692-
@Nonnull final Map<Value, Value> matchedAggregateValueMap) {
692+
@Nonnull final AggregateMappings aggregateMappings) {
693693
this.isImpossible = isImpossible;
694694
this.childCompensation = childCompensation;
695695
this.predicateCompensationMap = new LinkedIdentityMap<>();
@@ -700,7 +700,7 @@ private ForMatch(final boolean isImpossible,
700700
this.unmatchedQuantifiers.addAll(unmatchedQuantifiers);
701701
this.compensatedAliases = ImmutableSet.copyOf(compensatedAliases);
702702
this.resultCompensationFunction = resultCompensationFunction;
703-
this.matchedAggregateValueMap = ImmutableMap.copyOf(matchedAggregateValueMap);
703+
this.aggregateMappings = aggregateMappings;
704704
this.unmatchedForEachQuantifiersSupplier = Suppliers.memoize(this::computeUnmatchedForEachQuantifiers);
705705
}
706706

@@ -721,7 +721,6 @@ public Set<Quantifier> getMatchedQuantifiers() {
721721
return matchedQuantifiers;
722722
}
723723

724-
725724
@Nonnull
726725
@Override
727726
public Set<Quantifier> getUnmatchedQuantifiers() {
@@ -761,8 +760,8 @@ public ResultCompensationFunction getResultCompensationFunction() {
761760

762761
@Nonnull
763762
@Override
764-
public Map<Value, Value> getMatchedAggregateValueMap() {
765-
return matchedAggregateValueMap;
763+
public AggregateMappings getAggregateMappings() {
764+
return aggregateMappings;
766765
}
767766

768767
/**

fdb-record-layer-core/src/main/java/com/apple/foundationdb/record/query/plan/cascades/CorrelationIdentifier.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@ public static CorrelationIdentifier of(@Nonnull final String id) {
6161
* @return a new unique {@link CorrelationIdentifier}
6262
*/
6363
@Nonnull
64-
public static CorrelationIdentifier uniqueID() {
65-
return uniqueID(CorrelationIdentifier.class);
64+
public static CorrelationIdentifier uniqueId() {
65+
return uniqueId(CorrelationIdentifier.class);
6666
}
6767

6868
/**
@@ -73,8 +73,8 @@ public static CorrelationIdentifier uniqueID() {
7373
* @return a new unique {@link CorrelationIdentifier}
7474
*/
7575
@Nonnull
76-
public static CorrelationIdentifier uniqueID(@Nonnull final Class<?> clazz) {
77-
return uniqueID(clazz, clazz.getSimpleName().substring(0, 1).toLowerCase(Locale.ROOT));
76+
public static CorrelationIdentifier uniqueId(@Nonnull final Class<?> clazz) {
77+
return uniqueId(clazz, clazz.getSimpleName().substring(0, 1).toLowerCase(Locale.ROOT));
7878
}
7979

8080
/**
@@ -86,7 +86,7 @@ public static CorrelationIdentifier uniqueID(@Nonnull final Class<?> clazz) {
8686
* @return a new unique {@link CorrelationIdentifier}
8787
*/
8888
@Nonnull
89-
public static CorrelationIdentifier uniqueID(@Nonnull final Class<?> clazz, @Nonnull final String prefix) {
89+
public static CorrelationIdentifier uniqueId(@Nonnull final Class<?> clazz, @Nonnull final String prefix) {
9090
final CorrelationIdentifier id =
9191
Debugger.getIndexOptional(clazz)
9292
.map(i -> CorrelationIdentifier.of(prefix + i))

fdb-record-layer-core/src/main/java/com/apple/foundationdb/record/query/plan/cascades/KeyExpressionExpansionVisitor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@ public GraphExpansion visitExpression(@Nonnull final ListKeyExpression listKeyEx
404404
* a unique alias based on an increasing number that is human-readable otherwise.
405405
*/
406406
protected static CorrelationIdentifier newParameterAlias() {
407-
return CorrelationIdentifier.uniqueID(PredicateWithValueAndRanges.class);
407+
return CorrelationIdentifier.uniqueId(PredicateWithValueAndRanges.class);
408408
}
409409

410410
/**

0 commit comments

Comments
 (0)