docs: graphql query with optional `where` can return incorrect results
See original GitHub issueBug summary
If a graphql query includes an optional where
clause which filters on a relation (e.g. Form(where: { opportunity: { id: { _eq: $opportunityId} } })
) and the variable associated with the where
clause is undefined
(i.e. the where
clause should be ignored) that query will always return an empty result set if the relation (in this case Form.opportunity
) has no records.
The example schema
- In the following schema, both
ContactList
andOpportunity
have one associatedForm
object.
CREATE TABLE "Form" (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
name text
);
CREATE TABLE "Opportunity" (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
"formId" uuid NOT NULL REFERENCES "Form" ("id") ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED
);
CREATE TABLE "ContactList" (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
"formId" uuid NOT NULL REFERENCES "Form" ("id") ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED
);
The example query
Assume the database contains one ContactList
record with an associated Form
record, but does not contain any Opportunity
records.
# Important! the `opportunityId` variable is undefined (i.e. should be ignored)
query FormQuery($opportunityId: uuid){
Form(where: {
opportunity: { id: { _eq: $opportunityId} }
}) {
id
name
}
}
Expected result
- A single
Form
object should be returned (the one associated with theContactList
)
Actual result
- An empty array is returned.
Reproduction
A reproduction can be seen here: https://hasura-issue-4214.herokuapp.com/console/api-explorer.
Issue Analytics
- State:
- Created 4 years ago
- Comments:6 (3 by maintainers)
Top Results From Across the Web
Error handling - Apollo GraphQL Docs
A client sent the hash of a query string to execute via automatic persisted queries, but the server has disabled APQ. OPERATION_RESOLUTION_FAILURE. The...
Read more >Queries and Mutations - GraphQL
On this page, you'll learn in detail about how to query a GraphQL server. Fields#. At its simplest, GraphQL is about asking for...
Read more >Nulls in GraphQL: Cheatsheet - Hasura
A GraphQL query can have fields and inputs, with or without variables. Fields are always optional, whether nullable or not. ... In inputs,...
Read more >Resolver mapping template programming guide - AWS AppSync
If you run your GraphQL query, the data will be returned as normal. However, if you change the id argument to something other...
Read more >Optional variable in Graphql - Stack Overflow
You'll just have to update the client that's actually issuing the query to use the right conditional logic regarding whether or not the ......
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
undefined
doesn’t exist in GraphQL. Your js client will probably not send the variable to the server when you it isundefined
or set it tonull
(depends on the client).At the server, if the variable is declared to be
nullable
(as is the case in your example) the variable having an explicitnull
or the variable being absent are treated the same, i.e, the variable gets anull
value. So your gets translated to this:So the behaviour that you are seeing is because of how we handle
null
values for_operator
fields. When we a see a clause like{_eq: null}
, we ignore it. However, in your case, you are doing it inside a relationship. Now your query becomes:which means that you are querying for forms where there exists an opportunity. To get the behaviour that you need you can either construct the
where
clause dynamically by making it a variable or user the_or
and_and
operators.@0x777 Thanks for the detailed explanation. This was very helpful and is very much needed in the documentation. I think the confusion arrises when developers start creating filterable lists. In my case I stated by adding filters via parameters e.g.
and these filters worked great for columns on
user
but not for something likeas it ends up filtering out all users that don’t have entries in
user_interests
when$interests
is not set (which is not immediately obvious IMO)As mentioned, using the
_and
to add dynamic elements to the query proved to be the best solution for me. E.g.Hope this simple example proves useful to others in a similar boat.