Run separate GQL suits for different storage modes (#1346)
This commit is contained in:
parent
1a3c5af797
commit
06868c8be7
@ -65,11 +65,30 @@ def main():
|
||||
add_argument("--single-scenario", action="store_true", help="pause after every scenario")
|
||||
add_argument("--single-feature", action="store_true", help="pause after every feature")
|
||||
add_argument("--stats-file", default="", help="statistics output file")
|
||||
add_argument("--storage-mode", default="in_memory", help="Memgraph storage mode")
|
||||
add_argument("--storage-mode", help="Memgraph storage mode")
|
||||
|
||||
# Parse arguments
|
||||
parsed_args = argp.parse_args()
|
||||
|
||||
if parsed_args.storage_mode is None:
|
||||
if parsed_args.test_suite == "memgraph_V1_on_disk":
|
||||
parsed_args.storage_mode = "ON_DISK_TRANSACTIONAL"
|
||||
else:
|
||||
parsed_args.storage_mode = "IN_MEMORY_TRANSACTIONAL"
|
||||
|
||||
print(f"Test suite: {parsed_args.test_suite}")
|
||||
print(f"Storage mode: {parsed_args.storage_mode}")
|
||||
|
||||
if parsed_args.test_suite == "memgraph_V1_on_disk" and parsed_args.storage_mode != "ON_DISK_TRANSACTIONAL":
|
||||
raise Exception(
|
||||
"memgraph_V1_on_disk test suite can only be run with ON_DISK_TRANSACTIONAL storage mode. For other storage modes, use memgraph_V1 test suite."
|
||||
)
|
||||
|
||||
if parsed_args.test_suite == "memgraph_V1" and parsed_args.storage_mode == "ON_DISK_TRANSACTIONAL":
|
||||
raise Exception(
|
||||
"memgraph_V1 test suite cannot be run with ON_DISK_TRANSACTIONAL storage mode. For ON_DISK_TRANSACTIONAL storage mode, use memgraph_V1_on_disk test suite."
|
||||
)
|
||||
|
||||
# Find tests
|
||||
test_directory = os.path.join(SCRIPT_DIR, "tests", parsed_args.test_suite)
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
must_pass: false
|
||||
|
||||
- name: memgraph_V1_on_disk
|
||||
test_suite: memgraph_V1
|
||||
test_suite: memgraph_V1_on_disk
|
||||
storage_mode: ON_DISK_TRANSACTIONAL
|
||||
must_pass: true
|
||||
|
||||
|
@ -242,7 +242,7 @@ Feature: Foreach
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
FOREACH(i in [1, 2, 3] | FOREACH(j in [2] | MERGE (n { age : i })));
|
||||
FOREACH(i in [1, 2, 3] | FOREACH(j in [1] | MERGE (n { age : i })));
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
|
@ -0,0 +1,404 @@
|
||||
Feature: Aggregations
|
||||
|
||||
Scenario: Count test 01:
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a:A), (b:B), (c:C)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a) RETURN COUNT(a) AS n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| 3 |
|
||||
|
||||
Scenario: Count test 02:
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
RETURN COUNT(123) AS n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| 1 |
|
||||
|
||||
Scenario: Count test 03:
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
RETURN COUNT(true) AS n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| 1 |
|
||||
|
||||
Scenario: Count test 04:
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
RETURN COUNT('abcd') AS n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| 1 |
|
||||
|
||||
Scenario: Count test 05:
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a{x: 0}), (b{x: 0}), (c{x: 0}), (d{x: 1}), (e{x: 1})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a) RETURN COUNT(a) AS n, a.x
|
||||
"""
|
||||
Then the result should be:
|
||||
| n | a.x |
|
||||
| 3 | 0 |
|
||||
| 2 | 1 |
|
||||
|
||||
Scenario: Count test 06:
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (), (), (), (), ()
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) RETURN COUNT(*) AS n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| 5 |
|
||||
|
||||
Scenario: Count test 07:
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
RETURN count(null)
|
||||
"""
|
||||
Then the result should be:
|
||||
| count(null) |
|
||||
| 0 |
|
||||
|
||||
Scenario: Sum test 01:
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a{x: 1}), (b{x: 7}), (c{x: 5}), (d{x: 'x'})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a) RETURN SUM(a.x) AS n
|
||||
"""
|
||||
Then an error should be raised
|
||||
|
||||
Scenario: Sum test 02:
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a{x: 1}), (b), (c{x: 5}), (d{x: null})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a) RETURN SUM(a.x) AS n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| 6 |
|
||||
|
||||
Scenario: Sum test 03:
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a{x: 0, y:3}), (b{x: 0, y:1}), (c{x: 0}), (d{x: 1, y:4}), (e{x: 1})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a) RETURN SUM(a.y) AS n, a.x
|
||||
"""
|
||||
Then the result should be:
|
||||
| n | a.x |
|
||||
| 4 | 0 |
|
||||
| 4 | 1 |
|
||||
|
||||
Scenario: Sum test 04:
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
RETURN sum(null)
|
||||
"""
|
||||
Then the result should be:
|
||||
| sum(null) |
|
||||
| 0 |
|
||||
|
||||
Scenario: Avg test 01:
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a{x: 1}), (b{x: 7}), (c{x: 5}), (d{x: 'x'})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a) RETURN AVG(a.x) AS n
|
||||
"""
|
||||
Then an error should be raised
|
||||
|
||||
Scenario: Avg test 02:
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a{x: 1.25}), (b), (c{x: 4.75}), (d{x: null})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a) RETURN AVG(a.x) AS n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| 3.0 |
|
||||
|
||||
Scenario: Avg test 03:
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a{x: 0, y:3}), (b{x: 0, y:1}), (c{x: 0}), (d{x: 1, y:4}), (e{x: 1})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a) RETURN AVG(a.y) AS n, a.x
|
||||
"""
|
||||
Then the result should be:
|
||||
| n | a.x |
|
||||
| 2.0 | 0 |
|
||||
| 4.0 | 1 |
|
||||
|
||||
Scenario: Avg test 04:
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
RETURN avg(null)
|
||||
"""
|
||||
Then the result should be:
|
||||
| avg(null) |
|
||||
| null |
|
||||
|
||||
Scenario: Min test 01:
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a{x: 1}), (b{x: 7}), (c{x: 5}), (d{x: 'x'})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a) RETURN MIN(a.x) AS n
|
||||
"""
|
||||
Then an error should be raised
|
||||
|
||||
Scenario: Min test 02:
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a{x: 1}), (b), (c{x: 9}), (d{x: null})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a) RETURN MIN(a.x) AS n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| 1 |
|
||||
|
||||
Scenario: Min test 03:
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a{x: 0, y:3}), (b{x: 0, y:1}), (c{x: 0}), (d{x: 1, y:4}), (e{x: 1})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a) RETURN MIN(a.y) AS n, a.x
|
||||
"""
|
||||
Then the result should be:
|
||||
| n | a.x |
|
||||
| 1 | 0 |
|
||||
| 4 | 1 |
|
||||
|
||||
Scenario: Min test 04:
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
RETURN min(null)
|
||||
"""
|
||||
Then the result should be:
|
||||
| min(null) |
|
||||
| null |
|
||||
|
||||
Scenario: Max test 01:
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a{x: 1}), (b{x: 7}), (c{x: 5}), (d{x: 'x'})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a) RETURN MAX(a.x) AS n
|
||||
"""
|
||||
Then an error should be raised
|
||||
|
||||
Scenario: Max test 02:
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a{x: 1}), (b), (c{x: 9}), (d{x: null})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a) RETURN MAX(a.x) AS n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| 9 |
|
||||
|
||||
Scenario: Max test 03:
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a{x: 0, y:3}), (b{x: 0, y:1}), (c{x: 0}), (d{x: 1, y:4}), (e{x: 1})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a) RETURN Max(a.y) AS n, a.x
|
||||
"""
|
||||
Then the result should be:
|
||||
| n | a.x |
|
||||
| 3 | 0 |
|
||||
| 4 | 1 |
|
||||
|
||||
Scenario: Max test 04:
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
RETURN max(null)
|
||||
"""
|
||||
Then the result should be:
|
||||
| max(null) |
|
||||
| null |
|
||||
|
||||
Scenario: Collect test 01:
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a{x: 0}), (b{x: True}), (c{x: 'asdf'})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a) RETURN collect(a.x) AS n
|
||||
"""
|
||||
Then the result should be (ignoring element order for lists)
|
||||
| n |
|
||||
| [0, true, 'asdf'] |
|
||||
|
||||
Scenario: Collect test 02:
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a{x: 0}), (b{x: True}), (c{x: 'asdf'}), (d{x: null})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a) RETURN collect(a.x) AS n
|
||||
"""
|
||||
Then the result should be (ignoring element order for lists)
|
||||
| n |
|
||||
| [0, true, 'asdf'] |
|
||||
|
||||
Scenario: Collect test 03:
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE ({k: "a", v: 3}), ({k: "b", v: 1}), ({k: "c", v: 2})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a) RETURN collect(a.k + "_key", a.v + 10) AS n
|
||||
"""
|
||||
Then the result should be
|
||||
| n |
|
||||
| {a_key: 13, b_key: 11, c_key: 12} |
|
||||
|
||||
Scenario: Combined aggregations - some evauluates to null:
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (f)
|
||||
CREATE (n {property: 1})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) RETURN count(n) < n.property, count(n.property), count(n), avg(n.property), min(n.property), max(n.property), sum(n.property)
|
||||
"""
|
||||
Then the result should be:
|
||||
| count(n) < n.property | count(n.property) | count(n) | avg(n.property) | min(n.property) | max(n.property) | sum(n.property) |
|
||||
| false | 1 | 1 | 1.0 | 1 | 1 | 1 |
|
||||
| null | 0 | 1 | null | null | null | 0 |
|
||||
|
||||
Scenario: Graph projection test 01:
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a{x: 1}), (b{x: 2}), (c{x: 3}), (d{x: 4}), (a)-[:X]->(b), (b)-[:X]->(c), (c)-[:X]->(a), (a)-[:B]->(d)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH p=()-[:X]->() WITH project(p) as graph WITH graph.nodes as nodes UNWIND nodes as n RETURN n.x as x ORDER BY x DESC
|
||||
"""
|
||||
Then the result should be:
|
||||
| x |
|
||||
| 3 |
|
||||
| 2 |
|
||||
| 1 |
|
||||
|
||||
Scenario: Graph projection test 02:
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a{x: 1}), (b{x: 2}), (c{x: 3}), (d{x: 4}), (a)-[:X]->(b), (b)-[:X]->(c), (c)-[:X]->(a), (a)-[:B]->(d)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH p=()-[:Z]->() WITH project(p) as graph WITH graph.nodes as nodes UNWIND nodes as n RETURN n.x as x ORDER BY x DESC
|
||||
"""
|
||||
Then the result should be:
|
||||
| x |
|
||||
|
||||
Scenario: Graph projection test 03:
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a{x: 1}), (b{x: 2}), (c{x: 3}), (d{x: 4}), (a)-[:X {prop:1}]->(b), (b)-[:X {prop:2}]->(c), (c)-[:X {prop:3}]->(a), (a)-[:B {prop:4}]->(d)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH p=()-[:X]->() WITH project(p) as graph WITH graph.edges as edges UNWIND edges as e RETURN e.prop as y ORDER BY y DESC
|
||||
"""
|
||||
Then the result should be:
|
||||
| y |
|
||||
| 3 |
|
||||
| 2 |
|
||||
| 1 |
|
||||
|
||||
Scenario: Graph projection test 04:
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a{x: 1}), (b{x: 2}), (c{x: 3}), (d{x: 4}), (a)-[:X {prop:1}]->(b), (b)-[:X {prop:2}]->(c), (c)-[:X {prop:3}]->(a), (a)-[:B {prop:4}]->(d)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH p=()-[:Z]->() WITH project(p) as graph WITH graph.edges as edges UNWIND edges as e RETURN e.prop as y ORDER BY y DESC
|
||||
"""
|
||||
Then the result should be:
|
||||
| y |
|
@ -0,0 +1,173 @@
|
||||
Feature: Cartesian
|
||||
|
||||
Scenario: Match multiple patterns 01
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a:A), (b:B), (c:C), (a)-[:X]->(b), (c)-[:X]->(a)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a)-[]->(), (b) CREATE (a)-[r:R]->(b) RETURN a, b, r
|
||||
"""
|
||||
Then the result should be:
|
||||
| a | b | r |
|
||||
| (:C) | (:A) | [:R] |
|
||||
| (:C) | (:B) | [:R] |
|
||||
| (:C) | (:C) | [:R] |
|
||||
| (:A) | (:A) | [:R] |
|
||||
| (:A) | (:B) | [:R] |
|
||||
| (:A) | (:C) | [:R] |
|
||||
|
||||
Scenario: Match multiple patterns 02
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a:A), (b:B), (c:C), (d:D), (e:E), (f:F), (a)-[:X]->(b), (b)-[:X]->(c), (d)-[:X]->(e), (e)-[:X]->(f)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a:B)--(b), (c:E)--(d) CREATE (b)-[r:R]->(d) return b, d, r
|
||||
"""
|
||||
Then the result should be:
|
||||
| b | d | r |
|
||||
| (:A) | (:D) | [:R] |
|
||||
| (:A) | (:F) | [:R] |
|
||||
| (:C) | (:D) | [:R] |
|
||||
| (:C) | (:F) | [:R] |
|
||||
|
||||
Scenario: Match multiple patterns 03
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a:A), (b:B), (c:C), (d:D), (a)-[:R]->(b), (b)-[:R]->(c), (c)-[:R]->(d)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a:B)--(b), (c:B)--(d) RETURN b, d
|
||||
"""
|
||||
Then the result should be:
|
||||
| b | d |
|
||||
| (:A) | (:C) |
|
||||
| (:C) | (:A) |
|
||||
|
||||
Scenario: Match multiple patterns 04
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a:A), (b:B), (c:C), (d:D), (a)-[:R]->(b), (b)-[:R]->(c), (c)-[:R]->(d)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a:A)--(b), (c:A)--(d) RETURN a, b, c, d
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Multiple match 01
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a:A), (b:B), (c:C), (d:D), (a)-[:R]->(b), (b)-[:R]->(c), (c)-[:R]->(d)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a:B)--(b) MATCH (c:B)--(d) RETURN b, d
|
||||
"""
|
||||
Then the result should be:
|
||||
| b | d |
|
||||
| (:A) | (:A) |
|
||||
| (:A) | (:C) |
|
||||
| (:C) | (:A) |
|
||||
| (:C) | (:C) |
|
||||
|
||||
Scenario: Multiple match 02
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a:A), (b:B), (c:C), (d:D), (a)-[:R]->(b), (b)-[:R]->(c), (c)-[:R]->(d)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a:A)--(b) MATCH (a)--(c) RETURN a, b, c
|
||||
"""
|
||||
Then the result should be:
|
||||
| a | b | c |
|
||||
| (:A) | (:B) | (:B) |
|
||||
|
||||
Scenario: Multiple match 03
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a:A), (b:B), (c:C), (a)-[:X]->(b), (c)-[:X]->(a)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a)-[]->() MATCH (b) CREATE (a)-[r:R]->(b) RETURN a, b, r
|
||||
"""
|
||||
Then the result should be:
|
||||
| a | b | r |
|
||||
| (:C) | (:A) | [:R] |
|
||||
| (:C) | (:B) | [:R] |
|
||||
| (:C) | (:C) | [:R] |
|
||||
| (:A) | (:A) | [:R] |
|
||||
| (:A) | (:B) | [:R] |
|
||||
| (:A) | (:C) | [:R] |
|
||||
|
||||
Scenario: Multiple match 04
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a:A), (b:B), (c:C), (d:D), (e:E), (f:F), (a)-[:X]->(b), (b)-[:X]->(c), (d)-[:X]->(e), (e)-[:X]->(f)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a:B)--(b) MATCH (c:E)--(d) CREATE (b)-[r:R]->(d) return b, d, r
|
||||
"""
|
||||
Then the result should be:
|
||||
| b | d | r |
|
||||
| (:A) | (:D) | [:R] |
|
||||
| (:A) | (:F) | [:R] |
|
||||
| (:C) | (:D) | [:R] |
|
||||
| (:C) | (:F) | [:R] |
|
||||
|
||||
Scenario: Multiple match 05
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a:A), (b:B), (c:C)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH(a) MATCH(a) RETURN a
|
||||
"""
|
||||
Then the result should be:
|
||||
| a |
|
||||
| (:A) |
|
||||
| (:B) |
|
||||
| (:C) |
|
||||
|
||||
Scenario: Multiple match 06
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a:A), (b:B), (c:C), (a)-[:R]->(b), (b)-[:R]->(c)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a)-[]->() MATCH (a:B) MATCH (b:C) RETURN a, b
|
||||
"""
|
||||
Then the result should be:
|
||||
| a | b |
|
||||
| (:B) | (:C) |
|
||||
|
||||
Scenario: Multiple match 07
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a:A), (b:B), (c:C), (a)-[:R]->(b), (b)-[:R]->(c)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a)-[]->() MATCH (a:B) MATCH (a:C) RETURN a
|
||||
"""
|
||||
Then the result should be empty
|
@ -0,0 +1,99 @@
|
||||
Feature: Case
|
||||
|
||||
Scenario: Simple CASE:
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
UNWIND range(1, 3) as x RETURN CASE x WHEN 2 THEN "two" END
|
||||
"""
|
||||
Then the result should be:
|
||||
| CASE x WHEN 2 THEN "two" END |
|
||||
| null |
|
||||
| 'two' |
|
||||
| null |
|
||||
|
||||
Scenario: Simple CASE with ELSE:
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
UNWIND range(1, 3) as x RETURN CASE x WHEN 2 THEN "two" ELSE "nottwo" END as z
|
||||
"""
|
||||
Then the result should be:
|
||||
| z |
|
||||
| 'nottwo' |
|
||||
| 'two' |
|
||||
| 'nottwo' |
|
||||
|
||||
Scenario: Generic CASE:
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
UNWIND range(1, 3) as x RETURN CASE WHEN x > 1 THEN "greater" END as z
|
||||
"""
|
||||
Then the result should be:
|
||||
| z |
|
||||
| null |
|
||||
| 'greater' |
|
||||
| 'greater' |
|
||||
|
||||
Scenario: Generic CASE multiple matched whens:
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
UNWIND range(1, 3) as x RETURN CASE WHEN x > 10 THEN 10 WHEN x > 1 THEN 1 WHEN x > 0 THEN 0 WHEN x > "mirko" THEN 1000 END as z
|
||||
"""
|
||||
Then the result should be:
|
||||
| z |
|
||||
| 0 |
|
||||
| 1 |
|
||||
| 1 |
|
||||
|
||||
Scenario: Simple CASE in collect:
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
UNWIND range(1, 3) as x RETURN collect(CASE x WHEN 2 THEN "two" ELSE "nottwo" END) as z
|
||||
"""
|
||||
Then the result should be:
|
||||
| z |
|
||||
| ['nottwo', 'two', 'nottwo'] |
|
||||
|
||||
Scenario: Simple CASE nullcheck does not have match:
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
WITH 2 AS name RETURN CASE name WHEN 3 THEN 'something went wrong' WHEN null THEN "doesn't work" ELSE 'works' END
|
||||
"""
|
||||
Then the result should be:
|
||||
| CASE name WHEN 3 THEN 'something went wrong' WHEN null THEN "doesn't work" ELSE 'works' END |
|
||||
| 'works' |
|
||||
|
||||
Scenario: Simple CASE nullcheck does have match:
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
WITH 2 AS name RETURN CASE name WHEN 2 THEN 'works' WHEN null THEN "doesn't work" ELSE 'something went wrong' END
|
||||
"""
|
||||
Then the result should be:
|
||||
| CASE name WHEN 2 THEN 'works' WHEN null THEN "doesn't work" ELSE 'something went wrong' END |
|
||||
| 'works' |
|
||||
|
||||
Scenario: Generic CASE nullcheck does have match:
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
WITH 2 AS name RETURN CASE WHEN name is NULL THEN "doesn't work" WHEN name = 2 THEN "works" ELSE "something went wrong" END
|
||||
"""
|
||||
Then the result should be:
|
||||
| CASE WHEN name is NULL THEN "doesn't work" WHEN name = 2 THEN "works" ELSE "something went wrong" END |
|
||||
| 'works' |
|
||||
|
||||
Scenario: Generic CASE expression is null:
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
WITH null AS name RETURN CASE name WHEN null THEN "doesn't work" WHEN 2 THEN "doesn't work" ELSE 'works' END
|
||||
"""
|
||||
Then the result should be:
|
||||
| CASE name WHEN null THEN "doesn't work" WHEN 2 THEN "doesn't work" ELSE 'works' END |
|
||||
| 'works' |
|
@ -0,0 +1,177 @@
|
||||
Feature: Create
|
||||
|
||||
Scenario: Create empty node without clearing database
|
||||
When executing query:
|
||||
"""
|
||||
CREATE (n)
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Create node with label without clearing database
|
||||
When executing query:
|
||||
"""
|
||||
CREATE (n:L:K)
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Create node with int property without clearing database
|
||||
When executing query:
|
||||
"""
|
||||
CREATE (n{a: 1})
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Create node with float property without clearing database
|
||||
When executing query:
|
||||
"""
|
||||
CREATE (n{a: 1.0})
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Create node with string property without clearing database
|
||||
When executing query:
|
||||
"""
|
||||
CREATE (n{a: 'string'})
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Create node with bool properties without clearing database
|
||||
When executing query:
|
||||
"""
|
||||
CREATE (n{a: True, b: false})
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Create node with null property without clearing database
|
||||
When executing query:
|
||||
"""
|
||||
CREATE (n{a: NULL})
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Create node with properties without clearing database
|
||||
When executing query:
|
||||
"""
|
||||
CREATE (n{a: 1.0, b: false, c: 1, d: 'neki"string"', e: NULL})
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Create node with properties without clearing database
|
||||
When executing query:
|
||||
"""
|
||||
CREATE (n:L:K:T {a: 1.0, b: false, c: 1, d: 'neki"string"', e: NULL})
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Create multiple nodes connected by relationships
|
||||
When executing query:
|
||||
"""
|
||||
CREATE (a)-[b:X]->(c)<-[d:Y]-(e)
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Create multiple nodes connected by relationships
|
||||
When executing query:
|
||||
"""
|
||||
CREATE (n)-[:X]->(n)<-[:Y]-(n)
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Create multiple nodes connected by relationships with properties
|
||||
When executing query:
|
||||
"""
|
||||
CREATE (a)-[b:X{a: 1.0}]->(c)<-[d:Y{d: "xyz"}]-(e)
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Create empty node without clearing database:
|
||||
When executing query:
|
||||
"""
|
||||
CREATE (n) RETURN n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
|( )|
|
||||
|
||||
Scenario: Create node with labels without clearing database and return it
|
||||
When executing query:
|
||||
"""
|
||||
CREATE (n:A:B) RETURN n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
|(:A:B)|
|
||||
|
||||
Scenario: Create node with properties without clearing database and return it
|
||||
When executing query:
|
||||
"""
|
||||
CREATE (n{a: 1.0, b: FALSE, c: 1, d: 'neki"string"', e: NULL}) RETURN n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
|({a: 1.0, b: false, c: 1, d: 'neki"string"'}) |
|
||||
|
||||
Scenario: Create node with labels and properties without clearing database and return it
|
||||
When executing query:
|
||||
"""
|
||||
CREATE (n:A:B{a: 1.0, b: False, c: 1, d: 'neki"string"', e: NULL}) RETURN n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| (:A:B{a: 1.0, b: false, c: 1, d: 'neki"string"'}) |
|
||||
|
||||
Scenario: Create node with properties and labels without clearing database and return its properties
|
||||
When executing query:
|
||||
"""
|
||||
CREATE (n:A:B{a: 1.0, b: false, c: 1, d: 'neki"string"', e: NULL}) RETURN n.a, n.b, n.c, n.d, n.e
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.a | n.b | n.c | n.d | n.e |
|
||||
| 1.0 | false | 1 | 'neki"string"'| null |
|
||||
|
||||
Scenario: Create multiple nodes connected by relationships with properties and return it
|
||||
When executing query:
|
||||
"""
|
||||
CREATE (a)-[b:X{a: 1.0}]->(c)<-[d:Y{d: "xyz"}]-(e) RETURN b
|
||||
"""
|
||||
Then the result should be:
|
||||
| b |
|
||||
| [:X{a: 1.0}] |
|
||||
|
||||
Scenario: Multiple create 01:
|
||||
When executing query:
|
||||
"""
|
||||
CREATE (a)-[b:X{a: 1.0}]->(c)<-[d:Y{d: "xyz"}]-(e) CREATE (n:A:B{a: 1.0, b: False, c: 1, d: 'neki"string"', e: NULL}) RETURN b, n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n | b |
|
||||
| (:A:B{a: 1.0, b: false, c: 1, d: 'neki"string"'}) | [:X{a: 1.0}] |
|
||||
|
||||
Scenario: Multiple create 02:
|
||||
When executing query:
|
||||
"""
|
||||
CREATE (a)-[:X]->(b) CREATE (a)-[:Y]->(c)
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Multiple create 03:
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a:A), (b:B) CREATE (c:C), (a)-[:R]->(b) CREATE (b)-[:R]->(c)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a)-[]->() MATCH (a:B) MATCH (b:C) RETURN a, b
|
||||
"""
|
||||
Then the result should be:
|
||||
| a | b |
|
||||
| (:B) | (:C) |
|
||||
|
||||
Scenario: Multiple create 04:
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
CREATE (a:A) CREATE (a:B)
|
||||
"""
|
||||
Then an error should be raised
|
@ -0,0 +1,211 @@
|
||||
Feature: Delete
|
||||
|
||||
Scenario: Delete all from database and yield number of deleted items
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (n), (m), (o)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) DETACH DELETE n RETURN COUNT(*) AS cnt
|
||||
"""
|
||||
Then the result should be:
|
||||
| cnt |
|
||||
| 3 |
|
||||
|
||||
Scenario: Delete all from database and match nothing after
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (n), (m)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) DETACH DELETE n WITH n MATCH (m) RETURN COUNT(*) AS cnt
|
||||
"""
|
||||
Then the result should be:
|
||||
| cnt |
|
||||
| 0 |
|
||||
|
||||
Scenario: Delete relationship in the pattern
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (n)-[:REL]->(m), (k)-[:REL]->(z)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n)-[r:REL]->(m) DELETE r RETURN COUNT(*) AS cnt
|
||||
"""
|
||||
Then the result should be:
|
||||
| cnt |
|
||||
| 2 |
|
||||
|
||||
Scenario: Delete node and return property throws an error
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (n {prop: 1});
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) DETACH DELETE n RETURN n.prop AS prop
|
||||
"""
|
||||
Then an error should be raised
|
||||
|
||||
Scenario: Delete node, set property throws an error
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (n {prop: 1});
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) DETACH DELETE n SET n.prop = 2
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Delete node, set property and return throws an error
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (n {prop: 1});
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) DETACH DELETE n SET n.prop = 2 RETURN n
|
||||
"""
|
||||
Then an error should be raised
|
||||
|
||||
Scenario: Delete node, remove property throws an error
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (n {prop: 1});
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) DETACH DELETE n REMOVE n.prop
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Delete node, remove property and return throws an error
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (n {prop: 1});
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) DETACH DELETE n REMOVE n.prop RETURN n
|
||||
"""
|
||||
Then an error should be raised
|
||||
|
||||
Scenario: Delete node, set label throws an error
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (n {prop: 1});
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) DETACH DELETE n SET n:Label
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Delete node, set label and return throws an error
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (n {prop: 1});
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) DETACH DELETE n SET n:Label RETURN n
|
||||
"""
|
||||
Then an error should be raised
|
||||
|
||||
Scenario: Delete node, remove label throws an error
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (n:Label {prop: 1});
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) DETACH DELETE n REMOVE n:Label
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Delete node, remove label and return throws an error
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (n:Label {prop: 1});
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) DETACH DELETE n REMOVE n:Label RETURN n
|
||||
"""
|
||||
Then an error should be raised
|
||||
|
||||
Scenario: Delete node, set update properties and return throws an error
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (n:Label {prop: 1});
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) DETACH DELETE n SET n += {prop: 2} RETURN n
|
||||
"""
|
||||
Then an error should be raised
|
||||
|
||||
Scenario: Delete node, set properties throws an error
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (n:Label {prop: 1});
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) DETACH DELETE n SET n += {prop: 2}
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Delete node, set replace properties and return throws an error
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (n:Label {prop: 1});
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) DETACH DELETE n SET n = {prop: 2} RETURN n
|
||||
"""
|
||||
Then an error should be raised
|
||||
|
||||
Scenario: Delete node, set replace properties throws an error
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (n:Label {prop: 1});
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) DETACH DELETE n SET n = {prop: 2}
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Delete node, set property and return it with aggregation throws an error
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (n:Label {prop: 1});
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) DETACH DELETE n SET n.prop = 1 WITH n RETURN n
|
||||
"""
|
||||
Then an error should be raised
|
@ -0,0 +1,133 @@
|
||||
Feature: Expressions
|
||||
|
||||
Scenario: Test equal operator
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
CREATE (a)
|
||||
RETURN 1=1 and 1.0=1.0 and 'abc'='abc' and false=false and a.age is null as n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| true |
|
||||
|
||||
Scenario: Test not equal operator
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
CREATE (a{age: 1})
|
||||
RETURN not 1<>1 and 1.0<>1.1 and 'abcd'<>'abc' and false<>true and a.age is not null as n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| true |
|
||||
|
||||
Scenario: Test greater operator
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
RETURN 2>1 and not 1.0>1.1 and 'abcd'>'abc' as n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| true |
|
||||
|
||||
Scenario: Test less operator
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
RETURN not 2<1 and 1.0<1.1 and not 'abcd'<'abc' as n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| true |
|
||||
|
||||
Scenario: Test greater equal operator
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
RETURN 2>=2 and not 1.0>=1.1 and 'abcd'>='abc' as n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| true |
|
||||
|
||||
Scenario: Test less equal operator
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
RETURN 2<=2 and 1.0<=1.1 and not 'abcd'<='abc' as n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| true |
|
||||
|
||||
Scenario: Test plus operator
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
RETURN 3+2=1.09+3.91 as n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| true |
|
||||
|
||||
Scenario: Test minus operator
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
RETURN 3-2=1.09-0.09 as n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| true |
|
||||
|
||||
Scenario: Test multiply operator
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
RETURN 3*2=1.5*4 as n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| true |
|
||||
|
||||
Scenario: Test divide operator1
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
RETURN 3/2<>7.5/5 as n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| true |
|
||||
|
||||
Scenario: Test divide operator2
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
RETURN 3.0/2=7.5/5 as n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| true |
|
||||
|
||||
Scenario: Test mod operator
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
RETURN 3%2=1 as n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| true |
|
||||
|
||||
Scenario: Test one big logical equation
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
RETURN not true or true and false or not ((true xor false or true) and true or false xor true ) as n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| false |
|
@ -0,0 +1,257 @@
|
||||
# Copyright 2022 Memgraph Ltd.
|
||||
#
|
||||
# Use of this software is governed by the Business Source License
|
||||
# included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
# License, and you may not use this file except in compliance with the Business Source License.
|
||||
#
|
||||
# As of the Change Date specified in that file, in accordance with
|
||||
# the Business Source License, use of this software will be governed
|
||||
# by the Apache License, Version 2.0, included in the file
|
||||
# licenses/APL.txt.
|
||||
|
||||
Feature: Foreach
|
||||
Behaviour tests for memgraph FOREACH clause
|
||||
|
||||
Scenario: Foreach create
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
FOREACH( i IN [1, 2, 3] | CREATE (n {age : i}))
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) RETURN n.age
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.age |
|
||||
| 1 |
|
||||
| 2 |
|
||||
| 3 |
|
||||
And no side effects
|
||||
|
||||
Scenario: Foreach Foreach create
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
FOREACH( i IN [1, 2, 3] | CREATE (n {age : i})) FOREACH( i in [4, 5, 6] | CREATE (n {age : i}))
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) RETURN n.age
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.age |
|
||||
| 1 |
|
||||
| 2 |
|
||||
| 3 |
|
||||
| 4 |
|
||||
| 5 |
|
||||
| 6 |
|
||||
And no side effects
|
||||
|
||||
Scenario: Foreach shadowing
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
FOREACH( i IN [1] | FOREACH( i in [2, 3, 4] | CREATE (n {age : i})))
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) RETURN n.age
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.age |
|
||||
| 2 |
|
||||
| 3 |
|
||||
| 4 |
|
||||
And no side effects
|
||||
|
||||
Scenario: Foreach set
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (n1 { marked: false })-[:RELATES]->(n2 { marked: false })
|
||||
"""
|
||||
And having executed
|
||||
"""
|
||||
MATCH p=(n1)-[*]->(n2)
|
||||
FOREACH (n IN nodes(p) | SET n.marked = true)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n)
|
||||
RETURN n.marked
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.marked |
|
||||
| true |
|
||||
| true |
|
||||
And no side effects
|
||||
|
||||
Scenario: Foreach remove
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (n1 { marked: false })-[:RELATES]->(n2 { marked: false })
|
||||
"""
|
||||
And having executed
|
||||
"""
|
||||
MATCH p=(n1)-[*]->(n2)
|
||||
FOREACH (n IN nodes(p) | REMOVE n.marked)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n)
|
||||
RETURN n;
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| () |
|
||||
| () |
|
||||
And no side effects
|
||||
|
||||
# Scenario: Foreach delete
|
||||
# Given an empty graph
|
||||
# And having executed
|
||||
# """
|
||||
# CREATE (n1 { marked: false })-[:RELATES]->(n2 { marked: false })
|
||||
# """
|
||||
# And having executed
|
||||
# """
|
||||
# MATCH p=(n1)-[*]->(n2)
|
||||
# FOREACH (n IN nodes(p) | DETACH delete n)
|
||||
# """
|
||||
# When executing query:
|
||||
# """
|
||||
# MATCH (n)
|
||||
# RETURN n;
|
||||
# """
|
||||
# Then the result should be:
|
||||
# | |
|
||||
# And no side effects
|
||||
|
||||
Scenario: Foreach merge
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
FOREACH (i IN [1, 2, 3] | MERGE (n { age : i }))
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n)
|
||||
RETURN n.age;
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.age |
|
||||
| 1 |
|
||||
| 2 |
|
||||
| 3 |
|
||||
And no side effects
|
||||
|
||||
Scenario: Foreach nested
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
FOREACH (i IN [1, 2, 3] | FOREACH( j IN [1] | CREATE (k { prop : j })))
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n)
|
||||
RETURN n.prop;
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.prop |
|
||||
| 1 |
|
||||
| 1 |
|
||||
| 1 |
|
||||
|
||||
Scenario: Foreach multiple update clauses
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (n1 { marked1: false, marked2: false })-[:RELATES]->(n2 { marked1: false, marked2: false })
|
||||
"""
|
||||
And having executed
|
||||
"""
|
||||
MATCH p=(n1)-[*]->(n2)
|
||||
FOREACH (n IN nodes(p) | SET n.marked1 = true SET n.marked2 = true)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n)
|
||||
RETURN n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| ({marked1: true, marked2: true}) |
|
||||
| ({marked1: true, marked2: true}) |
|
||||
And no side effects
|
||||
|
||||
Scenario: Foreach multiple nested update clauses
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (n1 { marked1: false, marked2: false })-[:RELATES]->(n2 { marked1: false, marked2: false })
|
||||
"""
|
||||
And having executed
|
||||
"""
|
||||
MATCH p=(n1)-[*]->(n2)
|
||||
FOREACH (n IN nodes(p) | FOREACH (j IN [1] | SET n.marked1 = true SET n.marked2 = true))
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n)
|
||||
RETURN n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| ({marked1: true, marked2: true}) |
|
||||
| ({marked1: true, marked2: true}) |
|
||||
And no side effects
|
||||
|
||||
Scenario: Foreach match foreach return
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (n {prop: [[], [1,2]]});
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) FOREACH (i IN n.prop | CREATE (:V { i: i})) RETURN n;
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| ({prop: [[], [1, 2]]}) |
|
||||
And no side effects
|
||||
|
||||
Scenario: Foreach on null value
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (n);
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) FOREACH (i IN n.prop | CREATE (:V { i: i}));
|
||||
"""
|
||||
Then the result should be:
|
||||
| |
|
||||
And no side effects
|
||||
|
||||
Scenario: Foreach nested merge
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
FOREACH(i in [1, 2, 3] | FOREACH(j in [1] | MERGE (n { age : i })));
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n)
|
||||
RETURN n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| ({age: 1}) |
|
||||
| ({age: 2}) |
|
||||
| ({age: 3}) |
|
||||
And no side effects
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,265 @@
|
||||
Feature: List operators
|
||||
|
||||
Scenario: In test1
|
||||
When executing query:
|
||||
"""
|
||||
WITH [1, 2, 3, 4] AS l
|
||||
RETURN 3 IN l as x
|
||||
"""
|
||||
Then the result should be:
|
||||
| x |
|
||||
| true |
|
||||
|
||||
Scenario: In test2
|
||||
When executing query:
|
||||
"""
|
||||
WITH [1, '2', 3, 4] AS l
|
||||
RETURN 2 IN l as x
|
||||
"""
|
||||
Then the result should be:
|
||||
| x |
|
||||
| false |
|
||||
|
||||
Scenario: In test4
|
||||
When executing query:
|
||||
"""
|
||||
WITH [1, [2, 3], 4] AS l
|
||||
RETURN [3, 2] IN l as x
|
||||
"""
|
||||
Then the result should be:
|
||||
| x |
|
||||
| false |
|
||||
|
||||
Scenario: In test5
|
||||
When executing query:
|
||||
"""
|
||||
WITH [[1, 2], 3, 4] AS l
|
||||
RETURN 1 IN l as x
|
||||
"""
|
||||
Then the result should be:
|
||||
| x |
|
||||
| false |
|
||||
|
||||
Scenario: In test6
|
||||
When executing query:
|
||||
"""
|
||||
WITH [1, [[2, 3], 4]] AS l
|
||||
RETURN [[2, 3], 4] IN l as x
|
||||
"""
|
||||
Then the result should be:
|
||||
| x |
|
||||
| true |
|
||||
|
||||
Scenario: In test7
|
||||
When executing query:
|
||||
"""
|
||||
WITH [1, [[2, 3], 4]] AS l
|
||||
RETURN [1, [[2, 3], 4]] IN l as x
|
||||
"""
|
||||
Then the result should be:
|
||||
| x |
|
||||
| false |
|
||||
|
||||
Scenario: Index test1
|
||||
When executing query:
|
||||
"""
|
||||
WITH [1, 2, 3, 4] AS l
|
||||
RETURN l[2] as x
|
||||
"""
|
||||
Then the result should be:
|
||||
| x |
|
||||
| 3 |
|
||||
|
||||
Scenario: Index test2
|
||||
When executing query:
|
||||
"""
|
||||
WITH [1, 2, 3, 4] AS l
|
||||
RETURN l[-2] as x
|
||||
"""
|
||||
Then the result should be:
|
||||
| x |
|
||||
| 3 |
|
||||
|
||||
Scenario: Index test3
|
||||
When executing query:
|
||||
"""
|
||||
WITH [1, 2, 3, 4] AS l
|
||||
RETURN l[2][0] as x
|
||||
"""
|
||||
Then an error should be raised
|
||||
|
||||
Scenario: Index test4
|
||||
When executing query:
|
||||
"""
|
||||
WITH [1, 2, [3], 4] AS l
|
||||
RETURN l[2][0] as x
|
||||
"""
|
||||
Then the result should be:
|
||||
| x |
|
||||
| 3 |
|
||||
|
||||
Scenario: Index test5
|
||||
When executing query:
|
||||
"""
|
||||
WITH [[1, [2, [3]]], 4] AS l
|
||||
RETURN l[0][1][1][0] as x
|
||||
"""
|
||||
Then the result should be:
|
||||
| x |
|
||||
| 3 |
|
||||
|
||||
Scenario: Slice test1
|
||||
When executing query:
|
||||
"""
|
||||
WITH [1, 2, 3, 4] AS l
|
||||
RETURN l[0..2] as x
|
||||
"""
|
||||
Then the result should be, in order:
|
||||
| x |
|
||||
| [1, 2] |
|
||||
|
||||
Scenario: Slice test2
|
||||
When executing query:
|
||||
"""
|
||||
WITH [1, 2, 3, 4] AS l
|
||||
RETURN l[-2..5] as x
|
||||
"""
|
||||
Then the result should be, in order:
|
||||
| x |
|
||||
| [3, 4] |
|
||||
|
||||
Scenario: Slice test3
|
||||
When executing query:
|
||||
"""
|
||||
WITH [1, 2, 3, 4] AS l
|
||||
RETURN l[-2..4] as x
|
||||
"""
|
||||
Then the result should be, in order:
|
||||
| x |
|
||||
| [3, 4] |
|
||||
|
||||
Scenario: Slice test4
|
||||
When executing query:
|
||||
"""
|
||||
WITH [1, 2, 3, 4] AS l
|
||||
RETURN l[-1..4] as x
|
||||
"""
|
||||
Then the result should be, in order:
|
||||
| x |
|
||||
| [4] |
|
||||
|
||||
Scenario: Slice test5
|
||||
When executing query:
|
||||
"""
|
||||
WITH [1, 2, 3, 4] AS l
|
||||
RETURN l[-2..-2] as x
|
||||
"""
|
||||
Then the result should be, in order:
|
||||
| x |
|
||||
| [] |
|
||||
|
||||
Scenario: Slice test6
|
||||
When executing query:
|
||||
"""
|
||||
WITH [1, 2, 3, 4] AS l
|
||||
RETURN l[4..-2] as x
|
||||
"""
|
||||
Then the result should be, in order:
|
||||
| x |
|
||||
| [] |
|
||||
|
||||
Scenario: Concatenate test1
|
||||
When executing query:
|
||||
"""
|
||||
WITH [1, 2, 3, 4] AS l1, [5, 6, 7] AS l2
|
||||
RETURN l1+l2 as x
|
||||
"""
|
||||
Then the result should be, in order:
|
||||
| x |
|
||||
| [1, 2, 3, 4, 5, 6, 7] |
|
||||
|
||||
Scenario: Concatenate test2
|
||||
When executing query:
|
||||
"""
|
||||
WITH [[1, [2]]] AS l1, [[[3], 4]] AS l2
|
||||
RETURN l1+l2 as x
|
||||
"""
|
||||
Then the result should be, in order:
|
||||
| x |
|
||||
| [[1, [2]], [[3], 4]] |
|
||||
|
||||
Scenario: Concatenate test3
|
||||
When executing query:
|
||||
"""
|
||||
WITH [1, 2, 3, 4] AS l1, NULL AS l2
|
||||
RETURN l1+l2 as x
|
||||
"""
|
||||
Then the result should be, in order:
|
||||
| x |
|
||||
| null |
|
||||
|
||||
Scenario: Concatenate test4
|
||||
When executing query:
|
||||
"""
|
||||
WITH [] AS l1, [] AS l2
|
||||
RETURN l1+l2 as x
|
||||
"""
|
||||
Then the result should be, in order:
|
||||
| x |
|
||||
| [] |
|
||||
|
||||
Scenario: Unwind test
|
||||
When executing query:
|
||||
"""
|
||||
UNWIND [ [[1], 2], [3], 4] as l
|
||||
RETURN l
|
||||
"""
|
||||
Then the result should be:
|
||||
| l |
|
||||
| [[1], 2] |
|
||||
| [3] |
|
||||
| 4 |
|
||||
|
||||
Scenario: Unwind + InList test1
|
||||
When executing query:
|
||||
"""
|
||||
UNWIND [[1,2], [3,4]] as l
|
||||
RETURN 2 in l as x
|
||||
"""
|
||||
Then the result should be:
|
||||
| x |
|
||||
| true |
|
||||
| false |
|
||||
|
||||
Scenario: Unwind + InList test2
|
||||
When executing query:
|
||||
"""
|
||||
WITH [[1,2], [3,4]] as list
|
||||
UNWIND list as l
|
||||
RETURN 2 in l as x
|
||||
"""
|
||||
Then the result should be:
|
||||
| x |
|
||||
| true |
|
||||
| false |
|
||||
|
||||
Scenario: Unwind + InList test3
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE ({id: 1}), ({id: 2}), ({id: 3}), ({id: 4})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
WITH [1, 2, 3] as list
|
||||
MATCH (n) WHERE n.id in list
|
||||
WITH n
|
||||
WITH n, [1, 2] as list
|
||||
WHERE n.id in list
|
||||
RETURN n.id as id
|
||||
ORDER BY id;
|
||||
"""
|
||||
Then the result should be:
|
||||
| id |
|
||||
| 1 |
|
||||
| 2 |
|
167
tests/gql_behave/tests/memgraph_V1_on_disk/features/map.feature
Normal file
167
tests/gql_behave/tests/memgraph_V1_on_disk/features/map.feature
Normal file
@ -0,0 +1,167 @@
|
||||
Feature: Creating map values
|
||||
|
||||
Scenario: Creating a map with multiple properties from a vertex
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (:Employee {name: "Andy", surname: "Walker", age: 24, id: 1234});
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (e:Employee) RETURN {name: e.name, surname: e.surname, age: e.age} AS public_data;
|
||||
"""
|
||||
Then the result should be:
|
||||
| public_data |
|
||||
| {age: 24, name: 'Andy', surname: 'Walker'} |
|
||||
|
||||
Scenario: Creating instances of a map with multiple properties from a vertex
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (:Employee {name: "Andy", surname: "Walker", age: 24, id: 1234}), (:Person), (:Person);
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (e:Employee), (n:Person) RETURN {name: e.name, surname: e.surname, age: e.age} AS public_data;
|
||||
"""
|
||||
Then the result should be:
|
||||
| public_data |
|
||||
| {age: 24, name: 'Andy', surname: 'Walker'} |
|
||||
| {age: 24, name: 'Andy', surname: 'Walker'} |
|
||||
|
||||
Scenario: Creating a map with multiple properties from each vertex
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (:Cat {name: "Luigi", age: 11}), (:Dog {name: "Don", age: 10}), (:Owner {name: "Ivan"});
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (m:Cat), (n:Dog), (o:Owner) SET o += {catName: m.name, catAge: m.age, dogName: n.name, dogAge: n.age} RETURN o;
|
||||
"""
|
||||
Then the result should be:
|
||||
| o |
|
||||
| (:Owner {catAge: 11, catName: 'Luigi', dogAge: 10, dogName: 'Don', name: 'Ivan'}) |
|
||||
|
||||
Scenario: Creating distinct maps with multiple properties, each from one vertex
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
FOREACH (i in range(1, 5) | CREATE (:Node {prop1: i, prop2: 2 * i}));
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) RETURN {prop1: n.prop1, prop2: n.prop2} AS prop_data;
|
||||
"""
|
||||
Then the result should be:
|
||||
| prop_data |
|
||||
| {prop1: 1, prop2: 2} |
|
||||
| {prop1: 2, prop2: 4} |
|
||||
| {prop1: 3, prop2: 6} |
|
||||
| {prop1: 4, prop2: 8} |
|
||||
| {prop1: 5, prop2: 10} |
|
||||
|
||||
Scenario: Creating a map with multiple properties from a vertex; one property is null
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (:Employee {name: "Andy", surname: "Walker", age: 24, id: 1234});
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (e:Employee) RETURN {name: e.name, surname: e.surname, age: e.age, null_prop: e.nonexistent} AS public_data;
|
||||
"""
|
||||
Then the result should be:
|
||||
| public_data |
|
||||
| {age: 24, name: 'Andy', null_prop: null, surname: 'Walker'} |
|
||||
|
||||
Scenario: Creating a map with multiple properties from an edge
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (m)-[:ROUTE {km: 466, cross_border: true}]->(n);
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH ()-[r:ROUTE]->() RETURN {km: r.km, cross_border: r.cross_border} AS route_data;
|
||||
"""
|
||||
Then the result should be:
|
||||
| route_data |
|
||||
| {cross_border: true, km: 466} |
|
||||
|
||||
Scenario: Creating instances of a map with multiple properties from an edge
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (m)-[:ROUTE {km: 466, cross_border: true}]->(n), (:City), (:City);
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (:City), ()-[r:ROUTE]->() RETURN {km: r.km, cross_border: r.cross_border} AS route_data;
|
||||
"""
|
||||
Then the result should be:
|
||||
| route_data |
|
||||
| {cross_border: true, km: 466} |
|
||||
| {cross_border: true, km: 466} |
|
||||
|
||||
Scenario: Creating a map with multiple properties from each edge
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (m)-[:HIGHWAY {km: 466, cross_border: true}]->(n), (m)-[:FLIGHT {km: 350, daily: true}]->(n);
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH ()-[h:HIGHWAY]->(), ()-[f:FLIGHT]->()
|
||||
RETURN {km_hwy: h.km, cross_border: h.cross_border, km_air: f.km, daily_flight: f.daily} AS routes_data;
|
||||
"""
|
||||
Then the result should be:
|
||||
| routes_data |
|
||||
| {cross_border: true, daily_flight: true, km_air: 350, km_hwy: 466} |
|
||||
|
||||
Scenario: Creating distinct maps with multiple properties, each from one edge
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
MERGE (m:City) MERGE (n:Country) FOREACH (i in range(1, 5) | CREATE (m)-[:IN {prop1: i, prop2: 2 * i}]->(n));
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (m)-[r]->(n) RETURN {prop1: r.prop1, prop2: r.prop2} AS prop_data;
|
||||
"""
|
||||
Then the result should be:
|
||||
| prop_data |
|
||||
| {prop1: 1, prop2: 2} |
|
||||
| {prop1: 2, prop2: 4} |
|
||||
| {prop1: 3, prop2: 6} |
|
||||
| {prop1: 4, prop2: 8} |
|
||||
| {prop1: 5, prop2: 10} |
|
||||
|
||||
Scenario: Creating a map with multiple properties from an edge; one property is null
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (m)-[:ROUTE {km: 466, cross_border: true}]->(n);
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH ()-[r:ROUTE]->() RETURN {km: r.km, cross_border: r.cross_border, null_prop: r.nonexistent} AS route_data;
|
||||
"""
|
||||
Then the result should be:
|
||||
| route_data |
|
||||
| {cross_border: true, km: 466, null_prop: null} |
|
||||
|
||||
Scenario: Creating a map with multiple properties from both a vertex and an edge
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (m:City {name: "Split", highway_connected: true})-[:ROUTE {km: 466, cross_border: true}]->(n:City {name: "Ljubljana"});
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (m:City {name: "Split"})-[r:ROUTE]->()
|
||||
RETURN {km: r.km, cross_border: r.cross_border, start_city: m.name, highway_connected: m.highway_connected} AS route_data;
|
||||
"""
|
||||
Then the result should be:
|
||||
| route_data |
|
||||
| {cross_border: true, highway_connected: true, km: 466, start_city: 'Split'} |
|
@ -0,0 +1,45 @@
|
||||
Feature: Map operators
|
||||
|
||||
Scenario: Returning a map
|
||||
When executing query:
|
||||
"""
|
||||
RETURN {a: 1, b: 'bla', c: [1, 2], d: {a: 42}} as result
|
||||
"""
|
||||
Then the result should be:
|
||||
| result |
|
||||
| {a: 1, b: 'bla', c: [1, 2], d: {a: 42}} |
|
||||
|
||||
|
||||
Scenario: Storing a map property
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE ({prop: {x: 1, y: true, z: "bla"}})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) RETURN n.prop
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.prop |
|
||||
| {x: 1, y: true, z: 'bla'} |
|
||||
|
||||
|
||||
Scenario: A property lookup on a map literal
|
||||
When executing query:
|
||||
"""
|
||||
WITH {a: 1, b: 'bla', c: {d: 42}} AS x RETURN x.a, x.c.d
|
||||
"""
|
||||
Then the result should be:
|
||||
| x.a | x.c.d |
|
||||
| 1 | 42 |
|
||||
|
||||
|
||||
Scenario: Map indexing
|
||||
When executing query:
|
||||
"""
|
||||
WITH {a: 1, b: 'bla', c: {d: 42}} AS x RETURN x["a"] as xa, x["c"]["d"] as xcd, x["z"] as xz
|
||||
"""
|
||||
Then the result should be:
|
||||
| xa | xcd | xz |
|
||||
| 1 | 42 | null |
|
@ -0,0 +1,87 @@
|
||||
Feature: Map projection
|
||||
|
||||
Scenario: Returning an empty map projection
|
||||
When executing query:
|
||||
"""
|
||||
WITH {} AS map
|
||||
RETURN map {} AS result
|
||||
"""
|
||||
Then the result should be:
|
||||
| result |
|
||||
| {} |
|
||||
|
||||
Scenario: Returning a map projection with each type of map projection element
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (n:Actor {name: "Morgan", lastName: "Freeman"})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
WITH 85 as age
|
||||
MATCH (actor:Actor)
|
||||
RETURN actor {.*, .name, age, oscars: 1} AS result
|
||||
"""
|
||||
Then the result should be:
|
||||
| result |
|
||||
| {age: 85, lastName: 'Freeman', name: 'Morgan', oscars: 1} |
|
||||
|
||||
Scenario: Projecting from a null value
|
||||
When executing query:
|
||||
"""
|
||||
WITH "value" AS var
|
||||
OPTIONAL MATCH (n:Nonexistent)
|
||||
RETURN n {.*} AS result0, n {.prop} AS result1, n {prop: "value"} AS result2, n {var} AS result3;
|
||||
"""
|
||||
Then the result should be:
|
||||
| result0 | result1 | result2 | result3 |
|
||||
| null | null | null | null |
|
||||
|
||||
Scenario: Projecting a nonexistent property
|
||||
When executing query:
|
||||
"""
|
||||
WITH {name: "Morgan", lastName: "Freeman"} as actor
|
||||
RETURN actor.age;
|
||||
"""
|
||||
Then the result should be:
|
||||
| actor.age |
|
||||
| null |
|
||||
|
||||
Scenario: Storing a map projection as a property
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
WITH {name: "Morgan", lastName: "Freeman"} as person
|
||||
WITH person {.*, wonOscars: true} as actor
|
||||
CREATE (n:Movie {lead: actor});
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (movie:Movie)
|
||||
RETURN movie.lead
|
||||
"""
|
||||
Then the result should be:
|
||||
| movie.lead |
|
||||
| {lastName: 'Freeman', name: 'Morgan', wonOscars: true} |
|
||||
|
||||
Scenario: Looking up the properties of a map projection
|
||||
When executing query:
|
||||
"""
|
||||
WITH {name: "Morgan", lastName: "Freeman"} as actor, {oscars: 1} as awards
|
||||
WITH actor {.*, awards: awards} AS actor
|
||||
RETURN actor.name, actor.awards.oscars;
|
||||
"""
|
||||
Then the result should be:
|
||||
| actor.name | actor.awards.oscars |
|
||||
| 'Morgan' | 1 |
|
||||
|
||||
Scenario: Indexing a map projection
|
||||
When executing query:
|
||||
"""
|
||||
WITH {name: "Morgan", lastName: "Freeman"} as actor, {oscars: 1} as awards
|
||||
WITH actor {.*, awards: awards} AS actor
|
||||
RETURN actor["name"], actor["awards"]["oscars"]
|
||||
"""
|
||||
Then the result should be:
|
||||
| actor["name"] | actor["awards"]["oscars"] |
|
||||
| 'Morgan' | 1 |
|
@ -0,0 +1,687 @@
|
||||
Feature: Match
|
||||
|
||||
Scenario: Create node and self relationships and match
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (n)-[:X]->(n)<-[:Y]-(n)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH ()-[a]-()-[b]-() RETURN a, b
|
||||
"""
|
||||
Then the result should be:
|
||||
| a | b |
|
||||
| [:X] | [:Y] |
|
||||
| [:Y] | [:X] |
|
||||
|
||||
Scenario: Create node and self relationship and match
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (n)-[:X]->(n)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH ()-[a]-() RETURN a
|
||||
"""
|
||||
Then the result should be:
|
||||
| a |
|
||||
| [:X] |
|
||||
|
||||
Scenario: Create node and self relationships and match
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (n)-[:X]->(n)<-[:Y]-(n)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH ()<-[a]-()-[b]->() RETURN a, b
|
||||
"""
|
||||
Then the result should be:
|
||||
| a | b |
|
||||
| [:X] | [:Y] |
|
||||
| [:Y] | [:X] |
|
||||
|
||||
Scenario: Create multiple nodes and relationships and match
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE ()-[:X]->()<-[:Y]-()
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH ()-[a]-()-[b]-() RETURN a, b
|
||||
"""
|
||||
Then the result should be:
|
||||
| a | b |
|
||||
| [:X] | [:Y] |
|
||||
| [:Y] | [:X] |
|
||||
|
||||
Scenario: Create multiple nodes and relationships and match
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE ()-[:X]->()<-[:Y]-()
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH ()<-[a]-()-[b]-() RETURN a, b
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Create cycle and match
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (a)-[:X]->()-[:Y]->()-[:Z]->(a)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH ()-[a]->()-[b]->() RETURN a, b
|
||||
"""
|
||||
Then the result should be:
|
||||
| a | b |
|
||||
| [:X] | [:Y] |
|
||||
| [:Y] | [:Z] |
|
||||
| [:Z] | [:X] |
|
||||
|
||||
Scenario: Create cycle and match
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (a)-[:X]->()-[:Y]->()-[:Z]->(a)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH ()-[a]-()-[b]-() RETURN a, b
|
||||
"""
|
||||
Then the result should be:
|
||||
| a | b |
|
||||
| [:X] | [:Y] |
|
||||
| [:Y] | [:Z] |
|
||||
| [:Z] | [:X] |
|
||||
| [:X] | [:Z] |
|
||||
| [:Y] | [:X] |
|
||||
| [:Z] | [:Y] |
|
||||
|
||||
Scenario: Create cycle and match
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (a)-[:X]->()-[:Y]->()-[:Z]->(a)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH ()<-[a]-()-[b]->() RETURN a, b
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Create cycle and match
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (a)-[:X]->()-[:Y]->()-[:Z]->(a)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH ()-[a]->()-[]->()-[]->()-[]->() RETURN a
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Create two nodes with three relationships and match
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (a)-[:X]->(b)-[:Y]->(a)-[:Z]->(b)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH ()-[a]->()-[b]->()-[c]->() RETURN a, b, c
|
||||
"""
|
||||
Then the result should be:
|
||||
| a | b | c |
|
||||
| [:X] | [:Y] | [:Z] |
|
||||
| [:Z] | [:Y] | [:X] |
|
||||
|
||||
Scenario: Create two nodes with three relationships and match
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (a)-[:X]->(b)-[:Y]->(a)-[:Z]->(b)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH ()-[a]-()-[b]-()-[c]-() RETURN a, b, c
|
||||
"""
|
||||
Then the result should be:
|
||||
| a | b | c |
|
||||
| [:X] | [:Y] | [:Z] |
|
||||
| [:X] | [:Z] | [:Y] |
|
||||
| [:Y] | [:X] | [:Z] |
|
||||
| [:Y] | [:Z] | [:X] |
|
||||
| [:Z] | [:Y] | [:X] |
|
||||
| [:Z] | [:X] | [:Y] |
|
||||
| [:X] | [:Y] | [:Z] |
|
||||
| [:X] | [:Z] | [:Y] |
|
||||
| [:Y] | [:X] | [:Z] |
|
||||
| [:Y] | [:Z] | [:X] |
|
||||
| [:Z] | [:Y] | [:X] |
|
||||
| [:Z] | [:X] | [:Y] |
|
||||
|
||||
Scenario: Create two nodes with three relationships and match
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (a)-[:X{a: 1.0}]->(b)-[:Y]->(a)-[:Z]->(b)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH ()-[a{a: 1.0}]-()-[b]-()-[c]-() RETURN a, b, c
|
||||
"""
|
||||
Then the result should be:
|
||||
| a | b | c |
|
||||
| [:X{a: 1.0}] | [:Y] | [:Z] |
|
||||
| [:X{a: 1.0}] | [:Z] | [:Y] |
|
||||
| [:X{a: 1.0}] | [:Y] | [:Z] |
|
||||
| [:X{a: 1.0}] | [:Z] | [:Y] |
|
||||
|
||||
Scenario: Create two nodes with three relationships and match
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (a)-[:X{a: 1.0}]->(b)-[:Y]->(a)-[:Z]->(b)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH ()-[a{a: 1.0}]-()-[b]-()-[c:Y]-() RETURN a, b, c
|
||||
"""
|
||||
Then the result should be:
|
||||
| a | b | c |
|
||||
| [:X{a: 1.0}] | [:Z] | [:Y] |
|
||||
| [:X{a: 1.0}] | [:Z] | [:Y] |
|
||||
|
||||
Scenario: Create two nodes with three relationships and match
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (a)-[:X{a: 1.0}]->(b)-[:Y{a: 1.0}]->(a)-[:Z]->(b)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH ()-[a{a: 1.0}]-()-[b]-()-[c:Y]-() RETURN a, b, c
|
||||
"""
|
||||
Then the result should be:
|
||||
| a | b | c |
|
||||
| [:X{a: 1.0}] | [:Z] | [:Y{a: 1.0}] |
|
||||
| [:X{a: 1.0}] | [:Z] | [:Y{a: 1.0}] |
|
||||
|
||||
Scenario: Create two nodes with three relationships and match
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (a)-[:X{a: 1.0}]->(b)-[:Y{a: 1.0}]->(a)-[:Z]->(b)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH ()-[a{a: 1.0}]-()-[b]-()-[c{a: 1.0}]-() RETURN a, b, c, c.a as t
|
||||
"""
|
||||
Then the result should be:
|
||||
| a | b | c | t |
|
||||
| [:X{a: 1.0}] | [:Z] | [:Y{a: 1.0}] | 1.0 |
|
||||
| [:X{a: 1.0}] | [:Z] | [:Y{a: 1.0}] | 1.0 |
|
||||
| [:Y{a: 1.0}] | [:Z] | [:X{a: 1.0}] | 1.0 |
|
||||
| [:Y{a: 1.0}] | [:Z] | [:X{a: 1.0}] | 1.0 |
|
||||
|
||||
Scenario: Create two nodes with three relationships and match
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (a:T{c: True})-[:X{x: 2.5}]->(:A:B)-[:Y]->()-[:Z{r: 1}]->(a)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (:T{c: True})-[a:X{x: 2.5}]->(node:A:B)-[:Y]->()-[:Z{r: 1}]->() RETURN a AS node, node AS a
|
||||
"""
|
||||
Then the result should be:
|
||||
| node | a |
|
||||
| [:X{x: 2.5}] | (:A:B) |
|
||||
|
||||
Scenario: Create and match with label
|
||||
Given graph "graph_01"
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:Person) RETURN n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| (:Person {age: 20}) |
|
||||
| (:Person :Student {age: 20}) |
|
||||
| (:Person {age: 21}) |
|
||||
|
||||
Scenario: Create and match with label
|
||||
Given graph "graph_01"
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:Student) RETURN n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| (:Person :Student {age: 20}) |
|
||||
| (:Student {age: 21}) |
|
||||
|
||||
Scenario: Create, match with label and property
|
||||
Given graph "graph_01"
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:Person {age: 20}) RETURN n AS x
|
||||
"""
|
||||
Then the result should be:
|
||||
| x |
|
||||
| (:Person {age: 20}) |
|
||||
| (:Person :Student {age: 20}) |
|
||||
|
||||
Scenario: Create, match with label and filter property using WHERE
|
||||
Given graph "graph_01"
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:Person) WHERE n.age = 20 RETURN n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| (:Person {age: 20}) |
|
||||
| (:Person :Student {age: 20}) |
|
||||
|
||||
Scenario: Create and match with property
|
||||
Given graph "graph_01"
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n {age: 20}) RETURN n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| (:Person {age: 20}) |
|
||||
| (:Person :Student {age: 20}) |
|
||||
|
||||
Scenario: Create and match pattern with cross referencing variables in property maps
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE ({x: 1, y: 5, z: 3})-[:E]->({x: 10, y: 1, z: 3})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n {x: m.y, z: m.z})-[]-(m {y: n.x, z: n.z}) RETURN n, m
|
||||
"""
|
||||
Then the result should be:
|
||||
| n | m |
|
||||
| ({x: 1, y: 5, z: 3}) | ({x: 10, y: 1, z: 3}) |
|
||||
|
||||
Scenario: Test match with order by
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE({a: 1}), ({a: 2}), ({a: 3}), ({a: 4}), ({a: 5})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) RETURN n.a ORDER BY n.a
|
||||
"""
|
||||
Then the result should be, in order:
|
||||
| n.a |
|
||||
| 1 |
|
||||
| 2 |
|
||||
| 3 |
|
||||
| 4 |
|
||||
| 5 |
|
||||
|
||||
Scenario: Test match with order by and skip
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE({a: 1}), ({a: 2}), ({a: 3}), ({a: 4}), ({a: 5})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) RETURN n.a ORDER BY n.a SKIP 3
|
||||
"""
|
||||
Then the result should be, in order:
|
||||
| n.a |
|
||||
| 4 |
|
||||
| 5 |
|
||||
|
||||
Scenario: Test match with order by and limit
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE({a: 1}), ({a: 2}), ({a: 3}), ({a: 4}), ({a: 5})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) RETURN n.a ORDER BY n.a LIMIT 2
|
||||
"""
|
||||
Then the result should be, in order:
|
||||
| n.a |
|
||||
| 1 |
|
||||
| 2 |
|
||||
|
||||
Scenario: Test match with order by, skip and limit
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE({a: 1}), ({a: 2}), ({a: 3}), ({a: 4}), ({a: 5})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) RETURN n.a ORDER BY n.a SKIP 2 LIMIT 2
|
||||
"""
|
||||
Then the result should be, in order:
|
||||
| n.a |
|
||||
| 3 |
|
||||
| 4 |
|
||||
|
||||
Scenario: Test match with order by and skip
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE({a: 1}), ({a: 2}), ({a: 3}), ({a: 4}), ({a: 5})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) RETURN n.a ORDER BY n.a SKIP 6
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Test match with order by and limit
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE({a: 1}), ({a: 2}), ({a: 3}), ({a: 4}), ({a: 5})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) RETURN n.a ORDER BY n.a LIMIT 0
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Test match with order by and date
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE({a: DATE('2021-12-31')}), ({a: DATE('2021-11-11')}), ({a: DATE('2021-12-28')})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) RETURN n.a ORDER BY n.a
|
||||
"""
|
||||
Then the result should be, in order:
|
||||
| n.a |
|
||||
| 2021-11-11 |
|
||||
| 2021-12-28 |
|
||||
| 2021-12-31 |
|
||||
|
||||
Scenario: Test match with order by and localtime
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE({a: LOCALTIME('09:12:31')}), ({a: LOCALTIME('09:09:20')}), ({a: LOCALTIME('09:11:21')})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) RETURN n.a ORDER BY n.a
|
||||
"""
|
||||
Then the result should be, in order:
|
||||
| n.a |
|
||||
| 09:09:20.000000000 |
|
||||
| 09:11:21.000000000 |
|
||||
| 09:12:31.000000000 |
|
||||
|
||||
Scenario: Test match with order by and localdatetime
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE({a: LOCALDATETIME('2021-11-22T09:12:31')}), ({a: LOCALDATETIME('2021-11-23T09:10:30')}), ({a: LOCALDATETIME('2021-11-10T09:14:21')})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) RETURN n.a ORDER BY n.a
|
||||
"""
|
||||
Then the result should be, in order:
|
||||
| n.a |
|
||||
| 2021-11-10T09:14:21.000000000 |
|
||||
| 2021-11-22T09:12:31.000000000 |
|
||||
| 2021-11-23T09:10:30.000000000 |
|
||||
|
||||
Scenario: Test match with order by and duration
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE({a: DURATION('P12DT3M')}), ({a: DURATION('P11DT8M')}), ({a: DURATION('P11DT60H')})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) RETURN n.a ORDER BY n.a
|
||||
"""
|
||||
Then the result should be, in order:
|
||||
| n.a |
|
||||
| P11DT8M |
|
||||
| P12DT3M |
|
||||
| P13DT12H |
|
||||
|
||||
Scenario: Test distinct
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE({a: 1}), ({a: 4}), ({a: 3}), ({a: 1}), ({a: 4})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) RETURN DISTINCT n.a
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.a |
|
||||
| 1 |
|
||||
| 3 |
|
||||
| 4 |
|
||||
|
||||
Scenario: Test match unbounded variable path
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE ({a: 1}) -[:r]-> ({a:2}) -[:r]-> ({a:3})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) -[r*]-> (m) RETURN n.a, m.a
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.a | m.a |
|
||||
| 1 | 2 |
|
||||
| 1 | 3 |
|
||||
| 2 | 3 |
|
||||
|
||||
Scenario: Test match 0 length variable path
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE ({a: 1}) -[:r]-> ({a:2}) -[:r]-> ({a:3})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) -[r*0]-> (m) RETURN n.a, m.a
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.a | m.a |
|
||||
| 1 | 1 |
|
||||
| 2 | 2 |
|
||||
| 3 | 3 |
|
||||
|
||||
Scenario: Test match bounded variable path
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE ({a: 1}) -[:r]-> ({a:2}) -[:r]-> ({a:3})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) -[r*0..1]-> (m) RETURN n.a, m.a
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.a | m.a |
|
||||
| 1 | 1 |
|
||||
| 1 | 2 |
|
||||
| 2 | 2 |
|
||||
| 2 | 3 |
|
||||
| 3 | 3 |
|
||||
|
||||
Scenario: Test match filtered edge type variable path
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE ({a: 1}) -[:r1]-> ({a:2}) -[:r2]-> ({a:3})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) -[:r1*]-> (m) RETURN n.a, m.a
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.a | m.a |
|
||||
| 1 | 2 |
|
||||
|
||||
Scenario: Test match filtered properties variable path
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE ({a: 1}) -[:r {p1: 1, p2: 2}]-> ({a:2}) -[:r {p1: 1, p2: 3}]-> ({a:3})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) -[*{p1: 1, p2:2}]-> (m) RETURN n.a, m.a
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.a | m.a |
|
||||
| 1 | 2 |
|
||||
|
||||
Scenario: Named path with length function.
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:starting)-[:type]->()
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH path = (:starting) -[*0..1]-> () RETURN size(path)
|
||||
"""
|
||||
Then the result should be:
|
||||
| size(path) |
|
||||
| 0 |
|
||||
| 1 |
|
||||
|
||||
Scenario: Variable expand to existing symbol 1
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (p1:Person {id: 1})-[:KNOWS]->(:Person {id: 2})-[:KNOWS]->(:Person {id: 3})-[:KNOWS]->(:Person {id: 4})-[:KNOWS]->(p1);
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH path = (pers:Person {id: 3})-[:KNOWS*2]->(pers) RETURN path;
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Variable expand to existing symbol 2
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (p1:Person {id: 1})-[:KNOWS]->(:Person {id: 2})-[:KNOWS]->(:Person {id: 3})-[:KNOWS]->(:Person {id: 4})-[:KNOWS]->(p1);
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH path = (pers:Person {id: 3})-[:KNOWS*]->(pers) RETURN path
|
||||
"""
|
||||
Then the result should be:
|
||||
| path |
|
||||
| <(:Person{id:3})-[:KNOWS]->(:Person{id:4})-[:KNOWS]->(:Person{id:1})-[:KNOWS]->(:Person{id:2})-[:KNOWS]->(:Person{id:3})> |
|
||||
|
||||
Scenario: Variable expand to existing symbol 3
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (p1:Person {id: 1})-[:KNOWS]->(:Person {id: 2})-[:KNOWS]->(:Person {id: 3})-[:KNOWS]->(:Person {id: 4})-[:KNOWS]->(p1);
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH path = (pers:Person {id: 3})-[:KNOWS*0..]->(pers) RETURN path
|
||||
"""
|
||||
Then the result should be:
|
||||
| path |
|
||||
| <(:Person{id:3})> |
|
||||
| <(:Person{id:3})-[:KNOWS]->(:Person{id:4})-[:KNOWS]->(:Person{id:1})-[:KNOWS]->(:Person{id:2})-[:KNOWS]->(:Person{id:3})> |
|
||||
|
||||
Scenario: Variable expand to existing symbol 4
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (p1:Person {id: 1})-[:KNOWS]->(:Person {id: 2})-[:KNOWS]->(:Person {id: 3})-[:KNOWS]->(:Person {id: 4})-[:KNOWS]->(p1);
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH path = (pers:Person {id: 3})-[:KNOWS*2..6]->(pers) RETURN path
|
||||
"""
|
||||
Then the result should be:
|
||||
| path |
|
||||
| <(:Person{id:3})-[:KNOWS]->(:Person{id:4})-[:KNOWS]->(:Person{id:1})-[:KNOWS]->(:Person{id:2})-[:KNOWS]->(:Person{id:3})> |
|
||||
|
||||
Scenario: Variable expand to existing symbol 5
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (p1:Person {id: 1})-[:KNOWS]->(:Person {id: 2})-[:KNOWS]->(:Person {id: 3})-[:KNOWS]->(:Person {id: 4})-[:KNOWS]->(p1);
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH path = (pers:Person {id: 3})-[:KNOWS*5..]->(pers) RETURN path
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Variable expand to existing symbol 6
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (p1:Person {id: 1})-[:KNOWS]->(p1);
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH path = (pers:Person {id: 1})-[:KNOWS*]->(pers) RETURN path
|
||||
"""
|
||||
Then the result should be
|
||||
| path |
|
||||
| <(:Person{id:1})-[:KNOWS]->(:Person{id:1})> |
|
||||
|
||||
Scenario: Variable expand to existing symbol 7
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (p1:Person {id: 1})-[:KNOWS]->(p1);
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH path = (pers:Person {id: 1})-[:KNOWS*0..]->(pers) RETURN path
|
||||
"""
|
||||
Then the result should be
|
||||
| path |
|
||||
| <(:Person{id:1})> |
|
||||
| <(:Person{id:1})-[:KNOWS]->(:Person{id:1})> |
|
||||
|
||||
Scenario: Variable expand to existing symbol 8
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (p1:Person {id: 1})-[:KNOWS]->(p1);
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH path = (pers:Person {id: 1})-[:KNOWS*2..]->(pers) RETURN path
|
||||
"""
|
||||
Then the result should be empty
|
@ -0,0 +1,78 @@
|
||||
Feature: Memgraph only tests (queries in which we choose to be incompatible with neo4j)
|
||||
|
||||
Scenario: Multiple sets (undefined behaviour)
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (n{x: 3})-[:X]->(m{x: 5})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n)--(m) SET n.x = n.x + 1 SET m.x = m.x + 2 SET m.x = n.x RETURN n.x
|
||||
"""
|
||||
# TODO: Figure out if we can define a test with multiple possible outputs in cucumber,
|
||||
# until then this test just documents behaviour instead of testing it.
|
||||
# Then the result should be:
|
||||
# | n.x | | n.x |
|
||||
# | 5 | or | 7 |
|
||||
# | 5 | | 7 |
|
||||
|
||||
Scenario: Multiple comparisons
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
RETURN 1 < 10 > 5 < 7 > 6 < 8 AS x
|
||||
"""
|
||||
Then the result should be:
|
||||
| x |
|
||||
| true |
|
||||
|
||||
Scenario: Use deleted node
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
CREATE(a:A), (b:B), (c:C), (a)-[:T]->(b) WITH a DETACH DELETE a WITH a MATCH(a)-[r:T]->() RETURN r
|
||||
"""
|
||||
Then an error should be raised
|
||||
|
||||
Scenario: In test3
|
||||
When executing query:
|
||||
"""
|
||||
WITH [[1], 2, 3, 4] AS l
|
||||
RETURN 1 IN l as x
|
||||
"""
|
||||
Then the result should be:
|
||||
| x |
|
||||
| false |
|
||||
|
||||
Scenario: In test8
|
||||
When executing query:
|
||||
"""
|
||||
WITH [[[[1]]], 2, 3, 4] AS l
|
||||
RETURN 1 IN l as x
|
||||
"""
|
||||
Then the result should be:
|
||||
| x |
|
||||
| false |
|
||||
|
||||
Scenario: Keyword as symbolic name
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE(a:DELete)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) RETURN n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| (:DELete) |
|
||||
|
||||
Scenario: Aggregation in CASE:
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) RETURN CASE count(n) WHEN 10 THEN 10 END
|
||||
"""
|
||||
Then an error should be raised
|
@ -0,0 +1,205 @@
|
||||
Feature: All Shortest Path
|
||||
|
||||
Scenario: Test match allShortest upper bound
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (n {a:'0'})-[:r {w: 1}]->({a:'1'})-[:r {w: 1}]->({a:'2'}), (n)-[:r {w: 1}]->({a:'3'})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n {a:'0'})-[le *allShortest 1 (e, n | e.w ) w]->(m) RETURN m.a
|
||||
"""
|
||||
Then the result should be:
|
||||
| m.a |
|
||||
| '1' |
|
||||
| '3' |
|
||||
|
||||
Scenario: Test match allShortest upper bound 2
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (a {a:'0'})-[:r {w: 2}]->(b {a:'1'})-[:r {w: 3}]->(c {a:'2'}),
|
||||
(a)-[:re {w: 2}]->(b),
|
||||
(b)-[:re {w:3}]->(c),
|
||||
({a: '4'})<-[:r {w: 1}]-(a),
|
||||
({a: '5'})<-[:r {w: 1}]-(a),
|
||||
(c)-[:r {w: 1}]->({a: '6'}),
|
||||
(c)-[:r {w: 1}]->({a: '7'})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH path=(n {a:'0'})-[r *allShortest ..2 (e, n | 1 ) w]->(m {a:'2'}) RETURN COUNT(path) AS c
|
||||
"""
|
||||
Then the result should be:
|
||||
| c |
|
||||
| 4 |
|
||||
|
||||
Scenario: Test match allShortest filtered
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (n {a:'0'})-[:r {w: 1}]->({a:'1'})-[:r {w: 1}]->({a:'2'}), (n)-[:r {w: 1}]->({a:'3'})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n {a:'0'})-[le *allShortest 1 (e, n | e.w ) w (e, n | n.a = '3')]->(m) RETURN m.a
|
||||
"""
|
||||
Then the result should be:
|
||||
| m.a |
|
||||
| '3' |
|
||||
|
||||
Scenario: Test match allShortest resulting edge list
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (n {a:'0'})-[:r {w: 1}]->({a:'1'})-[:r {w: 2}]->({a:'2'}), (n)-[:r {w: 4}]->({a:'3'})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n {a:'0'})-[le *allShortest 10 (e, n | e.w ) w]->(m) RETURN m.a, size(le) as s, w
|
||||
"""
|
||||
Then the result should be:
|
||||
| m.a | s | w |
|
||||
| '1' | 1 | 1 |
|
||||
| '2' | 2 | 3 |
|
||||
| '3' | 1 | 4 |
|
||||
|
||||
Scenario: Test match allShortest single edge type filtered
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (n {a:'0'})-[:r0 {w: 1}]->({a:'1'})-[:r {w: 2}]->({a:'2'}), (n)-[:r {w: 3}]->({a:'4'})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH ()-[le:r0 *allShortest 10 (e, n | e.w) w]->(m)
|
||||
RETURN size(le) AS s, m.a
|
||||
"""
|
||||
Then the result should be:
|
||||
| s | m.a |
|
||||
| 1 | '1' |
|
||||
|
||||
Scenario: Test match allShortest multiple edge types filtered
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (n {a:'0'})-[:r0 {w: 1}]->({a:'1'})-[:r1 {w: 2}]->({a:'2'}), (n)-[:r {w: 3}]->({a:'4'})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH ()-[le :r0|:r1 *allShortest 10 (e, n | e.w) w]->(m) WHERE size(le) > 1
|
||||
RETURN size(le) AS s, (le[0]).w AS r0, (le[1]).w AS r1
|
||||
"""
|
||||
Then the result should be:
|
||||
| s | r0 | r1 |
|
||||
| 2 | 1 | 2 |
|
||||
|
||||
Scenario: Test match allShortest property filters
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (n {a:'0'})-[:r {w: 1}]->({a:'1'})-[:r {w: 2}]->({a:'2'}), (n)-[:r {w: 3}]->({a:'4'})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH ()-[le *allShortest 10 {w:1} (e, n | e.w ) total_weight]->(m)
|
||||
RETURN size(le) AS s, (le[0]).w AS r0
|
||||
"""
|
||||
Then the result should be:
|
||||
| s | r0 |
|
||||
| 1 | 1 |
|
||||
|
||||
Scenario: Test match allShortest weight not a number
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (n {a:'0'})-[:r {w: 'not a number'}]->({a:'1'})-[:r {w: 2}]->({a:'2'}), (n)-[:r {w: 3}]->({a:'4'})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH ()-[le *allShortest 10 (e, n | e.w ) total_weight]->(m)
|
||||
RETURN le, total_weight
|
||||
"""
|
||||
Then an error should be raised
|
||||
|
||||
Scenario: Test match allShortest negative weight
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (n {a:'0'})-[:r {w: -1}]->({a:'1'})-[:r {w: 2}]->({a:'2'}), (n)-[:r {w: 3}]->({a:'4'})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH ()-[le *allShortest 10 (e, n | e.w ) total_weight]->(m)
|
||||
RETURN le, total_weight
|
||||
"""
|
||||
Then an error should be raised
|
||||
|
||||
Scenario: Test match allShortest weight duration
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (n {a:'0'})-[:r {w: DURATION('PT1S')}]->({a:'1'})-[:r {w: DURATION('PT2S')}]->({a:'2'}), (n)-[:r {w: DURATION('PT4S')}]->({a:'3'})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n {a:'0'})-[le *allShortest 10 (e, n | e.w ) w]->(m) RETURN m.a, size(le) as s, w
|
||||
"""
|
||||
Then the result should be:
|
||||
| m.a | s | w |
|
||||
| '1' | 1 | PT1S |
|
||||
| '2' | 2 | PT3S |
|
||||
| '3' | 1 | PT4S |
|
||||
|
||||
Scenario: Test match allShortest weight negative duration
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (n {a:'0'})-[:r {w: DURATION({seconds: -1})}]->({a:'1'})-[:r {w: DURATION('PT2S')}]->({a:'2'}), (n)-[:r {w: DURATION('PT4S')}]->({a:'3'})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n {a:'0'})-[le *allShortest 10 (e, n | e.w ) w]->(m) RETURN m.a, size(le) as s, w
|
||||
"""
|
||||
Then an error should be raised
|
||||
|
||||
Scenario: Test match allShortest weight mixed numeric and duration as weights
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (n {a:'0'})-[:r {w: 2}]->({a:'1'})-[:r {w: DURATION('PT2S')}]->({a:'2'}), (n)-[:r {w: DURATION('PT4S')}]->({a:'3'})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n {a:'0'})-[le *allShortest 10 (e, n | e.w ) w]->(m) RETURN m.a, size(le) as s, w
|
||||
"""
|
||||
Then an error should be raised
|
||||
|
||||
Scenario: Test allShortest return both paths of same length
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (n {a:'0'})-[:r {w: 2}]->({a:'1'})-[:r {w: 3}]->({a:'2'}), (n)-[:r {w: 5}]->({a:'2'})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH path=(n {a:'0'})-[r *allShortest (e, n | e.w ) w]->(m {a:'2'}) RETURN COUNT(path);
|
||||
"""
|
||||
Then the result should be:
|
||||
| COUNT(path) |
|
||||
| 2 |
|
||||
|
||||
Scenario: Test allShortest on different edge between two nodes
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (n:One), (o:Two), (m:Three), (n)-[:TYPE {cost: 0.3}]->(o), (o)-[:TYPE {cost: 40}]->(m), (o)-[:TYPE {cost: 20}]->(m)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH p=(h:One)-[r*allshortest ..5 (e, v | e.cost) total_cost]->(k:Three) return total_cost;
|
||||
"""
|
||||
Then the result should be:
|
||||
| total_cost |
|
||||
| 20.3 |
|
@ -0,0 +1,105 @@
|
||||
Feature: Bfs
|
||||
|
||||
Scenario: Test match BFS upper bound
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (n {a:'0'})-[:r]->({a:'1.1'})-[:r]->({a:'2.1'}), (n)-[:r]->({a:'1.2'})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n {a:'0'})-[*bfs..1]->(m) RETURN n.a, m.a
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.a | m.a |
|
||||
| '0' | '1.1' |
|
||||
| '0' | '1.2' |
|
||||
|
||||
Scenario: Test match BFS lower bound
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (n {a:'0'})-[:r]->({a:'1.1'})-[:r]->({a:'2.1'})-[:r]->({a:'3.1'})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n {a:'0'})-[*bfs 2..]->(m) RETURN n.a, m.a
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.a | m.a |
|
||||
| '0' | '2.1' |
|
||||
| '0' | '3.1' |
|
||||
|
||||
Scenario: Test match BFS filtered
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (n {a:'0'})-[:r]->({a:'1.1'})-[:r]->({a:'2.1'}), (n)-[:r]->({a:'1.2'})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n {a:'0'})-[*bfs..10 (e, m| m.a = '1.1' OR m.a = '0')]->(m) RETURN n.a, m.a
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.a | m.a |
|
||||
| '0' | '1.1' |
|
||||
|
||||
Scenario: Test match BFS resulting edge list
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:Starting)-[:r {id: 0}]->()-[:r {id: 1}]->()-[:r {id: 2}]->()-[:r {id: 3}]->()
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (:Starting)-[r *bfs..10]->(m) WHERE size(r) > 3
|
||||
RETURN size(r) AS s, (r[0]).id AS r0, (r[2]).id AS r2
|
||||
"""
|
||||
Then the result should be:
|
||||
| s | r0 | r2 |
|
||||
| 4 | 0 | 2 |
|
||||
|
||||
Scenario: Test match BFS single edge type filtered
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE ()-[:r0 {id: 0}]->()-[:r1 {id: 1}]->()-[:r2 {id: 2}]->()-[:r3 {id: 3}]->()
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH ()-[r:r0 *bfs..10]->(m)
|
||||
RETURN size(r) AS s, (r[0]).id AS r0
|
||||
"""
|
||||
Then the result should be:
|
||||
| s | r0 |
|
||||
| 1 | 0 |
|
||||
|
||||
Scenario: Test match BFS multiple edge types filtered
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE ()-[:r0 {id: 0}]->()-[:r1 {id: 1}]->()-[:r2 {id: 2}]->()-[:r3 {id: 3}]->()
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH ()-[r :r0|:r1 *bfs..10 ]->(m) WHERE size(r) > 1
|
||||
RETURN size(r) AS s, (r[0]).id AS r0, (r[1]).id AS r1
|
||||
"""
|
||||
Then the result should be:
|
||||
| s | r0 | r1 |
|
||||
| 2 | 0 | 1 |
|
||||
|
||||
Scenario: Test match BFS property filters
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE ()-[:r0 {id: 0}]->()-[:r1 {id: 1}]->()-[:r2 {id: 2}]->()-[:r3 {id: 3}]->()
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH ()-[r *bfs..10 {id: 1}]->(m)
|
||||
RETURN size(r) AS s, (r[0]).id AS r0
|
||||
"""
|
||||
Then the result should be:
|
||||
| s | r0 |
|
||||
| 1 | 1 |
|
@ -0,0 +1,541 @@
|
||||
Feature: WHERE exists
|
||||
|
||||
Scenario: Test exists with empty edge and node specifiers
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:One {prop:1})-[:TYPE]->(:Two)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:One) WHERE exists((n)-[]-()) RETURN n.prop;
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.prop |
|
||||
| 1 |
|
||||
|
||||
Scenario: Test exists with empty edge and node specifiers return 2 entries
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:One {prop:1})-[:TYPE]->(:Two), (:One {prop: 3})-[:TYPE]->(:Two)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:One) WHERE exists((n)-[]-()) RETURN n.prop ORDER BY n.prop;
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.prop |
|
||||
| 1 |
|
||||
| 3 |
|
||||
|
||||
Scenario: Test exists with edge specifier
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:One {prop:1})-[:TYPE]->(:Two)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:One) WHERE exists((n)-[:TYPE]-()) RETURN n.prop;
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.prop |
|
||||
| 1 |
|
||||
|
||||
Scenario: Test exists with wrong edge specifier
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:One {prop:1})-[:TYPE]->(:Two)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:One) WHERE exists((n)-[:TYPE2]-()) RETURN n.prop;
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Test exists with correct edge direction
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:One {prop:1})-[:TYPE]->(:Two)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:One) WHERE exists((n)-[:TYPE]->()) RETURN n.prop;
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.prop |
|
||||
| 1 |
|
||||
|
||||
Scenario: Test exists with wrong edge direction
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:One {prop:1})-[:TYPE]->(:Two)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:One) WHERE exists((n)<-[:TYPE]-()) RETURN n.prop;
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Test exists with destination node label
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:One {prop:1})-[:TYPE]->(:Two)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:One) WHERE exists((n)-[]->(:Two)) RETURN n.prop;
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.prop |
|
||||
| 1 |
|
||||
|
||||
Scenario: Test exists with wrong destination node label
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:One {prop:1})-[:TYPE]->(:Two)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:One) WHERE exists((n)-[]->(:Three)) RETURN n.prop;
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Test exists with destination node property
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:One {prop:1})-[:TYPE]->(:Two {prop: 2})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:One) WHERE exists((n)-[]->({prop: 2})) RETURN n.prop;
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.prop |
|
||||
| 1 |
|
||||
|
||||
Scenario: Test exists with wrong destination node property
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:One {prop:1})-[:TYPE]->(:Two {prop: 2})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:One) WHERE exists((n)-[]->({prop: 3})) RETURN n.prop;
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Test exists with edge property
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:One {prop:1})-[:TYPE {prop: 1}]->(:Two {prop: 2})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:One) WHERE exists((n)-[:TYPE {prop: 1}]->()) RETURN n.prop;
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.prop |
|
||||
| 1 |
|
||||
|
||||
Scenario: Test exists with wrong edge property
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:One {prop:1})-[:TYPE {prop: 1}]->(:Two {prop: 2})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:One) WHERE exists((n)-[:TYPE {prop: 2}]->()) RETURN n.prop;
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Test exists with both edge property and node label property
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:One {prop:1})-[:TYPE {prop: 1}]->(:Two {prop: 2})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:One) WHERE exists((n)-[:TYPE {prop: 1}]->(:Two {prop: 2})) RETURN n.prop;
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.prop |
|
||||
| 1 |
|
||||
|
||||
Scenario: Test exists with correct edge property and wrong node label property
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:One {prop:1})-[:TYPE {prop: 1}]->(:Two {prop: 2})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:One) WHERE exists((n)-[:TYPE {prop: 1}]->(:Two {prop: 3})) RETURN n.prop;
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Test exists with wrong edge property and correct node label property
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:One {prop:1})-[:TYPE {prop: 1}]->(:Two {prop: 2})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:One) WHERE exists((n)-[:TYPE {prop: 2}]->(:Two {prop:2})) RETURN n.prop;
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Test exists with wrong edge property and wrong node label property
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:One {prop:1})-[:TYPE {prop: 1}]->(:Two {prop: 2})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:One) WHERE exists((n)-[:TYPE {prop: 2}]->(:Two {prop:3})) RETURN n.prop;
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Test exists AND exists
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:One {prop:1})-[:TYPE {prop: 1}]->(:Two {prop: 2})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:One) WHERE exists((n)-[:TYPE]->()) AND exists((n)-[]->(:Two)) RETURN n.prop;
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.prop |
|
||||
| 1 |
|
||||
|
||||
Scenario: Test exists OR exists first condition
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:One {prop:1})-[:TYPE {prop: 1}]->(:Two {prop: 2})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:One) WHERE exists((n)-[:TYPE]->()) OR exists((n)-[]->(:Three)) RETURN n.prop;
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.prop |
|
||||
| 1 |
|
||||
|
||||
Scenario: Test exists OR exists second condition
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:One {prop:1})-[:TYPE {prop: 1}]->(:Two {prop: 2})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:One) WHERE exists((n)-[:TYPE2]->()) OR exists((n)-[]->(:Two)) RETURN n.prop;
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.prop |
|
||||
| 1 |
|
||||
|
||||
Scenario: Test exists OR exists fail
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:One {prop:1})-[:TYPE {prop: 1}]->(:Two {prop: 2})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:One) WHERE exists((n)-[:TYPE2]->()) OR exists((n)-[]->(:Three)) RETURN n.prop;
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Test NOT exists
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:One {prop:1})-[:TYPE {prop: 1}]->(:Two {prop: 2})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:One) WHERE NOT exists((n)-[:TYPE2]->()) RETURN n.prop;
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.prop |
|
||||
| 1 |
|
||||
|
||||
Scenario: Test multi-hop first in sequence
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:One {prop:1})-[:TYPE {prop: 1}]->(:Two {prop: 2})-[:TYPE {prop:2}]->(:Three {prop: 3})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) WHERE exists((n)-[]->()-[]->()) RETURN n.prop;
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.prop |
|
||||
| 1 |
|
||||
|
||||
Scenario: Test multi-hop in middle sequence
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:One {prop:1})-[:TYPE {prop: 1}]->(:Two {prop: 2})-[:TYPE {prop:2}]->(:Three {prop: 3})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) WHERE exists(()-[]->(n)-[]->()) RETURN n.prop;
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.prop |
|
||||
| 2 |
|
||||
|
||||
Scenario: Test multi-hop at the end of the sequence
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:One {prop:1})-[:TYPE {prop: 1}]->(:Two {prop: 2})-[:TYPE {prop:2}]->(:Three {prop: 3})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) WHERE exists(()-[]->()-[]->(n)) RETURN n.prop;
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.prop |
|
||||
| 3 |
|
||||
|
||||
Scenario: Test multi-hop not exists
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:One {prop:1})-[:TYPE {prop: 1}]->(:Two {prop: 2})-[:TYPE {prop:2}]->(:Three {prop: 3})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) WHERE exists(()-[]->(n)<-[]-()) RETURN n.prop;
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Test multi-hop with filters
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:One {prop:1})-[:TYPE {prop: 1}]->(:Two {prop: 2})-[:TYPE {prop:2}]->(:Three {prop: 3})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) WHERE exists(({prop: 1})-[:TYPE]->(n)-[{prop:2}]->(:Three)) RETURN n.prop;
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.prop |
|
||||
| 2 |
|
||||
|
||||
Scenario: Test multi-hop with wrong filters
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:One {prop:1})-[:TYPE {prop: 1}]->(:Two {prop: 2})-[:TYPE {prop:2}]->(:Three {prop: 3})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) WHERE exists(({prop: 1})-[:TYPE]->(n)-[:TYPE2]->(:Three)) RETURN n.prop;
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Test node-only hop
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:One {prop:1})-[:TYPE {prop: 1}]->(:Two {prop: 2})-[:TYPE {prop:2}]->(:Three {prop: 3})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) WHERE exists((n)) RETURN n.prop;
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.prop |
|
||||
| 1 |
|
||||
| 2 |
|
||||
| 3 |
|
||||
|
||||
Scenario: Test exists with different edge type
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:One {prop:1})-[:TYPE]->(:Two)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:One) WHERE exists((n)-[:TYPE2]->()) RETURN n.prop;
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Test exists with correct edge type multiple edges
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:One {prop:1})-[:TYPE]->(:Two {prop: 10}), (:One {prop: 2})-[:TYPE]->(:Two {prop: 11});
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:Two) WHERE exists((n)<-[:TYPE]-()) RETURN n.prop ORDER BY n.prop;
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.prop |
|
||||
| 10 |
|
||||
| 11 |
|
||||
|
||||
Scenario: Test exists does not work in WITH clauses
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:One {prop:1})-[:TYPE]->(:Two);
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:Two) WITH n WHERE exists((n)<-[:TYPE]-()) RETURN n.prop;
|
||||
"""
|
||||
Then an error should be raised
|
||||
|
||||
Scenario: Test exists is not null
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:One {prop:1})-[:TYPE]->(:Two);
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:One) WHERE exists((n)-[]-()) is not null RETURN n.prop;
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.prop |
|
||||
| 1 |
|
||||
|
||||
Scenario: Test exists is null
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:One {prop:1})-[:TYPE]->(:Two);
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:One) WHERE exists((n)-[]-()) is null RETURN n.prop;
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Test exists equal to true
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:One {prop:1})-[:TYPE]->(:Two);
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:One) WHERE exists((n)-[]-()) = true RETURN n.prop;
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.prop |
|
||||
| 1 |
|
||||
|
||||
Scenario: Test exists equal to true
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:One {prop:1})-[:TYPE]->(:Two);
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:One) WHERE exists((n)-[]-()) = false RETURN n.prop;
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Test exists in list
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:One {prop:1})-[:TYPE]->(:Two);
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:One) WHERE exists((n)-[]-()) in [true] RETURN n.prop;
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.prop |
|
||||
| 1 |
|
||||
|
||||
Scenario: Test BFS hop
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:One {prop:1})-[:TYPE {prop: 1}]->(:Two {prop: 2})-[:TYPE {prop:2}]->(:Three {prop: 3})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:One) WHERE exists((n)-[*bfs]->(:Three)) RETURN n.prop;
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.prop |
|
||||
| 1 |
|
||||
|
||||
Scenario: Test exists not in list
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:One {prop:1})-[:TYPE]->(:Two);
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:One) WHERE exists((n)-[]-()) in [false] RETURN n.prop;
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Test exists on multihop patterns without results
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
MATCH (n) DETACH DELETE n;
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH ()-[]-(m)-[]->(a) WHERE m.prop=1 and a.prop=3 and exists(()-[]->(m)) RETURN m, a;
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Test exists does not work in SetProperty clauses
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:One {prop:1})-[:TYPE]->(:Two);
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:Two) SET n.prop = exists((n)<-[:TYPE]-()) RETURN n.prop;
|
||||
"""
|
||||
Then an error should be raised
|
||||
|
||||
Scenario: Test exists does not work in RETURN clauses
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:One {prop:1})-[:TYPE]->(:Two);
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) RETURN exists((n)-[]-());
|
||||
"""
|
||||
Then an error should be raised
|
@ -0,0 +1,157 @@
|
||||
Feature: Weighted Shortest Path
|
||||
|
||||
Scenario: Test match wShortest upper bound
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (n {a:'0'})-[:r {w: 1}]->({a:'1'})-[:r {w: 1}]->({a:'2'}), (n)-[:r {w: 1}]->({a:'3'})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n {a:'0'})-[le *wShortest 1 (e, n | e.w ) w]->(m) RETURN m.a
|
||||
"""
|
||||
Then the result should be:
|
||||
| m.a |
|
||||
| '1' |
|
||||
| '3' |
|
||||
|
||||
Scenario: Test match wShortest filtered
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (n {a:'0'})-[:r {w: 1}]->({a:'1'})-[:r {w: 1}]->({a:'2'}), (n)-[:r {w: 1}]->({a:'3'})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n {a:'0'})-[le *wShortest 1 (e, n | e.w ) w (e, n | n.a = '3')]->(m) RETURN m.a
|
||||
"""
|
||||
Then the result should be:
|
||||
| m.a |
|
||||
| '3' |
|
||||
|
||||
Scenario: Test match wShortest resulting edge list
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (n {a:'0'})-[:r {w: 1}]->({a:'1'})-[:r {w: 2}]->({a:'2'}), (n)-[:r {w: 4}]->({a:'3'})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n {a:'0'})-[le *wShortest 10 (e, n | e.w ) w]->(m) RETURN m.a, size(le) as s, w
|
||||
"""
|
||||
Then the result should be:
|
||||
| m.a | s | w |
|
||||
| '1' | 1 | 1 |
|
||||
| '2' | 2 | 3 |
|
||||
| '3' | 1 | 4 |
|
||||
|
||||
Scenario: Test match wShortest single edge type filtered
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (n {a:'0'})-[:r0 {w: 1}]->({a:'1'})-[:r {w: 2}]->({a:'2'}), (n)-[:r {w: 3}]->({a:'4'})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH ()-[le:r0 *wShortest 10 (e, n | e.w) w]->(m)
|
||||
RETURN size(le) AS s, m.a
|
||||
"""
|
||||
Then the result should be:
|
||||
| s | m.a |
|
||||
| 1 | '1' |
|
||||
|
||||
Scenario: Test match wShortest multiple edge types filtered
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (n {a:'0'})-[:r0 {w: 1}]->({a:'1'})-[:r1 {w: 2}]->({a:'2'}), (n)-[:r {w: 3}]->({a:'4'})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH ()-[le :r0|:r1 *wShortest 10 (e, n | e.w) w]->(m) WHERE size(le) > 1
|
||||
RETURN size(le) AS s, (le[0]).w AS r0, (le[1]).w AS r1
|
||||
"""
|
||||
Then the result should be:
|
||||
| s | r0 | r1 |
|
||||
| 2 | 1 | 2 |
|
||||
|
||||
Scenario: Test match wShortest property filters
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (n {a:'0'})-[:r {w: 1}]->({a:'1'})-[:r {w: 2}]->({a:'2'}), (n)-[:r {w: 3}]->({a:'4'})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH ()-[le *wShortest 10 {w:1} (e, n | e.w ) total_weight]->(m)
|
||||
RETURN size(le) AS s, (le[0]).w AS r0
|
||||
"""
|
||||
Then the result should be:
|
||||
| s | r0 |
|
||||
| 1 | 1 |
|
||||
|
||||
Scenario: Test match wShortest weight not a number
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (n {a:'0'})-[:r {w: 'not a number'}]->({a:'1'})-[:r {w: 2}]->({a:'2'}), (n)-[:r {w: 3}]->({a:'4'})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH ()-[le *wShortest 10 (e, n | e.w ) total_weight]->(m)
|
||||
RETURN le, total_weight
|
||||
"""
|
||||
Then an error should be raised
|
||||
|
||||
Scenario: Test match wShortest negative weight
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (n {a:'0'})-[:r {w: -1}]->({a:'1'})-[:r {w: 2}]->({a:'2'}), (n)-[:r {w: 3}]->({a:'4'})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH ()-[le *wShortest 10 (e, n | e.w ) total_weight]->(m)
|
||||
RETURN le, total_weight
|
||||
"""
|
||||
Then an error should be raised
|
||||
|
||||
Scenario: Test match wShortest weight duration
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (n {a:'0'})-[:r {w: DURATION('PT1S')}]->({a:'1'})-[:r {w: DURATION('PT2S')}]->({a:'2'}), (n)-[:r {w: DURATION('PT4S')}]->({a:'3'})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n {a:'0'})-[le *wShortest 10 (e, n | e.w ) w]->(m) RETURN m.a, size(le) as s, w
|
||||
"""
|
||||
Then the result should be:
|
||||
| m.a | s | w |
|
||||
| '1' | 1 | PT1S |
|
||||
| '2' | 2 | PT3S |
|
||||
| '3' | 1 | PT4S |
|
||||
|
||||
Scenario: Test match wShortest weight negative duration
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (n {a:'0'})-[:r {w: DURATION({seconds: -1})}]->({a:'1'})-[:r {w: DURATION('PT2S')}]->({a:'2'}), (n)-[:r {w: DURATION('PT4S')}]->({a:'3'})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n {a:'0'})-[le *wShortest 10 (e, n | e.w ) w]->(m) RETURN m.a, size(le) as s, w
|
||||
"""
|
||||
Then an error should be raised
|
||||
|
||||
Scenario: Test match wShortest weight mixed numeric and duration as weights
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (n {a:'0'})-[:r {w: 2}]->({a:'1'})-[:r {w: DURATION('PT2S')}]->({a:'2'}), (n)-[:r {w: DURATION('PT4S')}]->({a:'3'})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n {a:'0'})-[le *wShortest 10 (e, n | e.w ) w]->(m) RETURN m.a, size(le) as s, w
|
||||
"""
|
||||
Then an error should be raised
|
@ -0,0 +1,419 @@
|
||||
Feature: Merge feature
|
||||
|
||||
Scenario: Merge node test01
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:X{a: 1})
|
||||
"""
|
||||
And having executed:
|
||||
"""
|
||||
MERGE(n:X)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH(n) RETURN n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| (:X{a: 1}) |
|
||||
|
||||
Scenario: Merge node test02
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:X)
|
||||
"""
|
||||
And having executed:
|
||||
"""
|
||||
MERGE(n:X:Y)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH(n) RETURN n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| (:X) |
|
||||
| (:X:Y) |
|
||||
|
||||
Scenario: Merge node test03
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:Y{a: 1})
|
||||
"""
|
||||
And having executed:
|
||||
"""
|
||||
MERGE(n:X)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH(n) RETURN n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| (:X) |
|
||||
| (:Y{a: 1}) |
|
||||
|
||||
Scenario: Merge node test04
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE ({a: 1, b: 2})
|
||||
"""
|
||||
And having executed:
|
||||
"""
|
||||
MERGE(n{a: 1, b: 2})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH(n) RETURN n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| ({a: 1, b: 2}) |
|
||||
|
||||
Scenario: Merge node test05
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE ({a: 2})
|
||||
"""
|
||||
And having executed:
|
||||
"""
|
||||
MERGE(n{a: 1, b:2})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH(n) RETURN n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| ({a: 2}) |
|
||||
| ({a: 1, b: 2}) |
|
||||
|
||||
Scenario: Merge node test06
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE ({a: 2})
|
||||
"""
|
||||
And having executed:
|
||||
"""
|
||||
MERGE(n{a: 2, b: 2})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH(n) RETURN n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| ({a: 2}) |
|
||||
| ({a: 2, b: 2}) |
|
||||
|
||||
Scenario: Merge node test07
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE ({a: 2})
|
||||
"""
|
||||
And having executed:
|
||||
"""
|
||||
MERGE(n:A{a: 2})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH(n) RETURN n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| (:A{a: 2}) |
|
||||
| ({a: 2}) |
|
||||
|
||||
Scenario: Merge node test08
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:A:B{a: 2, b: 1})
|
||||
"""
|
||||
And having executed:
|
||||
"""
|
||||
MERGE(n:A{a: 2})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH(n) RETURN n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| (:A:B{a: 2, b: 1}) |
|
||||
|
||||
Scenario: Merge node test09
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (:A{a: 2}), (:A{a: 2}), (:A{a: 1})
|
||||
"""
|
||||
And having executed:
|
||||
"""
|
||||
MATCH(n:A)
|
||||
MERGE(m:B{x: n.a})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH(n:B) RETURN *
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| (:B{x: 1}) |
|
||||
| (:B{x: 2}) |
|
||||
|
||||
Scenario: Merge relationship test01
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (a), (b), (a)-[:X]->(b)
|
||||
"""
|
||||
And having executed:
|
||||
"""
|
||||
MATCH (a)--(b)
|
||||
MERGE ((a)-[r:X]-(b))
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH ()-[r]->() RETURN *
|
||||
"""
|
||||
Then the result should be:
|
||||
| r |
|
||||
| [:X] |
|
||||
|
||||
Scenario: Merge relationship test02
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (a), (b), (a)-[:X]->(b)
|
||||
"""
|
||||
And having executed:
|
||||
"""
|
||||
MATCH (a)--(b)
|
||||
MERGE ((a)-[r:Y]-(b))
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH ()-[r]->() RETURN *
|
||||
"""
|
||||
Then the result should be:
|
||||
| r |
|
||||
| [:X] |
|
||||
| [:Y] |
|
||||
|
||||
Scenario: Merge relationship test03
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (a), (b), (a)-[:X{a: 1}]->(b)
|
||||
"""
|
||||
And having executed:
|
||||
"""
|
||||
MATCH (a)--(b)
|
||||
MERGE ((a)-[r:X{a: 1}]-(b))
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH ()-[r]->() RETURN *
|
||||
"""
|
||||
Then the result should be:
|
||||
| r |
|
||||
| [:X{a: 1}] |
|
||||
|
||||
Scenario: Merge relationship test04
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (a), (b), (a)-[:X{a: 1}]->(b)
|
||||
"""
|
||||
And having executed:
|
||||
"""
|
||||
MATCH (a)--(b)
|
||||
MERGE ((a)-[r:X{a: 2}]-(b))
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH ()-[r]->() RETURN *
|
||||
"""
|
||||
Then the result should be:
|
||||
| r |
|
||||
| [:X{a: 1}] |
|
||||
| [:X{a: 2}] |
|
||||
|
||||
Scenario: Merge relationship test05
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (a), (b), (a)-[:X{a: 1}]->(b)
|
||||
"""
|
||||
And having executed:
|
||||
"""
|
||||
MATCH (a)--(b)
|
||||
MERGE ((a)-[r:Y{a: 1}]-(b))
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH ()-[r]->() RETURN *
|
||||
"""
|
||||
Then the result should be:
|
||||
| r |
|
||||
| [:X{a: 1}] |
|
||||
| [:Y{a: 1}] |
|
||||
|
||||
Scenario: Merge relationship test06
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (a:A{a: 1}), (b:B{b: 1}), (c:C), (a)-[:X]->(c), (c)<-[:Y]-(b)
|
||||
"""
|
||||
And having executed:
|
||||
"""
|
||||
MERGE (:A)-[:X]->(:C)<-[:Y]-(:B)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a)-[r]->(b) RETURN *
|
||||
"""
|
||||
Then the result should be:
|
||||
| a | r | b |
|
||||
| (:A{a: 1}) | [:X] | (:C) |
|
||||
| (:B{b: 1}) | [:Y] | (:C) |
|
||||
|
||||
Scenario: Merge relationship test07
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (a:A{a: 1}), (b:B{b: 1}), (c:C), (a)-[:X{x: 1}]->(c), (c)<-[:Y{y: 1}]-(b)
|
||||
"""
|
||||
And having executed:
|
||||
"""
|
||||
MERGE (:A)-[:X]->(:D)<-[:Y]-(:B)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a)-[r]->(b) RETURN *
|
||||
"""
|
||||
Then the result should be:
|
||||
| a | r | b |
|
||||
| (:A) | [:X] | (:D) |
|
||||
| (:B) | [:Y] | (:D) |
|
||||
| (:A{a: 1}) | [:X{x: 1}] | (:C) |
|
||||
| (:B{b: 1}) | [:Y{y: 1}] | (:C) |
|
||||
|
||||
Scenario: Merge relationship test08
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (a:A:X), (b:B:Y)
|
||||
"""
|
||||
And having executed:
|
||||
"""
|
||||
MATCH (a:A), (b:B)
|
||||
MERGE (a)-[:R]-(b)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a)-[r]-(b) RETURN *
|
||||
"""
|
||||
Then the result should be:
|
||||
| a | r | b |
|
||||
| (:A:X) | [:R] | (:B:Y) |
|
||||
| (:B:Y) | [:R] | (:A:X) |
|
||||
|
||||
Scenario: Merge relationship test09
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (a:A{a: 1}), (b:B{a: 2}), (c:C{a: 2})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n)
|
||||
MERGE (m:X{a: n.a})
|
||||
MERGE (n)-[r:R]->(m)
|
||||
RETURN *
|
||||
"""
|
||||
Then the result should be:
|
||||
| n | r | m |
|
||||
| (:A{a: 1}) | [:R] | (:X{a: 1}) |
|
||||
| (:B{a: 2}) | [:R] | (:X{a: 2}) |
|
||||
| (:C{a: 2}) | [:R] | (:X{a: 2}) |
|
||||
|
||||
Scenario: Merge relationship test10
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (a:A{a: 1}), (b:B{a: 2}), (c:C{a: 2})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n)
|
||||
MERGE (n)-[r:R]->(m:X{a: n.a})
|
||||
RETURN *
|
||||
"""
|
||||
Then the result should be:
|
||||
| n | r | m |
|
||||
| (:A{a: 1}) | [:R] | (:X{a: 1}) |
|
||||
| (:B{a: 2}) | [:R] | (:X{a: 2}) |
|
||||
| (:C{a: 2}) | [:R] | (:X{a: 2}) |
|
||||
|
||||
Scenario: Merge OnCreate test01
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
MERGE (a:X)
|
||||
ON CREATE SET a.a = 1
|
||||
RETURN *
|
||||
"""
|
||||
Then the result should be:
|
||||
| a |
|
||||
| (:X{a: 1}) |
|
||||
|
||||
Scenario: Merge OnMatch test01
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE(:A), (:A), (:B)
|
||||
"""
|
||||
And having executed:
|
||||
"""
|
||||
MERGE (a:A)
|
||||
ON MATCH SET a.a = 1
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) RETURN *
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| (:A{a: 1}) |
|
||||
| (:A{a: 1}) |
|
||||
| (:B) |
|
||||
|
||||
Scenario: Merge with Unwind test01
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE ({a: 1})
|
||||
"""
|
||||
And having executed:
|
||||
"""
|
||||
UNWIND [1, 2, 3] AS a
|
||||
MERGE({a: a})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) RETURN *
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| ({a: 1}) |
|
||||
| ({a: 2}) |
|
||||
| ({a: 3)) |
|
@ -0,0 +1,68 @@
|
||||
Feature: Parameters
|
||||
|
||||
Scenario: Simple parameter names:
|
||||
Given an empty graph
|
||||
And parameters are:
|
||||
| y | 2 |
|
||||
| x | 1 |
|
||||
When executing query:
|
||||
"""
|
||||
RETURN $x, $y, 5
|
||||
"""
|
||||
Then the result should be:
|
||||
| $x | $y | 5 |
|
||||
| 1 | 2 | 5 |
|
||||
|
||||
Scenario: Integers as parameter names:
|
||||
Given an empty graph
|
||||
And parameters are:
|
||||
| 0 | 5 |
|
||||
| 2 | 6 |
|
||||
When executing query:
|
||||
"""
|
||||
RETURN $0, $2
|
||||
"""
|
||||
Then the result should be:
|
||||
| $0 | $2 |
|
||||
| 5 | 6 |
|
||||
|
||||
Scenario: Escaped symbolic names as parameter names:
|
||||
Given an empty graph
|
||||
And parameters are:
|
||||
| a b | 2 |
|
||||
| a `b | 3 |
|
||||
When executing query:
|
||||
"""
|
||||
RETURN $`a b`, $`a ``b`
|
||||
"""
|
||||
Then the result should be:
|
||||
| $`a b` | $`a ``b` |
|
||||
| 2 | 3 |
|
||||
|
||||
Scenario: Lists as parameters:
|
||||
Given an empty graph
|
||||
And parameters are:
|
||||
| a | [1, 2, 3] |
|
||||
When executing query:
|
||||
"""
|
||||
RETURN $a
|
||||
"""
|
||||
Then the result should be:
|
||||
| $a |
|
||||
| [1, 2, 3] |
|
||||
|
||||
Scenario: Parameters in match:
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (a {x : 10})
|
||||
"""
|
||||
And parameters are:
|
||||
| a | 10 |
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a {x : $a}) RETURN a.x
|
||||
"""
|
||||
Then the result should be:
|
||||
| a.x |
|
||||
| 10 |
|
@ -0,0 +1,185 @@
|
||||
Feature: String operators
|
||||
|
||||
Scenario: StartsWith test1
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE(a{name: "ai'M'e"}), (b{name: "AiMe"}), (c{name: "aime"})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n)
|
||||
WHERE n.name STARTS WITH 'aim'
|
||||
return n.name
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.name |
|
||||
| 'aime' |
|
||||
|
||||
Scenario: StartsWith test2
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE(a{name: "ai'M'e"}), (b{name: "AiMe"}), (c{name: "aime"})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n)
|
||||
WHERE n.name STARTS WITH "ai'M"
|
||||
return n.name
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.name |
|
||||
| 'ai'M'e' |
|
||||
|
||||
Scenario: StartsWith test3
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE(a{name: 1}), (b{name: 2}), (c{name: null})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n)
|
||||
WHERE n.name STARTS WITH 1
|
||||
return n.name
|
||||
"""
|
||||
Then an error should be raised
|
||||
|
||||
Scenario: StartsWith test5
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE(a{name: 1}), (b{name: 2}), (c{name: null})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n)
|
||||
WHERE n.name STARTS WITH true
|
||||
return n.name
|
||||
"""
|
||||
Then an error should be raised
|
||||
|
||||
|
||||
Scenario: EndsWith test1
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE(a{name: "ai'M'E"}), (b{name: "AiMe"}), (c{name: "aime"})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n)
|
||||
WHERE n.name ENDS WITH 'e'
|
||||
return n.name
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.name |
|
||||
| 'AiMe' |
|
||||
| 'aime' |
|
||||
|
||||
Scenario: EndsWith test2
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE(a{name: "ai'M'e"}), (b{name: "AiMe"}), (c{name: "aime"})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n)
|
||||
WHERE n.name ENDS WITH "M'e"
|
||||
return n.name
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.name |
|
||||
| 'ai'M'e' |
|
||||
|
||||
Scenario: EndsWith test3
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE(a{name: 1}), (b{name: 2}), (c{name: null})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n)
|
||||
WHERE n.name ENDS WITH 1
|
||||
return n.name
|
||||
"""
|
||||
Then an error should be raised
|
||||
|
||||
Scenario: EndsWith test5
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE(a{name: 1}), (b{name: 2}), (c{name: null})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n)
|
||||
WHERE n.name ENDS WITH true
|
||||
return n.name
|
||||
"""
|
||||
Then an error should be raised
|
||||
|
||||
|
||||
Scenario: Contains test1
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE(a{name: "ai'M'e"}), (b{name: "AiMe"}), (c{name: "aime"})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n)
|
||||
WHERE n.name CONTAINS 'iM'
|
||||
return n.name
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.name |
|
||||
| 'AiMe' |
|
||||
|
||||
Scenario: Contains test2
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE(a{name: "ai'M'e"}), (b{name: "AiMe"}), (c{name: "aime"})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n)
|
||||
WHERE n.name CONTAINS "i'M"
|
||||
return n.name
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.name |
|
||||
| 'ai'M'e' |
|
||||
|
||||
Scenario: Contains test3
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE(a{name: 1}), (b{name: 2}), (c{name: null})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n)
|
||||
WHERE n.name CONTAINS 1
|
||||
return n.name
|
||||
"""
|
||||
Then an error should be raised
|
||||
|
||||
|
||||
Scenario: Contains test5
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE(a{name: 1}), (b{name: 2}), (c{name: null})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n)
|
||||
WHERE n.name CONTAINS true
|
||||
return n.name
|
||||
"""
|
||||
Then an error should be raised
|
@ -0,0 +1,408 @@
|
||||
# Copyright 2023 Memgraph Ltd.
|
||||
#
|
||||
# Use of this software is governed by the Business Source License
|
||||
# included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
# License, and you may not use this file except in compliance with the Business Source License.
|
||||
#
|
||||
# As of the Change Date specified in that file, in accordance with
|
||||
# the Business Source License, use of this software will be governed
|
||||
# by the Apache License, Version 2.0, included in the file
|
||||
# licenses/APL.txt.
|
||||
|
||||
Feature: Subqueries
|
||||
Behaviour tests for memgraph CALL clause which contains a subquery
|
||||
|
||||
Scenario: Subquery without bounded symbols
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (:Label1 {prop: 1})-[:TYPE]->(:Label2 {prop: 2})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:Label1)
|
||||
CALL {
|
||||
MATCH (n:Label1)-[:TYPE]->(m:Label2)
|
||||
RETURN m
|
||||
}
|
||||
RETURN m.prop;
|
||||
"""
|
||||
Then the result should be:
|
||||
| m.prop |
|
||||
| 2 |
|
||||
|
||||
Scenario: Subquery without bounded symbols and without match
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (:Label1 {prop: 1})-[:TYPE]->(:Label2 {prop: 2})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
CALL {
|
||||
MATCH (n:Label1)-[:TYPE]->(m:Label2)
|
||||
RETURN m
|
||||
}
|
||||
RETURN m.prop;
|
||||
"""
|
||||
Then the result should be:
|
||||
| m.prop |
|
||||
| 2 |
|
||||
|
||||
Scenario: Subquery returning primitive
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (:Label1 {prop: 1})-[:TYPE]->(:Label2 {prop: 2})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
CALL {
|
||||
MATCH (n:Label1)-[:TYPE]->(m:Label2)
|
||||
RETURN m.prop AS prop
|
||||
}
|
||||
RETURN prop;
|
||||
"""
|
||||
Then the result should be:
|
||||
| prop |
|
||||
| 2 |
|
||||
|
||||
Scenario: Subquery returning 2 values
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (:Label1 {prop: 1})-[:TYPE]->(:Label2 {prop: 2})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:Label1)
|
||||
CALL {
|
||||
MATCH (m:Label1)-[:TYPE]->(o:Label2)
|
||||
RETURN m, o
|
||||
}
|
||||
RETURN m.prop, o.prop;
|
||||
"""
|
||||
Then the result should be:
|
||||
| m.prop | o.prop |
|
||||
| 1 | 2 |
|
||||
|
||||
Scenario: Subquery returning nothing because match did not find any results
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (:Label1 {prop: 1})-[:TYPE]->(:Label2 {prop: 2})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:Label3)
|
||||
CALL {
|
||||
MATCH (m:Label1)-[:TYPE]->(:Label2)
|
||||
RETURN m
|
||||
}
|
||||
RETURN m.prop;
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Subquery returning a multiple of results since we join elements from basic query and the subquery
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (:Label1 {prop: 1})-[:TYPE]->(:Label2 {prop: 2})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:Label1)
|
||||
CALL {
|
||||
MATCH (m)
|
||||
RETURN m
|
||||
}
|
||||
RETURN n.prop, m.prop
|
||||
ORDER BY n.prop, m.prop;
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.prop | m.prop |
|
||||
| 1 | 1 |
|
||||
| 1 | 2 |
|
||||
|
||||
Scenario: Subquery returning a cartesian product
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (:Label1 {prop: 1})-[:TYPE]->(:Label2 {prop: 2})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n)
|
||||
CALL {
|
||||
MATCH (m)
|
||||
RETURN m
|
||||
}
|
||||
RETURN n.prop, m.prop
|
||||
ORDER BY n.prop, m.prop;
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.prop | m.prop |
|
||||
| 1 | 1 |
|
||||
| 1 | 2 |
|
||||
| 2 | 1 |
|
||||
| 2 | 2 |
|
||||
|
||||
Scenario: Subquery with bounded symbols
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (:Label1 {prop: 1})-[:TYPE]->(:Label2 {prop: 2})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:Label1)
|
||||
CALL {
|
||||
WITH n
|
||||
MATCH (n)-[:TYPE]->(m:Label2)
|
||||
RETURN m
|
||||
}
|
||||
RETURN m.prop;
|
||||
"""
|
||||
Then the result should be:
|
||||
| m.prop |
|
||||
| 2 |
|
||||
|
||||
Scenario: Subquery with invalid bounded symbols
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (:Label1 {prop: 1})-[:TYPE]->(:Label2 {prop: 2})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:Label1)
|
||||
CALL {
|
||||
WITH o
|
||||
MATCH (o)-[:TYPE]->(m:Label2)
|
||||
RETURN m
|
||||
}
|
||||
RETURN m.prop;
|
||||
"""
|
||||
Then an error should be raised
|
||||
|
||||
Scenario: Subquery returning primitive but not aliased
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (:Label1 {prop: 1})-[:TYPE]->(:Label2 {prop: 2})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:Label1)
|
||||
CALL {
|
||||
WITH n
|
||||
MATCH (n)-[:TYPE]->(m:Label2)
|
||||
RETURN m.prop
|
||||
}
|
||||
RETURN n;
|
||||
"""
|
||||
Then an error should be raised
|
||||
|
||||
Scenario: Subquery returning one primitive and others aliased
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (:Label1 {prop: 1})-[:TYPE]->(:Label2 {prop: 2})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:Label1)
|
||||
CALL {
|
||||
WITH n
|
||||
MATCH (o)-[:TYPE]->(m:Label2)
|
||||
RETURN m.prop, o
|
||||
}
|
||||
RETURN n;
|
||||
"""
|
||||
Then an error should be raised
|
||||
|
||||
Scenario: Subquery returning already declared variable in outer scope
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (:Label1 {prop: 1})-[:TYPE]->(:Label2 {prop: 2})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:Label1), (m:Label2)
|
||||
CALL {
|
||||
WITH n
|
||||
MATCH (n:Label1)-[:TYPE]->(m:Label2)
|
||||
RETURN m
|
||||
}
|
||||
RETURN n;
|
||||
"""
|
||||
Then an error should be raised
|
||||
|
||||
Scenario: Subquery after subquery
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (:Label1 {prop: 1})-[:TYPE]->(:Label2 {prop: 2})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n)
|
||||
CALL {
|
||||
MATCH (m)
|
||||
RETURN m
|
||||
}
|
||||
CALL {
|
||||
MATCH (o)
|
||||
RETURN o
|
||||
}
|
||||
RETURN n.prop, m.prop, o.prop
|
||||
ORDER BY n.prop, m.prop, o.prop;
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.prop | m.prop | o.prop |
|
||||
| 1 | 1 | 1 |
|
||||
| 1 | 1 | 2 |
|
||||
| 1 | 2 | 1 |
|
||||
| 1 | 2 | 2 |
|
||||
| 2 | 1 | 1 |
|
||||
| 2 | 1 | 2 |
|
||||
| 2 | 2 | 1 |
|
||||
| 2 | 2 | 2 |
|
||||
|
||||
Scenario: Subquery with union
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (:Person {figure: "grandpa"})<-[:CHILD_OF]-(:Person {figure: "dad"})-[:PARENT_OF]->(:Person {figure: "child"})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (p:Person {figure: "dad"})
|
||||
CALL {
|
||||
WITH p
|
||||
OPTIONAL MATCH (p)-[:CHILD_OF]->(other:Person)
|
||||
RETURN other
|
||||
UNION
|
||||
WITH p
|
||||
OPTIONAL MATCH (p)-[:PARENT_OF]->(other:Person)
|
||||
RETURN other
|
||||
} RETURN DISTINCT p.figure, count(other) as cnt;
|
||||
"""
|
||||
Then the result should be:
|
||||
| p.figure | cnt |
|
||||
| 'dad' | 2 |
|
||||
|
||||
Scenario: Subquery cloning nodes
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (:Person {name: "Alen"}), (:Person {name: "Bruce"})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (p:Person)
|
||||
CALL {
|
||||
WITH p
|
||||
UNWIND range (1, 3) AS i
|
||||
CREATE (n:Person {name: p.name})
|
||||
RETURN n
|
||||
}
|
||||
RETURN n;
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| (:Person {name: 'Alen'}) |
|
||||
| (:Person {name: 'Alen'}) |
|
||||
| (:Person {name: 'Alen'}) |
|
||||
| (:Person {name: 'Bruce'}) |
|
||||
| (:Person {name: 'Bruce'}) |
|
||||
| (:Person {name: 'Bruce'}) |
|
||||
|
||||
Scenario: Subquery in subquery
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (:Label {id: 1}), (:Label {id: 2})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (p:Label)
|
||||
CALL {
|
||||
MATCH (r:Label)
|
||||
CALL {
|
||||
MATCH (s:Label)
|
||||
RETURN s
|
||||
}
|
||||
RETURN r, s
|
||||
}
|
||||
RETURN p.id, r.id, s.id;
|
||||
"""
|
||||
Then the result should be:
|
||||
| p.id | r.id | s.id |
|
||||
| 1 | 1 | 1 |
|
||||
| 1 | 1 | 2 |
|
||||
| 1 | 2 | 1 |
|
||||
| 1 | 2 | 2 |
|
||||
| 2 | 1 | 1 |
|
||||
| 2 | 1 | 2 |
|
||||
| 2 | 2 | 1 |
|
||||
| 2 | 2 | 2 |
|
||||
|
||||
Scenario: Counter inside subquery
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (:Counter {count: 0})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
UNWIND [0, 1, 2] AS x
|
||||
CALL {
|
||||
MATCH (n:Counter)
|
||||
SET n.count = n.count + 1
|
||||
RETURN n.count AS innerCount
|
||||
}
|
||||
WITH innerCount
|
||||
MATCH (n:Counter)
|
||||
RETURN innerCount, n.count AS totalCount
|
||||
"""
|
||||
Then the result should be:
|
||||
| innerCount | totalCount |
|
||||
| 1 | 3 |
|
||||
| 2 | 3 |
|
||||
| 3 | 3 |
|
||||
|
||||
Scenario: Advance command on multiple subqueries
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
CALL {
|
||||
CREATE (create_node:Movie {title: "Forrest Gump"})
|
||||
}
|
||||
CALL {
|
||||
MATCH (n) RETURN n
|
||||
}
|
||||
RETURN n.title AS title;
|
||||
"""
|
||||
Then the result should be:
|
||||
| title |
|
||||
| 'Forrest Gump' |
|
||||
|
||||
Scenario: Advance command on multiple subqueries with manual accumulate
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
CALL {
|
||||
CREATE (create_node:Movie {title: "Forrest Gump"})
|
||||
RETURN create_node
|
||||
}
|
||||
WITH create_node
|
||||
CALL {
|
||||
MATCH (n) RETURN n
|
||||
}
|
||||
RETURN n.title AS title;
|
||||
"""
|
||||
Then the result should be:
|
||||
| title |
|
||||
| 'Forrest Gump' |
|
@ -0,0 +1,135 @@
|
||||
Feature: Union
|
||||
|
||||
Scenario: Test return *
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
WITH 5 AS X, 3 AS Y RETURN * UNION WITH 9 AS X, 4 AS Y RETURN *;
|
||||
"""
|
||||
Then the result should be:
|
||||
| X | Y |
|
||||
| 5 | 3 |
|
||||
| 9 | 4 |
|
||||
|
||||
Scenario: Test return * with swapped parameters
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
WITH 5 AS X, 3 AS Y RETURN * UNION WITH 9 AS Y, 4 AS X RETURN *;
|
||||
"""
|
||||
Then the result should be:
|
||||
| X | Y |
|
||||
| 5 | 3 |
|
||||
| 4 | 9 |
|
||||
|
||||
Scenario: Test return * and named parameters
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
WITH 5 AS X, 3 AS Y RETURN * UNION WITH 9 AS Y, 4 AS X RETURN Y, X;
|
||||
"""
|
||||
Then the result should be:
|
||||
| X | Y |
|
||||
| 5 | 3 |
|
||||
| 4 | 9 |
|
||||
|
||||
Scenario: Test distinct single elements are returned
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a: A{x: 1, y: 1}), (b: A{x: 1, y: 2}), (c: A{x: 2, y: 1}), (d: A{x: 1, y:1})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a: A{x:1}) RETURN a.x AS X UNION MATCH (a: A{y:1}) RETURN a.x AS X;
|
||||
"""
|
||||
Then the result should be:
|
||||
| X |
|
||||
| 1 |
|
||||
| 2 |
|
||||
|
||||
Scenario: Test all single elements are returned
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a: A{x: 1, y: 1}), (b: A{x: 1, y: 2}), (c: A{x: 2, y: 1}), (d: A{x: 1, y:1})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a: A{x:1}) RETURN a.x AS X UNION ALL MATCH (a: A{y:1}) RETURN a.x AS X;
|
||||
"""
|
||||
Then the result should be:
|
||||
| X |
|
||||
| 1 |
|
||||
| 1 |
|
||||
| 1 |
|
||||
| 1 |
|
||||
| 2 |
|
||||
| 1 |
|
||||
|
||||
Scenario: Test distinct elements are returned
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a: A{x: 1, y: 1}), (b: A{x: 1, y: 2}), (c: A{x: 2, y: 1}), (d: A{x: 1, y:1})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a: A{x:1}) RETURN a.x AS X, a.y AS Y UNION MATCH (a: A{y:1}) RETURN a.x AS X, a.y AS Y;
|
||||
"""
|
||||
Then the result should be:
|
||||
| X | Y |
|
||||
| 1 | 1 |
|
||||
| 1 | 2 |
|
||||
| 2 | 1 |
|
||||
|
||||
Scenario: Test all elements are returned
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a: A{x: 1, y: 1}), (b: A{x: 1, y: 2}), (c: A{x: 2, y: 1}), (d: A{x: 1, y:1})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a: A{x:1}) RETURN a.x AS X, a.y AS Y UNION ALL MATCH (a: A{y:1}) RETURN a.x AS X, a.y AS Y;
|
||||
"""
|
||||
Then the result should be:
|
||||
| X | Y |
|
||||
| 1 | 1 |
|
||||
| 1 | 2 |
|
||||
| 1 | 1 |
|
||||
| 1 | 1 |
|
||||
| 2 | 1 |
|
||||
| 1 | 1 |
|
||||
|
||||
Scenario: Test union combinator 1
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a) RETURN a.x as V UNION ALL MATCH (a) RETURN a.y AS V UNION MATCH (a) RETURN a.y + a.x AS V;
|
||||
"""
|
||||
Then an error should be raised
|
||||
|
||||
Scenario: Test union combinator 2
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a) RETURN a.x as V UNION MATCH (a) RETURN a.y AS V UNION ALL MATCH (a) RETURN a.y + a.x AS V;
|
||||
"""
|
||||
Then an error should be raised
|
||||
|
||||
Scenario: Different names of return expressions
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
RETURN 10 as x UNION RETURN 11 as y
|
||||
"""
|
||||
Then an error should be raised
|
||||
|
||||
Scenario: Different number of return expressions
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
RETURN 10 as x, 11 as y UNION RETURN 11 as y
|
||||
"""
|
||||
Then an error should be raised
|
@ -0,0 +1,292 @@
|
||||
Feature: Update clauses
|
||||
|
||||
Scenario: Match create return test
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (:x_1), (:z2_), (:qw34)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a:x_1), (b:z2_), (c:qw34)
|
||||
CREATE (a)-[x:X]->(b) CREATE (b)<-[y:Y]-(c)
|
||||
RETURN x, y
|
||||
"""
|
||||
Then the result should be:
|
||||
| x | y |
|
||||
| [:X] | [:Y] |
|
||||
|
||||
Scenario: Multiple matches in one query
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (:x{age: 5}), (:y{age: 4}), (:z), (:x), (:y)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a:x), (b:y), (c:z)
|
||||
WHERE a.age=5
|
||||
MATCH (b{age: 4})
|
||||
RETURN a, b, c
|
||||
"""
|
||||
Then the result should be:
|
||||
| a | b | c |
|
||||
| (:x{age: 5}) | (:y{age: 4}) | (:z) |
|
||||
|
||||
Scenario: Match set one property return test
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (:q)-[:X]->()
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a:q)-[b]-(c)
|
||||
SET a.name='Sinisa'
|
||||
RETURN a, b, c
|
||||
"""
|
||||
Then the result should be:
|
||||
| a | b | c |
|
||||
| (:q{name: 'Sinisa'}) | [:X] | () |
|
||||
|
||||
Scenario: Match set properties from node to node return test
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (:q{name: 'Sinisa', x: 'y'})-[:X]->({name: 'V', o: 'Traktor'})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a:q)-[b]-(c)
|
||||
SET c=a
|
||||
RETURN a, b, c
|
||||
"""
|
||||
Then the result should be:
|
||||
| a | b | c |
|
||||
| (:q{name: 'Sinisa', x: 'y'}) | [:X] | ({name: 'Sinisa', x: 'y'}) |
|
||||
|
||||
Scenario: Match set properties from node to relationship return test
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (:q{x: 'y'})-[:X]->({y: 't'})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a:q)-[b]-(c)
|
||||
SET b=a
|
||||
RETURN a, b, c
|
||||
"""
|
||||
Then the result should be:
|
||||
| a | b | c |
|
||||
| (:q{x: 'y'}) | [:X{x: 'y'}] | ({y: 't'}) |
|
||||
|
||||
Scenario: Match set properties from relationship to node return test
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (:q)-[:X{x: 'y'}]->({y: 't'})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a:q)-[b]-(c)
|
||||
SET a=b
|
||||
RETURN a, b, c
|
||||
"""
|
||||
Then the result should be:
|
||||
| a | b | c |
|
||||
| (:q{x: 'y'}) | [:X{x: 'y'}] | ({y: 't'}) |
|
||||
|
||||
Scenario: Match node set properties without return
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (n1:Node {test: 1})
|
||||
CREATE (n2:Node {test: 2})
|
||||
CREATE (n3:Node {test: 3})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n:Node)
|
||||
SET n.test = 4
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
|
||||
Scenario: Match, set properties from relationship to relationship, return test
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
CREATE ()-[b:X{x: 'y'}]->()-[a:Y]->()
|
||||
SET a=b
|
||||
RETURN a, b
|
||||
"""
|
||||
Then the result should be:
|
||||
| a | b |
|
||||
| [:Y{x: 'y'}] | [:X{x: 'y'}] |
|
||||
|
||||
Scenario: Create, set adding properties, return test
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
CREATE ()-[b:X{x: 'y', y: 'z'}]->()-[a:Y{x: 'z'}]->()
|
||||
SET a += b
|
||||
RETURN a, b
|
||||
"""
|
||||
Then the result should be:
|
||||
| a | b |
|
||||
| [:Y{x: 'y', y: 'z'}] | [:X{x: 'y', y: 'z'}] |
|
||||
|
||||
Scenario: Create node and add labels using set, return test
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
CREATE (a)
|
||||
SET a :sinisa:vu
|
||||
RETURN a
|
||||
"""
|
||||
Then the result should be:
|
||||
| a |
|
||||
| (:sinisa:vu) |
|
||||
|
||||
Scenario: Create node and delete it
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (n)
|
||||
DELETE (n)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n)
|
||||
RETURN n
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Create node with relationships and delete it, check for relationships
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (n)-[:X]->()
|
||||
CREATE (n)-[:Y]->()
|
||||
DETACH DELETE (n)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH ()-[n]->()
|
||||
RETURN n
|
||||
"""
|
||||
Then the result should be empty
|
||||
|
||||
Scenario: Create node with relationships and delete it, check for nodes
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (n:l{a: 1})-[:X]->()
|
||||
CREATE (n)-[:Y]->()
|
||||
DETACH DELETE (n)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n)
|
||||
RETURN n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
|( )|
|
||||
|( )|
|
||||
|
||||
Scenario: Create node with relationships and delete it (without parentheses), check for nodes
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (n:l{a: 1})-[:X]->()
|
||||
CREATE (n)-[:Y]->()
|
||||
DETACH DELETE n
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n)
|
||||
RETURN n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
|( )|
|
||||
|( )|
|
||||
|
||||
Scenario: Set test:
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (a:A{x: 1}), (b:B{x: 2}), (c:C{x: 3}), (a)-[:T]->(b), (b)-[:T]->(c), (c)-[:T]->(a)
|
||||
"""
|
||||
And having executed:
|
||||
"""
|
||||
MATCH (d)--(e) WHERE abs(d.x - e.x)<=1 SET d.x=d.x+2, e.x=e.x+2
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH(x) RETURN x
|
||||
"""
|
||||
Then the result should be:
|
||||
| x |
|
||||
| (:A{x: 5}) |
|
||||
| (:B{x: 10}) |
|
||||
| (:C{x: 7}) |
|
||||
|
||||
Scenario: Remove 01
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a:A:B:C)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) REMOVE n:A:B:C RETURN n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| () |
|
||||
|
||||
Scenario: Remove 02
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a:A:B:C)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) REMOVE n:B:C RETURN n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| (:A) |
|
||||
|
||||
Scenario: Remove 03
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a{a: 1, b: 1.0, c: 's', d: false})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) REMOVE n:A:B, n.a REMOVE n.b, n.c, n.d RETURN n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| () |
|
||||
|
||||
Scenario: Remove 04
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a:A:B{a: 1, b: 's', c: 1.0, d: true})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) REMOVE n:B, n.a, n.d RETURN n
|
||||
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| (:A{b: 's', c: 1.0}) |
|
251
tests/gql_behave/tests/memgraph_V1_on_disk/features/with.feature
Normal file
251
tests/gql_behave/tests/memgraph_V1_on_disk/features/with.feature
Normal file
@ -0,0 +1,251 @@
|
||||
Feature: With
|
||||
|
||||
Scenario: With test 01:
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (a:A), (b:B), (c:C), (d:D), (e:E), (a)-[:R]->(b), (b)-[:R]->(c), (b)-[:R]->(d), (c)-[:R]->(a), (c)-[:R]->(e), (d)-[:R]->(e)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (:A)--(a)-->() WITH a, COUNT(*) AS n WHERE n > 1 RETURN a
|
||||
"""
|
||||
Then the result should be:
|
||||
| a |
|
||||
| (:B) |
|
||||
|
||||
Scenario: With test 02:
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a:A{x: 1}), (b:B{x: 2}), (c:C{x: 3}), (d:D{x: 4}), (a)-[:R]->(b), (b)-[:R]->(c), (c)-[:R]->(d), (d)-[:R]->(a)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (a)--(b)
|
||||
WITH a, MAX(b.x) AS s
|
||||
RETURN a, s
|
||||
"""
|
||||
Then the result should be:
|
||||
| a | s |
|
||||
| (:A{x: 1}) | 4 |
|
||||
| (:B{x: 2}) | 3 |
|
||||
| (:C{x: 3}) | 4 |
|
||||
| (:D{x: 4}) | 3 |
|
||||
|
||||
Scenario: With test 03:
|
||||
Given an empty graph
|
||||
And having executed
|
||||
"""
|
||||
CREATE (a:A{x: 1}), (b:B{x: 2}), (a)-[:R]->(b), (a)-[:R]->(b), (b)-[:R]->(a), (b)-[:R]->(a)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (b)--(a)--(c)
|
||||
WITH a, (SUM(b.x)+SUM(c.x)) AS s
|
||||
RETURN a, s
|
||||
"""
|
||||
Then the result should be:
|
||||
| a | s |
|
||||
| (:A{x: 1}) | 48 |
|
||||
| (:B{x: 2}) | 24 |
|
||||
|
||||
Scenario: With test 04:
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (a:A{x: 1}), (b:B{x: 2}), (c:C{x: 3}), (d:D{x: 4}), (e:E{x: 5}), (a)-[:R]->(b), (b)-[:R]->(c), (b)-[:R]->(d), (c)-[:R]->(a), (c)-[:R]->(e), (d)-[:R]->(e)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (c)--(a:B)--(b)--(d)
|
||||
WITH a, b, SUM(c.x)+SUM(d.x) AS n RETURN a, b, n
|
||||
"""
|
||||
Then the result should be:
|
||||
| a | b | n |
|
||||
| (:B{x: 2}) | (:A{x: 1}) | 13 |
|
||||
| (:B{x: 2}) | (:C{x: 3}) | 22 |
|
||||
| (:B{x: 2}) | (:D{x: 4}) | 14 |
|
||||
|
||||
Scenario: With test 05:
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (a:A{x: 1}), (b:B{x: 2}), (c:C{x: 3}), (d:D{x: 4}), (e:E{x: 5}), (a)-[:R]->(b), (b)-[:R]->(c), (b)-[:R]->(d), (c)-[:R]->(a), (c)-[:R]->(e), (d)-[:R]->(e)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (c)--(a:B)--(b)--(d)
|
||||
WITH a, b, AVG(c.x + d.x) AS n RETURN a, b, n
|
||||
"""
|
||||
Then the result should be:
|
||||
| a | b | n |
|
||||
| (:B{x: 2}) | (:A{x: 1}) | 6.5 |
|
||||
| (:B{x: 2}) | (:C{x: 3}) | 5.5 |
|
||||
| (:B{x: 2}) | (:D{x: 4}) | 7.0 |
|
||||
|
||||
Scenario: With test 06:
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (a:A{x: 1}), (b:B{x: 2}), (c:C{x: 3}), (d:D{x: 4}), (e:E{x: 5}), (a)-[:R]->(b), (b)-[:R]->(c), (b)-[:R]->(d), (c)-[:R]->(a), (c)-[:R]->(e), (d)-[:R]->(e)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (c)--(a:B)--(b)--(d)
|
||||
WITH a, b, AVG(c.x + d.x) AS n RETURN MAX(n) AS n
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| 7.0 |
|
||||
|
||||
Scenario: With test 07:
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (a:A{x: 1}), (b:B{x: 2}), (c:C{x: 3}), (d:D{x: 4}), (e:E{x: 5}), (a)-[:R]->(b), (b)-[:R]->(c), (b)-[:R]->(d), (c)-[:R]->(a), (c)-[:R]->(e), (d)-[:R]->(e)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (c)--(a:B)--(b)--(d)
|
||||
WITH a, b, AVG(c.x + d.x) AS n
|
||||
WITH a, MAX(n) AS n RETURN a, n
|
||||
"""
|
||||
Then the result should be:
|
||||
| a | n |
|
||||
| (:B{x: 2}) | 7.0 |
|
||||
|
||||
Scenario: With test 08:
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
CREATE (a), (b) WITH a, b CREATE (a)-[r:R]->(b) RETURN r
|
||||
"""
|
||||
Then the result should be:
|
||||
| r |
|
||||
| [:R] |
|
||||
|
||||
Scenario: With test 09:
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
CREATE (a), (b) WITH a, b SET a:X SET b:Y WITH a, b MATCH(x:X) RETURN x
|
||||
"""
|
||||
Then the result should be:
|
||||
| x |
|
||||
| (:X) |
|
||||
|
||||
Scenario: With test 10:
|
||||
Given an empty graph
|
||||
When executing query:
|
||||
"""
|
||||
CREATE (a), (b), (a)-[:R]->(b) WITH a, b SET a:X SET b:Y
|
||||
WITH a MATCH(x:X)--(b) RETURN x, x AS y
|
||||
"""
|
||||
Then the result should be:
|
||||
| x | y |
|
||||
| (:X) | (:X) |
|
||||
|
||||
Scenario: With test 10:
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (a:A{x: 1}), (b:B{x: 2}), (c:C{x: 3}), (d:D{x: 4}), (e:E{x: 5}), (a)-[:R]->(b), (b)-[:R]->(c), (b)-[:R]->(d), (c)-[:R]->(a), (c)-[:R]->(e), (d)-[:R]->(e)
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (c)--(a:B)--(b)--(d) WITH a, b, AVG(c.x + d.x) AS av WITH AVG(av) AS avg
|
||||
MATCH (c)--(a:B)--(b)--(d) WITH a, b, avg, AVG(c.x + d.x) AS av WHERE av>avg RETURN av
|
||||
"""
|
||||
Then the result should be:
|
||||
| av |
|
||||
| 6.5 |
|
||||
| 7.0 |
|
||||
|
||||
Scenario: With test 11:
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE(:A{a: 1}), (:B{a: 1}), (:C{a: 1}), (:D{a: 4}), (:E{a: 5})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH(n) WITH n.a AS a
|
||||
ORDER BY a LIMIT 4
|
||||
RETURN a
|
||||
"""
|
||||
Then the result should be, in order:
|
||||
| a |
|
||||
| 1 |
|
||||
| 1 |
|
||||
| 1 |
|
||||
| 4 |
|
||||
|
||||
Scenario: With test 12:
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE(:A{a: 1}), (:B{a: 5}), (:C{a: 2}), (:D{a: 3}), (:E{a: 5})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH(n) WITH n.a AS a
|
||||
ORDER BY a SKIP 2
|
||||
RETURN a
|
||||
"""
|
||||
Then the result should be, in order:
|
||||
| a |
|
||||
| 3 |
|
||||
| 5 |
|
||||
| 5 |
|
||||
|
||||
Scenario: With test 13:
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE(:A{a: 1}), (:B{a: 5}), (:C{a: 2}), (:D{a: 3}), (:E{a: 5})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH(n) WITH n.a AS a
|
||||
ORDER BY a
|
||||
RETURN a
|
||||
"""
|
||||
Then the result should be, in order:
|
||||
| a |
|
||||
| 1 |
|
||||
| 2 |
|
||||
| 3 |
|
||||
| 5 |
|
||||
| 5 |
|
||||
|
||||
Scenario: With test 14:
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE(:A{a: 1}), (:B{a: 5}), (:C{a: 1}), (:D{a: 3}), (:E{a: 5})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH(n) WITH DISTINCT n.a AS a
|
||||
RETURN a
|
||||
"""
|
||||
Then the result should be:
|
||||
| a |
|
||||
| 1 |
|
||||
| 3 |
|
||||
| 5 |
|
||||
|
||||
Scenario: With test 15:
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE ({id: 0})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n) WITH n RETURN *
|
||||
"""
|
||||
Then the result should be:
|
||||
| n |
|
||||
| ({id: 0}) |
|
@ -0,0 +1,4 @@
|
||||
CREATE (n:Person {age: 20});
|
||||
CREATE (n:Person:Student {age: 20});
|
||||
CREATE (n:Person {age: 21});
|
||||
CREATE (n:Student {age:21})
|
Loading…
Reference in New Issue
Block a user