Empty list returned from nested filters, mis-assigned filter object #589
Description
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 GraphQLPlayground
I've reduced my query into the simplest reproducible state, showing:
Example Query
{
Department(filter: { id: 1 }) {
name
crew {
assignments(filter: { id: 1}) {
id
}
}
schedule {
# actuals (
# first: 0
# ) {
# value
# }
averageHoursOverrides(
filter: {hours_gte: 1}
) {
hours
}
}
}
}
Result 1
{
"data": {
"Department": [
{
"name": "Animation",
"crew": [assignment[], ...assignment[]], # populated correctly
"schedule": {
"averageHoursOverrides": [] #empty list
}
}
]
}
}
Enabling debug output shows the generated query:
MATCH (`department`:`Department`) WHERE (`department`.id = $filter.id) RETURN `department` { .name ,crew: [(`department`)<-[:`BELONGS_TO`]-(`department_crew`:`Crew`) | `department_crew` {assignments: [(`department_crew`)-[:`ASSIGNED_TO`]->(`department_crew_assignments`:`Assignment`) WHERE (`department_crew_assignments`.id = $1_filter.id) | `department_crew_assignments` { .id }] }] ,schedule: head([(`department`)-[:`HAS_SCHEDULE`]->(`department_schedule`:`Schedule`) | `department_schedule` {averageHoursOverrides: [(`department_schedule`)<-[:`CONNECTED_TO`]-(`department_schedule_averageHoursOverrides`:`AverageHoursOverride`) WHERE (`department_schedule_averageHoursOverrides`.hours >= $1_filter.hours_gte) | `department_schedule_averageHoursOverrides` { .hours }] }]) } AS `department`
With the filter object
{
"offset": 0,
"first": -1,
"filter": {
"id": 1
},
"1_filter": {
"id": 1
}
}
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:
{
"data": {
"Department": [
{
"name": "Animation",
"crew": [assignment[], ...assignment[]], # populated correctly
"schedule": {
"actuals": [], # empty list
"averageHoursOverrides": [<AverageHourOverride>] # populated correctly
}
}
]
}
}
Along with the generated query
MATCH (`department`:`Department`) WHERE (`department`.id = $filter.id) RETURN `department` { .name ,crew: [(`department`)<-[:`BELONGS_TO`]-(`department_crew`:`Crew`) | `department_crew` {assignments: [(`department_crew`)-[:`ASSIGNED_TO`]->(`department_crew_assignments`:`Assignment`) WHERE (`department_crew_assignments`.id = $1_filter.id) | `department_crew_assignments` { .id }] }] ,schedule: head([(`department`)-[:`HAS_SCHEDULE`]->(`department_schedule`:`Schedule`) | `department_schedule` {actuals: [(`department_schedule`)<-[:`CONNECTED_TO`]-(`department_schedule_actuals`:`Actuals`) | `department_schedule_actuals` { .crewWeeks }][..0] ,averageHoursOverrides: [(`department_schedule`)<-[:`CONNECTED_TO`]-(`department_schedule_averageHoursOverrides`:`AverageHoursOverride`) WHERE (`department_schedule_averageHoursOverrides`.hours >= $3_filter.hours_gte) | `department_schedule_averageHoursOverrides` { .hours }] }]) } AS `department`
And filter object
{
"offset": 0,
"first": -1,
"filter": {
"id": 1
},
"1_first": 0,
"3_filter": {
"hours_gte": 0
},
"1_filter": {
"id": 1
}
}
Again we have WHERE ('department_schedule_averageHoursOverrides'.hours >= $3_filter.hours_gte)
where $3_filter.hours_gte is correct
Summary
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.