Skip to content

Commit 9059271

Browse files
committed
ordering sort of works
1 parent 6adbd65 commit 9059271

File tree

21 files changed

+546
-347
lines changed

21 files changed

+546
-347
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ public QueryPredicate getPredicate() {
6262
return predicate;
6363
}
6464

65+
public boolean isTautology() {
66+
return predicate.isTautology();
67+
}
68+
6569
public boolean isConstrained() {
6670
return !getPredicate().isTautology();
6771
}

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

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -216,9 +216,9 @@ public List<MatchedOrderingPart> computeMatchedOrderingParts(@Nonnull final Matc
216216
final var candidateParameterIds = getOrderingAliases();
217217
final var normalizedValues = Sets.newHashSetWithExpectedSize(normalizedKeyExpressions.size());
218218

219-
final var selectHavingResultValue = selectHavingExpression.getResultValue();
220-
final var deconstructedValue = Values.deconstructRecord(selectHavingResultValue);
221-
final var aliasMap = AliasMap.ofAliases(Iterables.getOnlyElement(selectHavingResultValue.getCorrelatedTo()), Quantifier.current());
219+
final var selectHavingResultType = selectHavingExpression.getResultValue().getResultType();
220+
final var deconstructedValues =
221+
Values.deconstructRecord(QuantifiedObjectValue.of(Quantifier.current(), selectHavingResultType));
222222

223223
// Compute the ordering for this index by collecting the result values of the selectHaving statement
224224
// associated with each sortParameterId. Note that for most aggregate indexes, the aggregate value is
@@ -249,7 +249,7 @@ public List<MatchedOrderingPart> computeMatchedOrderingParts(@Nonnull final Matc
249249
}
250250

251251
// Grab the value for this sortParameterID from the selectHaving result columns
252-
final var value = deconstructedValue.get(permutedIndex).rebase(aliasMap);
252+
final var value = deconstructedValues.get(permutedIndex);
253253

254254
if (normalizedValues.add(value)) {
255255
final var matchedOrderingPart =
@@ -301,7 +301,6 @@ public Ordering computeOrderingFromScanComparisons(@Nonnull final ScanComparison
301301
final int groupingCount = ((GroupingKeyExpression)index.getRootExpression()).getGroupingCount();
302302

303303
if (!isPermuted() && groupingCount == 0) {
304-
// TODO this should be something like anything-order.
305304
return Ordering.empty();
306305
}
307306

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

Lines changed: 0 additions & 63 deletions
This file was deleted.

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

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
import com.google.common.base.Verify;
3333
import com.google.common.collect.ImmutableBiMap;
3434
import com.google.common.collect.ImmutableList;
35-
import com.google.common.collect.ImmutableMap;
3635
import com.google.common.collect.ImmutableSet;
3736
import com.google.common.collect.Iterables;
3837
import com.google.common.collect.Sets;
@@ -43,7 +42,6 @@
4342
import java.util.Set;
4443
import java.util.function.Function;
4544
import java.util.function.Supplier;
46-
import java.util.stream.Stream;
4745

4846
/**
4947
* Interface for all kinds of compensation. A compensation is the byproduct of expression DAG matching.
@@ -415,7 +413,7 @@ default ForMatch derived(final boolean isImpossible,
415413
@Nonnull final Set<? extends Quantifier> unmatchedQuantifiers,
416414
@Nonnull final Set<CorrelationIdentifier> compensatedAliases,
417415
@Nonnull final ResultCompensationFunction resultCompensationFunction,
418-
@Nonnull final AggregateMappings aggregateMappings) {
416+
@Nonnull final GroupByMappings groupByMappings) {
419417
//
420418
// At least one of these conditions must be true:
421419
// - it is an impossible compensation (in which case the predicate compensation map may be empty)
@@ -428,7 +426,7 @@ default ForMatch derived(final boolean isImpossible,
428426
!predicateCompensationMap.isEmpty() || resultCompensationFunction.isNeeded() || isNeededForFiltering());
429427

430428
return new ForMatch(isImpossible, this, predicateCompensationMap, matchedQuantifiers,
431-
unmatchedQuantifiers, compensatedAliases, resultCompensationFunction, aggregateMappings);
429+
unmatchedQuantifiers, compensatedAliases, resultCompensationFunction, groupByMappings);
432430
}
433431

434432
/**
@@ -479,7 +477,7 @@ default boolean isFinalNeeded() {
479477
ResultCompensationFunction getResultCompensationFunction();
480478

481479
@Nonnull
482-
AggregateMappings getAggregateMappings();
480+
GroupByMappings getGroupByMappings();
483481

484482
/**
485483
* Specific implementation of union-ing two compensations both of type {@link WithSelectCompensation}.
@@ -575,7 +573,7 @@ default Compensation union(@Nonnull Compensation otherCompensation) {
575573
ImmutableSet.of(),
576574
Sets.union(getCompensatedAliases(), otherWithSelectCompensation.getCompensatedAliases()),
577575
newResultResultCompensationFunction,
578-
AggregateMappings.empty());
576+
GroupByMappings.empty());
579577
}
580578

581579
/**
@@ -606,26 +604,40 @@ default Compensation intersect(@Nonnull Compensation otherCompensation) {
606604
return Compensation.impossibleCompensation();
607605
}
608606

609-
final var newMatchedAggregateMap =
610-
Stream.concat(getAggregateMappings().getMatchedAggregateMap().entrySet().stream(),
611-
otherWithSelectCompensation.getAggregateMappings().getMatchedAggregateMap().entrySet().stream())
612-
.collect(ImmutableMap.toImmutableMap(Map.Entry::getKey,
613-
Map.Entry::getValue,
614-
(l, r) -> l));
615-
final var newUnmatchedAggregateMapBuilder =
607+
final var newMatchedGroupingsMapBuilder = ImmutableBiMap.<Value, Value>builder();
608+
final var matchedGroupingsMap = getGroupByMappings().getMatchedGroupingsMap();
609+
newMatchedGroupingsMapBuilder.putAll(matchedGroupingsMap);
610+
for (final var entry : otherWithSelectCompensation.getGroupByMappings().getMatchedGroupingsMap().entrySet()) {
611+
if (!matchedGroupingsMap.containsKey(entry.getKey())) {
612+
newMatchedGroupingsMapBuilder.put(entry);
613+
}
614+
}
615+
616+
final var newMatchedAggregatesMapBuilder = ImmutableBiMap.<Value, Value>builder();
617+
final var matchedAggregatesMap = getGroupByMappings().getMatchedAggregatesMap();
618+
newMatchedAggregatesMapBuilder.putAll(matchedAggregatesMap);
619+
for (final var entry : otherWithSelectCompensation.getGroupByMappings().getMatchedAggregatesMap().entrySet()) {
620+
if (!matchedAggregatesMap.containsKey(entry.getKey())) {
621+
newMatchedAggregatesMapBuilder.put(entry);
622+
}
623+
}
624+
final var newMatchedAggregatesMap = newMatchedAggregatesMapBuilder.build();
625+
final var newUnmatchedAggregatesMapBuilder =
616626
ImmutableBiMap.<CorrelationIdentifier, Value>builder();
617-
final var unmatchedAggregateMap = getAggregateMappings().getUnmatchedAggregateMap();
627+
final var unmatchedAggregateMap = getGroupByMappings().getUnmatchedAggregatesMap();
618628
for (final var entry : unmatchedAggregateMap.entrySet()) {
619-
if (!newMatchedAggregateMap.containsKey(entry.getValue())) {
620-
newUnmatchedAggregateMapBuilder.put(entry);
629+
if (!newMatchedAggregatesMap.containsKey(entry.getValue())) {
630+
newUnmatchedAggregatesMapBuilder.put(entry);
621631
}
622632
}
623-
for (final var entry : otherWithSelectCompensation.getAggregateMappings().getUnmatchedAggregateMap().entrySet()) {
624-
if (!newMatchedAggregateMap.containsKey(entry.getValue())) {
625-
newUnmatchedAggregateMapBuilder.put(entry);
633+
for (final var entry : otherWithSelectCompensation.getGroupByMappings().getUnmatchedAggregatesMap().entrySet()) {
634+
if (!newMatchedAggregatesMap.containsKey(entry.getValue()) &&
635+
!unmatchedAggregateMap.inverse().containsKey(entry.getValue())) {
636+
newUnmatchedAggregatesMapBuilder.put(entry);
626637
}
627638
}
628-
final var newAggregateMappings = AggregateMappings.of(newMatchedAggregateMap, newUnmatchedAggregateMapBuilder.build());
639+
final var newGroupByMappings = GroupByMappings.of(newMatchedGroupingsMapBuilder.build(),
640+
newMatchedAggregatesMap, newUnmatchedAggregatesMapBuilder.build());
629641

630642
final ResultCompensationFunction newResultResultCompensationFunction;
631643
final var resultCompensationFunction = getResultCompensationFunction();
@@ -638,7 +650,7 @@ default Compensation intersect(@Nonnull Compensation otherCompensation) {
638650
Verify.verify(otherResultCompensationFunction.isNeeded());
639651
// pick the one from this side -- it does not matter as both candidates have the same shape
640652
newResultResultCompensationFunction =
641-
resultCompensationFunction.amend(unmatchedAggregateMap, newMatchedAggregateMap);
653+
resultCompensationFunction.amend(unmatchedAggregateMap, newMatchedAggregatesMap);
642654
}
643655

644656
final var otherCompensationMap =
@@ -656,7 +668,7 @@ default Compensation intersect(@Nonnull Compensation otherCompensation) {
656668
// either compensation and let the planner figure out which one wins. We just pick one side here.
657669
// 2. TODO.
658670
combinedPredicateMap.put(entry.getKey(),
659-
entry.getValue().amend(unmatchedAggregateMap, newMatchedAggregateMap));
671+
entry.getValue().amend(unmatchedAggregateMap, newMatchedAggregatesMap));
660672
}
661673
}
662674

@@ -690,7 +702,7 @@ default Compensation intersect(@Nonnull Compensation otherCompensation) {
690702
intersectedUnmatchedQuantifiers,
691703
getCompensatedAliases(), // both compensated aliases must be identical, but too expensive to check
692704
newResultResultCompensationFunction,
693-
newAggregateMappings);
705+
newGroupByMappings);
694706
}
695707
}
696708

@@ -720,7 +732,7 @@ class ForMatch implements WithSelectCompensation {
720732
@Nonnull
721733
private final ResultCompensationFunction resultCompensationFunction;
722734
@Nonnull
723-
private final AggregateMappings aggregateMappings;
735+
private final GroupByMappings groupByMappings;
724736

725737
@Nonnull
726738
private final Supplier<Set<Quantifier>> unmatchedForEachQuantifiersSupplier;
@@ -732,7 +744,7 @@ private ForMatch(final boolean isImpossible,
732744
@Nonnull final Collection<? extends Quantifier> unmatchedQuantifiers,
733745
@Nonnull final Set<CorrelationIdentifier> compensatedAliases,
734746
@Nonnull final ResultCompensationFunction resultCompensationFunction,
735-
@Nonnull final AggregateMappings aggregateMappings) {
747+
@Nonnull final GroupByMappings groupByMappings) {
736748
this.isImpossible = isImpossible;
737749
this.childCompensation = childCompensation;
738750
this.predicateCompensationMap = new LinkedIdentityMap<>();
@@ -743,7 +755,7 @@ private ForMatch(final boolean isImpossible,
743755
this.unmatchedQuantifiers.addAll(unmatchedQuantifiers);
744756
this.compensatedAliases = ImmutableSet.copyOf(compensatedAliases);
745757
this.resultCompensationFunction = resultCompensationFunction;
746-
this.aggregateMappings = aggregateMappings;
758+
this.groupByMappings = groupByMappings;
747759
this.unmatchedForEachQuantifiersSupplier = Suppliers.memoize(this::computeUnmatchedForEachQuantifiers);
748760
}
749761

@@ -803,8 +815,8 @@ public ResultCompensationFunction getResultCompensationFunction() {
803815

804816
@Nonnull
805817
@Override
806-
public AggregateMappings getAggregateMappings() {
807-
return aggregateMappings;
818+
public GroupByMappings getGroupByMappings() {
819+
return groupByMappings;
808820
}
809821

810822
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* GroupByMappings.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+
27+
import javax.annotation.Nonnull;
28+
29+
public class GroupByMappings {
30+
@Nonnull
31+
private final BiMap<Value, Value> matchedGroupingsMap;
32+
@Nonnull
33+
private final BiMap<Value, Value> matchedAggregatesMap;
34+
35+
@Nonnull
36+
private final BiMap<CorrelationIdentifier, Value> unmatchedAggregatesMap;
37+
38+
private GroupByMappings(@Nonnull final BiMap<Value, Value> matchedGroupingsMap,
39+
@Nonnull final BiMap<Value, Value> matchedAggregatesMap,
40+
@Nonnull final BiMap<CorrelationIdentifier, Value> unmatchedAggregatesMap) {
41+
this.matchedGroupingsMap = matchedGroupingsMap;
42+
this.matchedAggregatesMap = matchedAggregatesMap;
43+
this.unmatchedAggregatesMap = unmatchedAggregatesMap;
44+
}
45+
46+
@Nonnull
47+
public BiMap<Value, Value> getMatchedGroupingsMap() {
48+
return matchedGroupingsMap;
49+
}
50+
51+
@Nonnull
52+
public BiMap<Value, Value> getMatchedAggregatesMap() {
53+
return matchedAggregatesMap;
54+
}
55+
56+
@Nonnull
57+
public BiMap<CorrelationIdentifier, Value> getUnmatchedAggregatesMap() {
58+
return unmatchedAggregatesMap;
59+
}
60+
61+
public static GroupByMappings empty() {
62+
return of(ImmutableBiMap.of(), ImmutableBiMap.of(), ImmutableBiMap.of());
63+
}
64+
65+
@Nonnull
66+
public static GroupByMappings of(@Nonnull final BiMap<Value, Value> matchedGroupingsMap,
67+
@Nonnull final BiMap<Value, Value> matchedAggregateMap,
68+
@Nonnull final BiMap<CorrelationIdentifier, Value> unmatchedAggregatesMap) {
69+
return new GroupByMappings(ImmutableBiMap.copyOf(matchedGroupingsMap),
70+
ImmutableBiMap.copyOf(matchedAggregateMap),
71+
ImmutableBiMap.copyOf(unmatchedAggregatesMap));
72+
}
73+
}

0 commit comments

Comments
 (0)