-
Notifications
You must be signed in to change notification settings - Fork 273
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
fix(federation): correct order of @skip and @include conditions on the same selection #6137
Conversation
…n the same selection PR #6120 was the wrong solution. JS doesn't actually maintain the order of the conditions, like I thought. Instead, it always puts `@skip` first and `@include` second, the opposite of what Rust was doing. The queries I was testing with just happened to pass in #6120. This changes the implementation of `Conditions::from_directives` to pick the directives out manually instead of iterating. Technically, this does two iterations of the directive list...but, the code is a bit simpler, I think.
✅ Docs Preview ReadyNo new or changed pages found. |
@goto-bus-stop, please consider creating a changeset entry in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just one question/request. Otherwise, I like the refactoring!
"skip" => true, | ||
_ => continue, | ||
|
||
if let Some(skip) = directives.get("skip") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It appears that the directives
may have multiple skip/include directive applications. This will handle only one of each type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Per the spec @skip
and @include
are not repeatable so they cannot appear multiple times.
Ok(Self::from_variables(variables)) | ||
} | ||
|
||
// TODO(@goto-bus-stop): what exactly is the difference between this and `Self::merge`? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, merge
makes more sense. It's unclear why update_with
is so loose in the Boolean(false)
cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I played around a bit more with this code and learned what this actually does.
If you nested condition nodes, update_with()
will remove from the inner node those conditions that were already matched by the outer node. So it's very different from merge()
:)
I'll add a doc comment for that
CI performance tests
|
PR #6120 was the wrong solution. JS doesn't actually maintain the order
of the conditions, like I thought. Instead, it always puts
@skip
firstand
@include
second, the opposite of what Rust was doing.https://github.com/apollographql/federation/blob/cc4573471696ef78d04fa00c4cf8e5c50314ba9f/query-graphs-js/src/pathContext.ts#L13-L33
The queries I was testing with just happened to pass in #6120.
This changes the implementation of
Conditions::from_directives
topick the directives out manually instead of iterating. Technically, this
does two iterations of the directive list...but, the code is a bit
simpler, I think.
In the second commit I do a small refactor to replace the
is_negated
boolean by a
ConditionKind
enum. I found it quite tricky toconstantly translate the skip/include concepts to negation or not
while reading the code, so I hope this simplifies it a bit.