@@ -131,7 +131,9 @@ ExecuteQuery(query, schema, variableValues, initialValue):
131131- Let {queryType} be the root Query type in {schema}.
132132- Assert: {queryType} is an Object type.
133133- 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,
135137 queryType, initialValue, variableValues)} _ normally_ (allowing
136138 parallelization).
137139- Let {errors} be the list of all _ field error_ raised while executing the
@@ -153,7 +155,9 @@ ExecuteMutation(mutation, schema, variableValues, initialValue):
153155- Let {mutationType} be the root Mutation type in {schema}.
154156- Assert: {mutationType} is an Object type.
155157- 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,
157161 mutationType, initialValue, variableValues)} _ serially_ .
158162- Let {errors} be the list of all _ field error_ raised while executing the
159163 selection set.
@@ -256,7 +260,7 @@ CreateSourceEventStream(subscription, schema, variableValues, initialValue):
256260- Let {subscriptionType} be the root Subscription type in {schema}.
257261- Assert: {subscriptionType} is an Object type.
258262- 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,
260264 selectionSet, variableValues)}.
261265- If {groupedFieldSet} does not have exactly one entry, raise a _ request error_ .
262266- Let {fields} be the value of the first entry in {groupedFieldSet}.
@@ -301,7 +305,9 @@ ExecuteSubscriptionEvent(subscription, schema, variableValues, initialValue):
301305- Let {subscriptionType} be the root Subscription type in {schema}.
302306- Assert: {subscriptionType} is an Object type.
303307- 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,
305311 subscriptionType, initialValue, variableValues)} _ normally_ (allowing
306312 parallelization).
307313- Let {errors} be the list of all _ field error_ raised while executing the
@@ -322,20 +328,17 @@ Unsubscribe(responseStream):
322328
323329- Cancel {responseStream}
324330
325- ## Executing Selection Sets
331+ ## Executing Field Sets
326332
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.
330336
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.
334339
335- ExecuteSelectionSet(selectionSet , objectType, objectValue, variableValues):
340+ ExecuteFieldSet(groupedFieldSet , objectType, objectValue, variableValues):
336341
337- - Let {groupedFieldSet} be the result of {CollectFields(objectType,
338- selectionSet, variableValues)}.
339342- Initialize {resultMap} to an empty ordered map.
340343- For each {groupedFieldSet} as {responseKey} and {fields}:
341344 - 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()}
490493is maintained through execution, ensuring that fields appear in the executed
491494response in a stable and predictable order.
492495
493- CollectFields(objectType, selectionSet, variableValues, visitedFragments):
496+ CollectFields(objectType, selectionSet, variableValues, groupedFieldSet,
497+ visitedFragments):
494498
499+ - If {groupedFieldSet} is not provided, initialize it an empty ordered map of
500+ lists.
495501- If {visitedFragments} is not provided, initialize it to the empty set.
496- - Initialize {groupedFields} to an empty ordered map of lists.
497502- For each {selection} in {selectionSet}:
498503 - If {selection} provides the directive ` @skip ` , let {skipDirective} be that
499504 directive.
@@ -508,7 +513,7 @@ CollectFields(objectType, selectionSet, variableValues, visitedFragments):
508513 - If {selection} is a {Field}:
509514 - Let {responseKey} be the response key of {selection} (the alias if
510515 defined, otherwise the field name).
511- - Let {groupForResponseKey} be the list in {groupedFields } for
516+ - Let {groupForResponseKey} be the list in {groupedFieldSet } for
512517 {responseKey}; if no such list exists, create it as an empty list.
513518 - Append {selection} to the {groupForResponseKey}.
514519 - If {selection} is a {FragmentSpread}:
@@ -524,31 +529,16 @@ CollectFields(objectType, selectionSet, variableValues, visitedFragments):
524529 - If {DoesFragmentTypeApply(objectType, fragmentType)} is false, continue
525530 with the next {selection} in {selectionSet}.
526531 - 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)}.
536534 - If {selection} is an {InlineFragment}:
537535 - Let {fragmentType} be the type condition on {selection}.
538536 - If {fragmentType} is not {null} and {DoesFragmentTypeApply(objectType,
539537 fragmentType)} is false, continue with the next {selection} in
540538 {selectionSet}.
541539 - 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)}.
552542
553543DoesFragmentTypeApply(objectType, fragmentType):
554544
@@ -565,6 +555,30 @@ DoesFragmentTypeApply(objectType, fragmentType):
565555Note: The steps in {CollectFields()} evaluating the ` @skip ` and ` @include `
566556directives may be applied in either order since they apply commutatively.
567557
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+
568582## Executing Fields
569583
570584Each field requested in the grouped field set that is defined on the selected
@@ -692,8 +706,9 @@ CompleteValue(fieldType, fields, result, variableValues):
692706 - Let {objectType} be {fieldType}.
693707 - Otherwise if {fieldType} is an Interface or Union type.
694708 - 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,
697712 objectType, result, variableValues)} _ normally_ (allowing for
698713 parallelization).
699714
@@ -761,15 +776,6 @@ sub-selections.
761776After resolving the value for ` me ` , the selection sets are merged together so
762777` firstName ` and ` lastName ` can be resolved for one value.
763778
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-
773779### Handling Field Errors
774780
775781A _ field error_ is an error raised from a particular field during value
0 commit comments