Skip to content

Commit ace86d2

Browse files
committed
pullng up unmatched values
1 parent 11125d6 commit ace86d2

File tree

25 files changed

+469
-289
lines changed

25 files changed

+469
-289
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;
@@ -387,7 +386,7 @@ default ForMatch derived(final boolean isImpossible,
387386
@Nonnull final Set<? extends Quantifier> unmatchedQuantifiers,
388387
@Nonnull final Set<CorrelationIdentifier> compensatedAliases,
389388
@Nonnull final ResultCompensationFunction resultCompensationFunction,
390-
@Nonnull final Map<Value, Value> matchedAggregateValueMap) {
389+
@Nonnull final AggregateMappings aggregateMappings) {
391390
//
392391
// At least one of these conditions must be true:
393392
// - it is an impossible compensation (in which case the predicate compensation map may be empty)
@@ -400,7 +399,7 @@ default ForMatch derived(final boolean isImpossible,
400399
!predicateCompensationMap.isEmpty() || resultCompensationFunction.isNeeded() || isNeededForFiltering());
401400

402401
return new ForMatch(isImpossible, this, predicateCompensationMap, matchedQuantifiers,
403-
unmatchedQuantifiers, compensatedAliases, resultCompensationFunction, matchedAggregateValueMap);
402+
unmatchedQuantifiers, compensatedAliases, resultCompensationFunction, aggregateMappings);
404403
}
405404

406405
/**
@@ -451,7 +450,7 @@ default boolean isFinalNeeded() {
451450
ResultCompensationFunction getResultCompensationFunction();
452451

453452
@Nonnull
454-
Map<Value, Value> getMatchedAggregateValueMap();
453+
AggregateMappings getAggregateMappings();
455454

456455
/**
457456
* Specific implementation of union-ing two compensations both of type {@link WithSelectCompensation}.
@@ -490,6 +489,11 @@ default Compensation union(@Nonnull Compensation otherCompensation) {
490489
return impossibleCompensation();
491490
}
492491

492+
final Compensation unionedChildCompensation = getChildCompensation().union(otherWithSelectCompensation.getChildCompensation());
493+
if (unionedChildCompensation.isImpossible() || !unionedChildCompensation.canBeDeferred()) {
494+
return Compensation.impossibleCompensation();
495+
}
496+
493497
final ResultCompensationFunction newResultResultCompensationFunction;
494498
final var resultCompensationFunction = getResultCompensationFunction();
495499
final var otherResultCompensationFunction = otherWithSelectCompensation.getResultCompensationFunction();
@@ -503,7 +507,8 @@ default Compensation union(@Nonnull Compensation otherCompensation) {
503507
newResultResultCompensationFunction = resultCompensationFunction;
504508
}
505509

506-
final var otherCompensationMap = otherWithSelectCompensation.getPredicateCompensationMap();
510+
final var otherCompensationMap =
511+
otherWithSelectCompensation.getPredicateCompensationMap();
507512
final var combinedPredicateMap = new LinkedIdentityMap<QueryPredicate, PredicateCompensationFunction>();
508513

509514
combinedPredicateMap.putAll(getPredicateCompensationMap());
@@ -526,11 +531,6 @@ default Compensation union(@Nonnull Compensation otherCompensation) {
526531
combinedPredicateMap.put(otherEntry.getKey(), otherEntry.getValue());
527532
}
528533

529-
final Compensation unionedChildCompensation = getChildCompensation().union(otherWithSelectCompensation.getChildCompensation());
530-
if (unionedChildCompensation.isImpossible() || !unionedChildCompensation.canBeDeferred()) {
531-
return Compensation.impossibleCompensation();
532-
}
533-
534534
if (!unionedChildCompensation.isNeededForFiltering() &&
535535
!newResultResultCompensationFunction.isNeeded() && combinedPredicateMap.isEmpty()) {
536536
return Compensation.noCompensation();
@@ -546,7 +546,7 @@ default Compensation union(@Nonnull Compensation otherCompensation) {
546546
ImmutableSet.of(),
547547
Sets.union(getCompensatedAliases(), otherWithSelectCompensation.getCompensatedAliases()),
548548
newResultResultCompensationFunction,
549-
ImmutableMap.of());
549+
AggregateMappings.empty());
550550
}
551551

552552
/**
@@ -567,6 +567,23 @@ default Compensation intersect(@Nonnull Compensation otherCompensation) {
567567
}
568568
final var otherWithSelectCompensation = (WithSelectCompensation)otherCompensation;
569569

570+
final Compensation childCompensation = getChildCompensation();
571+
Verify.verify(!(childCompensation instanceof WithSelectCompensation) ||
572+
((WithSelectCompensation)childCompensation).getUnmatchedForEachQuantifiers().isEmpty());
573+
574+
final Compensation intersectedChildCompensation =
575+
childCompensation.intersect(otherWithSelectCompensation.getChildCompensation());
576+
if (intersectedChildCompensation.isImpossible() || !intersectedChildCompensation.canBeDeferred()) {
577+
return Compensation.impossibleCompensation();
578+
}
579+
580+
final var newMatchedAggregateMap =
581+
Stream.concat(getAggregateMappings().getMatchedAggregateMap().entrySet().stream(),
582+
otherWithSelectCompensation.getAggregateMappings().getMatchedAggregateMap().entrySet().stream())
583+
.collect(ImmutableMap.toImmutableMap(Map.Entry::getKey,
584+
Map.Entry::getValue,
585+
(l, r) -> l));
586+
570587
final ResultCompensationFunction newResultResultCompensationFunction;
571588
final var resultCompensationFunction = getResultCompensationFunction();
572589
final var otherResultCompensationFunction = otherWithSelectCompensation.getResultCompensationFunction();
@@ -595,16 +612,6 @@ default Compensation intersect(@Nonnull Compensation otherCompensation) {
595612
}
596613
}
597614

598-
final Compensation childCompensation = getChildCompensation();
599-
Verify.verify(!(childCompensation instanceof WithSelectCompensation) ||
600-
((WithSelectCompensation)childCompensation).getUnmatchedForEachQuantifiers().isEmpty());
601-
602-
final Compensation intersectedChildCompensation =
603-
childCompensation.intersect(otherWithSelectCompensation.getChildCompensation());
604-
if (intersectedChildCompensation.isImpossible() || !intersectedChildCompensation.canBeDeferred()) {
605-
return Compensation.impossibleCompensation();
606-
}
607-
608615
if (!intersectedChildCompensation.isNeededForFiltering() &&
609616
!newResultResultCompensationFunction.isNeeded() && combinedPredicateMap.isEmpty()) {
610617
return Compensation.noCompensation();
@@ -614,13 +621,6 @@ default Compensation intersect(@Nonnull Compensation otherCompensation) {
614621
return intersectedChildCompensation;
615622
}
616623

617-
final var newMatchedAggregateValueMap =
618-
Stream.concat(getMatchedAggregateValueMap().entrySet().stream(),
619-
otherWithSelectCompensation.getMatchedAggregateValueMap().entrySet().stream())
620-
.collect(ImmutableMap.toImmutableMap(Map.Entry::getKey,
621-
Map.Entry::getValue,
622-
(l, r) -> l));
623-
624624
// Note that at the current time each side can only contribute at most one foreach quantifier, thus the
625625
// intersection should also only contain at most one for each quantifier.
626626
final Sets.SetView<Quantifier> intersectedMatchedQuantifiers =
@@ -642,7 +642,7 @@ default Compensation intersect(@Nonnull Compensation otherCompensation) {
642642
intersectedUnmatchedQuantifiers,
643643
getCompensatedAliases(), // both compensated aliases must be identical, but too expensive to check
644644
newResultResultCompensationFunction,
645-
newMatchedAggregateValueMap);
645+
AggregateMappings.empty());
646646
}
647647
}
648648

@@ -672,7 +672,7 @@ class ForMatch implements WithSelectCompensation {
672672
@Nonnull
673673
private final ResultCompensationFunction resultCompensationFunction;
674674
@Nonnull
675-
private final Map<Value, Value> matchedAggregateValueMap;
675+
private final AggregateMappings aggregateMappings;
676676

677677
@Nonnull
678678
private final Supplier<Set<Quantifier>> unmatchedForEachQuantifiersSupplier;
@@ -684,7 +684,7 @@ private ForMatch(final boolean isImpossible,
684684
@Nonnull final Collection<? extends Quantifier> unmatchedQuantifiers,
685685
@Nonnull final Set<CorrelationIdentifier> compensatedAliases,
686686
@Nonnull final ResultCompensationFunction resultCompensationFunction,
687-
@Nonnull final Map<Value, Value> matchedAggregateValueMap) {
687+
@Nonnull final AggregateMappings aggregateMappings) {
688688
this.isImpossible = isImpossible;
689689
this.childCompensation = childCompensation;
690690
this.predicateCompensationMap = new LinkedIdentityMap<>();
@@ -695,7 +695,7 @@ private ForMatch(final boolean isImpossible,
695695
this.unmatchedQuantifiers.addAll(unmatchedQuantifiers);
696696
this.compensatedAliases = ImmutableSet.copyOf(compensatedAliases);
697697
this.resultCompensationFunction = resultCompensationFunction;
698-
this.matchedAggregateValueMap = ImmutableMap.copyOf(matchedAggregateValueMap);
698+
this.aggregateMappings = aggregateMappings;
699699
this.unmatchedForEachQuantifiersSupplier = Suppliers.memoize(this::computeUnmatchedForEachQuantifiers);
700700
}
701701

@@ -716,7 +716,6 @@ public Set<Quantifier> getMatchedQuantifiers() {
716716
return matchedQuantifiers;
717717
}
718718

719-
720719
@Nonnull
721720
@Override
722721
public Set<Quantifier> getUnmatchedQuantifiers() {
@@ -756,8 +755,8 @@ public ResultCompensationFunction getResultCompensationFunction() {
756755

757756
@Nonnull
758757
@Override
759-
public Map<Value, Value> getMatchedAggregateValueMap() {
760-
return matchedAggregateValueMap;
758+
public AggregateMappings getAggregateMappings() {
759+
return aggregateMappings;
761760
}
762761

763762
/**

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
@@ -306,7 +306,7 @@ public GraphExpansion visitExpression(@Nonnull final ListKeyExpression listKeyEx
306306
* a unique alias based on an increasing number that is human-readable otherwise.
307307
*/
308308
protected static CorrelationIdentifier newParameterAlias() {
309-
return CorrelationIdentifier.uniqueID(PredicateWithValueAndRanges.class);
309+
return CorrelationIdentifier.uniqueId(PredicateWithValueAndRanges.class);
310310
}
311311

312312
/**

0 commit comments

Comments
 (0)