Skip to content
This repository was archived by the owner on Sep 3, 2021. It is now read-only.

Commit 6e7a357

Browse files
Fix for issue #446 (#469)
* Fixes #446 Removes decideRelationTypeDirection as a result of refactoring the decision it was making when filtering the incoming direction of a relationship type. It had an undefined input argument for such cases, so a comparison was failing to ever result in swapping the variables for .from / .to nodes and reversing the relationship direction. This is done due to the use of a more static template once these variables get used to produce Cypher. Also removes a few unused function arguments * Adds test for #446 fix Issue #446 occured when filtering incoming relationships through a relationship type. This case was not tested in the TCK. Only outgoing cases were tested when querying from Person to Company, filtering over the `Person.employmentHistory` field. So a new test has been added that covers the reverse, querying from Company to Person, filtering over the `Company.employeeHistory` field.
1 parent f77e327 commit 6e7a357

File tree

2 files changed

+47
-55
lines changed

2 files changed

+47
-55
lines changed

src/translate.js

+24-54
Original file line numberDiff line numberDiff line change
@@ -333,9 +333,7 @@ export const relationTypeFieldOnNodeType = ({
333333
cypherParams
334334
}) => {
335335
if (innerSchemaTypeRelation.from === innerSchemaTypeRelation.to) {
336-
tailParams.initial = `${initial}${fieldName}: {${
337-
subSelection[0]
338-
}}${skipLimit} ${commaIfTail}`;
336+
tailParams.initial = `${initial}${fieldName}: {${subSelection[0]}}${skipLimit} ${commaIfTail}`;
339337
return [tailParams, subSelection];
340338
}
341339
const relationshipVariableName = `${nestedVariable}_relation`;
@@ -586,9 +584,7 @@ const directedNodeTypeFieldOnRelationType = ({
586584
}}]${!isArrayType(fieldType) ? ')' : ''}${skipLimit} ${commaIfTail}`;
587585
return [tailParams, subSelection];
588586
} else {
589-
tailParams.initial = `${initial}${fieldName}: ${variableName} {${
590-
subSelection[0]
591-
}}${skipLimit} ${commaIfTail}`;
587+
tailParams.initial = `${initial}${fieldName}: ${variableName} {${subSelection[0]}}${skipLimit} ${commaIfTail}`;
592588
// Case of a renamed directed field
593589
// e.g., 'from: Movie' -> 'Movie: Movie'
594590
return [tailParams, subSelection];
@@ -743,9 +739,7 @@ export const neo4jType = ({
743739
return {
744740
initial: `${initial}${fieldName}: ${
745741
fieldIsArray
746-
? `reduce(a = [], INSTANCE IN ${variableName}.${fieldName} | a + {${
747-
subSelection[0]
748-
}})${commaIfTail}`
742+
? `reduce(a = [], INSTANCE IN ${variableName}.${fieldName} | a + {${subSelection[0]}})${commaIfTail}`
749743
: temporalOrderingFieldExists(parentSchemaType, parentFilterParams)
750744
? `${safeVariableName}.${fieldName}${commaIfTail}`
751745
: `{${subSelection[0]}}${commaIfTail}`
@@ -2147,9 +2141,6 @@ const processFilterArgument = ({
21472141
schema
21482142
});
21492143
translations = translateFilterArguments({
2150-
fieldArgs,
2151-
params,
2152-
filterParamKey,
21532144
filterFieldMap,
21542145
filterCypherParam,
21552146
rootIsRelationType,
@@ -2440,9 +2431,6 @@ const deserializeFilterFieldName = name => {
24402431
};
24412432

24422433
const translateFilterArguments = ({
2443-
fieldArgs,
2444-
params,
2445-
filterParamKey,
24462434
filterFieldMap,
24472435
filterCypherParam,
24482436
variableName,
@@ -2460,9 +2448,6 @@ const translateFilterArguments = ({
24602448
filterValue: value,
24612449
rootIsRelationType,
24622450
variableName,
2463-
fieldArgs,
2464-
params,
2465-
filterParamKey,
24662451
schemaType,
24672452
schema
24682453
});
@@ -2483,9 +2468,6 @@ const translateFilterArgument = ({
24832468
fieldName,
24842469
rootIsRelationType,
24852470
variableName,
2486-
fieldArgs,
2487-
params,
2488-
filterParamKey,
24892471
filterParam,
24902472
parentSchemaType,
24912473
schemaType,
@@ -2544,9 +2526,6 @@ const translateFilterArgument = ({
25442526
filterValue,
25452527
variableName,
25462528
fieldName,
2547-
fieldArgs,
2548-
params,
2549-
filterParamKey,
25502529
filterParam,
25512530
schema,
25522531
parentSchemaType,
@@ -2744,9 +2723,6 @@ const translateInputFilter = ({
27442723
filterValue,
27452724
variableName,
27462725
fieldName,
2747-
fieldArgs,
2748-
params,
2749-
filterParamKey,
27502726
filterParam,
27512727
schema,
27522728
parentSchemaType,
@@ -2788,7 +2764,6 @@ const translateInputFilter = ({
27882764
isReflexiveTypeDirectedField
27892765
] = decideRelationFilterMetadata({
27902766
fieldName,
2791-
parentSchemaType,
27922767
schemaType,
27932768
variableName,
27942769
innerSchemaType,
@@ -2995,7 +2970,6 @@ const translateRelationFilter = ({
29952970

29962971
const decideRelationFilterMetadata = ({
29972972
fieldName,
2998-
parentSchemaType,
29992973
schemaType,
30002974
variableName,
30012975
innerSchemaType,
@@ -3028,28 +3002,39 @@ const decideRelationFilterMetadata = ({
30283002
relatedType = typeVariables.typeName;
30293003
} else if (innerRelationTypeDirective) {
30303004
isRelationType = true;
3031-
[thisType, relatedType, relDirection] = decideRelationTypeDirection(
3032-
schemaType,
3033-
innerRelationTypeDirective
3034-
);
3005+
thisType = innerRelationTypeDirective.from;
3006+
relatedType = innerRelationTypeDirective.to;
3007+
relLabel = innerRelationTypeDirective.name;
3008+
relDirection = 'OUT';
30353009
if (thisType === relatedType) {
30363010
isReflexiveRelationType = true;
30373011
if (fieldName === 'from') {
30383012
isReflexiveTypeDirectedField = true;
30393013
relDirection = 'IN';
30403014
} else if (fieldName === 'to') {
30413015
isReflexiveTypeDirectedField = true;
3042-
relDirection = 'OUT';
30433016
}
30443017
}
3045-
relLabel = innerRelationTypeDirective.name;
30463018
} else if (relationTypeDirective) {
30473019
isRelationTypeNode = true;
3048-
[thisType, relatedType, relDirection] = decideRelationTypeDirection(
3049-
parentSchemaType,
3050-
relationTypeDirective
3051-
);
3020+
thisType = relationTypeDirective.from;
3021+
relatedType = relationTypeDirective.to;
30523022
relLabel = variableName;
3023+
relDirection = 'OUT';
3024+
// if not a reflexive relationship type
3025+
if (thisType !== relatedType) {
3026+
const filteredType =
3027+
innerSchemaType && innerSchemaType.name ? innerSchemaType.name : '';
3028+
// then the connecting node type field on a relationship type filter
3029+
// may be incoming or outgoing; thisType could be .from or .to
3030+
if (filteredType === thisType) {
3031+
// then a filter argument for the incoming direction is being used
3032+
// when querying the node type it goes out from
3033+
thisType = relatedType;
3034+
relatedType = filteredType;
3035+
relDirection = 'IN';
3036+
}
3037+
}
30533038
}
30543039
return [
30553040
thisType,
@@ -3064,21 +3049,6 @@ const decideRelationFilterMetadata = ({
30643049
];
30653050
};
30663051

3067-
const decideRelationTypeDirection = (schemaType, relationTypeDirective) => {
3068-
let fromType = relationTypeDirective.from;
3069-
let toType = relationTypeDirective.to;
3070-
let relDirection = 'OUT';
3071-
if (fromType !== toType) {
3072-
if (schemaType && schemaType.name === toType) {
3073-
const temp = fromType;
3074-
fromType = toType;
3075-
toType = temp;
3076-
relDirection = 'IN';
3077-
}
3078-
}
3079-
return [fromType, toType, relDirection];
3080-
};
3081-
30823052
const buildRelationPredicate = ({
30833053
rootIsRelationType,
30843054
parentFieldName,

test/helpers/tck/filterTck.md

+23-1
Original file line numberDiff line numberDiff line change
@@ -2350,7 +2350,7 @@ MATCH (`person`:`Person`) WHERE (EXISTS((`person`)-[:WORKS_AT]->(:Company)) AND
23502350
MATCH (`person`:`Person`) WHERE (`person`.name = $filter.name) AND (EXISTS((`person`)-[:WORKS_AT]->(:Company)) AND ALL(`company` IN [(`person`)-[:WORKS_AT]->(`_company`:Company) | `_company`] WHERE (`company`.name = $filter.company.name))) RETURN `person` { .name ,company: head([(`person`)-[:`WORKS_AT`]->(`person_company`:`Company`) WHERE (`person_company`.name = $1_filter.name) AND (((`person_company`.founded.year = $1_filter.founded.year))) | `person_company` { .name }]) } AS `person`
23512351
```
23522352

2353-
### Nested filter on relationship type field
2353+
### Nested filter on relationship type field (filter outgoing)
23542354

23552355
```graphql
23562356
{
@@ -2374,6 +2374,28 @@ MATCH (`person`:`Person`) WHERE (`person`.name = $filter.name) AND (EXISTS((`per
23742374
MATCH (`person`:`Person`) WHERE (`person`.name = $filter.name) RETURN `person` { .name ,employmentHistory: [(`person`)-[`person_employmentHistory_relation`:`WORKED_AT`]->(:`Company`) WHERE (`person_employmentHistory_relation`.role = $1_filter.role) AND (ALL(`person_filter_company` IN [(`person`)-[`person_employmentHistory_relation`]->(`_company`:Company) | `_company`] WHERE (`person_filter_company`.name = $1_filter.Company.name))) | person_employmentHistory_relation {start: { year: `person_employmentHistory_relation`.start.year },Company: head([(:`Person`)-[`person_employmentHistory_relation`]->(`person_employmentHistory_Company`:`Company`) | person_employmentHistory_Company { .name }]) }] } AS `person`
23752375
```
23762376

2377+
### Nested filter on relationship type field (filter incoming)
2378+
2379+
```graphql
2380+
{
2381+
Company(filter: { name: "Neo4j" }) {
2382+
name
2383+
employeeHistory(filter: { role: "Developer", Person: { name: "jane" } }) {
2384+
start {
2385+
year
2386+
}
2387+
Person {
2388+
name
2389+
}
2390+
}
2391+
}
2392+
}
2393+
```
2394+
2395+
```cypher
2396+
MATCH (`company`:`Company`) WHERE (`company`.name = $filter.name) RETURN `company` { .name ,employeeHistory: [(`company`)<-[`company_employeeHistory_relation`:`WORKED_AT`]-(:`Person`) WHERE (`company_employeeHistory_relation`.role = $1_filter.role) AND (ALL(`company_filter_person` IN [(`company`)<-[`company_employeeHistory_relation`]-(`_person`:Person) | `_person`] WHERE (`company_filter_person`.name = $1_filter.Person.name))) | company_employeeHistory_relation {start: { year: `company_employeeHistory_relation`.start.year },Person: head([(:`Company`)<-[`company_employeeHistory_relation`]-(`company_employeeHistory_Person`:`Person`) | company_employeeHistory_Person { .name }]) }] } AS `company`
2397+
```
2398+
23772399
### Nested filters on reflexive relationship type field
23782400

23792401
```graphql

0 commit comments

Comments
 (0)