21
21
package com .apple .foundationdb .record .query .plan .plans ;
22
22
23
23
import com .apple .foundationdb .record .EvaluationContext ;
24
- import com .apple .foundationdb .record .EvaluationContextBuilder ;
25
24
import com .apple .foundationdb .record .ExecuteProperties ;
26
25
import com .apple .foundationdb .record .PlanDeserializer ;
27
26
import com .apple .foundationdb .record .PlanSerializationContext ;
28
27
import com .apple .foundationdb .record .RecordCoreException ;
29
28
import com .apple .foundationdb .record .RecordCursor ;
30
29
import com .apple .foundationdb .record .metadata .expressions .KeyExpression ;
31
- import com .apple .foundationdb .record .planprotos .PRecordQueryIntersectionOnValuesPlan ;
30
+ import com .apple .foundationdb .record .planprotos .PRecordQueryMultiIntersectionOnValuesPlan ;
32
31
import com .apple .foundationdb .record .planprotos .PRecordQueryPlan ;
33
32
import com .apple .foundationdb .record .provider .foundationdb .FDBRecordStoreBase ;
34
- import com .apple .foundationdb .record .provider .foundationdb .cursors .IntersectionCursor ;
35
33
import com .apple .foundationdb .record .provider .foundationdb .cursors .IntersectionMultiCursor ;
34
+ import com .apple .foundationdb .record .query .plan .cascades .Column ;
36
35
import com .apple .foundationdb .record .query .plan .cascades .CorrelationIdentifier ;
37
36
import com .apple .foundationdb .record .query .plan .cascades .Memoizer ;
38
37
import com .apple .foundationdb .record .query .plan .cascades .OrderingPart .ProvidedOrderingPart ;
39
38
import com .apple .foundationdb .record .query .plan .cascades .Quantifier ;
40
39
import com .apple .foundationdb .record .query .plan .cascades .Quantifiers ;
41
40
import com .apple .foundationdb .record .query .plan .cascades .Reference ;
42
41
import com .apple .foundationdb .record .query .plan .cascades .typing .Type ;
42
+ import com .apple .foundationdb .record .query .plan .cascades .values .RecordConstructorValue ;
43
43
import com .apple .foundationdb .record .query .plan .cascades .values .Value ;
44
44
import com .apple .foundationdb .record .query .plan .cascades .values .translation .TranslationMap ;
45
45
import com .google .auto .service .AutoService ;
@@ -72,20 +72,34 @@ public class RecordQueryMultiIntersectionOnValuesPlan extends RecordQueryInterse
72
72
private final Value resultValue ;
73
73
74
74
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 ()));
77
77
this .comparisonKeyOrderingParts = null ;
78
+ this .resultValue = Value .fromValueProto (serializationContext ,
79
+ recordQueryMultiIntersectionOnValuesPlanProto .getResultValue ());
78
80
}
79
81
80
82
private RecordQueryMultiIntersectionOnValuesPlan (@ Nonnull final List <Quantifier .Physical > quantifiers ,
81
83
@ Nullable final List <ProvidedOrderingPart > comparisonKeyOrderingParts ,
82
84
@ 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 ,
83
96
final boolean reverse ) {
84
97
super (quantifiers ,
85
98
new ComparisonKeyFunction .OnValues (Quantifier .current (), comparisonKeyValues ),
86
99
reverse );
87
100
this .comparisonKeyOrderingParts =
88
101
comparisonKeyOrderingParts == null ? null : ImmutableList .copyOf (comparisonKeyOrderingParts );
102
+ this .resultValue = resultValue ;
89
103
}
90
104
91
105
@ Nonnull
@@ -122,7 +136,38 @@ public List<? extends Value> getComparisonKeyValues() {
122
136
@ Nonnull
123
137
@ Override
124
138
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 ());
126
171
}
127
172
128
173
@ Nonnull
@@ -153,7 +198,7 @@ public <M extends Message> RecordCursor<QueryResult> executePlan(@Nonnull final
153
198
}
154
199
final var childEvaluationContext =
155
200
childEvaluationContextBuilder .build (context .getTypeRepository ());
156
-
201
+ return QueryResult . ofComputed ( getResultValue (). eval ( store , childEvaluationContext ));
157
202
})
158
203
.skipThenLimit (executeProperties .getSkip (), executeProperties .getReturnedRowLimit ());
159
204
}
@@ -166,6 +211,7 @@ public RecordQueryMultiIntersectionOnValuesPlan translateCorrelations(@Nonnull f
166
211
return new RecordQueryMultiIntersectionOnValuesPlan (Quantifiers .narrow (Quantifier .Physical .class , translatedQuantifiers ),
167
212
comparisonKeyOrderingParts ,
168
213
getComparisonKeyValues (),
214
+ resultValue ,
169
215
isReverse ());
170
216
}
171
217
@@ -178,6 +224,7 @@ public RecordQueryMultiIntersectionOnValuesPlan withChildrenReferences(@Nonnull
178
224
.collect (ImmutableList .toImmutableList ()),
179
225
comparisonKeyOrderingParts ,
180
226
getComparisonKeyValues (),
227
+ resultValue ,
181
228
isReverse ());
182
229
}
183
230
@@ -188,48 +235,56 @@ public RecordQueryMultiIntersectionOnValuesPlan strictlySorted(@Nonnull final Me
188
235
189
236
@ Nonnull
190
237
@ 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 ();
193
243
}
194
244
195
245
@ Nonnull
196
246
@ Override
197
247
public PRecordQueryPlan toRecordQueryPlanProto (@ Nonnull final PlanSerializationContext serializationContext ) {
198
- return PRecordQueryPlan .newBuilder ().setIntersectionOnValuesPlan (toProto (serializationContext )).build ();
248
+ return PRecordQueryPlan .newBuilder ()
249
+ .setMultiIntersectionOnValuesPlan (toProto (serializationContext )).build ();
199
250
}
200
251
201
252
@ Nonnull
202
253
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 );
205
256
}
206
257
207
258
@ Nonnull
208
259
public static RecordQueryMultiIntersectionOnValuesPlan intersection (@ Nonnull final List <Quantifier .Physical > quantifiers ,
209
260
@ Nonnull final List <ProvidedOrderingPart > comparisonKeyOrderingParts ,
261
+ @ Nonnull final List <Value > commonValues ,
262
+ @ Nonnull final List <Value > pickupValues ,
210
263
final boolean isReverse ) {
211
264
return new RecordQueryMultiIntersectionOnValuesPlan (quantifiers ,
212
265
comparisonKeyOrderingParts ,
213
266
ProvidedOrderingPart .comparisonKeyValues (comparisonKeyOrderingParts , isReverse ),
267
+ commonValues ,
268
+ pickupValues ,
214
269
isReverse );
215
270
}
216
271
217
272
/**
218
273
* Deserializer.
219
274
*/
220
275
@ AutoService (PlanDeserializer .class )
221
- public static class Deserializer implements PlanDeserializer <PRecordQueryIntersectionOnValuesPlan , RecordQueryMultiIntersectionOnValuesPlan > {
276
+ public static class Deserializer implements PlanDeserializer <PRecordQueryMultiIntersectionOnValuesPlan , RecordQueryMultiIntersectionOnValuesPlan > {
222
277
@ Nonnull
223
278
@ Override
224
- public Class <PRecordQueryIntersectionOnValuesPlan > getProtoMessageClass () {
225
- return PRecordQueryIntersectionOnValuesPlan .class ;
279
+ public Class <PRecordQueryMultiIntersectionOnValuesPlan > getProtoMessageClass () {
280
+ return PRecordQueryMultiIntersectionOnValuesPlan .class ;
226
281
}
227
282
228
283
@ Nonnull
229
284
@ Override
230
285
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 );
233
288
}
234
289
}
235
290
}
0 commit comments