Open henrygeddes opened 3 years ago
PR for temporary fix I've spent a bit of time looking into this issue as it was affecting multiple queries on a work related project. I have found a temporary fix which I've created a PR for: https://github.com/neo4j-graphql/neo4j-graphql-js/pull/606
What I discovered:
buildCypherSelection
fails to set the filter object for nested queries. This is due to paramIndex being reset for each sub query, which then overwrites an existing filter in the filter object.
Example query:
{
Department(filter: { id: "department-id" }) {
crew {
leave(filter: {id: "leave"}){
id
}
assignments(filter: { id: "crewAssignments"}) {
id
}
}
vendorInstances {
assignments(filter: { id: "vendorAssignments"}) {
id
}
department(filter: { id: "department"}) {
id
}
}
}
}
As this object is built recursively the filters for the second sub query are applied first:
1_filter: { id: "vendorAssignments"}
3_filter: { id: "department"}
paramIndex
is then reset to 1 for the next subquery, which then overwrites the above object with:
1_filter: { id: "leave" }
3_filter: { id: "crewAssignments" }
This gives us a final filter object of:
{
"offset": 0,
"first": -1,
"filter": {
"id": "department-id"
},
"1_filter": {
"id": "leave"
},
"3_filter": {
"id": "crewAssignments"
},
"cypherParams": {
"username": "<removed>"
}
}
As a temporary fix I have added an additional parameter to buildCypherSelection
which tracks paramIndex's that have already been used. Then instead of incrementing paramIndex
we use getNextParamIndex
which finds the highest used index and increments it by 1. This ensures paramIndex
is always unique for any part of the selection.
This results in a filter object of:
neo4j-graphql-js {
"offset": 0,
"first": -1,
"filter": {
"id": "department-id"
},
"11_filter": {
"id": "vendorAssignments"
},
"14_filter": {
"id": "department"
},
"2_filter": {
"id": "leave"
},
"5_filter": {
"id": "crewAssignments"
},
"cypherParams": {
"username": "<removed>"
}
}
This is a pretty hacky fix that is intended as a temporary solution (and to help explain the core issue). Our project is now using a fork with this fix and it is working as intended, but I understand there's likely a much better way to handle this. I'm also aware that you are planning on refactoring recurse
and paramIndex
which will probably fix this issue.
@michaeldgraham
If you need any more information or have any questions please feel free to contact me (reply to this issue and I'll give you my personal email).
I've recently run into a bug which causes the first list of a sub node of a query return as empty.
We are using:
neo4j-graphql-js: ^2.19.2
apollo-server: ^2.20.0
neo4j:4.1.1
(Docker) Tested through GraphQLPlaygroundI've reduced my query into the simplest reproducible state, showing:
Example Query
Result 1
Enabling debug output shows the generated query:
With the filter object
Note in the filter for AverageHoursOverride,
WHERE ('department_schedule_averageHoursOverrides'.hours >= $1_filter.hours_gte
$1_filter.hours_gte does not exist (and instead this filter item takes the value of the first filter)Result 2 By uncommenting
actuals
(another list), we get the response:Along with the generated query
And filter object
Again we have
WHERE ('department_schedule_averageHoursOverrides'.hours >= $3_filter.hours_gte)
where $3_filter.hours_gte is correctSummary It looks like something is causing the second filter item to be mis-assigned, taking the value of the first filter. This only occurs for the second filter, all subsequent filters take the correct value.
Please let me know if there's anymore information I can provide.