Run separate GQL suits for different storage modes (#1346)

This commit is contained in:
Andi 2023-10-11 11:42:41 +02:00 committed by GitHub
parent 1a3c5af797
commit 06868c8be7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 6735 additions and 3 deletions

View File

@ -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)

View File

@ -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

View File

@ -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:
"""

View File

@ -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 |

View File

@ -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

View File

@ -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' |

View File

@ -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

View File

@ -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

View File

@ -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 |

View File

@ -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

View File

@ -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 |

View 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'} |

View File

@ -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 |

View File

@ -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 |

View File

@ -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

View File

@ -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

View File

@ -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 |

View File

@ -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 |

View File

@ -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

View File

@ -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

View File

@ -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)) |

View File

@ -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 |

View File

@ -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

View File

@ -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' |

View File

@ -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

View File

@ -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}) |

View 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}) |

View File

@ -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})