@@ -132,9 +132,11 @@ ExecuteQuery(query, schema, variableValues, initialValue):
132
132
- Let {queryType} be the root Query type in {schema}.
133
133
- Assert: {queryType} is an Object type.
134
134
- Let {selectionSet} be the top level Selection Set in {query}.
135
+ - Let {groupedFieldSet} be the result of {CollectRootFields(queryType,
136
+ selectionSet, variableValues)}.
135
137
- Let {data}, {defers} and {streams} be the result of running
136
- {ExecuteSelectionSet(selectionSet , queryType, initialValue, variableValues)}
137
- _ normally_ (allowing parallelization).
138
+ {ExecuteGroupedFieldSet(groupedFieldSet , queryType, initialValue,
139
+ variableValues)} _ normally_ (allowing parallelization).
138
140
- Let {errors} be the list of all _ field error_ raised while executing the
139
141
selection set.
140
142
- If {defers} is an empty map and {streams} is an empty list:
@@ -219,7 +221,7 @@ variableValues):
219
221
entries of {fieldDetails}.
220
222
- Let {selectionSet} be a new selection set consisting of {fields}.
221
223
- Let {data}, {childDefers} and {childStreams} be the result of running
222
- {ExecuteSelectionSet (selectionSet, objectType, objectValue,
224
+ {ExecuteGroupedFieldSet (selectionSet, objectType, objectValue,
223
225
variableValues, path)}.
224
226
- Let {childErrors} be the list of all _ field error_ raised while
225
227
executing the selection set.
@@ -336,8 +338,10 @@ ExecuteMutation(mutation, schema, variableValues, initialValue):
336
338
- Let {mutationType} be the root Mutation type in {schema}.
337
339
- Assert: {mutationType} is an Object type.
338
340
- Let {selectionSet} be the top level Selection Set in {mutation}.
341
+ - Let {groupedFieldSet} be the result of {CollectRootFields(mutationType,
342
+ selectionSet, variableValues)}.
339
343
- Let {data}, {defers} and {streams} be the result of running
340
- {ExecuteSelectionSet(selectionSet , mutationType, initialValue,
344
+ {ExecuteGroupedFieldSet(groupedFieldSet , mutationType, initialValue,
341
345
variableValues)} _ serially_ .
342
346
- Let {errors} be the list of all _ field error_ raised while executing the
343
347
selection set.
@@ -446,8 +450,8 @@ CreateSourceEventStream(subscription, schema, variableValues, initialValue):
446
450
- Let {subscriptionType} be the root Subscription type in {schema}.
447
451
- Assert: {subscriptionType} is an Object type.
448
452
- Let {selectionSet} be the top level Selection Set in {subscription}.
449
- - Let {groupedFieldSet} be the result of running
450
- {CollectFields(subscriptionType, selectionSet, variableValues)}.
453
+ - Let {groupedFieldSet} be the result of {CollectRootFields(subscriptionType,
454
+ selectionSet, variableValues)}.
451
455
- If {groupedFieldSet} does not have exactly one entry, raise a _ request error_ .
452
456
- Let {fieldDetails} be the value of the first entry in {groupedFieldSet}.
453
457
- Let {fieldDetail} be the first entry in {fieldDetails}.
@@ -496,8 +500,10 @@ ExecuteSubscriptionEvent(subscription, schema, variableValues, initialValue):
496
500
- Let {subscriptionType} be the root Subscription type in {schema}.
497
501
- Assert: {subscriptionType} is an Object type.
498
502
- Let {selectionSet} be the top level Selection Set in {subscription}.
503
+ - Let {groupedFieldSet} be the result of {CollectRootFields(subscriptionType,
504
+ selectionSet, variableValues)}.
499
505
- Let {data}, {defers} and {streams} be the result of running
500
- {ExecuteSelectionSet(selectionSet , subscriptionType, initialValue,
506
+ {ExecuteGroupedFieldSet(groupedFieldSet , subscriptionType, initialValue,
501
507
variableValues)} _ normally_ (allowing parallelization).
502
508
- Let {errors} be the list of all _ field error_ raised while executing the
503
509
selection set.
@@ -523,22 +529,19 @@ Unsubscribe(responseStream):
523
529
524
530
- Cancel {responseStream}
525
531
526
- ## Executing Selection Sets
532
+ ## Executing Grouped Field Sets
527
533
528
- To execute a selection set, the object value being evaluated and the object type
529
- need to be known, as well as whether it must be executed serially, or may be
530
- executed in parallel.
534
+ To execute a grouped field set, the object value being evaluated and the object
535
+ type need to be known, as well as whether it must be executed serially, or may
536
+ be executed in parallel.
531
537
532
- First, the selection set is turned into a grouped field set; then, each
533
- represented field in the grouped field set produces an entry into a response
534
- map.
538
+ Each represented field in the grouped field set produces an entry into a
539
+ response map.
535
540
536
- ExecuteSelectionSet(selectionSet , objectType, objectValue, variableValues,
541
+ ExecuteGroupedFieldSet(groupedFieldSet , objectType, objectValue, variableValues,
537
542
parentPath):
538
543
539
544
- If {parentPath} is not provided, initialize it to an empty list.
540
- - Let {groupedFieldSet} be the result of running {CollectFields(objectType,
541
- selectionSet, variableValues)}.
542
545
- Initialize {resultMap} to an empty ordered map.
543
546
- Let {defers} be an empty unordered map.
544
547
- Let {streams} be an empty list.
@@ -607,8 +610,8 @@ is explained in greater detail in the Field Collection section below.
607
610
608
611
** Errors and Non-Null Fields**
609
612
610
- If during {ExecuteSelectionSet ()} a field with a non-null {fieldType} raises a
611
- _ field error_ then that error must propagate to this entire selection set,
613
+ If during {ExecuteGroupedFieldSet ()} a field with a non-null {fieldType} raises
614
+ a _ field error_ then that error must propagate to this entire selection set,
612
615
either resolving to {null} if allowed or further propagated to a parent field.
613
616
614
617
If this occurs, any sibling fields which have not yet executed or have not yet
@@ -747,6 +750,7 @@ response in a stable and predictable order.
747
750
CollectFields(objectType, selectionSet, variableValues, isDeferred,
748
751
visitedFragments):
749
752
753
+ - Initialize {groupedFieldSet} to an empty ordered map of lists.
750
754
- If {isDeferred} is not provided, initialize it to {false}.
751
755
- If {visitedFragments} is not provided, initialize it to the empty set.
752
756
- Initialize {groupedFields} to an empty ordered map of lists.
@@ -765,7 +769,7 @@ visitedFragments):
765
769
- Let {field} be {selection}.
766
770
- Let {responseKey} be the response key of {field} (the alias if defined,
767
771
otherwise the field name).
768
- - Let {groupForResponseKey} be the list in {groupedFields } for
772
+ - Let {groupForResponseKey} be the list in {groupedFieldSet } for
769
773
{responseKey}; if no such list exists, create it as an empty list.
770
774
- Let {fieldDetail} be an unordered map containing {field} and {isDeferred}.
771
775
- Append {fieldDetail} to the {groupForResponseKey}.
@@ -794,7 +798,7 @@ visitedFragments):
794
798
- For each {fragmentGroup} in {fragmentGroupedFieldSet}:
795
799
- Let {responseKey} be the response key shared by all fields in
796
800
{fragmentGroup}.
797
- - Let {groupForResponseKey} be the list in {groupedFields } for
801
+ - Let {groupForResponseKey} be the list in {groupedFieldSet } for
798
802
{responseKey}; if no such list exists, create it as an empty list.
799
803
- Append all items in {fragmentGroup} to {groupForResponseKey}.
800
804
- If {selection} is an {InlineFragment}:
@@ -815,10 +819,10 @@ visitedFragments):
815
819
- For each {fragmentGroup} in {fragmentGroupedFieldSet}:
816
820
- Let {responseKey} be the response key shared by all fields in
817
821
{fragmentGroup}.
818
- - Let {groupForResponseKey} be the list in {groupedFields } for
822
+ - Let {groupForResponseKey} be the list in {groupedFieldSet } for
819
823
{responseKey}; if no such list exists, create it as an empty list.
820
824
- Append all items in {fragmentGroup} to {groupForResponseKey}.
821
- - Return {groupedFields}.
825
+ - Return {groupedFields} and {visitedFragments} .
822
826
823
827
DoesFragmentTypeApply(objectType, fragmentType):
824
828
@@ -835,6 +839,39 @@ DoesFragmentTypeApply(objectType, fragmentType):
835
839
Note: The steps in {CollectFields()} evaluating the ` @skip ` and ` @include `
836
840
directives may be applied in either order since they apply commutatively.
837
841
842
+ ### Root Field Collection
843
+
844
+ Root field collection processes the operation's top-level selection set:
845
+
846
+ CollectRootFields(rootType, operationSelectionSet, variableValues):
847
+
848
+ - Initialize {visitedFragments} to the empty set.
849
+ - Let {groupedFieldSet} be the result of calling {CollectFields(rootType,
850
+ operationSelectionSet, variableValues, visitedFragments)}.
851
+ - Return {groupedFieldSet}.
852
+
853
+ ### Object Subfield Collection
854
+
855
+ Object subfield collection processes a field's sub-selection sets:
856
+
857
+ CollectSubfields(objectType, fields, variableValues):
858
+
859
+ - Initialize {visitedFragments} to the empty set.
860
+ - Initialize {groupedSubfieldSet} to an empty ordered map of lists.
861
+ - For each {field} in {fields}:
862
+ - Let {fieldSelectionSet} be the selection set of {field}.
863
+ - If {fieldSelectionSet} is null or empty, continue to the next field.
864
+ - Let {fieldGroupedFieldSet} be the result of calling
865
+ {CollectFields(objectType, fragmentSelectionSet, variableValues,
866
+ visitedFragments)}.
867
+ - For each {fieldGroup} in {fieldGroupedFieldSet}:
868
+ - Let {responseKey} be the response key shared by all fields in
869
+ {fragmentGroup}.
870
+ - Let {groupForResponseKey} be the list in {groupedFieldSet} for
871
+ {responseKey}; if no such list exists, create it as an empty list.
872
+ - Append all items in {fieldGroup} to {groupForResponseKey}.
873
+ - Return {groupedSubfieldSet}.
874
+
838
875
## Executing Fields
839
876
840
877
Each field requested in the grouped field set that is defined on the selected
@@ -980,10 +1017,11 @@ CompleteValue(fieldType, fields, result, variableValues, path):
980
1017
- Otherwise if {fieldType} is an Interface or Union type.
981
1018
- Let {objectType} be the result of running {ResolveAbstractType(fieldType,
982
1019
result)}.
983
- - Let {subSelectionSet} be the result of running {MergeSelectionSets(fields)}.
1020
+ - Let {groupedSubfieldSet} be the result of calling
1021
+ {CollectSubfields(objectType, fields, variableValues)}.
984
1022
- Let {completedResult}, {defers} and {streams} be the result of running
985
- {ExecuteSelectionSet(subSelectionSet , objectType, result, variableValues ,
986
- path)} _ normally_ (allowing for parallelization).
1023
+ {ExecuteGroupedFieldSet(groupedSubfieldSet , objectType, result,
1024
+ variableValues, path)} _ normally_ (allowing for parallelization).
987
1025
- Return {completedResult}, {defers} and {streams}.
988
1026
989
1027
** Coercing Results**
@@ -1047,17 +1085,9 @@ sub-selections.
1047
1085
}
1048
1086
```
1049
1087
1050
- After resolving the value for ` me ` , the selection sets are merged together so
1051
- ` firstName ` and ` lastName ` can be resolved for one value.
1052
-
1053
- MergeSelectionSets(fields):
1054
-
1055
- - Let {selectionSet} be an empty list.
1056
- - For each {field} in {fields}:
1057
- - Let {fieldSelectionSet} be the selection set of {field}.
1058
- - If {fieldSelectionSet} is null or empty, continue to the next field.
1059
- - Append all selections in {fieldSelectionSet} to {selectionSet}.
1060
- - Return {selectionSet}.
1088
+ After resolving the value for ` me ` , the selection sets are merged together by
1089
+ calling {CollectSubfields()} so ` firstName ` and ` lastName ` can be resolved for
1090
+ one value.
1061
1091
1062
1092
### Handling Field Errors
1063
1093
0 commit comments