Skip to content

Commit 2f5e9b8

Browse files
committed
ordering sort of works
1 parent 0da7963 commit 2f5e9b8

File tree

21 files changed

+544
-345
lines changed

21 files changed

+544
-345
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
@Override
6670
public boolean equals(final Object o) {
6771
if (this == o) {

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
@@ -215,9 +215,9 @@ public List<MatchedOrderingPart> computeMatchedOrderingParts(@Nonnull final Matc
215215
final var candidateParameterIds = getOrderingAliases();
216216
final var normalizedValues = Sets.newHashSetWithExpectedSize(normalizedKeyExpressions.size());
217217

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

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

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

253253
if (normalizedValues.add(value)) {
254254
final var matchedOrderingPart =
@@ -286,7 +286,6 @@ public Ordering computeOrderingFromScanComparisons(@Nonnull final ScanComparison
286286
final int groupingCount = ((GroupingKeyExpression)index.getRootExpression()).getGroupingCount();
287287

288288
if (!isPermuted() && groupingCount == 0) {
289-
// TODO this should be something like anything-order.
290289
return Ordering.empty();
291290
}
292291

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.
@@ -410,7 +408,7 @@ default ForMatch derived(final boolean isImpossible,
410408
@Nonnull final Set<? extends Quantifier> unmatchedQuantifiers,
411409
@Nonnull final Set<CorrelationIdentifier> compensatedAliases,
412410
@Nonnull final ResultCompensationFunction resultCompensationFunction,
413-
@Nonnull final AggregateMappings aggregateMappings) {
411+
@Nonnull final GroupByMappings groupByMappings) {
414412
//
415413
// At least one of these conditions must be true:
416414
// - it is an impossible compensation (in which case the predicate compensation map may be empty)
@@ -423,7 +421,7 @@ default ForMatch derived(final boolean isImpossible,
423421
!predicateCompensationMap.isEmpty() || resultCompensationFunction.isNeeded() || isNeededForFiltering());
424422

425423
return new ForMatch(isImpossible, this, predicateCompensationMap, matchedQuantifiers,
426-
unmatchedQuantifiers, compensatedAliases, resultCompensationFunction, aggregateMappings);
424+
unmatchedQuantifiers, compensatedAliases, resultCompensationFunction, groupByMappings);
427425
}
428426

429427
/**
@@ -474,7 +472,7 @@ default boolean isFinalNeeded() {
474472
ResultCompensationFunction getResultCompensationFunction();
475473

476474
@Nonnull
477-
AggregateMappings getAggregateMappings();
475+
GroupByMappings getGroupByMappings();
478476

479477
/**
480478
* Specific implementation of union-ing two compensations both of type {@link WithSelectCompensation}.
@@ -570,7 +568,7 @@ default Compensation union(@Nonnull Compensation otherCompensation) {
570568
ImmutableSet.of(),
571569
Sets.union(getCompensatedAliases(), otherWithSelectCompensation.getCompensatedAliases()),
572570
newResultResultCompensationFunction,
573-
AggregateMappings.empty());
571+
GroupByMappings.empty());
574572
}
575573

576574
/**
@@ -601,26 +599,40 @@ default Compensation intersect(@Nonnull Compensation otherCompensation) {
601599
return Compensation.impossibleCompensation();
602600
}
603601

604-
final var newMatchedAggregateMap =
605-
Stream.concat(getAggregateMappings().getMatchedAggregateMap().entrySet().stream(),
606-
otherWithSelectCompensation.getAggregateMappings().getMatchedAggregateMap().entrySet().stream())
607-
.collect(ImmutableMap.toImmutableMap(Map.Entry::getKey,
608-
Map.Entry::getValue,
609-
(l, r) -> l));
610-
final var newUnmatchedAggregateMapBuilder =
602+
final var newMatchedGroupingsMapBuilder = ImmutableBiMap.<Value, Value>builder();
603+
final var matchedGroupingsMap = getGroupByMappings().getMatchedGroupingsMap();
604+
newMatchedGroupingsMapBuilder.putAll(matchedGroupingsMap);
605+
for (final var entry : otherWithSelectCompensation.getGroupByMappings().getMatchedGroupingsMap().entrySet()) {
606+
if (!matchedGroupingsMap.containsKey(entry.getKey())) {
607+
newMatchedGroupingsMapBuilder.put(entry);
608+
}
609+
}
610+
611+
final var newMatchedAggregatesMapBuilder = ImmutableBiMap.<Value, Value>builder();
612+
final var matchedAggregatesMap = getGroupByMappings().getMatchedAggregatesMap();
613+
newMatchedAggregatesMapBuilder.putAll(matchedAggregatesMap);
614+
for (final var entry : otherWithSelectCompensation.getGroupByMappings().getMatchedAggregatesMap().entrySet()) {
615+
if (!matchedAggregatesMap.containsKey(entry.getKey())) {
616+
newMatchedAggregatesMapBuilder.put(entry);
617+
}
618+
}
619+
final var newMatchedAggregatesMap = newMatchedAggregatesMapBuilder.build();
620+
final var newUnmatchedAggregatesMapBuilder =
611621
ImmutableBiMap.<CorrelationIdentifier, Value>builder();
612-
final var unmatchedAggregateMap = getAggregateMappings().getUnmatchedAggregateMap();
622+
final var unmatchedAggregateMap = getGroupByMappings().getUnmatchedAggregatesMap();
613623
for (final var entry : unmatchedAggregateMap.entrySet()) {
614-
if (!newMatchedAggregateMap.containsKey(entry.getValue())) {
615-
newUnmatchedAggregateMapBuilder.put(entry);
624+
if (!newMatchedAggregatesMap.containsKey(entry.getValue())) {
625+
newUnmatchedAggregatesMapBuilder.put(entry);
616626
}
617627
}
618-
for (final var entry : otherWithSelectCompensation.getAggregateMappings().getUnmatchedAggregateMap().entrySet()) {
619-
if (!newMatchedAggregateMap.containsKey(entry.getValue())) {
620-
newUnmatchedAggregateMapBuilder.put(entry);
628+
for (final var entry : otherWithSelectCompensation.getGroupByMappings().getUnmatchedAggregatesMap().entrySet()) {
629+
if (!newMatchedAggregatesMap.containsKey(entry.getValue()) &&
630+
!unmatchedAggregateMap.inverse().containsKey(entry.getValue())) {
631+
newUnmatchedAggregatesMapBuilder.put(entry);
621632
}
622633
}
623-
final var newAggregateMappings = AggregateMappings.of(newMatchedAggregateMap, newUnmatchedAggregateMapBuilder.build());
634+
final var newGroupByMappings = GroupByMappings.of(newMatchedGroupingsMapBuilder.build(),
635+
newMatchedAggregatesMap, newUnmatchedAggregatesMapBuilder.build());
624636

625637
final ResultCompensationFunction newResultResultCompensationFunction;
626638
final var resultCompensationFunction = getResultCompensationFunction();
@@ -633,7 +645,7 @@ default Compensation intersect(@Nonnull Compensation otherCompensation) {
633645
Verify.verify(otherResultCompensationFunction.isNeeded());
634646
// pick the one from this side -- it does not matter as both candidates have the same shape
635647
newResultResultCompensationFunction =
636-
resultCompensationFunction.amend(unmatchedAggregateMap, newMatchedAggregateMap);
648+
resultCompensationFunction.amend(unmatchedAggregateMap, newMatchedAggregatesMap);
637649
}
638650

639651
final var otherCompensationMap =
@@ -651,7 +663,7 @@ default Compensation intersect(@Nonnull Compensation otherCompensation) {
651663
// either compensation and let the planner figure out which one wins. We just pick one side here.
652664
// 2. TODO.
653665
combinedPredicateMap.put(entry.getKey(),
654-
entry.getValue().amend(unmatchedAggregateMap, newMatchedAggregateMap));
666+
entry.getValue().amend(unmatchedAggregateMap, newMatchedAggregatesMap));
655667
}
656668
}
657669

@@ -685,7 +697,7 @@ default Compensation intersect(@Nonnull Compensation otherCompensation) {
685697
intersectedUnmatchedQuantifiers,
686698
getCompensatedAliases(), // both compensated aliases must be identical, but too expensive to check
687699
newResultResultCompensationFunction,
688-
newAggregateMappings);
700+
newGroupByMappings);
689701
}
690702
}
691703

@@ -715,7 +727,7 @@ class ForMatch implements WithSelectCompensation {
715727
@Nonnull
716728
private final ResultCompensationFunction resultCompensationFunction;
717729
@Nonnull
718-
private final AggregateMappings aggregateMappings;
730+
private final GroupByMappings groupByMappings;
719731

720732
@Nonnull
721733
private final Supplier<Set<Quantifier>> unmatchedForEachQuantifiersSupplier;
@@ -727,7 +739,7 @@ private ForMatch(final boolean isImpossible,
727739
@Nonnull final Collection<? extends Quantifier> unmatchedQuantifiers,
728740
@Nonnull final Set<CorrelationIdentifier> compensatedAliases,
729741
@Nonnull final ResultCompensationFunction resultCompensationFunction,
730-
@Nonnull final AggregateMappings aggregateMappings) {
742+
@Nonnull final GroupByMappings groupByMappings) {
731743
this.isImpossible = isImpossible;
732744
this.childCompensation = childCompensation;
733745
this.predicateCompensationMap = new LinkedIdentityMap<>();
@@ -738,7 +750,7 @@ private ForMatch(final boolean isImpossible,
738750
this.unmatchedQuantifiers.addAll(unmatchedQuantifiers);
739751
this.compensatedAliases = ImmutableSet.copyOf(compensatedAliases);
740752
this.resultCompensationFunction = resultCompensationFunction;
741-
this.aggregateMappings = aggregateMappings;
753+
this.groupByMappings = groupByMappings;
742754
this.unmatchedForEachQuantifiersSupplier = Suppliers.memoize(this::computeUnmatchedForEachQuantifiers);
743755
}
744756

@@ -798,8 +810,8 @@ public ResultCompensationFunction getResultCompensationFunction() {
798810

799811
@Nonnull
800812
@Override
801-
public AggregateMappings getAggregateMappings() {
802-
return aggregateMappings;
813+
public GroupByMappings getGroupByMappings() {
814+
return groupByMappings;
803815
}
804816

805817
/**
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)