@@ -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 {ExecuteGroupedFieldSet(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 {ExecuteGroupedFieldSet(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 {ExecuteGroupedFieldSet(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,18 @@ Unsubscribe(responseStream):
322
328
323
329
- Cancel {responseStream}
324
330
325
- ## Executing Selection Sets
331
+ ## Executing Grouped 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
+ ExecuteGroupedFieldSet(groupedFieldSet, objectType, objectValue,
341
+ variableValues):
336
342
337
- - Let {groupedFieldSet} be the result of {CollectFields(objectType,
338
- selectionSet, variableValues)}.
339
343
- Initialize {resultMap} to an empty ordered map.
340
344
- For each {groupedFieldSet} as {responseKey} and {fields}:
341
345
- Let {fieldName} be the name of the first entry in {fields}. Note: This value
@@ -492,8 +496,7 @@ response in a stable and predictable order.
492
496
493
497
CollectFields(objectType, selectionSet, variableValues, visitedFragments):
494
498
495
- - If {visitedFragments} is not provided, initialize it to the empty set.
496
- - Initialize {groupedFields} to an empty ordered map of lists.
499
+ - Initialize {groupedFieldSet} to an empty ordered map of lists.
497
500
- For each {selection} in {selectionSet}:
498
501
- If {selection} provides the directive ` @skip ` , let {skipDirective} be that
499
502
directive.
@@ -508,7 +511,7 @@ CollectFields(objectType, selectionSet, variableValues, visitedFragments):
508
511
- If {selection} is a {Field}:
509
512
- Let {responseKey} be the response key of {selection} (the alias if
510
513
defined, otherwise the field name).
511
- - Let {groupForResponseKey} be the list in {groupedFields } for
514
+ - Let {groupForResponseKey} be the list in {groupedFieldSet } for
512
515
{responseKey}; if no such list exists, create it as an empty list.
513
516
- Append {selection} to the {groupForResponseKey}.
514
517
- If {selection} is a {FragmentSpread}:
@@ -525,12 +528,12 @@ CollectFields(objectType, selectionSet, variableValues, visitedFragments):
525
528
with the next {selection} in {selectionSet}.
526
529
- Let {fragmentSelectionSet} be the top-level selection set of {fragment}.
527
530
- Let {fragmentGroupedFieldSet} be the result of calling
528
- {CollectFields(objectType, fragmentSelectionSet , variableValues,
531
+ {CollectFields(objectType, fieldSelectionSet , variableValues,
529
532
visitedFragments)}.
530
533
- For each {fragmentGroup} in {fragmentGroupedFieldSet}:
531
534
- Let {responseKey} be the response key shared by all fields in
532
535
{fragmentGroup}.
533
- - Let {groupForResponseKey} be the list in {groupedFields } for
536
+ - Let {groupForResponseKey} be the list in {groupedFieldSet } for
534
537
{responseKey}; if no such list exists, create it as an empty list.
535
538
- Append all items in {fragmentGroup} to {groupForResponseKey}.
536
539
- If {selection} is an {InlineFragment}:
@@ -545,10 +548,10 @@ CollectFields(objectType, selectionSet, variableValues, visitedFragments):
545
548
- For each {fragmentGroup} in {fragmentGroupedFieldSet}:
546
549
- Let {responseKey} be the response key shared by all fields in
547
550
{fragmentGroup}.
548
- - Let {groupForResponseKey} be the list in {groupedFields } for
551
+ - Let {groupForResponseKey} be the list in {groupedFieldSet } for
549
552
{responseKey}; if no such list exists, create it as an empty list.
550
553
- Append all items in {fragmentGroup} to {groupForResponseKey}.
551
- - Return {groupedFields}.
554
+ - Return {groupedFields} and {visitedFragments} .
552
555
553
556
DoesFragmentTypeApply(objectType, fragmentType):
554
557
@@ -565,6 +568,39 @@ DoesFragmentTypeApply(objectType, fragmentType):
565
568
Note: The steps in {CollectFields()} evaluating the ` @skip ` and ` @include `
566
569
directives may be applied in either order since they apply commutatively.
567
570
571
+ ### Root Field Collection
572
+
573
+ Root field collection processes the operation's top-level selection set:
574
+
575
+ CollectRootFields(rootType, operationSelectionSet, variableValues):
576
+
577
+ - Initialize {visitedFragments} to the empty set.
578
+ - Let {groupedFieldSet} be the result of calling {CollectFields(rootType,
579
+ operationSelectionSet, variableValues, visitedFragments)}.
580
+ - Return {groupedFieldSet}.
581
+
582
+ ### Object Subfield Collection
583
+
584
+ Object subfield collection processes a field's sub-selection sets:
585
+
586
+ CollectSubfields(objectType, fields, variableValues):
587
+
588
+ - Initialize {visitedFragments} to the empty set.
589
+ - Initialize {groupedSubfieldSet} to an empty ordered map of lists.
590
+ - For each {field} in {fields}:
591
+ - Let {fieldSelectionSet} be the selection set of {field}.
592
+ - If {fieldSelectionSet} is null or empty, continue to the next field.
593
+ - Let {fieldGroupedFieldSet} be the result of calling
594
+ {CollectFields(objectType, fragmentSelectionSet, variableValues,
595
+ visitedFragments)}.
596
+ - For each {fieldGroup} in {fieldGroupedFieldSet}:
597
+ - Let {responseKey} be the response key shared by all fields in
598
+ {fragmentGroup}.
599
+ - Let {groupForResponseKey} be the list in {groupedFieldSet} for
600
+ {responseKey}; if no such list exists, create it as an empty list.
601
+ - Append all items in {fieldGroup} to {groupForResponseKey}.
602
+ - Return {groupedSubfieldSet}.
603
+
568
604
## Executing Fields
569
605
570
606
Each field requested in the grouped field set that is defined on the selected
@@ -692,8 +728,9 @@ CompleteValue(fieldType, fields, result, variableValues):
692
728
- Let {objectType} be {fieldType}.
693
729
- Otherwise if {fieldType} is an Interface or Union type.
694
730
- Let {objectType} be {ResolveAbstractType(fieldType, result)}.
695
- - Let {subSelectionSet} be the result of calling {MergeSelectionSets(fields)}.
696
- - Return the result of evaluating {ExecuteSelectionSet(subSelectionSet,
731
+ - Let {groupedSubfieldSet} be the result of calling
732
+ {CollectSubfields(objectType, fields, variableValues)}.
733
+ - Return the result of evaluating {ExecuteGroupedFieldSet(groupedSubfieldSet,
697
734
objectType, result, variableValues)} _ normally_ (allowing for
698
735
parallelization).
699
736
@@ -758,17 +795,9 @@ sub-selections.
758
795
}
759
796
```
760
797
761
- After resolving the value for ` me ` , the selection sets are merged together so
762
- ` firstName ` and ` lastName ` can be resolved for one value.
763
-
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}.
798
+ After resolving the value for ` me ` , the selection sets are merged together by
799
+ calling {CollectSubfields()} so ` firstName ` and ` lastName ` can be resolved for
800
+ one value.
772
801
773
802
### Handling Field Errors
774
803
0 commit comments