@@ -131,7 +131,9 @@ ExecuteQuery(query, schema, variableValues, initialValue):
131
131
- Let {queryType} be the root Query type in {schema}.
132
132
- Assert: {queryType} is an Object type.
133
133
- Let {selectionSet} be the top level Selection Set in {query}.
134
- - Let {data} be the result of running {ExecuteSelectionSet(selectionSet,
134
+ - Let {groupedFieldSet} be the result of {CollectRootFields(queryType,
135
+ selectionSet, variableValues)}.
136
+ - Let {data} be the result of running {ExecuteFieldSet(groupedFieldSet,
135
137
queryType, initialValue, variableValues)} _ normally_ (allowing
136
138
parallelization).
137
139
- Let {errors} be the list of all _ field error_ raised while executing the
@@ -153,7 +155,9 @@ ExecuteMutation(mutation, schema, variableValues, initialValue):
153
155
- Let {mutationType} be the root Mutation type in {schema}.
154
156
- Assert: {mutationType} is an Object type.
155
157
- Let {selectionSet} be the top level Selection Set in {mutation}.
156
- - Let {data} be the result of running {ExecuteSelectionSet(selectionSet,
158
+ - Let {groupedFieldSet} be the result of {CollectRootFields(mutationType,
159
+ selectionSet, variableValues)}.
160
+ - Let {data} be the result of running {ExecuteFieldSet(groupedFieldSet,
157
161
mutationType, initialValue, variableValues)} _ serially_ .
158
162
- Let {errors} be the list of all _ field error_ raised while executing the
159
163
selection set.
@@ -256,7 +260,7 @@ CreateSourceEventStream(subscription, schema, variableValues, initialValue):
256
260
- Let {subscriptionType} be the root Subscription type in {schema}.
257
261
- Assert: {subscriptionType} is an Object type.
258
262
- Let {selectionSet} be the top level Selection Set in {subscription}.
259
- - Let {groupedFieldSet} be the result of {CollectFields (subscriptionType,
263
+ - Let {groupedFieldSet} be the result of {CollectRootFields (subscriptionType,
260
264
selectionSet, variableValues)}.
261
265
- If {groupedFieldSet} does not have exactly one entry, raise a _ request error_ .
262
266
- Let {fields} be the value of the first entry in {groupedFieldSet}.
@@ -301,7 +305,9 @@ ExecuteSubscriptionEvent(subscription, schema, variableValues, initialValue):
301
305
- Let {subscriptionType} be the root Subscription type in {schema}.
302
306
- Assert: {subscriptionType} is an Object type.
303
307
- Let {selectionSet} be the top level Selection Set in {subscription}.
304
- - Let {data} be the result of running {ExecuteSelectionSet(selectionSet,
308
+ - Let {groupedFieldSet} be the result of {CollectRootFields(subscriptionType,
309
+ selectionSet, variableValues)}.
310
+ - Let {data} be the result of running {ExecuteFieldSet(groupedFieldSet,
305
311
subscriptionType, initialValue, variableValues)} _ normally_ (allowing
306
312
parallelization).
307
313
- Let {errors} be the list of all _ field error_ raised while executing the
@@ -322,20 +328,17 @@ Unsubscribe(responseStream):
322
328
323
329
- Cancel {responseStream}
324
330
325
- ## Executing Selection Sets
331
+ ## Executing Field Sets
326
332
327
- To execute a selection set, the object value being evaluated and the object type
328
- need to be known, as well as whether it must be executed serially, or may be
329
- executed in parallel.
333
+ To execute a grouped field set, the object value being evaluated and the object
334
+ type need to be known, as well as whether it must be executed serially, or may
335
+ be executed in parallel.
330
336
331
- First, the selection set is turned into a grouped field set; then, each
332
- represented field in the grouped field set produces an entry into a response
333
- map.
337
+ Each represented field in the grouped field set produces an entry into a
338
+ response map.
334
339
335
- ExecuteSelectionSet(selectionSet , objectType, objectValue, variableValues):
340
+ ExecuteFieldSet(groupedFieldSet , objectType, objectValue, variableValues):
336
341
337
- - Let {groupedFieldSet} be the result of {CollectFields(objectType,
338
- selectionSet, variableValues)}.
339
342
- Initialize {resultMap} to an empty ordered map.
340
343
- For each {groupedFieldSet} as {responseKey} and {fields}:
341
344
- Let {fieldName} be the name of the first entry in {fields}. Note: This value
@@ -490,10 +493,12 @@ The depth-first-search order of the field groups produced by {CollectFields()}
490
493
is maintained through execution, ensuring that fields appear in the executed
491
494
response in a stable and predictable order.
492
495
493
- CollectFields(objectType, selectionSet, variableValues, visitedFragments):
496
+ CollectFields(objectType, selectionSet, variableValues, groupedFieldSet,
497
+ visitedFragments):
494
498
499
+ - If {groupedFieldSet} is not provided, initialize it an empty ordered map of
500
+ lists.
495
501
- If {visitedFragments} is not provided, initialize it to the empty set.
496
- - Initialize {groupedFields} to an empty ordered map of lists.
497
502
- For each {selection} in {selectionSet}:
498
503
- If {selection} provides the directive ` @skip ` , let {skipDirective} be that
499
504
directive.
@@ -508,7 +513,7 @@ CollectFields(objectType, selectionSet, variableValues, visitedFragments):
508
513
- If {selection} is a {Field}:
509
514
- Let {responseKey} be the response key of {selection} (the alias if
510
515
defined, otherwise the field name).
511
- - Let {groupForResponseKey} be the list in {groupedFields } for
516
+ - Let {groupForResponseKey} be the list in {groupedFieldSet } for
512
517
{responseKey}; if no such list exists, create it as an empty list.
513
518
- Append {selection} to the {groupForResponseKey}.
514
519
- If {selection} is a {FragmentSpread}:
@@ -524,31 +529,16 @@ CollectFields(objectType, selectionSet, variableValues, visitedFragments):
524
529
- If {DoesFragmentTypeApply(objectType, fragmentType)} is false, continue
525
530
with the next {selection} in {selectionSet}.
526
531
- Let {fragmentSelectionSet} be the top-level selection set of {fragment}.
527
- - Let {fragmentGroupedFieldSet} be the result of calling
528
- {CollectFields(objectType, fragmentSelectionSet, variableValues,
529
- visitedFragments)}.
530
- - For each {fragmentGroup} in {fragmentGroupedFieldSet}:
531
- - Let {responseKey} be the response key shared by all fields in
532
- {fragmentGroup}.
533
- - Let {groupForResponseKey} be the list in {groupedFields} for
534
- {responseKey}; if no such list exists, create it as an empty list.
535
- - Append all items in {fragmentGroup} to {groupForResponseKey}.
532
+ - Call {CollectFields(objectType, fragmentSelectionSet, variableValues,
533
+ groupedFieldSet, visitedFragments)}.
536
534
- If {selection} is an {InlineFragment}:
537
535
- Let {fragmentType} be the type condition on {selection}.
538
536
- If {fragmentType} is not {null} and {DoesFragmentTypeApply(objectType,
539
537
fragmentType)} is false, continue with the next {selection} in
540
538
{selectionSet}.
541
539
- Let {fragmentSelectionSet} be the top-level selection set of {selection}.
542
- - Let {fragmentGroupedFieldSet} be the result of calling
543
- {CollectFields(objectType, fragmentSelectionSet, variableValues,
544
- visitedFragments)}.
545
- - For each {fragmentGroup} in {fragmentGroupedFieldSet}:
546
- - Let {responseKey} be the response key shared by all fields in
547
- {fragmentGroup}.
548
- - Let {groupForResponseKey} be the list in {groupedFields} for
549
- {responseKey}; if no such list exists, create it as an empty list.
550
- - Append all items in {fragmentGroup} to {groupForResponseKey}.
551
- - Return {groupedFields}.
540
+ - Call {CollectFields(objectType, fragmentSelectionSet, variableValues,
541
+ groupedFieldSet, visitedFragments)}.
552
542
553
543
DoesFragmentTypeApply(objectType, fragmentType):
554
544
@@ -565,6 +555,30 @@ DoesFragmentTypeApply(objectType, fragmentType):
565
555
Note: The steps in {CollectFields()} evaluating the ` @skip ` and ` @include `
566
556
directives may be applied in either order since they apply commutatively.
567
557
558
+ ### Root Field Collection
559
+
560
+ Root field collection processes the operation's top-level selection set:
561
+
562
+ CollectRootFields(rootType, operationSelectionSet, variableValues):
563
+
564
+ - Initialize {groupedFieldSet} to an empty ordered map of lists.
565
+ - Call {CollectFields(rootType, operationSelectionSet, groupedFieldSet)}.
566
+ - Return {groupedFieldSet}.
567
+
568
+ ### Object Subfield Collection
569
+
570
+ Root field collection processes the operation's top-level selection set:
571
+
572
+ CollectSubfields(objectType, fields, variableValues):
573
+
574
+ - Initialize {groupedSubfieldSet} to an empty ordered map of lists.
575
+ - For each {field} in {fields}:
576
+ - Let {fieldSelectionSet} be the selection set of {field}.
577
+ - If {fieldSelectionSet} is null or empty, continue to the next field.
578
+ - Call {CollectFields(objectType, fieldSelectionSet, variableValues,
579
+ groupedSubfieldSet)}.
580
+ - Return {groupedSubfieldSet}.
581
+
568
582
## Executing Fields
569
583
570
584
Each field requested in the grouped field set that is defined on the selected
@@ -692,8 +706,9 @@ CompleteValue(fieldType, fields, result, variableValues):
692
706
- Let {objectType} be {fieldType}.
693
707
- Otherwise if {fieldType} is an Interface or Union type.
694
708
- Let {objectType} be {ResolveAbstractType(fieldType, result)}.
695
- - Let {subSelectionSet} be the result of calling {MergeSelectionSets(fields)}.
696
- - Return the result of evaluating {ExecuteSelectionSet(subSelectionSet,
709
+ - Let {groupedSubfieldSet} be the result of calling
710
+ {CollectSubfields(objectType, fields, variableValues)}.
711
+ - Return the result of evaluating {ExecuteFieldSet(groupedSubfieldSet,
697
712
objectType, result, variableValues)} _ normally_ (allowing for
698
713
parallelization).
699
714
@@ -761,15 +776,6 @@ sub-selections.
761
776
After resolving the value for ` me ` , the selection sets are merged together so
762
777
` firstName ` and ` lastName ` can be resolved for one value.
763
778
764
- MergeSelectionSets(fields):
765
-
766
- - Let {selectionSet} be an empty list.
767
- - For each {field} in {fields}:
768
- - Let {fieldSelectionSet} be the selection set of {field}.
769
- - If {fieldSelectionSet} is null or empty, continue to the next field.
770
- - Append all selections in {fieldSelectionSet} to {selectionSet}.
771
- - Return {selectionSet}.
772
-
773
779
### Handling Field Errors
774
780
775
781
A _ field error_ is an error raised from a particular field during value
0 commit comments