-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Description
When a query with an obligatory variable $myId with a default value, such as 1, is cached, the value in the query plan that is saved is the value that is used at the time of saving (e.g. 2, since a value for $myId may have been provided with the query). This means that any subsequent call to the same query, that does not specify $myId, incorrectly uses that same value saved at the time of the first call, i.e. 2 in this example, even though a default value of 1 was specified in the query.
To reproduce, launch graphql-engine with a single capability, e.g. as:
$ cabal new-run --project-file=cabal.project.dev-sh --RTS -- exe:graphql-engine +RTS -N1 -T -RTS --database-url=postgres://postgres:postgres@127.0.0.1:25432/postgres serve --enable-console --console-assets-dir /somewhere/change/this/.../graphql-engine/console/static/distThen create a test table with a single column id (integer auto-increment), and create two entries. Open the console and run:
query MyQuery($myId :Int! = 1) {
test(where: {id: {_eq: $myId}}) {
id
}
}Query variables:
{"myId": 2}Observe that the item with id 2 is returned (as expected).
Now remove the query variables, and run the same query again, so that we expect to get the entry with id 1. Instead,
{
"data": {
"test": [
{
"id": 2
}
]
}
}The origin of this problem lies in the fact that the query plan that gets saved (generated by Hasura.GraphQL.Validate.validateGQ) incorporates the provided values. I suspect we'll need to refactor these functions somewhat. I would prefer to separate the query validation from the variable validation much more strongly, so that we can validate and cache the query plan independently from the query variables. Such separation would have probably avoided #3773, and its unreported variant for subscriptions (the latter is briefly discussed in #4538).