Skip to content

Commit 6f8edd8

Browse files
committed
serialization for multi intersection implemented
1 parent 46804ab commit 6f8edd8

File tree

5 files changed

+114
-23
lines changed

5 files changed

+114
-23
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,9 @@ private ConstructSelectHavingResult constructSelectHaving(@Nonnull final Quantif
286286
groupByExpression.getGroupingValue() == null
287287
? null : FieldValue.ofOrdinalNumber(groupByQun.getFlowedObjectValue(), 0);
288288

289-
final var aggregateValueReference = FieldValue.ofOrdinalNumberAndFuseIfPossible(FieldValue.ofOrdinalNumber(groupByQun.getFlowedObjectValue(), groupingValueReference == null ? 0 : 1), 0);
289+
final var aggregateValueReference =
290+
FieldValue.ofOrdinalNumberAndFuseIfPossible(FieldValue.ofOrdinalNumber(groupByQun.getFlowedObjectValue(),
291+
groupingValueReference == null ? 0 : 1), 0);
290292

291293
final var placeholderAliases = ImmutableList.<CorrelationIdentifier>builder();
292294
final var selectHavingGraphExpansionBuilder = GraphExpansion.builder().addQuantifier(groupByQun);

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
import com.apple.foundationdb.record.query.plan.plans.RecordQueryFetchFromPartialRecordPlan;
5050
import com.apple.foundationdb.record.query.plan.plans.RecordQueryIndexPlan;
5151
import com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan;
52+
import com.apple.foundationdb.record.util.pair.NonnullPair;
5253
import com.google.common.base.Preconditions;
5354
import com.google.common.base.Verify;
5455
import com.google.common.collect.ImmutableList;
@@ -409,6 +410,23 @@ protected int getGroupingCount() {
409410
: keyExpressionGroupingCount;
410411
}
411412

413+
@Nonnull
414+
public NonnullPair<List<Value>, Value> getGroupingAndAggregateAccessors() {
415+
final var selectHavingResultValue = selectHavingExpression.getResultValue();
416+
final var selectHavingResultType = (Type.Record)selectHavingResultValue.getResultType();
417+
final var unbasedResultValue =
418+
QuantifiedObjectValue.of(Quantifier.current(), selectHavingResultType);
419+
420+
final var groupingCount = getGroupingCount();
421+
Verify.verify(selectHavingResultType.getFields().size() >= groupingCount);
422+
423+
final var deconstructedRecord = Values.deconstructRecord(unbasedResultValue);
424+
final var groupingAccessorValues =
425+
ImmutableList.copyOf(deconstructedRecord.subList(0, groupingCount));
426+
final var aggregateAccessorValue = deconstructedRecord.get(groupingCount);
427+
return NonnullPair.of(groupingAccessorValues, aggregateAccessorValue);
428+
}
429+
412430
/**
413431
* Creates a new {@link IndexKeyValueToPartialRecord} to facilitate the correct copying of information from the
414432
* index-tuple structure to a partial record (which in this case is dynamically-typed).

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

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636
import com.apple.foundationdb.record.provider.foundationdb.FDBStoreTimer;
3737
import com.apple.foundationdb.record.provider.foundationdb.cursors.IntersectionCursor;
3838
import com.apple.foundationdb.record.query.plan.AvailableFields;
39-
import com.apple.foundationdb.record.query.plan.explain.ExplainPlanVisitor;
4039
import com.apple.foundationdb.record.query.plan.cascades.AliasMap;
4140
import com.apple.foundationdb.record.query.plan.cascades.CorrelationIdentifier;
4241
import com.apple.foundationdb.record.query.plan.cascades.OrderingPart.ProvidedOrderingPart;
@@ -48,6 +47,8 @@
4847
import com.apple.foundationdb.record.query.plan.cascades.explain.PlannerGraph;
4948
import com.apple.foundationdb.record.query.plan.cascades.expressions.RelationalExpression;
5049
import com.apple.foundationdb.record.query.plan.cascades.values.Value;
50+
import com.apple.foundationdb.record.query.plan.explain.ExplainPlanVisitor;
51+
import com.google.common.base.Suppliers;
5152
import com.google.common.base.Verify;
5253
import com.google.common.collect.ImmutableList;
5354
import com.google.common.collect.ImmutableMap;
@@ -62,6 +63,7 @@
6263
import java.util.Objects;
6364
import java.util.Set;
6465
import java.util.function.Function;
66+
import java.util.function.Supplier;
6567
import java.util.stream.Collectors;
6668
import java.util.stream.Stream;
6769

@@ -88,7 +90,7 @@ public abstract class RecordQueryIntersectionPlan implements RecordQueryPlanWith
8890
protected final boolean reverse;
8991

9092
@Nonnull
91-
private final Value resultValue;
93+
private final Supplier<Value> resultValueSupplier;
9294

9395
protected RecordQueryIntersectionPlan(@Nonnull final PlanSerializationContext serializationContext,
9496
@Nonnull final PRecordQueryIntersectionPlan recordQueryIntersectionPlanProto) {
@@ -100,7 +102,7 @@ protected RecordQueryIntersectionPlan(@Nonnull final PlanSerializationContext se
100102
this.quantifiers = quantifiersBuilder.build();
101103
this.comparisonKeyFunction = ComparisonKeyFunction.fromComparisonKeyFunctionProto(serializationContext, Objects.requireNonNull(recordQueryIntersectionPlanProto.getComparisonKeyFunction()));
102104
this.reverse = recordQueryIntersectionPlanProto.getReverse();
103-
this.resultValue = RecordQuerySetPlan.mergeValues(quantifiers);
105+
this.resultValueSupplier = Suppliers.memoize(this::computeResultValue);
104106
}
105107

106108
@SuppressWarnings("PMD.UnusedFormalParameter")
@@ -110,7 +112,7 @@ protected RecordQueryIntersectionPlan(@Nonnull List<Quantifier.Physical> quantif
110112
this.quantifiers = ImmutableList.copyOf(quantifiers);
111113
this.comparisonKeyFunction = comparisonKeyFunction;
112114
this.reverse = reverse;
113-
this.resultValue = RecordQuerySetPlan.mergeValues(quantifiers);
115+
this.resultValueSupplier = Suppliers.memoize(this::computeResultValue);
114116
}
115117

116118
@Nonnull
@@ -177,7 +179,12 @@ public Set<CorrelationIdentifier> getCorrelatedToWithoutChildren() {
177179
@Nonnull
178180
@Override
179181
public Value getResultValue() {
180-
return resultValue;
182+
return resultValueSupplier.get();
183+
}
184+
185+
@Nonnull
186+
protected Value computeResultValue() {
187+
return RecordQuerySetPlan.mergeValues(quantifiers);
181188
}
182189

183190
@Override

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

Lines changed: 72 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,25 +21,25 @@
2121
package com.apple.foundationdb.record.query.plan.plans;
2222

2323
import com.apple.foundationdb.record.EvaluationContext;
24-
import com.apple.foundationdb.record.EvaluationContextBuilder;
2524
import com.apple.foundationdb.record.ExecuteProperties;
2625
import com.apple.foundationdb.record.PlanDeserializer;
2726
import com.apple.foundationdb.record.PlanSerializationContext;
2827
import com.apple.foundationdb.record.RecordCoreException;
2928
import com.apple.foundationdb.record.RecordCursor;
3029
import com.apple.foundationdb.record.metadata.expressions.KeyExpression;
31-
import com.apple.foundationdb.record.planprotos.PRecordQueryIntersectionOnValuesPlan;
30+
import com.apple.foundationdb.record.planprotos.PRecordQueryMultiIntersectionOnValuesPlan;
3231
import com.apple.foundationdb.record.planprotos.PRecordQueryPlan;
3332
import com.apple.foundationdb.record.provider.foundationdb.FDBRecordStoreBase;
34-
import com.apple.foundationdb.record.provider.foundationdb.cursors.IntersectionCursor;
3533
import com.apple.foundationdb.record.provider.foundationdb.cursors.IntersectionMultiCursor;
34+
import com.apple.foundationdb.record.query.plan.cascades.Column;
3635
import com.apple.foundationdb.record.query.plan.cascades.CorrelationIdentifier;
3736
import com.apple.foundationdb.record.query.plan.cascades.Memoizer;
3837
import com.apple.foundationdb.record.query.plan.cascades.OrderingPart.ProvidedOrderingPart;
3938
import com.apple.foundationdb.record.query.plan.cascades.Quantifier;
4039
import com.apple.foundationdb.record.query.plan.cascades.Quantifiers;
4140
import com.apple.foundationdb.record.query.plan.cascades.Reference;
4241
import com.apple.foundationdb.record.query.plan.cascades.typing.Type;
42+
import com.apple.foundationdb.record.query.plan.cascades.values.RecordConstructorValue;
4343
import com.apple.foundationdb.record.query.plan.cascades.values.Value;
4444
import com.apple.foundationdb.record.query.plan.cascades.values.translation.TranslationMap;
4545
import com.google.auto.service.AutoService;
@@ -72,20 +72,34 @@ public class RecordQueryMultiIntersectionOnValuesPlan extends RecordQueryInterse
7272
private final Value resultValue;
7373

7474
protected RecordQueryMultiIntersectionOnValuesPlan(@Nonnull final PlanSerializationContext serializationContext,
75-
@Nonnull final PRecordQueryIntersectionOnValuesPlan recordQueryIntersectionOnValuesPlanProto) {
76-
super(serializationContext, Objects.requireNonNull(recordQueryIntersectionOnValuesPlanProto.getSuper()));
75+
@Nonnull final PRecordQueryMultiIntersectionOnValuesPlan recordQueryMultiIntersectionOnValuesPlanProto) {
76+
super(serializationContext, Objects.requireNonNull(recordQueryMultiIntersectionOnValuesPlanProto.getSuper()));
7777
this.comparisonKeyOrderingParts = null;
78+
this.resultValue = Value.fromValueProto(serializationContext,
79+
recordQueryMultiIntersectionOnValuesPlanProto.getResultValue());
7880
}
7981

8082
private RecordQueryMultiIntersectionOnValuesPlan(@Nonnull final List<Quantifier.Physical> quantifiers,
8183
@Nullable final List<ProvidedOrderingPart> comparisonKeyOrderingParts,
8284
@Nonnull final List<? extends Value> comparisonKeyValues,
85+
@Nonnull final List<Value> commonValues,
86+
@Nonnull final List<Value> pickupValues,
87+
final boolean reverse) {
88+
this(quantifiers, comparisonKeyOrderingParts, comparisonKeyValues,
89+
computeResultValue(quantifiers, commonValues, pickupValues), reverse);
90+
}
91+
92+
private RecordQueryMultiIntersectionOnValuesPlan(@Nonnull final List<Quantifier.Physical> quantifiers,
93+
@Nullable final List<ProvidedOrderingPart> comparisonKeyOrderingParts,
94+
@Nonnull final List<? extends Value> comparisonKeyValues,
95+
@Nonnull final Value resultValue,
8396
final boolean reverse) {
8497
super(quantifiers,
8598
new ComparisonKeyFunction.OnValues(Quantifier.current(), comparisonKeyValues),
8699
reverse);
87100
this.comparisonKeyOrderingParts =
88101
comparisonKeyOrderingParts == null ? null : ImmutableList.copyOf(comparisonKeyOrderingParts);
102+
this.resultValue = resultValue;
89103
}
90104

91105
@Nonnull
@@ -122,7 +136,38 @@ public List<? extends Value> getComparisonKeyValues() {
122136
@Nonnull
123137
@Override
124138
public Set<Type> getDynamicTypes() {
125-
return getComparisonKeyValues().stream().flatMap(comparisonKeyValue -> comparisonKeyValue.getDynamicTypes().stream()).collect(ImmutableSet.toImmutableSet());
139+
return getComparisonKeyValues().stream()
140+
.flatMap(comparisonKeyValue ->
141+
comparisonKeyValue.getDynamicTypes().stream()).collect(ImmutableSet.toImmutableSet());
142+
}
143+
144+
@Nonnull
145+
@Override
146+
protected Value computeResultValue() {
147+
return resultValue;
148+
}
149+
150+
@Nonnull
151+
private static Value computeResultValue(@Nonnull final List<? extends Quantifier> quantifiers,
152+
@Nonnull final List<Value> commonValues,
153+
@Nonnull final List<Value> pickupValues) {
154+
final var columnBuilder = ImmutableList.<Column<? extends Value>>builder();
155+
156+
// grab the common values from the first quantifier
157+
final var commonTranslationMap =
158+
TranslationMap.ofAliases(Quantifier.current(), quantifiers.get(0).getAlias());
159+
for (final var commonValue : commonValues) {
160+
columnBuilder.add(Column.unnamedOf(commonValue.translateCorrelations(commonTranslationMap)));
161+
}
162+
163+
for (int i = 0; i < quantifiers.size(); i++) {
164+
final var quantifier = quantifiers.get(i);
165+
final var pickUpTranslationMap =
166+
TranslationMap.ofAliases(Quantifier.current(), quantifier.getAlias());
167+
columnBuilder.add(Column.unnamedOf(pickupValues.get(i).translateCorrelations(pickUpTranslationMap)));
168+
}
169+
170+
return RecordConstructorValue.ofColumns(columnBuilder.build());
126171
}
127172

128173
@Nonnull
@@ -153,7 +198,7 @@ public <M extends Message> RecordCursor<QueryResult> executePlan(@Nonnull final
153198
}
154199
final var childEvaluationContext =
155200
childEvaluationContextBuilder.build(context.getTypeRepository());
156-
201+
return QueryResult.ofComputed(getResultValue().eval(store, childEvaluationContext));
157202
})
158203
.skipThenLimit(executeProperties.getSkip(), executeProperties.getReturnedRowLimit());
159204
}
@@ -166,6 +211,7 @@ public RecordQueryMultiIntersectionOnValuesPlan translateCorrelations(@Nonnull f
166211
return new RecordQueryMultiIntersectionOnValuesPlan(Quantifiers.narrow(Quantifier.Physical.class, translatedQuantifiers),
167212
comparisonKeyOrderingParts,
168213
getComparisonKeyValues(),
214+
resultValue,
169215
isReverse());
170216
}
171217

@@ -178,6 +224,7 @@ public RecordQueryMultiIntersectionOnValuesPlan withChildrenReferences(@Nonnull
178224
.collect(ImmutableList.toImmutableList()),
179225
comparisonKeyOrderingParts,
180226
getComparisonKeyValues(),
227+
resultValue,
181228
isReverse());
182229
}
183230

@@ -188,48 +235,56 @@ public RecordQueryMultiIntersectionOnValuesPlan strictlySorted(@Nonnull final Me
188235

189236
@Nonnull
190237
@Override
191-
public PRecordQueryIntersectionOnValuesPlan toProto(@Nonnull final PlanSerializationContext serializationContext) {
192-
return PRecordQueryIntersectionOnValuesPlan.newBuilder().setSuper(toRecordQueryIntersectionPlan(serializationContext)).build();
238+
public PRecordQueryMultiIntersectionOnValuesPlan toProto(@Nonnull final PlanSerializationContext serializationContext) {
239+
return PRecordQueryMultiIntersectionOnValuesPlan.newBuilder()
240+
.setSuper(toRecordQueryIntersectionPlan(serializationContext))
241+
.setResultValue(resultValue.toValueProto(serializationContext))
242+
.build();
193243
}
194244

195245
@Nonnull
196246
@Override
197247
public PRecordQueryPlan toRecordQueryPlanProto(@Nonnull final PlanSerializationContext serializationContext) {
198-
return PRecordQueryPlan.newBuilder().setIntersectionOnValuesPlan(toProto(serializationContext)).build();
248+
return PRecordQueryPlan.newBuilder()
249+
.setMultiIntersectionOnValuesPlan(toProto(serializationContext)).build();
199250
}
200251

201252
@Nonnull
202253
public static RecordQueryMultiIntersectionOnValuesPlan fromProto(@Nonnull final PlanSerializationContext serializationContext,
203-
@Nonnull final PRecordQueryIntersectionOnValuesPlan recordQueryIntersectionOnValuesPlanProto) {
204-
return new RecordQueryMultiIntersectionOnValuesPlan(serializationContext, recordQueryIntersectionOnValuesPlanProto);
254+
@Nonnull final PRecordQueryMultiIntersectionOnValuesPlan recordQueryMultiIntersectionOnValuesPlanProto) {
255+
return new RecordQueryMultiIntersectionOnValuesPlan(serializationContext, recordQueryMultiIntersectionOnValuesPlanProto);
205256
}
206257

207258
@Nonnull
208259
public static RecordQueryMultiIntersectionOnValuesPlan intersection(@Nonnull final List<Quantifier.Physical> quantifiers,
209260
@Nonnull final List<ProvidedOrderingPart> comparisonKeyOrderingParts,
261+
@Nonnull final List<Value> commonValues,
262+
@Nonnull final List<Value> pickupValues,
210263
final boolean isReverse) {
211264
return new RecordQueryMultiIntersectionOnValuesPlan(quantifiers,
212265
comparisonKeyOrderingParts,
213266
ProvidedOrderingPart.comparisonKeyValues(comparisonKeyOrderingParts, isReverse),
267+
commonValues,
268+
pickupValues,
214269
isReverse);
215270
}
216271

217272
/**
218273
* Deserializer.
219274
*/
220275
@AutoService(PlanDeserializer.class)
221-
public static class Deserializer implements PlanDeserializer<PRecordQueryIntersectionOnValuesPlan, RecordQueryMultiIntersectionOnValuesPlan> {
276+
public static class Deserializer implements PlanDeserializer<PRecordQueryMultiIntersectionOnValuesPlan, RecordQueryMultiIntersectionOnValuesPlan> {
222277
@Nonnull
223278
@Override
224-
public Class<PRecordQueryIntersectionOnValuesPlan> getProtoMessageClass() {
225-
return PRecordQueryIntersectionOnValuesPlan.class;
279+
public Class<PRecordQueryMultiIntersectionOnValuesPlan> getProtoMessageClass() {
280+
return PRecordQueryMultiIntersectionOnValuesPlan.class;
226281
}
227282

228283
@Nonnull
229284
@Override
230285
public RecordQueryMultiIntersectionOnValuesPlan fromProto(@Nonnull final PlanSerializationContext serializationContext,
231-
@Nonnull final PRecordQueryIntersectionOnValuesPlan recordQueryIntersectionOnValuesPlanProto) {
232-
return RecordQueryMultiIntersectionOnValuesPlan.fromProto(serializationContext, recordQueryIntersectionOnValuesPlanProto);
286+
@Nonnull final PRecordQueryMultiIntersectionOnValuesPlan recordQueryMultiIntersectionOnValuesPlanProto) {
287+
return RecordQueryMultiIntersectionOnValuesPlan.fromProto(serializationContext, recordQueryMultiIntersectionOnValuesPlanProto);
233288
}
234289
}
235290
}

fdb-record-layer-core/src/main/proto/record_query_plan.proto

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1214,6 +1214,7 @@ message PRecordQueryPlan {
12141214
PTempTableScanPlan temp_table_scan_plan = 34;
12151215
PTempTableInsertPlan temp_table_insert_plan = 35;
12161216
PRecursiveUnionQueryPlan recursive_union_query_plan = 36;
1217+
PRecordQueryMultiIntersectionOnValuesPlan multi_intersection_on_values_plan = 37;
12171218
}
12181219
}
12191220

@@ -1577,6 +1578,14 @@ message PRecordQueryIntersectionOnValuesPlan {
15771578
optional PRecordQueryIntersectionPlan super = 1;
15781579
}
15791580

1581+
//
1582+
// PRecordQueryMultiIntersectionOnValuesPlan
1583+
//
1584+
message PRecordQueryMultiIntersectionOnValuesPlan {
1585+
optional PRecordQueryIntersectionPlan super = 1;
1586+
optional PValue result_value = 2;
1587+
}
1588+
15801589
//
15811590
// PRecordQueryInUnionPlan
15821591
//

0 commit comments

Comments
 (0)