graphql-compiler icon indicating copy to clipboard operation
graphql-compiler copied to clipboard

Add test for out-of order fold compilation for Cypher

Open LWprogramming opened this issue 6 years ago • 0 comments

Create a test for the behavior below, which produces the right result but is counter intuitive.

Consider the query:

graphql_input = '''
{
    Animal {
        name @output(out_name: "animal_name")
        in_Animal_ParentOf @fold {
            in_Animal_ParentOf {
                name @output(out_name: "grandparent_names_list")
            }
        }
        out_Animal_ParentOf {
            out_Animal_ParentOf @fold {
                name @output(out_name: "grandchild_names_list")
            }
        }
    }
}
'''

When compiled to Cypher, this becomes

MATCH (Animal___1:Animal)
MATCH (Animal___1)-[:Animal_ParentOf]->(Animal__out_Animal_ParentOf___1:Animal)
OPTIONAL MATCH (Animal___1)<-[:Animal_ParentOf]-(Animal__in_Animal_ParentOf___1:Animal)
OPTIONAL MATCH (Animal__in_Animal_ParentOf___1)<-[:Animal_ParentOf]-(Animal__in_Animal_ParentOf__in_Animal_ParentOf___1:Animal)
WITH
  Animal___1 AS Animal___1,
  Animal__out_Animal_ParentOf___1 AS Animal__out_Animal_ParentOf___1,
  collect(Animal__in_Animal_ParentOf___1) AS collected_Animal__in_Animal_ParentOf___1,
  collect(Animal__in_Animal_ParentOf__in_Animal_ParentOf___1) AS collected_Animal__in_Animal_ParentOf__in_Animal_ParentOf___1
OPTIONAL MATCH (Animal__out_Animal_ParentOf___1)-[:Animal_ParentOf]->(Animal__out_Animal_ParentOf__out_Animal_ParentOf___1:Animal)
WITH
  Animal___1 AS Animal___1,
  Animal__out_Animal_ParentOf___1 AS Animal__out_Animal_ParentOf___1,
  collected_Animal__in_Animal_ParentOf___1 AS collected_Animal__in_Animal_ParentOf___1,
  collected_Animal__in_Animal_ParentOf__in_Animal_ParentOf___1 AS collected_Animal__in_Animal_ParentOf__in_Animal_ParentOf___1,
  collect(Animal__out_Animal_ParentOf__out_Animal_ParentOf___1) AS collected_Animal__out_Animal_ParentOf__out_Animal_ParentOf___1
RETURN
  Animal___1.name AS `animal_name`,
  [x IN collected_Animal__out_Animal_ParentOf__out_Animal_ParentOf___1 | x.name] AS `grandchild_names_list`,
  [x IN collected_Animal__in_Animal_ParentOf__in_Animal_ParentOf___1 | x.name] AS `grandparent_names_list`

This is correct, but may be surprising the first time you see it.

The surprising thing here that the first traversal in the second scope is expanded first, since we extract all folds before emitting anything. Then, since we emit folds in sorted order (sorted by their corresponding FoldScopeLocations in CypherQuery’s folds attribute), the first traversal’s fold (Animal__in_Animal_ParentOf edge) is emitted, and finally the second fold is emitted. This is correct because you can re-order optional matches.

LWprogramming avatar Aug 16 '19 14:08 LWprogramming