Skip to content

Minor editorial tweaks following the merge of #1039 #1175

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jul 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions spec/Section 3 -- Type System.md
Original file line number Diff line number Diff line change
Expand Up @@ -775,8 +775,8 @@ type Person {
}
```

Valid operations must supply a _selection set_ for every field of an object
type, so this operation is not valid:
Valid operations must supply a _selection set_ for every field whose return type
is an object type, so this operation is not valid:
Comment on lines +778 to +779
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

User.name is a "field of an object type", but should not have a selection set.


```graphql counter-example
{
Expand Down
10 changes: 5 additions & 5 deletions spec/Section 5 -- Validation.md
Original file line number Diff line number Diff line change
Expand Up @@ -334,11 +334,11 @@ CollectSubscriptionFields(objectType, selectionSet, visitedFragments):
- If {DoesFragmentTypeApply(objectType, fragmentType)} is {false}, continue
with the next {selection} in {selectionSet}.
- Let {fragmentSelectionSet} be the top-level selection set of {fragment}.
- Let {fragmentCollectedFieldMap} be the result of calling
- Let {fragmentCollectedFieldsMap} be the result of calling
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+s throughout to match existing collectedFieldsMap term

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah thanks - that was my intent

{CollectSubscriptionFields(objectType, fragmentSelectionSet,
visitedFragments)}.
- For each {responseName} and {fragmentFields} in
{fragmentCollectedFieldMap}:
{fragmentCollectedFieldsMap}:
- Let {fieldsForResponseKey} be the _field set_ value in
{collectedFieldsMap} for the key {responseName}; otherwise create the
entry with an empty ordered set.
Expand All @@ -349,11 +349,11 @@ CollectSubscriptionFields(objectType, selectionSet, visitedFragments):
fragmentType)} is {false}, continue with the next {selection} in
{selectionSet}.
- Let {fragmentSelectionSet} be the top-level selection set of {selection}.
- Let {fragmentCollectedFieldMap} be the result of calling
- Let {fragmentCollectedFieldsMap} be the result of calling
{CollectSubscriptionFields(objectType, fragmentSelectionSet,
visitedFragments)}.
- For each {responseName} and {fragmentFields} in
{fragmentCollectedFieldMap}:
{fragmentCollectedFieldsMap}:
- Let {fieldsForResponseKey} be the _field set_ value in
{collectedFieldsMap} for the key {responseName}; otherwise create the
entry with an empty ordered set.
Expand Down Expand Up @@ -584,7 +584,7 @@ should be unambiguous. Therefore any two field selections which might both be
encountered for the same object are only valid if they are equivalent.

During execution, the simultaneous execution of fields with the same response
name is accomplished by {CollectSubfields()} before execution.
name is accomplished by performing {CollectSubfields()} before their execution.
Comment on lines 586 to +587
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

During execution, ... before execution. did not read well.


For simple hand-written GraphQL, this rule is obviously a clear developer error,
however nested fragments can make this difficult to detect manually.
Expand Down
33 changes: 16 additions & 17 deletions spec/Section 6 -- Execution.md
Original file line number Diff line number Diff line change
Expand Up @@ -369,9 +369,9 @@ continues until there are no more subfields to collect and execute.
operation. A root selection set always selects from a _root operation type_.

To execute the root selection set, the initial value being evaluated and the
root type must be known, as well as whether each field must be executed
serially, or normally by executing all fields in parallel (see
[Normal and Serial Execution](#sec-Normal-and-Serial-Execution).
root type must be known, as well as whether the fields must be executed in a
series, or normally by executing all fields in parallel (see
Comment on lines +372 to +373
Copy link
Member Author

@benjie benjie Jul 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"each field must be executed serially" sounds like the serial-ness is a property of the fields own execution (e.g. of its resolver and sub selection set), rather than it's contextual execution relative to its sibling fields. Minor tweak for clarity.

[Normal and Serial Execution](#sec-Normal-and-Serial-Execution)).

Executing the root selection set works similarly for queries (parallel),
mutations (serial), and subscriptions (where it is executed for each event in
Expand All @@ -396,10 +396,9 @@ executionMode):
### Field Collection

Before execution, each _selection set_ is converted to a _collected fields map_
by calling {CollectFields()} by collecting all fields with the same response
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Merely deleted by calling {CollectFields()} since the algorithms (including {CollectSubfields()} too) are mentioned in next paragraph, and by ... by ... read unpleasantly.

name, including those in referenced fragments, into an individual _field set_.
This ensures that multiple references to fields with the same response name will
only be executed once.
by collecting all fields with the same response name, including those in
referenced fragments, into an individual _field set_. This ensures that multiple
references to fields with the same response name will only be executed once.

:: A _collected fields map_ is an ordered map where each entry is a _response
name_ and its associated _field set_. A _collected fields map_ may be produced
Expand Down Expand Up @@ -436,8 +435,8 @@ fragment ExampleFragment on Query {
}
```

The depth-first-search order of the _field set_ produced by {CollectFields()} is
maintained through execution, ensuring that fields appear in the executed
The depth-first-search order of each _field set_ produced by {CollectFields()}
is maintained through execution, ensuring that fields appear in the executed
response in a stable and predictable order.

CollectFields(objectType, selectionSet, variableValues, visitedFragments):
Expand Down Expand Up @@ -475,11 +474,11 @@ CollectFields(objectType, selectionSet, variableValues, visitedFragments):
- If {DoesFragmentTypeApply(objectType, fragmentType)} is {false}, continue
with the next {selection} in {selectionSet}.
- Let {fragmentSelectionSet} be the top-level selection set of {fragment}.
- Let {fragmentCollectedFieldMap} be the result of calling
- Let {fragmentCollectedFieldsMap} be the result of calling
{CollectFields(objectType, fragmentSelectionSet, variableValues,
visitedFragments)}.
- For each {responseName} and {fragmentFields} in
{fragmentCollectedFieldMap}:
{fragmentCollectedFieldsMap}:
- Let {fieldsForResponseName} be the _field set_ value in
{collectedFieldsMap} for the key {responseName}; otherwise create the
entry with an empty ordered set.
Expand All @@ -490,11 +489,11 @@ CollectFields(objectType, selectionSet, variableValues, visitedFragments):
fragmentType)} is {false}, continue with the next {selection} in
{selectionSet}.
- Let {fragmentSelectionSet} be the top-level selection set of {selection}.
- Let {fragmentCollectedFieldMap} be the result of calling
- Let {fragmentCollectedFieldsMap} be the result of calling
{CollectFields(objectType, fragmentSelectionSet, variableValues,
visitedFragments)}.
- For each {responseName} and {fragmentFields} in
{fragmentCollectedFieldMap}:
{fragmentCollectedFieldsMap}:
- Let {fieldsForResponseName} be the _field set_ value in
{collectedFieldsMap} for the key {responseName}; otherwise create the
entry with an empty ordered set.
Expand All @@ -518,8 +517,8 @@ directives may be applied in either order since they apply commutatively.

**Merging Selection Sets**

In order to execute the sub-selections of a object typed field, all _selection
sets_ of each field with the same response name of the parent _field set_ are
In order to execute the sub-selections of an object typed field, all _selection
sets_ of each field with the same response name in the parent _field set_ are
merged together into a single _collected fields map_ representing the subfields
to be executed next.

Expand Down Expand Up @@ -554,9 +553,9 @@ CollectSubfields(objectType, fields, variableValues):
- For each {field} in {fields}:
- Let {fieldSelectionSet} be the selection set of {field}.
- If {fieldSelectionSet} is null or empty, continue to the next field.
- Let {fieldCollectedFieldMap} be the result of {CollectFields(objectType,
- Let {fieldCollectedFieldsMap} be the result of {CollectFields(objectType,
fieldSelectionSet, variableValues)}.
- For each {responseName} and {subfields} in {fieldCollectedFieldMap}:
- For each {responseName} and {subfields} in {fieldCollectedFieldsMap}:
- Let {fieldsForResponseName} be the _field set_ value in
{collectedFieldsMap} for the key {responseName}; otherwise create the
entry with an empty ordered set.
Expand Down