Skip to content

Replace ExecuteSelectionSet with ExecuteCollectedFields #1039

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 25 commits into from
Jul 1, 2025

Conversation

benjie
Copy link
Member

@benjie benjie commented Aug 21, 2023

Essentially this PR replaces the ExecuteSelectionSet method with ExecuteCollectedFields (which essentially just drops the first line of ExecuteSelectionSet, which was responsible for collecting fields to be executed). It then refactors the rest of the spec to accommodate this change, reducing the repetition in ExecuteQuery, ExecuteMutation and ExecuteSubscriptionEvent; and removing MergeSelectionSets (which generated a "virtual" selection set to accomodate the ExecuteSelectionSet method), instead adding a CollectSubfields algorithm which produces a grouped field set directly, ready for execution.

I extracted this common refactoring from a number of my attempts to write spec changes for the @defer and @stream directives - it turns out that this refactoring of the spec was always needed as a base for my changes. Similarly, @yaacovCR found similar in his attempts to address this same problem, and raised #999 extracted from his solution. This PR was introduced independently of #999 (other than using the CollectSubfields algorithm name) however there is significant alignment, so @yaacovCR suggested that I raise it as an alternative PR.

It may be easier to review this PR in "split" view rather than "unified" view.

@netlify
Copy link

netlify bot commented Aug 21, 2023

Deploy Preview for graphql-spec-draft ready!

Name Link
🔨 Latest commit cc17846
🔍 Latest deploy log https://app.netlify.com/projects/graphql-spec-draft/deploys/6864110092521d0008b6f11e
😎 Deploy Preview https://deploy-preview-1039--graphql-spec-draft.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@benjie
Copy link
Member Author

benjie commented Feb 5, 2024

(Rebased on main)

@benjie benjie force-pushed the benjie/incremental-common branch from b342b58 to a52310e Compare September 19, 2024 11:51
@benjie
Copy link
Member Author

benjie commented Sep 19, 2024

(Rebased on main)

@yaacovCR

This comment was marked as resolved.

@benjie

This comment was marked as resolved.

@yaacovCR

This comment was marked as resolved.

@Keweiqu
Copy link
Contributor

Keweiqu commented Oct 3, 2024

@benjie we need to formally define "grouped field set" in Section 2 "Language". You might have done so in a prior PR that I missed. Here is the link to us defining "section sets" in section 2 https://spec.graphql.org/draft/#sec-Selection-Sets

JoviDeCroock added a commit to JoviDeCroock/graphql-spec that referenced this pull request Feb 15, 2025
@benjie
Copy link
Member Author

benjie commented Apr 25, 2025

@leebyron To reflect your discussion above, I've renamed "ExecuteGroupedFieldSet" to "ExecuteCollectedFields" and that definitely flows better.

However, I think that "grouped field set" is still the right term to refer to the structure and actually defining a "field set" in general adds a lot of clarity to a number of algorithms (e.g. ExecuteField()) so I've both reworked the introduction to field collection in this PR and raised a separate PR that changes "grouped field set" to actually be Map<string, OrderedSet<FieldSelection>> rather than containing lists:

#1161

This makes the algorithms a lot clearer to me:

-CollectSubfields(objectType, fields, variableValues):
+CollectSubfields(objectType, fieldSet, variableValues):

^ Knowing that a "field set" is a set of field selections that share the same response key makes this algorithms purpose a lot clearer

-ExecuteField(objectType, objectValue, fieldType, fields, variableValues):
+ExecuteField(objectType, objectValue, fieldType, fieldSet, variableValues):

^ A lot more intuitive what fieldSet is (field selections representing the field to be executed) rather than fields (could be interpreted as the the fields requested on this field's selection set).

-CompleteValue(fieldType, fields, result, variableValues):
+CompleteValue(fieldType, fieldSet, result, variableValues):

^ Same

@benjie benjie force-pushed the benjie/incremental-common branch from c7532d1 to 6e76340 Compare April 25, 2025 09:00
@benjie benjie force-pushed the benjie/incremental-common branch from 6e76340 to 3c6dfb3 Compare April 25, 2025 09:01
Comment on lines 398 to 404
:: A _field set_ is a list of selected fields that share the same _response
name_ (the field alias if defined, otherwise the field's name).

Note: The order of field selections in a _field set_ is significant, hence the
algorithms in this specification model it as a list. Any later duplicated field
selections in a field set will not impact its interpretation, so using an
ordered set would yield equivalent results.
Copy link
Member Author

@benjie benjie May 1, 2025

Choose a reason for hiding this comment

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

@@ -757,7 +757,7 @@ type Person {
}
```

Valid operations must supply a nested field set for any field that returns an
Valid operations must supply a selection of fields for any field that returns an
Copy link
Contributor

Choose a reason for hiding this comment

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

Not directly related to this PR but a more precise wording would be to use selectionSet here as fragments are also valid, not only fields.

Suggested change
Valid operations must supply a selection of fields for any field that returns an
Valid operations must supply a valid sub _selection set_ for any field that returns an

@leebyron leebyron force-pushed the benjie/incremental-common branch from 1e42cc4 to d0fb75c Compare June 30, 2025 23:47
@leebyron leebyron force-pushed the benjie/incremental-common branch from ed11e66 to 9c4a529 Compare July 1, 2025 00:19
@leebyron
Copy link
Collaborator

leebyron commented Jul 1, 2025

@benjie I made some substantial editorial changes here, especially to one of the term names. Please review!

@leebyron leebyron force-pushed the benjie/incremental-common branch from e4a5199 to c776fa7 Compare July 1, 2025 01:18
@leebyron leebyron force-pushed the benjie/incremental-common branch from c776fa7 to 97d43ba Compare July 1, 2025 03:16
@leebyron leebyron merged commit 17e2a47 into main Jul 1, 2025
9 checks passed
@leebyron leebyron deleted the benjie/incremental-common branch July 1, 2025 16:54
@github-project-automation github-project-automation bot moved this from In Progress to Done in Benjie's GraphQL tasks Jul 1, 2025
@benjie
Copy link
Member Author

benjie commented Jul 2, 2025

Thanks Lee! Suggested edits raised in #1175

@benjie benjie restored the benjie/incremental-common branch July 2, 2025 12:56
leebyron pushed a commit that referenced this pull request Jul 2, 2025
* Resolve ambiguity - we mean return type

For `type User { name: String }`, `User.name` is a field of an object
type (`User`). Clarify that we mean the return type of the field, not
the type to which it belongs.

* Consistency with collectedFieldsMap

* Reword to avoid 'During execution, ... before execution.'

* Serial execution relates to the set of fields, not each individual field

* Add missing close parenthesis

* Remove duplicate 'by', specific algorithm is detailed in next paragraph

* CollectFields() produces many _field set_

* Minor edits
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
✏️ Editorial PR is non-normative or does not influence implementation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants