Skip to content

Commit 4290817

Browse files
committed
first plans
1 parent 4691cbe commit 4290817

File tree

9 files changed

+176
-53
lines changed

9 files changed

+176
-53
lines changed

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
import com.apple.foundationdb.record.query.plan.plans.RecordQueryIntersectionPlan;
6161
import com.apple.foundationdb.record.query.plan.plans.RecordQueryLoadByKeysPlan;
6262
import com.apple.foundationdb.record.query.plan.plans.RecordQueryMapPlan;
63+
import com.apple.foundationdb.record.query.plan.plans.RecordQueryMultiIntersectionOnValuesPlan;
6364
import com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan;
6465
import com.apple.foundationdb.record.query.plan.plans.RecordQueryPlanVisitor;
6566
import com.apple.foundationdb.record.query.plan.plans.RecordQueryPlanWithExplain;
@@ -338,6 +339,12 @@ public ExplainTokens visitInComparandJoinPlan(@Nonnull final RecordQueryInCompar
338339
return visitInJoinPlan(inComparandJoinPlan);
339340
}
340341

342+
@Nonnull
343+
@Override
344+
public ExplainTokens visitMultiIntersectionOnValuesPlan(@Nonnull final RecordQueryMultiIntersectionOnValuesPlan element) {
345+
return new ExplainTokens().addToString("TODO"); // TODO
346+
}
347+
341348
@Nonnull
342349
@Override
343350
public ExplainTokens visitInParameterJoinPlan(@Nonnull final RecordQueryInParameterJoinPlan inParameterJoinPlan) {

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ public Cardinalities visitTempTableInsertPlan(@Nonnull final TempTableInsertPlan
298298
@Nonnull
299299
@Override
300300
public Cardinalities visitRecordQueryIntersectionOnValuesPlan(@Nonnull final RecordQueryIntersectionOnValuesPlan intersectionOnValuesPlan) {
301-
return weakenCardinalities(fromChildren(intersectionOnValuesPlan));
301+
return intersectCardinalities(fromChildren(intersectionOnValuesPlan));
302302
}
303303

304304
@Nonnull
@@ -440,6 +440,12 @@ public Cardinalities visitRecordQueryInUnionPlan(@Nonnull final RecordQueryInUni
440440
}
441441

442442
@Nonnull
443+
@Override
444+
public Cardinalities visitRecordQueryMultiIntersectionOnValuesPlan(@Nonnull final RecordQueryMultiIntersectionOnValuesPlan recordQueryMultiIntersectionOnValuesPlan) {
445+
return intersectCardinalities(fromChildren(recordQueryMultiIntersectionOnValuesPlan));
446+
}
447+
448+
@Nonnull
443449
@Override
444450
public Cardinalities visitRecordQueryInParameterJoinPlan(@Nonnull final RecordQueryInParameterJoinPlan element) {
445451
return Cardinalities.unknownMaxCardinality();
@@ -713,7 +719,8 @@ private Cardinalities intersectCardinalities(@Nonnull Iterable<Cardinalities> ca
713719
maxCardinality = cardinalities.getMaxCardinality();
714720
} else {
715721
if (!cardinalities.getMaxCardinality().isUnknown()) {
716-
maxCardinality = Cardinality.ofCardinality(Math.min(maxCardinality.getCardinality(), cardinalities.getMaxCardinality().getCardinality()));
722+
maxCardinality = Cardinality.ofCardinality(Math.min(maxCardinality.getCardinality(),
723+
cardinalities.getMaxCardinality().getCardinality()));
717724
} else {
718725
maxCardinality = Cardinality.unknownCardinality();
719726
}

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
import com.apple.foundationdb.record.query.plan.plans.RecordQueryInValuesJoinPlan;
6363
import com.apple.foundationdb.record.query.plan.plans.RecordQueryIndexPlan;
6464
import com.apple.foundationdb.record.query.plan.plans.RecordQueryInsertPlan;
65+
import com.apple.foundationdb.record.query.plan.plans.RecordQueryMultiIntersectionOnValuesPlan;
6566
import com.apple.foundationdb.record.query.plan.plans.RecordQueryRecursiveUnionPlan;
6667
import com.apple.foundationdb.record.query.plan.plans.RecordQueryTableFunctionPlan;
6768
import com.apple.foundationdb.record.query.plan.plans.TempTableInsertPlan;
@@ -557,6 +558,12 @@ public Derivations visitInUnionOnKeyExpressionPlan(@Nonnull final RecordQueryInU
557558
throw new RecordCoreException("unsupported plan operator");
558559
}
559560

561+
@Nonnull
562+
@Override
563+
public Derivations visitMultiIntersectionOnValuesPlan(@Nonnull final RecordQueryMultiIntersectionOnValuesPlan element) {
564+
return null; //TODO
565+
}
566+
560567
@Nonnull
561568
@Override
562569
public Derivations visitInParameterJoinPlan(@Nonnull final RecordQueryInParameterJoinPlan inParameterJoinPlan) {

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import com.apple.foundationdb.record.query.plan.plans.RecordQueryInValuesJoinPlan;
4848
import com.apple.foundationdb.record.query.plan.plans.RecordQueryIndexPlan;
4949
import com.apple.foundationdb.record.query.plan.plans.RecordQueryInsertPlan;
50+
import com.apple.foundationdb.record.query.plan.plans.RecordQueryMultiIntersectionOnValuesPlan;
5051
import com.apple.foundationdb.record.query.plan.plans.RecordQueryRecursiveUnionPlan;
5152
import com.apple.foundationdb.record.query.plan.plans.RecordQueryTableFunctionPlan;
5253
import com.apple.foundationdb.record.query.plan.plans.TempTableInsertPlan;
@@ -335,6 +336,12 @@ public Boolean visitInUnionOnKeyExpressionPlan(@Nonnull final RecordQueryInUnion
335336
return true;
336337
}
337338

339+
@Nonnull
340+
@Override
341+
public Boolean visitMultiIntersectionOnValuesPlan(@Nonnull final RecordQueryMultiIntersectionOnValuesPlan element) {
342+
return true;
343+
}
344+
338345
@Nonnull
339346
@Override
340347
public Boolean visitInParameterJoinPlan(@Nonnull final RecordQueryInParameterJoinPlan inParameterJoinPlan) {

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
import com.apple.foundationdb.record.query.plan.plans.RecordQueryInValuesJoinPlan;
6161
import com.apple.foundationdb.record.query.plan.plans.RecordQueryIndexPlan;
6262
import com.apple.foundationdb.record.query.plan.plans.RecordQueryInsertPlan;
63+
import com.apple.foundationdb.record.query.plan.plans.RecordQueryMultiIntersectionOnValuesPlan;
6364
import com.apple.foundationdb.record.query.plan.plans.RecordQueryRecursiveUnionPlan;
6465
import com.apple.foundationdb.record.query.plan.plans.RecordQueryTableFunctionPlan;
6566
import com.apple.foundationdb.record.query.plan.plans.TempTableScanPlan;
@@ -515,6 +516,12 @@ public Ordering visitInUnionOnKeyExpressionPlan(@Nonnull final RecordQueryInUnio
515516
return Ordering.empty();
516517
}
517518

519+
@Nonnull
520+
@Override
521+
public Ordering visitMultiIntersectionOnValuesPlan(@Nonnull final RecordQueryMultiIntersectionOnValuesPlan element) {
522+
return Ordering.empty(); // TODO
523+
}
524+
518525
@Nonnull
519526
@Override
520527
public Ordering visitInParameterJoinPlan(@Nonnull final RecordQueryInParameterJoinPlan inParameterJoinPlan) {

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
import com.apple.foundationdb.record.query.plan.plans.RecordQueryInValuesJoinPlan;
4949
import com.apple.foundationdb.record.query.plan.plans.RecordQueryIndexPlan;
5050
import com.apple.foundationdb.record.query.plan.plans.RecordQueryInsertPlan;
51+
import com.apple.foundationdb.record.query.plan.plans.RecordQueryMultiIntersectionOnValuesPlan;
5152
import com.apple.foundationdb.record.query.plan.plans.RecordQueryRecursiveUnionPlan;
5253
import com.apple.foundationdb.record.query.plan.plans.RecordQueryTableFunctionPlan;
5354
import com.apple.foundationdb.record.query.plan.plans.TempTableScanPlan;
@@ -357,6 +358,12 @@ public Optional<List<Value>> visitInUnionOnKeyExpressionPlan(@Nonnull final Reco
357358
return primaryKeyFromSingleChild(inUnionOnKeyExpressionPlan);
358359
}
359360

361+
@Nonnull
362+
@Override
363+
public Optional<List<Value>> visitMultiIntersectionOnValuesPlan(@Nonnull final RecordQueryMultiIntersectionOnValuesPlan element) {
364+
return Optional.empty();
365+
}
366+
360367
@Nonnull
361368
@Override
362369
public Optional<List<Value>> visitInParameterJoinPlan(@Nonnull final RecordQueryInParameterJoinPlan inParameterJoinPlan) {

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import com.apple.foundationdb.record.query.plan.plans.RecordQueryInValuesJoinPlan;
4646
import com.apple.foundationdb.record.query.plan.plans.RecordQueryIndexPlan;
4747
import com.apple.foundationdb.record.query.plan.plans.RecordQueryInsertPlan;
48+
import com.apple.foundationdb.record.query.plan.plans.RecordQueryMultiIntersectionOnValuesPlan;
4849
import com.apple.foundationdb.record.query.plan.plans.RecordQueryRecursiveUnionPlan;
4950
import com.apple.foundationdb.record.query.plan.plans.RecordQueryTableFunctionPlan;
5051
import com.apple.foundationdb.record.query.plan.plans.TempTableInsertPlan;
@@ -317,6 +318,12 @@ public Boolean visitInUnionOnKeyExpressionPlan(@Nonnull final RecordQueryInUnion
317318
return true;
318319
}
319320

321+
@Nonnull
322+
@Override
323+
public Boolean visitMultiIntersectionOnValuesPlan(@Nonnull final RecordQueryMultiIntersectionOnValuesPlan element) {
324+
return false;
325+
}
326+
320327
@Nonnull
321328
@Override
322329
public Boolean visitInParameterJoinPlan(@Nonnull final RecordQueryInParameterJoinPlan inParameterJoinPlan) {

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

Lines changed: 107 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@
2121
package com.apple.foundationdb.record.query.plan.cascades.rules;
2222

2323
import com.apple.foundationdb.annotation.API;
24+
import com.apple.foundationdb.record.query.plan.cascades.AggregateIndexMatchCandidate;
2425
import com.apple.foundationdb.record.query.plan.cascades.AliasMap;
2526
import com.apple.foundationdb.record.query.plan.cascades.CascadesPlanner;
2627
import com.apple.foundationdb.record.query.plan.cascades.CascadesRuleCall;
28+
import com.apple.foundationdb.record.query.plan.cascades.Column;
2729
import com.apple.foundationdb.record.query.plan.cascades.ComparisonRange;
2830
import com.apple.foundationdb.record.query.plan.cascades.Compensation;
2931
import com.apple.foundationdb.record.query.plan.cascades.CorrelationIdentifier;
@@ -39,12 +41,18 @@
3941
import com.apple.foundationdb.record.query.plan.cascades.expressions.RelationalExpression;
4042
import com.apple.foundationdb.record.query.plan.cascades.expressions.SelectExpression;
4143
import com.apple.foundationdb.record.query.plan.cascades.matching.structure.BindingMatcher;
44+
import com.apple.foundationdb.record.query.plan.cascades.typing.Type;
45+
import com.apple.foundationdb.record.query.plan.cascades.values.QuantifiedObjectValue;
46+
import com.apple.foundationdb.record.query.plan.cascades.values.RecordConstructorValue;
4247
import com.apple.foundationdb.record.query.plan.cascades.values.Value;
43-
import com.apple.foundationdb.record.query.plan.plans.RecordQueryIntersectionPlan;
48+
import com.apple.foundationdb.record.query.plan.cascades.values.Values;
49+
import com.apple.foundationdb.record.query.plan.cascades.values.translation.TranslationMap;
50+
import com.apple.foundationdb.record.query.plan.plans.RecordQueryMultiIntersectionOnValuesPlan;
4451
import com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan;
4552
import com.apple.foundationdb.record.query.plan.plans.RecordQuerySetPlan;
4653
import com.apple.foundationdb.record.util.pair.NonnullPair;
4754
import com.apple.foundationdb.record.util.pair.Pair;
55+
import com.google.common.base.Verify;
4856
import com.google.common.collect.ImmutableList;
4957
import com.google.common.collect.ImmutableSet;
5058
import com.google.common.collect.Iterables;
@@ -62,8 +70,8 @@
6270

6371
import static com.apple.foundationdb.record.query.plan.cascades.matching.structure.MatchPartitionMatchers.ofExpressionAndMatches;
6472
import static com.apple.foundationdb.record.query.plan.cascades.matching.structure.MultiMatcher.some;
65-
import static com.apple.foundationdb.record.query.plan.cascades.matching.structure.PartialMatchMatchers.matchingAggregateIndexMatchCandidate;
6673
import static com.apple.foundationdb.record.query.plan.cascades.matching.structure.PartialMatchMatchers.completeMatch;
74+
import static com.apple.foundationdb.record.query.plan.cascades.matching.structure.PartialMatchMatchers.matchingAggregateIndexMatchCandidate;
6775
import static com.apple.foundationdb.record.query.plan.cascades.matching.structure.RelationalExpressionMatchers.anyExpression;
6876

6977
/**
@@ -248,19 +256,31 @@ protected IntersectionResult createIntersectionAndCompensation(@Nonnull final Me
248256
RecordQuerySetPlan.resolveComparisonDirection(comparisonOrderingParts);
249257
comparisonOrderingParts = RecordQuerySetPlan.adjustFixedBindings(comparisonOrderingParts, comparisonIsReverse);
250258

251-
final var newQuantifiers =
252-
partition
253-
.stream()
254-
.map(pair -> Objects.requireNonNull(matchToPlanMap.get(pair.getElement().getPartialMatch())))
255-
.map(memoizer::memoizePlans)
256-
.map(Quantifier::physical)
257-
.collect(ImmutableList.toImmutableList());
259+
final var newQuantifiersBuilder = ImmutableList.<Quantifier.Physical>builder();
260+
final var candidateTopAliasesBuilder = ImmutableList.<CorrelationIdentifier>builder();
261+
for (final var singleMatchedAccessWithIndex : partition) {
262+
final var singleMatchedAccess = singleMatchedAccessWithIndex.getElement();
263+
final var plan = Objects.requireNonNull(matchToPlanMap.get(
264+
singleMatchedAccess.getPartialMatch()));
265+
final var reference = memoizer.memoizePlans(plan);
266+
newQuantifiersBuilder.add(Quantifier.physical(reference));
267+
candidateTopAliasesBuilder.add(singleMatchedAccess.getCandidateTopAlias());
268+
}
258269

270+
final var newQuantifiers = newQuantifiersBuilder.build();
271+
final var commonAndPickUpValues =
272+
computeCommonAndPickUpValues(partition, commonPrimaryKeyValues.size());
273+
final var intersectionResultValue =
274+
computeIntersectionResultValue(newQuantifiers, commonAndPickUpValues.getLeft(), commonAndPickUpValues.getRight());
259275
final var intersectionPlan =
260-
RecordQueryIntersectionPlan.fromQuantifiers(newQuantifiers,
261-
comparisonOrderingParts, comparisonIsReverse);
276+
RecordQueryMultiIntersectionOnValuesPlan.intersection(newQuantifiers,
277+
comparisonOrderingParts, intersectionResultValue, comparisonIsReverse);
262278
final var compensatedIntersection =
263-
compensation.applyAllNeededCompensations(memoizer, intersectionPlan);
279+
compensation.applyAllNeededCompensations(memoizer, intersectionPlan,
280+
baseAlias -> computeTranslationMap(baseAlias,
281+
newQuantifiers, candidateTopAliasesBuilder.build(),
282+
(Type.Record)intersectionResultValue.getResultType(),
283+
commonPrimaryKeyValues.size()));
264284
expressionsBuilder.add(compensatedIntersection);
265285
}
266286
}
@@ -269,4 +289,79 @@ protected IntersectionResult createIntersectionAndCompensation(@Nonnull final Me
269289
return IntersectionResult.of(hasCommonOrdering ? intersectionOrdering : null, compensation,
270290
expressionsBuilder.build());
271291
}
292+
293+
@Nonnull
294+
private static NonnullPair<List<Value>, List<Value>> computeCommonAndPickUpValues(@Nonnull final List<Vectored<SingleMatchedAccess>> partition,
295+
final int numGrouped) {
296+
final var commonValuesAndPickUpValueByAccess =
297+
partition
298+
.stream()
299+
.map(singleMatchedAccessWithIndex ->
300+
singleMatchedAccessWithIndex.getElement()
301+
.getPartialMatch()
302+
.getMatchCandidate())
303+
.map(matchCandidate -> (AggregateIndexMatchCandidate)matchCandidate)
304+
.map(AggregateIndexMatchCandidate::getGroupingAndAggregateAccessors)
305+
.collect(ImmutableList.toImmutableList());
306+
307+
final var pickUpValuesBuilder = ImmutableList.<Value>builder();
308+
for (int i = 0; i < commonValuesAndPickUpValueByAccess.size(); i++) {
309+
final var commonAndPickUpValuePair = commonValuesAndPickUpValueByAccess.get(i);
310+
final var commonValues = commonAndPickUpValuePair.getLeft();
311+
Verify.verify(commonValues.size() == numGrouped);
312+
final var pickUpValue = commonAndPickUpValuePair.getRight();
313+
pickUpValuesBuilder.add(pickUpValue);
314+
}
315+
return NonnullPair.of(commonValuesAndPickUpValueByAccess.get(0).getLeft(), pickUpValuesBuilder.build());
316+
}
317+
318+
@Nonnull
319+
private static Value computeIntersectionResultValue(@Nonnull final List<? extends Quantifier> quantifiers,
320+
@Nonnull final List<Value> commonValues,
321+
@Nonnull final List<Value> pickUpValues) {
322+
final var columnBuilder = ImmutableList.<Column<? extends Value>>builder();
323+
324+
// grab the common values from the first quantifier
325+
final var commonTranslationMap =
326+
TranslationMap.ofAliases(Quantifier.current(), quantifiers.get(0).getAlias());
327+
for (final var commonValue : commonValues) {
328+
columnBuilder.add(Column.unnamedOf(commonValue.translateCorrelations(commonTranslationMap)));
329+
}
330+
331+
for (int i = 0; i < quantifiers.size(); i++) {
332+
final var quantifier = quantifiers.get(i);
333+
final var pickUpTranslationMap =
334+
TranslationMap.ofAliases(Quantifier.current(), quantifier.getAlias());
335+
columnBuilder.add(Column.unnamedOf(pickUpValues.get(i).translateCorrelations(pickUpTranslationMap)));
336+
}
337+
338+
return RecordConstructorValue.ofColumns(columnBuilder.build());
339+
}
340+
341+
private static TranslationMap computeTranslationMap(@Nonnull final CorrelationIdentifier intersectionAlias,
342+
@Nonnull final List<? extends Quantifier> quantifiers,
343+
@Nonnull final List<CorrelationIdentifier> candidateTopAliases,
344+
@Nonnull final Type.Record intersectionResultType,
345+
final int numGrouped) {
346+
final var builder = TranslationMap.builder();
347+
final var deconstructedIntersectionValues =
348+
Values.deconstructRecord(QuantifiedObjectValue.of(intersectionAlias, intersectionResultType));
349+
for (int quantifierIndex = 0; quantifierIndex < quantifiers.size(); quantifierIndex++) {
350+
final var quantifier = quantifiers.get(quantifierIndex);
351+
final var quantifierFlowedObjectType = (Type.Record)quantifier.getFlowedObjectType();
352+
final var quantifierFields = quantifierFlowedObjectType.getFields();
353+
Verify.verify(quantifierFields.size() == numGrouped + 1);
354+
final var columnBuilder =
355+
ImmutableList.<Column<? extends Value>>builder();
356+
for (int columnIndex = 0; columnIndex < numGrouped; columnIndex++) {
357+
columnBuilder.add(Column.of(quantifierFields.get(columnIndex), deconstructedIntersectionValues.get(columnIndex)));
358+
}
359+
columnBuilder.add(Column.of(quantifierFields.get(numGrouped),
360+
deconstructedIntersectionValues.get(numGrouped + quantifierIndex)));
361+
builder.when(candidateTopAliases.get(quantifierIndex)).then((alias, leaf) ->
362+
RecordConstructorValue.ofColumns(columnBuilder.build()));
363+
}
364+
365+
return builder.build();
366+
}
272367
}

0 commit comments

Comments
 (0)