diff --git a/cypherv2/convertQuery.go b/cypherv2/convertQuery.go index 111a71a43cd8a73029b03e8f508d50533014b35f..a08c94e44cf1ce3be603977ae5ebfa590ad3e3bc 100755 --- a/cypherv2/convertQuery.go +++ b/cypherv2/convertQuery.go @@ -346,11 +346,9 @@ func formQuery(JSONQuery *entityv2.IncomingQueryJSON) (*string, error) { for _, relation := range cacheData.relations { // if we need to do logic on relations, this with is required - withLine := fmt.Sprintf("WITH *, relationships(%s) AS %s_rel\n", relation.queryId, relation.queryId) - if relation.queryId != "" && strings.Contains(logic, relation.id) && !strings.Contains(totalQuery, withLine) { - totalQuery += withLine - logic = fmt.Sprintf("ALL(%s_rel_%s in %s_rel WHERE %s)", - relation.queryId, relation.id, relation.queryId, + if relation.queryId != "" && strings.Contains(logic, relation.id) { + logic = fmt.Sprintf("ALL(%s_rel_%s in %s WHERE %s)", + relation.queryId, relation.id, relation.id, strings.ReplaceAll(logic, relation.id, fmt.Sprintf("%s_rel_%s", relation.queryId, relation.id))) } } diff --git a/cypherv2/convertQuery_test.go b/cypherv2/convertQuery_test.go index e6b3918b0600ae4c4d6d6301c2340ec2dea18cea..0da55300e71638c6fabc30688cca02c416cee2c5 100755 --- a/cypherv2/convertQuery_test.go +++ b/cypherv2/convertQuery_test.go @@ -662,8 +662,7 @@ func TestV2RelationLogic(t *testing.T) { t.Log(*cypher) answer := `MATCH path_0 = (()-[id_1698231933579:CONTAINS*0..1]->()) - WITH *, relationships(path_0) AS path_0_rel - WHERE ALL(path_0_rel_id_1698231933579 in path_0_rel WHERE (path_0_rel_id_1698231933579.unitPrice < 10)) + WHERE ALL(path_0_rel_id_1698231933579 in id_1698231933579 WHERE (path_0_rel_id_1698231933579.unitPrice < 10)) RETURN * LIMIT 500` @@ -674,1418 +673,73 @@ func TestV2RelationLogic(t *testing.T) { assert.Equal(t, trimmedAnswer, trimmedCypher) } -// func TestSmallChain(t *testing.T) { -// query := []byte(`{ -// "databaseName": "TweedeKamer", -// "return": { -// "entities": [ -// 0, -// 1, -// 2 -// ], -// "relations": [ -// 0, -// 1 -// ] -// }, -// "entities": [ -// { -// "name": "parliament", -// "ID": 0, -// "constraints": [ -// { -// "attribute": "name", -// "value": "Geert", -// "dataType": "string", -// "matchType": "contains", -// "inID": -1, -// "inType": "" -// } -// ] -// }, -// { -// "name": "parties", -// "ID": 1, -// "constraints": [] -// }, -// { -// "name": "resolutions", -// "ID": 2, -// "constraints": [] -// } -// ], -// "relations": [ -// { -// "ID": 0, -// "name": "member_of", -// "depth": { -// "min": 1, -// "max": 1 -// }, -// "fromType": "entity", -// "fromID": 0, -// "toType": "entity", -// "toID": 1, -// "constraints": [] -// }, -// { -// "ID": 1, -// "name": "submits", -// "depth": { -// "min": 1, -// "max": 1 -// }, -// "fromType": "entity", -// "fromID": 0, -// "toType": "entity", -// "toID": 2, -// "constraints": [] -// } -// ], -// "groupBys": [], -// "machineLearning": [], -// "limit": 5000 -// } -// `) - -// var JSONQuery entity.IncomingQueryJSON -// json.Unmarshal(query, &JSONQuery) - -// s := NewService() -// cypher, _, err := s.ConvertQuery(&JSONQuery) -// if err != nil { -// fmt.Println(err) -// } - -// answer := `MATCH p0 = (e0:parliament)-[:member_of*1..1]-(e1:parties) -// WHERE e0.name CONTAINS "%Geert%" -// UNWIND relationships(p0) as r0 -// WITH * -// MATCH p1 = (e0:parliament)-[:submits*1..1]-(e2:resolutions) -// WHERE e0.name CONTAINS "%Geert%" -// UNWIND relationships(p1) as r1 -// WITH * -// UNWIND [r1,e0,e2,r0,e0,e1] AS x -// RETURN DISTINCT x -// LIMIT 5000;nodelink` - -// trimmedCypher := fixCypherSpaces(cypher) -// trimmedAnswer := fixCypherSpaces(&answer) - -// assert.Equal(t, trimmedAnswer, trimmedCypher) - -// } - -// // This one does not really have dependencies, the order doesnt matter, maybe sort on numbers between equal dependencies? -// func TestLargeQueryChain(t *testing.T) { -// query := []byte(`{ -// "databaseName": "TweedeKamer", -// "return": { -// "entities": [ -// 0, -// 1, -// 2, -// 3, -// 4 -// ], -// "relations": [ -// 0, -// 1, -// 2, -// 3 -// ] -// }, -// "entities": [ -// { -// "name": "parliament", -// "ID": 0, -// "constraints": [ -// { -// "attribute": "name", -// "value": "A", -// "dataType": "string", -// "matchType": "contains", -// "inID": -1, -// "inType": "" -// } -// ] -// }, -// { -// "name": "parties", -// "ID": 1, -// "constraints": [ -// { -// "attribute": "seats", -// "value": "10", -// "dataType": "int", -// "matchType": "LT", -// "inID": -1, -// "inType": "" -// } -// ] -// }, -// { -// "name": "resolutions", -// "ID": 2, -// "constraints": [ -// { -// "attribute": "date", -// "value": "mei", -// "dataType": "string", -// "matchType": "contains", -// "inID": -1, -// "inType": "" -// } -// ] -// }, -// { -// "name": "parliament", -// "ID": 3, -// "constraints": [] -// }, -// { -// "name": "parties", -// "ID": 4, -// "constraints": [ -// { -// "attribute": "name", -// "value": "Volkspartij voor Vrijheid en Democratie", -// "dataType": "string", -// "matchType": "==", -// "inID": -1, -// "inType": "" -// } -// ] -// } -// ], -// "relations": [ -// { -// "ID": 0, -// "name": "member_of", -// "depth": { -// "min": 1, -// "max": 1 -// }, -// "fromType": "entity", -// "fromID": 0, -// "toType": "entity", -// "toID": 1, -// "constraints": [] -// }, -// { -// "ID": 1, -// "name": "submits", -// "depth": { -// "min": 1, -// "max": 1 -// }, -// "fromType": "entity", -// "fromID": 1, -// "toType": "entity", -// "toID": 2, -// "constraints": [] -// }, -// { -// "ID": 2, -// "name": "submits", -// "depth": { -// "min": 1, -// "max": 1 -// }, -// "fromType": "entity", -// "fromID": 2, -// "toType": "entity", -// "toID": 3, -// "constraints": [] -// }, -// { -// "ID": 3, -// "name": "member_of", -// "depth": { -// "min": 1, -// "max": 1 -// }, -// "fromType": "entity", -// "fromID": 3, -// "toType": "entity", -// "toID": 4, -// "constraints": [] -// } -// ], -// "groupBys": [], -// "machineLearning": [], -// "limit": 5000 -// } - -// `) - -// var JSONQuery entity.IncomingQueryJSON -// json.Unmarshal(query, &JSONQuery) - -// s := NewService() -// cypher, _, err := s.ConvertQuery(&JSONQuery) -// if err != nil { -// fmt.Println(err) -// } - -// answer := `MATCH p0 = (e0:parliament)-[:member_of*1..1]-(e1:parties) -// WHERE e0.name CONTAINS "%A%" -// AND e1.seats < 10 -// UNWIND relationships(p0) as r0 -// WITH * -// MATCH p1 = (e1:parties)-[:submits*1..1]-(e2:resolutions) -// WHERE e1.seats < 10 -// AND e2.date CONTAINS "%mei%" -// UNWIND relationships(p1) as r1 -// WITH * -// MATCH p2 = (e2:resolutions)-[:submits*1..1]-(e3:parliament) -// WHERE e2.date CONTAINS "%mei%" -// UNWIND relationships(p2) as r2 -// WITH * -// MATCH p3 = (e3:parliament)-[:member_of*1..1]-(e4:parties) -// WHERE e4.name = "Volkspartij voor Vrijheid en Democratie" -// UNWIND relationships(p3) as r3 -// WITH * -// UNWIND [r3,e3,e4,r2,e2,e3,r1,e1,e2,r0,e0,e1] AS x -// RETURN DISTINCT x -// LIMIT 5000;nodelink` - -// trimmedCypher := fixCypherSpaces(cypher) -// trimmedAnswer := fixCypherSpaces(&answer) - -// assert.Equal(t, trimmedAnswer, trimmedCypher) - -// } - -// func TestInStatement(t *testing.T) { -// query := []byte(`{ -// "databaseName": "Movies3", -// "entities": [ -// { -// "id": 0, -// "name": "Person", -// "constraints": [] -// }, -// { -// "id": 1, -// "name": "Movie", -// "constraints": [] -// }, -// { -// "id": 2, -// "name": "Person", -// "constraints": [ -// { -// "attribute": "bornIn", -// "value": "", -// "dataType": "string", -// "matchType": "", -// "inID": 0, -// "inType": "groupBy" -// } -// ] -// } -// ], -// "relations": [ -// { -// "id": 0, -// "name": "ACTED_IN", -// "depth": { -// "min": 1, -// "max": 1 -// }, -// "fromType": "entity", -// "fromID": 0, -// "toType": "entity", -// "toID": 1, -// "constraints": [] -// } -// ], -// "groupBys": [ -// { -// "id": 0, -// "groupType": "entity", -// "groupID": [1], -// "groupAttribute": "imdbRating", -// "byType": "entity", -// "byID": [0], -// "byAttribute": "bornIn", -// "appliedModifier": "AVG", -// "relationID": 0, -// "constraints": [ -// { -// "attribute": "imdbRating", -// "value": "7.5", -// "dataType": "int", -// "matchType": "GT", -// "inID": -1, -// "inType": "" -// } -// ] -// } -// ], -// "machineLearning": [], -// "limit": 5000 -// } -// `) - -// answer := `MATCH p0 = (e0:Person)-[:ACTED_IN*1..1]-(e1:Movie) -// UNWIND relationships(p0) as r0 -// WITH * -// WITH e0.bornIn AS e0_bornIn, AVG(e1.imdbRating) AS AVG_imdbRating -// WHERE AVG_imdbRating > 7.5 -// MATCH (e2:Person) -// WHERE e2.bornIn IN e0_bornIn -// WITH * -// UNWIND [e2] AS x -// RETURN DISTINCT x -// LIMIT 5000;nodelink` - -// var JSONQuery entity.IncomingQueryJSON -// json.Unmarshal(query, &JSONQuery) - -// s := NewService() -// cypher, _, err := s.ConvertQuery(&JSONQuery) -// if err != nil { -// fmt.Println(err) -// } - -// trimmedCypher := fixCypherSpaces(cypher) -// trimmedAnswer := fixCypherSpaces(&answer) -// assert.Equal(t, trimmedAnswer, trimmedCypher) - -// } -// func TestMultipleByStatementDisconnected(t *testing.T) { -// query := []byte(`{ -// "databaseName": "Movies3", -// "entities": [ -// { -// "id": 0, -// "name": "Person", -// "constraints": [] -// }, -// { -// "id": 1, -// "name": "Movie", -// "constraints": [] -// }, -// { -// "id": 2, -// "name": "Person", -// "constraints": [] -// }, -// { -// "id": 3, -// "name": "Movie", -// "constraints": [] -// } -// ], -// "relations": [ -// { -// "id": 0, -// "name": "ACTED_IN", -// "depth": { -// "min": 1, -// "max": 1 -// }, -// "fromType": "entity", -// "fromID": 0, -// "toType": "entity", -// "toID": 1, -// "constraints": [] -// }, -// { -// "id": 2, -// "name": "ACTED_IN", -// "depth": { -// "min": 1, -// "max": 1 -// }, -// "fromType": "entity", -// "fromID": 2, -// "toType": "entity", -// "toID": 3, -// "constraints": [] -// } -// ], -// "groupBys": [ -// { -// "id": 0, -// "groupType": "entity", -// "groupID": [1,3], -// "groupAttribute": "imdbRating", -// "byType": "entity", -// "byID": [0,2], -// "byAttribute": "bornIn", -// "appliedModifier": "AVG", -// "relationID": 0, -// "constraints": [ -// { -// "attribute": "imdbRating", -// "value": "7.5", -// "dataType": "int", -// "matchType": "GT", -// "inID": -1, -// "inType": "" -// } -// ] -// } -// ], -// "machineLearning": [], -// "limit": 5000 -// } -// `) - -// answer := `MATCH p0 = (e0:Person)-[:ACTED_IN*1..1]-(e1:Movie) -// UNWIND relationships(p0) as r0 -// WITH * -// MATCH p1 = (e2:Person)-[:ACTED_IN*1..1]-(e3:Movie) -// UNWIND relationships(p1) as r2 -// WITH * -// UNWIND [e0,e2] AS e02L -// UNWIND [e1,e3] AS e13L -// WITH e02L.bornIn AS e02L_bornIn, AVG(e13L.imdbRating) AS AVG_imdbRating -// WHERE AVG_imdbRating > 7.5 -// RETURN e02L_bornIn, AVG_imdbRating -// LIMIT 5000;table` - -// var JSONQuery entity.IncomingQueryJSON -// json.Unmarshal(query, &JSONQuery) - -// s := NewService() -// cypher, _, err := s.ConvertQuery(&JSONQuery) -// if err != nil { -// fmt.Println(err) -// } - -// trimmedCypher := fixCypherSpaces(cypher) -// trimmedAnswer := fixCypherSpaces(&answer) -// assert.Equal(t, trimmedAnswer, trimmedCypher) - -// } -// func TestDoubleInStatement(t *testing.T) { -// query := []byte(`{ -// "databaseName": "Movies3", -// "entities": [ -// { -// "id": 0, -// "name": "Person", -// "constraints": [] -// }, -// { -// "id": 1, -// "name": "Movie", -// "constraints": [] -// }, -// { -// "id": 2, -// "name": "Person", -// "constraints": [ -// { -// "attribute": "bornIn", -// "value": "", -// "dataType": "string", -// "matchType": "", -// "inID": 0, -// "inType": "groupBy" -// } -// ] -// }, -// { -// "id": 3, -// "name": "Person", -// "constraints": [ -// { -// "attribute": "bornIn", -// "value": "", -// "dataType": "string", -// "matchType": "", -// "inID": 0, -// "inType": "groupBy" -// } -// ] -// } -// ], -// "relations": [ -// { -// "id": 0, -// "name": "ACTED_IN", -// "depth": { -// "min": 1, -// "max": 1 -// }, -// "fromType": "entity", -// "fromID": 0, -// "toType": "entity", -// "toID": 1, -// "constraints": [] -// } -// ], -// "groupBys": [ -// { -// "id": 0, -// "groupType": "entity", -// "groupID": [1], -// "groupAttribute": "imdbRating", -// "byType": "entity", -// "byID": [0], -// "byAttribute": "bornIn", -// "appliedModifier": "AVG", -// "relationID": 0, -// "constraints": [ -// { -// "attribute": "imdbRating", -// "value": "7.5", -// "dataType": "int", -// "matchType": "GT", -// "inID": -1, -// "inType": "" -// } -// ] -// } -// ], -// "machineLearning": [], -// "limit": 5000 -// } -// `) - -// answer := `MATCH p0 = (e0:Person)-[:ACTED_IN*1..1]-(e1:Movie) -// UNWIND relationships(p0) as r0 -// WITH * -// WITH e0.bornIn AS e0_bornIn, AVG(e1.imdbRating) AS AVG_imdbRating -// WHERE AVG_imdbRating > 7.5 -// MATCH (e2:Person) -// WHERE e2.bornIn IN e0_bornIn -// WITH * -// MATCH (e3:Person) -// WHERE e3.bornIn IN e0_bornIn -// WITH * -// UNWIND [e3] AS x -// RETURN DISTINCT x -// LIMIT 5000;nodelink` - -// var JSONQuery entity.IncomingQueryJSON -// json.Unmarshal(query, &JSONQuery) - -// s := NewService() -// cypher, _, err := s.ConvertQuery(&JSONQuery) -// if err != nil { -// fmt.Println(err) -// } - -// trimmedCypher := fixCypherSpaces(cypher) -// trimmedAnswer := fixCypherSpaces(&answer) -// assert.Equal(t, trimmedAnswer, trimmedCypher) - -// } -// func TestEndOnGroupBy(t *testing.T) { -// query := []byte(`{ -// "return": { -// "entities": [ -// 11, -// 12 -// ], -// "relations": [ -// 10 -// ], -// "groupBys": [ -// 1 -// ] -// }, -// "entities": [ -// { -// "name": "Person", -// "ID": 11, -// "constraints": [] -// }, -// { -// "name": "Movie", -// "ID": 12, -// "constraints": [] -// } -// ], -// "relations": [ -// { -// "ID": 10, -// "name": "DIRECTED", -// "depth": { -// "min": 1, -// "max": 1 -// }, -// "fromType": "entity", -// "fromID": 11, -// "toType": "entity", -// "toID": 12, -// "constraints": [] -// } -// ], -// "groupBys": [ -// { -// "id": 0, -// "groupType": "entity", -// "groupID": [11], -// "groupAttribute": "imdbRating", -// "byType": "entity", -// "byID": [12], -// "byAttribute": "bornIn", -// "appliedModifier": "AVG", -// "relationID": 10, -// "constraints": [] -// } -// ], -// "machineLearning": [], -// "limit": 5000, -// "databaseName": "Movies3" -// } -// `) - -// answer := `MATCH p0 = (e11:Person)-[:DIRECTED*1..1]-(e12:Movie) -// UNWIND relationships(p0) as r10 -// WITH * -// WITH e12.bornIn AS e12_bornIn, AVG(e11.imdbRating) AS AVG_imdbRating -// RETURN e12_bornIn, AVG_imdbRating -// LIMIT 5000;table` - -// var JSONQuery entity.IncomingQueryJSON -// json.Unmarshal(query, &JSONQuery) - -// s := NewService() -// cypher, _, err := s.ConvertQuery(&JSONQuery) -// if err != nil { -// fmt.Println(err) -// } - -// trimmedCypher := fixCypherSpaces(cypher) -// trimmedAnswer := fixCypherSpaces(&answer) -// assert.Equal(t, trimmedAnswer, trimmedCypher) -// } -// func TestSimpleQuery(t *testing.T) { -// query := []byte(`{ -// "return": { -// "entities": [ -// 11, -// 12 -// ], -// "relations": [ -// 10 -// ], -// "groupBys": [] -// }, -// "entities": [ -// { -// "name": "Person", -// "ID": 11, -// "constraints": [] -// }, -// { -// "name": "Movie", -// "ID": 12, -// "constraints": [] -// } -// ], -// "relations": [ -// { -// "ID": 10, -// "name": "DIRECTED", -// "depth": { -// "min": 1, -// "max": 1 -// }, -// "fromType": "entity", -// "fromID": 11, -// "toType": "entity", -// "toID": 12, -// "constraints": [] -// } -// ], -// "groupBys": [], -// "machineLearning": [], -// "limit": 5000, -// "databaseName": "Movies3" -// } -// `) - -// answer := `MATCH p0 = (e11:Person)-[:DIRECTED*1..1]-(e12:Movie) -// UNWIND relationships(p0) as r10 -// WITH * -// UNWIND [r10,e11,e12] AS x -// RETURN DISTINCT x -// LIMIT 5000;nodelink` - -// var JSONQuery entity.IncomingQueryJSON -// json.Unmarshal(query, &JSONQuery) - -// s := NewService() -// cypher, _, err := s.ConvertQuery(&JSONQuery) -// if err != nil { -// fmt.Println(err) -// } - -// trimmedCypher := fixCypherSpaces(cypher) -// trimmedAnswer := fixCypherSpaces(&answer) -// assert.Equal(t, trimmedAnswer, trimmedCypher) -// } -// func TestNoRelation(t *testing.T) { -// query := []byte(`{ -// "return": { -// "entities": [ -// 11, -// 12 -// ], -// "relations": [ -// 10 -// ], -// "groupBys": [] -// }, -// "entities": [ -// { -// "name": "Person", -// "ID": 11, -// "constraints": [] -// }, -// { -// "name": "Movie", -// "ID": 12, -// "constraints": [] -// } -// ], -// "relations": [], -// "groupBys": [], -// "machineLearning": [], -// "limit": 5000, -// "databaseName": "Movies3" -// } -// `) - -// var JSONQuery entity.IncomingQueryJSON -// json.Unmarshal(query, &JSONQuery) -// fmt.Println(JSONQuery) -// fmt.Println(" ") - -// s := NewService() -// _, _, err := s.ConvertQuery(&JSONQuery) -// if err != nil { -// assert.Equal(t, err.Error(), "Invalid query") -// } else { -// // It should error, thus it must not reach this -// t.Fail() -// } -// } - -// func TestNoEntities(t *testing.T) { -// query := []byte(`{ -// "return": { -// "entities": [ -// 11, -// 12 -// ], -// "relations": [ -// 10 -// ], -// "groupBys": [] -// }, -// "entities": [], -// "relations": [ -// { -// "ID": 10, -// "name": "DIRECTED", -// "depth": { -// "min": 1, -// "max": 1 -// }, -// "fromType": "entity", -// "fromID": 11, -// "toType": "entity", -// "toID": 12, -// "constraints": [] -// } -// ], -// "groupBys": [], -// "machineLearning": [], -// "limit": 5000, -// "databaseName": "Movies3" -// } -// `) - -// var JSONQuery entity.IncomingQueryJSON -// json.Unmarshal(query, &JSONQuery) -// fmt.Println(JSONQuery) -// fmt.Println(" ") - -// s := NewService() -// _, _, err := s.ConvertQuery(&JSONQuery) -// if err != nil { -// assert.Equal(t, err.Error(), "Invalid query") -// } else { -// // It should error, thus it must not reach this -// t.Fail() -// } -// } -// func TestTwoRelationsCycle(t *testing.T) { -// query := []byte(`{ -// "return": { -// "entities": [ -// 11, -// 12 -// ], -// "relations": [ -// 10 -// ], -// "groupBys": [] -// }, -// "entities": [ -// { -// "name": "Person", -// "ID": 11, -// "constraints": [] -// }, -// { -// "name": "Movie", -// "ID": 12, -// "constraints": [] -// } -// ], -// "relations": [ -// { -// "ID": 10, -// "name": "DIRECTED", -// "depth": { -// "min": 1, -// "max": 1 -// }, -// "fromType": "entity", -// "fromID": 11, -// "toType": "entity", -// "toID": 12, -// "constraints": [] -// }, -// { -// "ID": 11, -// "name": "ACTED_IN", -// "depth": { -// "min": 1, -// "max": 1 -// }, -// "fromType": "entity", -// "fromID": 12, -// "toType": "entity", -// "toID": 11, -// "constraints": [] -// } -// ], -// "groupBys": [], -// "machineLearning": [], -// "limit": 5000, -// "databaseName": "Movies3" -// } -// `) - -// var JSONQuery entity.IncomingQueryJSON -// json.Unmarshal(query, &JSONQuery) -// fmt.Println(JSONQuery) -// fmt.Println(" ") - -// s := NewService() -// cypher, _, err := s.ConvertQuery(&JSONQuery) -// if err != nil { -// fmt.Println(err) -// t.Fail() -// return -// } - -// if cypher == nil { -// t.Fail() -// return -// } - -// answer1 := `MATCH p0 = (e11:Person)-[:DIRECTED*1..1]-(e12:Movie) -// UNWIND relationships(p0) as r10 -// WITH * -// MATCH p1 = (e12:Movie)-[:ACTED_IN*1..1]-(e11:Person) -// UNWIND relationships(p1) as r11 -// WITH * -// UNWIND [r11,e12,e11,r10,e11,e12] AS x -// RETURN DISTINCT x -// LIMIT 5000;nodelink` - -// answer2 := `MATCH p1 = (e12:Movie)-[:ACTED_IN*1..1]-(e11:Person) -// UNWIND relationships(p1) as r11 -// WITH * -// MATCH p0 = (e11:Person)-[:DIRECTED*1..1]-(e12:Movie) -// UNWIND relationships(p0) as r10 -// WITH * -// UNWIND [r10,e11,e12,r11,e12,e11] AS x -// RETURN DISTINCT x -// LIMIT 5000;nodelink` - -// trimmedCypher := fixCypherSpaces(cypher) -// trimmedAnswer1 := fixCypherSpaces(&answer1) -// trimmedAnswer2 := fixCypherSpaces(&answer2) - -// fmt.Println(*cypher) -// // Both answers are correct -// if !(trimmedAnswer1 == trimmedCypher || trimmedAnswer2 == trimmedCypher) { -// t.Fail() -// } -// } - -// func TestCyclePlusDependency(t *testing.T) { -// query := []byte(`{ -// "return": { -// "entities": [ -// 11, -// 12 -// ], -// "relations": [ -// 10 -// ], -// "groupBys": [] -// }, -// "entities": [ -// { -// "name": "Person", -// "ID": 11, -// "constraints": [] -// }, -// { -// "name": "Movie", -// "ID": 12, -// "constraints": [] -// }, -// { -// "name": "Person", -// "ID": 13, -// "constraints": [] -// } -// ], -// "relations": [ -// { -// "ID": 10, -// "name": "DIRECTED", -// "depth": { -// "min": 1, -// "max": 1 -// }, -// "fromType": "entity", -// "fromID": 11, -// "toType": "entity", -// "toID": 12, -// "constraints": [] -// }, -// { -// "ID": 11, -// "name": "ACTED_IN", -// "depth": { -// "min": 1, -// "max": 1 -// }, -// "fromType": "entity", -// "fromID": 12, -// "toType": "entity", -// "toID": 11, -// "constraints": [] -// }, -// { -// "ID": 12, -// "name": "ACTED_IN", -// "depth": { -// "min": 1, -// "max": 1 -// }, -// "fromType": "entity", -// "fromID": 13, -// "toType": "entity", -// "toID": 12, -// "constraints": [] -// } -// ], -// "groupBys": [], -// "machineLearning": [], -// "limit": 5000, -// "databaseName": "Movies3" -// } -// `) - -// var JSONQuery entity.IncomingQueryJSON -// json.Unmarshal(query, &JSONQuery) -// fmt.Println(JSONQuery) -// fmt.Println(" ") - -// s := NewService() -// cypher, _, err := s.ConvertQuery(&JSONQuery) -// if err != nil { -// fmt.Println(err) -// t.Fail() -// return -// } - -// if cypher == nil { -// t.Fail() -// return -// } - -// answer := `MATCH p2 = (e13:Person)-[:ACTED_IN*1..1]-(e12:Movie) -// UNWIND relationships(p2) as r12 -// WITH * -// MATCH p1 = (e12:Movie)-[:ACTED_IN*1..1]-(e11:Person) -// UNWIND relationships(p1) as r11 -// WITH * -// MATCH p0 = (e11:Person)-[:DIRECTED*1..1]-(e12:Movie) -// UNWIND relationships(p0) as r10 -// WITH * -// UNWIND [r10,e11,e12,r11,e12,e11,r12,e13,e12] AS x -// RETURN DISTINCT x -// LIMIT 5000;nodelink` - -// trimmedCypher := fixCypherSpaces(cypher) -// trimmedAnswer := fixCypherSpaces(&answer) - -// fmt.Println(*cypher) -// assert.Equal(t, trimmedAnswer, trimmedCypher) -// } -// func TestTripleCycle(t *testing.T) { -// query := []byte(`{ -// "return": { -// "entities": [ -// 11, -// 12 -// ], -// "relations": [ -// 10 -// ], -// "groupBys": [] -// }, -// "entities": [ -// { -// "name": "Person", -// "ID": 11, -// "constraints": [] -// }, -// { -// "name": "Movie", -// "ID": 12, -// "constraints": [] -// }, -// { -// "name": "Person", -// "ID": 13, -// "constraints": [] -// } -// ], -// "relations": [ -// { -// "ID": 10, -// "name": "DIRECTED", -// "depth": { -// "min": 1, -// "max": 1 -// }, -// "fromType": "entity", -// "fromID": 11, -// "toType": "entity", -// "toID": 12, -// "constraints": [] -// }, -// { -// "ID": 11, -// "name": "ACTED_IN", -// "depth": { -// "min": 1, -// "max": 1 -// }, -// "fromType": "entity", -// "fromID": 12, -// "toType": "entity", -// "toID": 13, -// "constraints": [] -// }, -// { -// "ID": 12, -// "name": "ACTED_IN", -// "depth": { -// "min": 1, -// "max": 1 -// }, -// "fromType": "entity", -// "fromID": 13, -// "toType": "entity", -// "toID": 11, -// "constraints": [] -// } -// ], -// "groupBys": [], -// "machineLearning": [], -// "limit": 5000, -// "databaseName": "Movies3" -// } -// `) - -// var JSONQuery entity.IncomingQueryJSON -// json.Unmarshal(query, &JSONQuery) - -// s := NewService() -// cypher, _, err := s.ConvertQuery(&JSONQuery) -// if err != nil { -// fmt.Println(err) -// assert.Equal(t, err, errors.New("Cyclic query detected")) -// return -// } - -// if cypher == nil { -// t.Fail() -// return -// } -// t.Fail() -// } - -// func TestMultipleByStatementConnected(t *testing.T) { -// query := []byte(`{ -// "databaseName": "Movies3", -// "entities": [ -// { -// "id": 0, -// "name": "Person", -// "constraints": [] -// }, -// { -// "id": 1, -// "name": "Movie", -// "constraints": [] -// }, -// { -// "id": 2, -// "name": "Person", -// "constraints": [] -// } -// ], -// "relations": [ -// { -// "id": 0, -// "name": "ACTED_IN", -// "depth": { -// "min": 1, -// "max": 1 -// }, -// "fromType": "entity", -// "fromID": 0, -// "toType": "entity", -// "toID": 1, -// "constraints": [] -// }, -// { -// "id": 2, -// "name": "ACTED_IN", -// "depth": { -// "min": 1, -// "max": 1 -// }, -// "fromType": "entity", -// "fromID": 2, -// "toType": "entity", -// "toID": 1, -// "constraints": [] -// } -// ], -// "groupBys": [ -// { -// "id": 0, -// "groupType": "entity", -// "groupID": [1], -// "groupAttribute": "imdbRating", -// "byType": "entity", -// "byID": [0,2], -// "byAttribute": "bornIn", -// "appliedModifier": "AVG", -// "relationID": 0, -// "constraints": [ -// { -// "attribute": "imdbRating", -// "value": "7.5", -// "dataType": "int", -// "matchType": "GT", -// "inID": -1, -// "inType": "" -// } -// ] -// } -// ], -// "machineLearning": [], -// "limit": 5000 -// } -// `) - -// answer := `MATCH p0 = (e0:Person)-[:ACTED_IN*1..1]-(e1:Movie) -// UNWIND relationships(p0) as r0 -// WITH * -// MATCH p1 = (e2:Person)-[:ACTED_IN*1..1]-(e1:Movie) -// UNWIND relationships(p1) as r2 -// WITH * -// UNWIND [e0,e2] AS e02L -// WITH e02L.bornIn AS e02L_bornIn, AVG(e1.imdbRating) AS AVG_imdbRating -// WHERE AVG_imdbRating > 7.5 -// RETURN e02L_bornIn, AVG_imdbRating -// LIMIT 5000;table` - -// var JSONQuery entity.IncomingQueryJSON -// json.Unmarshal(query, &JSONQuery) - -// s := NewService() -// cypher, _, err := s.ConvertQuery(&JSONQuery) -// if err != nil { -// fmt.Println(err) -// } -// println(cypher) - -// trimmedCypher := fixCypherSpaces(cypher) -// trimmedAnswer := fixCypherSpaces(&answer) - -// fmt.Println(*cypher) -// assert.Equal(t, trimmedAnswer, trimmedCypher) - -// } - -// func TestRelationOnGroupBy(t *testing.T) { -// query := []byte(`{ -// "databaseName": "Movies3", -// "entities": [ -// { -// "id": 0, -// "name": "Person", -// "constraints": [] -// }, -// { -// "id": 1, -// "name": "Movie", -// "constraints": [] -// }, -// { -// "id": 2, -// "name": "Person", -// "constraints": [] -// }, -// { -// "id": 3, -// "name": "Movie", -// "constraints": [] -// } -// ], -// "relations": [ -// { -// "id": 0, -// "name": "ACTED_IN", -// "depth": { -// "min": 1, -// "max": 1 -// }, -// "fromType": "entity", -// "fromID": 0, -// "toType": "entity", -// "toID": 1, -// "constraints": [] -// }, -// { -// "id": 1, -// "name": "ACTED_IN", -// "depth": { -// "min": 1, -// "max": 1 -// }, -// "fromType": "entity", -// "fromID": 2, -// "toType": "entity", -// "toID": 1, -// "constraints": [] -// }, -// { -// "id": 2, -// "name": "ACTED_IN", -// "depth": { -// "min": 1, -// "max": 1 -// }, -// "fromType": "groupBy", -// "fromID": 0, -// "toType": "entity", -// "toID": 3, -// "constraints": [] -// } -// ], -// "groupBys": [ -// { -// "id": 0, -// "groupType": "entity", -// "groupID": [1], -// "groupAttribute": "imdbRating", -// "byType": "entity", -// "byID": [0,2], -// "byAttribute": "bornIn", -// "appliedModifier": "AVG", -// "relationID": 0, -// "constraints": [ -// { -// "attribute": "imdbRating", -// "value": "7.5", -// "dataType": "int", -// "matchType": "GT", -// "inID": -1, -// "inType": "" -// } -// ] -// } -// ], -// "machineLearning": [], -// "limit": 5000 -// } -// `) - -// answer1 := `MATCH p0 = (e0:Person)-[:ACTED_IN*1..1]-(e1:Movie) -// UNWIND relationships(p0) as r0 -// WITH * -// MATCH p1 = (e2:Person)-[:ACTED_IN*1..1]-(e1:Movie) -// UNWIND relationships(p1) as r1 -// WITH * -// UNWIND [e0,e2] AS e02L -// WITH e02L.bornIn AS e02L_bornIn, AVG(e1.imdbRating) AS AVG_imdbRating -// WHERE AVG_imdbRating > 7.5 -// MATCH p2 = (eg02L:Person)-[:ACTED_IN*1..1]-(e3:Movie) -// WHERE eg02L.bornIn IN e02L_bornIn -// UNWIND relationships(p2) as r2 -// WITH * -// UNWIND [r2,eg02L,e3] AS x -// RETURN DISTINCT x -// LIMIT 5000;nodelink` - -// answer2 := `MATCH p1 = (e2:Person)-[:ACTED_IN*1..1]-(e1:Movie) -// UNWIND relationships(p1) as r1 -// WITH * -// MATCH p0 = (e0:Person)-[:ACTED_IN*1..1]-(e1:Movie) -// UNWIND relationships(p0) as r0 -// WITH * -// UNWIND [e0,e2] AS e02L -// WITH e02L.bornIn AS e02L_bornIn, AVG(e1.imdbRating) AS AVG_imdbRating -// WHERE AVG_imdbRating > 7.5 -// MATCH p2 = (eg02L:Person)-[:ACTED_IN*1..1]-(e3:Movie) -// WHERE eg02L.bornIn IN e02L_bornIn -// UNWIND relationships(p2) as r2 -// WITH * -// UNWIND [r2,eg02L,e3] AS x -// RETURN DISTINCT x -// LIMIT 5000;nodelink` - -// var JSONQuery entity.IncomingQueryJSON -// json.Unmarshal(query, &JSONQuery) - -// s := NewService() -// cypher, _, err := s.ConvertQuery(&JSONQuery) -// if err != nil { -// fmt.Println(err) -// } - -// trimmedCypher := fixCypherSpaces(cypher) -// trimmedAnswer1 := fixCypherSpaces(&answer1) -// trimmedAnswer2 := fixCypherSpaces(&answer2) - -// if !(trimmedCypher == trimmedAnswer1 || trimmedCypher == trimmedAnswer2) { -// t.Fail() -// } -// } +func TestV2RelationLogic2(t *testing.T) { + query := []byte(`{ + "databaseName": "neo4j", + "query": [ + { + "ID": "path_0", + "node": { + "ID": "id_1700302584692", + "label": "Employee", + "relation": { + "depth": { + "min": 1, + "max": 1 + }, + "direction": "BOTH", + "node": { + "ID": "id_1700302388489", + "label": "Order", + "relation": { + "ID": "id_1698231933579", + "label": "CONTAINS", + "depth": { + "min": 1, + "max": 1 + }, + "direction": "TO", + "node": {} + } + } + } + } + } + ], + "limit": 500, + "return": [ + "*" + ], + "logic": [ + "<", + "@id_1698231933579.unitPrice", + "10" + ] + }`) + + var JSONQuery entityv2.IncomingQueryJSON + err := json.Unmarshal(query, &JSONQuery) + if err != nil { + fmt.Println(err) + t.Log(err) + } + + s := NewService() + cypher, _, err := s.ConvertQuery(&JSONQuery) + if err != nil { + fmt.Println(err) + t.Log(err) + } + t.Log(*cypher) + + answer := `MATCH path_0 = ((id_1700302584692:Employee)-[*1..1]-(id_1700302388489:Order)-[id_1698231933579:CONTAINS*1..1]->()) + WHERE ALL(path_0_rel_id_1698231933579 in id_1698231933579 WHERE (path_0_rel_id_1698231933579.unitPrice < 10)) + RETURN * + LIMIT 500` + + fmt.Printf("Cypher: %s\n", answer) + trimmedCypher := fixCypherSpaces(cypher) + trimmedAnswer := fixCypherSpaces(&answer) + + assert.Equal(t, trimmedAnswer, trimmedCypher) +}