Skip to content

Commit 56d98d9

Browse files
committed
first plans
1 parent 9c37465 commit 56d98d9

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
@@ -296,7 +296,7 @@ public Cardinalities visitTempTableInsertPlan(@Nonnull final TempTableInsertPlan
296296
@Nonnull
297297
@Override
298298
public Cardinalities visitRecordQueryIntersectionOnValuesPlan(@Nonnull final RecordQueryIntersectionOnValuesPlan intersectionOnValuesPlan) {
299-
return weakenCardinalities(fromChildren(intersectionOnValuesPlan));
299+
return intersectCardinalities(fromChildren(intersectionOnValuesPlan));
300300
}
301301

302302
@Nonnull
@@ -438,6 +438,12 @@ public Cardinalities visitRecordQueryInUnionPlan(@Nonnull final RecordQueryInUni
438438
}
439439

440440
@Nonnull
441+
@Override
442+
public Cardinalities visitRecordQueryMultiIntersectionOnValuesPlan(@Nonnull final RecordQueryMultiIntersectionOnValuesPlan recordQueryMultiIntersectionOnValuesPlan) {
443+
return intersectCardinalities(fromChildren(recordQueryMultiIntersectionOnValuesPlan));
444+
}
445+
446+
@Nonnull
441447
@Override
442448
public Cardinalities visitRecordQueryInParameterJoinPlan(@Nonnull final RecordQueryInParameterJoinPlan element) {
443449
return Cardinalities.unknownMaxCardinality();
@@ -710,7 +716,8 @@ private Cardinalities intersectCardinalities(@Nonnull Iterable<Cardinalities> ca
710716
maxCardinality = cardinalities.getMaxCardinality();
711717
} else {
712718
if (!cardinalities.getMaxCardinality().isUnknown()) {
713-
maxCardinality = Cardinality.ofCardinality(Math.min(maxCardinality.getCardinality(), cardinalities.getMaxCardinality().getCardinality()));
719+
maxCardinality = Cardinality.ofCardinality(Math.min(maxCardinality.getCardinality(),
720+
cardinalities.getMaxCardinality().getCardinality()));
714721
} else {
715722
maxCardinality = Cardinality.unknownCardinality();
716723
}

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
@@ -61,6 +61,7 @@
6161
import com.apple.foundationdb.record.query.plan.plans.RecordQueryInValuesJoinPlan;
6262
import com.apple.foundationdb.record.query.plan.plans.RecordQueryIndexPlan;
6363
import com.apple.foundationdb.record.query.plan.plans.RecordQueryInsertPlan;
64+
import com.apple.foundationdb.record.query.plan.plans.RecordQueryMultiIntersectionOnValuesPlan;
6465
import com.apple.foundationdb.record.query.plan.plans.RecordQueryRecursiveUnionPlan;
6566
import com.apple.foundationdb.record.query.plan.plans.RecordQueryTableFunctionPlan;
6667
import com.apple.foundationdb.record.query.plan.plans.TempTableInsertPlan;
@@ -556,6 +557,12 @@ public Derivations visitInUnionOnKeyExpressionPlan(@Nonnull final RecordQueryInU
556557
throw new RecordCoreException("unsupported plan operator");
557558
}
558559

560+
@Nonnull
561+
@Override
562+
public Derivations visitMultiIntersectionOnValuesPlan(@Nonnull final RecordQueryMultiIntersectionOnValuesPlan element) {
563+
return null; //TODO
564+
}
565+
559566
@Nonnull
560567
@Override
561568
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
@@ -59,6 +59,7 @@
5959
import com.apple.foundationdb.record.query.plan.plans.RecordQueryInValuesJoinPlan;
6060
import com.apple.foundationdb.record.query.plan.plans.RecordQueryIndexPlan;
6161
import com.apple.foundationdb.record.query.plan.plans.RecordQueryInsertPlan;
62+
import com.apple.foundationdb.record.query.plan.plans.RecordQueryMultiIntersectionOnValuesPlan;
6263
import com.apple.foundationdb.record.query.plan.plans.RecordQueryRecursiveUnionPlan;
6364
import com.apple.foundationdb.record.query.plan.plans.RecordQueryTableFunctionPlan;
6465
import com.apple.foundationdb.record.query.plan.plans.TempTableScanPlan;
@@ -513,6 +514,12 @@ public Ordering visitInUnionOnKeyExpressionPlan(@Nonnull final RecordQueryInUnio
513514
return Ordering.empty();
514515
}
515516

517+
@Nonnull
518+
@Override
519+
public Ordering visitMultiIntersectionOnValuesPlan(@Nonnull final RecordQueryMultiIntersectionOnValuesPlan element) {
520+
return Ordering.empty(); // TODO
521+
}
522+
516523
@Nonnull
517524
@Override
518525
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
/**
@@ -246,19 +254,31 @@ protected IntersectionResult createIntersectionAndCompensation(@Nonnull final Me
246254
RecordQuerySetPlan.resolveComparisonDirection(comparisonOrderingParts);
247255
comparisonOrderingParts = RecordQuerySetPlan.adjustFixedBindings(comparisonOrderingParts, comparisonIsReverse);
248256

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

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

0 commit comments

Comments
 (0)