@@ -446,7 +446,8 @@ The depth-first-search order of the _field set_ produced by {CollectFields()} is
446446maintained through execution, ensuring that fields appear in the executed
447447response in a stable and predictable order.
448448
449- CollectFields(objectType, selectionSet, variableValues, visitedFragments):
449+ CollectFields(objectType, selectionSet, variableValues, visitedFragments,
450+ fragmentVariables):
450451
451452- If {visitedFragments} is not provided, initialize it to the empty set.
452453- Initialize {collectedFieldsMap} to an empty ordered map of ordered sets.
@@ -464,10 +465,12 @@ CollectFields(objectType, selectionSet, variableValues, visitedFragments):
464465 - If {selection} is a {Field}:
465466 - Let {responseName} be the _ response name_ of {selection} (the alias if
466467 defined, otherwise the field name).
467- - Let {fieldsForResponseName} be the _ field set _ value in
468+ - Let {fieldsForResponseName} be the _ field map _ value in
468469 {collectedFieldsMap} for the key {responseName}; otherwise create the
469470 entry with an empty ordered set.
470- - Add {selection} to the {fieldsForResponseName}.
471+ - Let {fieldDetails} be a new unordered map containing {fragmentVariables}.
472+ - Set the entry for {field} on {fieldDetails} to {selection}.
473+ - Add {fieldDetails} to the {fieldsForResponseName}.
471474 - If {selection} is a {FragmentSpread}:
472475 - Let {fragmentSpreadName} be the name of {selection}.
473476 - If {fragmentSpreadName} is in {visitedFragments}, continue with the next
@@ -480,10 +483,19 @@ CollectFields(objectType, selectionSet, variableValues, visitedFragments):
480483 - Let {fragmentType} be the type condition on {fragment}.
481484 - If {DoesFragmentTypeApply(objectType, fragmentType)} is {false}, continue
482485 with the next {selection} in {selectionSet}.
486+ - Let {variableDefinitions} be the variable definitions for {fragment}.
487+ - Initialize {signatures} to an empty list.
488+ - For each {variableDefinition} of {variableDefinitions}:
489+ - Append the result of {GetVariableSignature(variableDefinition)} to
490+ {signatures}.
491+ - Let {values} be the result of {CoerceArgumentValues(fragment,
492+ argumentDefinitions, variableValues, fragmentVariables)}.
493+ - Let {newFragmentVariables} be an unordered map containing {signatures} and
494+ {values}.
483495 - Let {fragmentSelectionSet} be the top-level selection set of {fragment}.
484496 - Let {fragmentCollectedFieldMap} be the result of calling
485497 {CollectFields(objectType, fragmentSelectionSet, variableValues,
486- visitedFragments)}.
498+ visitedFragments, newFragmentVariables )}.
487499 - For each {responseName} and {fragmentFields} in
488500 {fragmentCollectedFieldMap}:
489501 - Let {fieldsForResponseName} be the _ field set_ value in
@@ -498,7 +510,7 @@ CollectFields(objectType, selectionSet, variableValues, visitedFragments):
498510 - Let {fragmentSelectionSet} be the top-level selection set of {selection}.
499511 - Let {fragmentCollectedFieldMap} be the result of calling
500512 {CollectFields(objectType, fragmentSelectionSet, variableValues,
501- visitedFragments)}.
513+ visitedFragments, fragmentVariables )}.
502514 - For each {responseName} and {fragmentFields} in
503515 {fragmentCollectedFieldMap}:
504516 - Let {fieldsForResponseName} be the _ field set_ value in
@@ -720,134 +732,6 @@ A correct executor must generate the following result for that _selection set_:
720732}
721733```
722734
723- ### Field Collection
724-
725- Before execution, the _ selection set_ is converted to a grouped field set by
726- calling {CollectFields()}. Each entry in the grouped field set is a list of
727- fields that share a response key (the alias if defined, otherwise the field
728- name). This ensures all fields with the same response key (including those in
729- referenced fragments) are executed at the same time.
730-
731- As an example, collecting the fields of this selection set would collect two
732- instances of the field ` a ` and one of field ` b ` :
733-
734- ``` graphql example
735- {
736- a {
737- subfield1
738- }
739- ... ExampleFragment
740- }
741-
742- fragment ExampleFragment on Query {
743- a {
744- subfield2
745- }
746- b
747- }
748- ```
749-
750- The depth-first-search order of the field groups produced by {CollectFields()}
751- is maintained through execution, ensuring that fields appear in the executed
752- response in a stable and predictable order.
753-
754- CollectFields(objectType, selectionSet, variableValues, visitedFragments,
755- fragmentVariables):
756-
757- - If {visitedFragments} is not provided, initialize it to the empty set.
758- - Initialize {groupedFields} to an empty ordered map of lists.
759- - For each {selection} in {selectionSet}:
760- - If {selection} provides the directive ` @skip ` , let {skipDirective} be that
761- directive.
762- - Let {directiveValues} be the result of {GetDirectiveValues(skipDirective,
763- variableValues, fragmentVariables)}.
764- - If the entry for the {if} argument within {directiveValues} is {true},
765- continue with the next {selection} in {selectionSet}.
766- - If {selection} provides the directive ` @include ` , let {includeDirective} be
767- that directive.
768- - Let {directiveValues} be the result of
769- {GetDirectiveValues(includeDirective, variableValues, fragmentVariables)}.
770- - If the entry for the {if} argument within {directiveValues} is not {true},
771- - If {selection} is a {Field}:
772- - Let {responseKey} be the response key of {selection} (the alias if
773- defined, otherwise the field name).
774- - Let {groupForResponseKey} be the list in {groupedFields} for
775- {responseKey}; if no such list exists, create it as an empty list.
776- - Let {fieldDetails} be a new unordered map containing {fragmentVariables}.
777- - Set the entry for {field} on {fieldDetails} to {selection}.
778- - Append {fieldDetails} to the {groupForResponseKey}.
779- - If {selection} is a {FragmentSpread}:
780- - Let {fragmentSpreadName} be the name of {selection}.
781- - If {fragmentSpreadName} is in {visitedFragments}, continue with the next
782- {selection} in {selectionSet}.
783- - Add {fragmentSpreadName} to {visitedFragments}.
784- - Let {fragment} be the Fragment in the current Document whose name is
785- {fragmentSpreadName}.
786- - If no such {fragment} exists, continue with the next {selection} in
787- {selectionSet}.
788- - Let {fragmentType} be the type condition on {fragment}.
789- - If {DoesFragmentTypeApply(objectType, fragmentType)} is {false}, continue
790- with the next {selection} in {selectionSet}.
791- - Let {variableDefinitions} be the variable definitions for {fragment}.
792- - Initialize {signatures} to an empty list.
793- - For each {variableDefinition} of {variableDefinitions}:
794- - Append the result of {GetVariableSignature(variableDefinition)} to
795- {signatures}.
796- - Let {values} be the result of {CoerceArgumentValues(fragment,
797- argumentDefinitions, variableValues, fragmentVariables)}.
798- - Let {newFragmentVariables} be an unordered map containing {signatures} and
799- {values}.
800- - Let {fragmentGroupedFieldSet} be the result of calling
801- {CollectFields(objectType, fragmentSelectionSet, variableValues,
802- visitedFragments, newFragmentVariables)}.
803- - For each {fragmentGroup} in {fragmentGroupedFieldSet}:
804- - Let {responseKey} be the response key shared by all fields in
805- {fragmentGroup}.
806- - Let {groupForResponseKey} be the list in {groupedFields} for
807- {responseKey}; if no such list exists, create it as an empty list.
808- - Append all items in {fragmentGroup} to {groupForResponseKey}.
809- - If {selection} is an {InlineFragment}:
810- - Let {fragmentType} be the type condition on {selection}.
811- - If {fragmentType} is not {null} and {DoesFragmentTypeApply(objectType,
812- fragmentType)} is {false}, continue with the next {selection} in
813- {selectionSet}.
814- - Let {fragmentSelectionSet} be the top-level selection set of {selection}.
815- - Let {fragmentGroupedFieldSet} be the result of calling
816- {CollectFields(objectType, fragmentSelectionSet, variableValues,
817- visitedFragments, fragmentVariables)}.
818- - For each {fragmentGroup} in {fragmentGroupedFieldSet}:
819- - Let {responseKey} be the response key shared by all fields in
820- {fragmentGroup}.
821- - Let {groupForResponseKey} be the list in {groupedFields} for
822- {responseKey}; if no such list exists, create it as an empty list.
823- - Append all items in {fragmentGroup} to {groupForResponseKey}.
824- - Return {groupedFields}.
825-
826- DoesFragmentTypeApply(objectType, fragmentType):
827-
828- - If {fragmentType} is an Object Type:
829- - If {objectType} and {fragmentType} are the same type, return {true},
830- otherwise return {false}.
831- - If {fragmentType} is an Interface Type:
832- - If {objectType} is an implementation of {fragmentType}, return {true}
833- otherwise return {false}.
834- - If {fragmentType} is a Union:
835- - If {objectType} is a possible type of {fragmentType}, return {true}
836- otherwise return {false}.
837-
838- Note: The steps in {CollectFields()} evaluating the ` @skip ` and ` @include `
839- directives may be applied in either order since they apply commutatively.
840-
841- GetDirectiveValues(directive, variableValues, fragmentVariables):
842-
843- - Let {directiveName} be the name of {directive}.
844- - Let {directiveDefinition} be the definition for {directiveName} within the
845- schema.
846- - Assert {directiveDefinition} is defined.
847- - Let {argumentDefinitions} be the arguments defined by {directiveDefinition}.
848- - Return the result of {CoerceArgumentValues(directiveDefinition,
849- argumentDefinitions, variableValues, fragmentVariables)}.
850-
851735## Executing Fields
852736
853737Each entry in a result map is the result of executing a field on an object type
0 commit comments