81289d0663
Reviewers: buda Reviewed By: buda Subscribers: matej.gradicek Differential Revision: https://phabricator.memgraph.io/D122
485 lines
12 KiB
Gherkin
485 lines
12 KiB
Gherkin
#
|
|
# Copyright 2017 "Neo Technology",
|
|
# Network Engine for Objects in Lund AB (http://neotechnology.com)
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
#
|
|
|
|
Feature: MergeNodeAcceptance
|
|
|
|
Scenario: Merge node when no nodes exist
|
|
Given an empty graph
|
|
When executing query:
|
|
"""
|
|
MERGE (a)
|
|
RETURN count(*) AS n
|
|
"""
|
|
Then the result should be:
|
|
| n |
|
|
| 1 |
|
|
And the side effects should be:
|
|
| +nodes | 1 |
|
|
|
|
Scenario: Merge node with label
|
|
Given an empty graph
|
|
When executing query:
|
|
"""
|
|
MERGE (a:Label)
|
|
RETURN labels(a)
|
|
"""
|
|
Then the result should be:
|
|
| labels(a) |
|
|
| ['Label'] |
|
|
And the side effects should be:
|
|
| +nodes | 1 |
|
|
| +labels | 1 |
|
|
|
|
Scenario: Merge node with label add label on create
|
|
Given an empty graph
|
|
When executing query:
|
|
"""
|
|
MERGE (a:Label)
|
|
ON CREATE SET a:Foo
|
|
RETURN labels(a)
|
|
"""
|
|
Then the result should be (ignoring element order for lists):
|
|
| labels(a) |
|
|
| ['Label', 'Foo'] |
|
|
And the side effects should be:
|
|
| +nodes | 1 |
|
|
| +labels | 2 |
|
|
|
|
Scenario: Merge node with label add property on create
|
|
Given an empty graph
|
|
When executing query:
|
|
"""
|
|
MERGE (a:Label)
|
|
ON CREATE SET a.prop = 42
|
|
RETURN a.prop
|
|
"""
|
|
Then the result should be:
|
|
| a.prop |
|
|
| 42 |
|
|
And the side effects should be:
|
|
| +nodes | 1 |
|
|
| +labels | 1 |
|
|
| +properties | 1 |
|
|
|
|
Scenario: Merge node with label when it exists
|
|
Given an empty graph
|
|
And having executed:
|
|
"""
|
|
CREATE (:Label {id: 1})
|
|
"""
|
|
When executing query:
|
|
"""
|
|
MERGE (a:Label)
|
|
RETURN a.id
|
|
"""
|
|
Then the result should be:
|
|
| a.id |
|
|
| 1 |
|
|
And no side effects
|
|
|
|
Scenario: Merge node should create when it doesn't match, properties
|
|
Given an empty graph
|
|
And having executed:
|
|
"""
|
|
CREATE ({prop: 42})
|
|
"""
|
|
When executing query:
|
|
"""
|
|
MERGE (a {prop: 43})
|
|
RETURN a.prop
|
|
"""
|
|
Then the result should be:
|
|
| a.prop |
|
|
| 43 |
|
|
And the side effects should be:
|
|
| +nodes | 1 |
|
|
| +properties | 1 |
|
|
|
|
Scenario: Merge node should create when it doesn't match, properties and label
|
|
Given an empty graph
|
|
And having executed:
|
|
"""
|
|
CREATE (:Label {prop: 42})
|
|
"""
|
|
When executing query:
|
|
"""
|
|
MERGE (a:Label {prop: 43})
|
|
RETURN a.prop
|
|
"""
|
|
Then the result should be:
|
|
| a.prop |
|
|
| 43 |
|
|
And the side effects should be:
|
|
| +nodes | 1 |
|
|
| +labels | 1 |
|
|
| +properties | 1 |
|
|
|
|
Scenario: Merge node with prop and label
|
|
Given an empty graph
|
|
And having executed:
|
|
"""
|
|
CREATE (:Label {prop: 42})
|
|
"""
|
|
When executing query:
|
|
"""
|
|
MERGE (a:Label {prop: 42})
|
|
RETURN a.prop
|
|
"""
|
|
Then the result should be:
|
|
| a.prop |
|
|
| 42 |
|
|
And no side effects
|
|
|
|
Scenario: Merge node with label add label on match when it exists
|
|
Given an empty graph
|
|
And having executed:
|
|
"""
|
|
CREATE (:Label)
|
|
"""
|
|
When executing query:
|
|
"""
|
|
MERGE (a:Label)
|
|
ON MATCH SET a:Foo
|
|
RETURN labels(a)
|
|
"""
|
|
Then the result should be:
|
|
| labels(a) |
|
|
| ['Label', 'Foo'] |
|
|
And the side effects should be:
|
|
| +labels | 1 |
|
|
|
|
Scenario: Merge node with label add property on update when it exists
|
|
Given an empty graph
|
|
And having executed:
|
|
"""
|
|
CREATE (:Label)
|
|
"""
|
|
When executing query:
|
|
"""
|
|
MERGE (a:Label)
|
|
ON CREATE SET a.prop = 42
|
|
RETURN a.prop
|
|
"""
|
|
Then the result should be:
|
|
| a.prop |
|
|
| null |
|
|
And no side effects
|
|
|
|
Scenario: Merge node and set property on match
|
|
Given an empty graph
|
|
And having executed:
|
|
"""
|
|
CREATE (:Label)
|
|
"""
|
|
When executing query:
|
|
"""
|
|
MERGE (a:Label)
|
|
ON MATCH SET a.prop = 42
|
|
RETURN a.prop
|
|
"""
|
|
Then the result should be:
|
|
| a.prop |
|
|
| 42 |
|
|
And the side effects should be:
|
|
| +properties | 1 |
|
|
|
|
Scenario: Should work when finding multiple elements
|
|
Given an empty graph
|
|
When executing query:
|
|
"""
|
|
CREATE (:X)
|
|
CREATE (:X)
|
|
MERGE (:X)
|
|
"""
|
|
Then the result should be empty
|
|
And the side effects should be:
|
|
| +nodes | 2 |
|
|
| +labels | 2 |
|
|
|
|
Scenario: Should handle argument properly
|
|
Given an empty graph
|
|
And having executed:
|
|
"""
|
|
CREATE ({x: 42}),
|
|
({x: 'not42'})
|
|
"""
|
|
When executing query:
|
|
"""
|
|
WITH 42 AS x
|
|
MERGE (c:N {x: x})
|
|
"""
|
|
Then the result should be empty
|
|
And the side effects should be:
|
|
| +nodes | 1 |
|
|
| +labels | 1 |
|
|
| +properties | 1 |
|
|
|
|
Scenario: Should handle arguments properly with only write clauses
|
|
Given an empty graph
|
|
When executing query:
|
|
"""
|
|
CREATE (a {p: 1})
|
|
MERGE ({v: a.p})
|
|
"""
|
|
Then the result should be empty
|
|
And the side effects should be:
|
|
| +nodes | 2 |
|
|
| +properties | 2 |
|
|
|
|
Scenario: Should be able to merge using property from match
|
|
Given an empty graph
|
|
And having executed:
|
|
"""
|
|
CREATE (:Person {name: 'A', bornIn: 'New York'})
|
|
CREATE (:Person {name: 'B', bornIn: 'Ohio'})
|
|
CREATE (:Person {name: 'C', bornIn: 'New Jersey'})
|
|
CREATE (:Person {name: 'D', bornIn: 'New York'})
|
|
CREATE (:Person {name: 'E', bornIn: 'Ohio'})
|
|
CREATE (:Person {name: 'F', bornIn: 'New Jersey'})
|
|
"""
|
|
When executing query:
|
|
"""
|
|
MATCH (person:Person)
|
|
MERGE (city:City {name: person.bornIn})
|
|
"""
|
|
Then the result should be empty
|
|
And the side effects should be:
|
|
| +nodes | 3 |
|
|
| +labels | 3 |
|
|
| +properties | 3 |
|
|
|
|
Scenario: Should be able to use properties from match in ON CREATE
|
|
Given an empty graph
|
|
And having executed:
|
|
"""
|
|
CREATE (:Person {bornIn: 'New York'}),
|
|
(:Person {bornIn: 'Ohio'})
|
|
"""
|
|
When executing query:
|
|
"""
|
|
MATCH (person:Person)
|
|
MERGE (city:City)
|
|
ON CREATE SET city.name = person.bornIn
|
|
RETURN person.bornIn
|
|
"""
|
|
Then the result should be:
|
|
| person.bornIn |
|
|
| 'New York' |
|
|
| 'Ohio' |
|
|
And the side effects should be:
|
|
| +nodes | 1 |
|
|
| +labels | 1 |
|
|
| +properties | 1 |
|
|
|
|
Scenario: Should be able to use properties from match in ON MATCH
|
|
Given an empty graph
|
|
And having executed:
|
|
"""
|
|
CREATE (:Person {bornIn: 'New York'}),
|
|
(:Person {bornIn: 'Ohio'})
|
|
"""
|
|
When executing query:
|
|
"""
|
|
MATCH (person:Person)
|
|
MERGE (city:City)
|
|
ON MATCH SET city.name = person.bornIn
|
|
RETURN person.bornIn
|
|
"""
|
|
Then the result should be:
|
|
| person.bornIn |
|
|
| 'New York' |
|
|
| 'Ohio' |
|
|
And the side effects should be:
|
|
| +nodes | 1 |
|
|
| +labels | 1 |
|
|
| +properties | 1 |
|
|
|
|
Scenario: Should be able to use properties from match in ON MATCH and ON CREATE
|
|
Given an empty graph
|
|
And having executed:
|
|
"""
|
|
CREATE (:Person {bornIn: 'New York'}),
|
|
(:Person {bornIn: 'Ohio'})
|
|
"""
|
|
When executing query:
|
|
"""
|
|
MATCH (person:Person)
|
|
MERGE (city:City)
|
|
ON MATCH SET city.name = person.bornIn
|
|
ON CREATE SET city.name = person.bornIn
|
|
RETURN person.bornIn
|
|
"""
|
|
Then the result should be:
|
|
| person.bornIn |
|
|
| 'New York' |
|
|
| 'Ohio' |
|
|
And the side effects should be:
|
|
| +nodes | 1 |
|
|
| +labels | 1 |
|
|
| +properties | 2 |
|
|
|
|
Scenario: Should be able to set labels on match
|
|
Given an empty graph
|
|
And having executed:
|
|
"""
|
|
CREATE ()
|
|
"""
|
|
When executing query:
|
|
"""
|
|
MERGE (a)
|
|
ON MATCH SET a:L
|
|
"""
|
|
Then the result should be empty
|
|
And the side effects should be:
|
|
| +labels | 1 |
|
|
|
|
Scenario: Should be able to set labels on match and on create
|
|
Given an empty graph
|
|
And having executed:
|
|
"""
|
|
CREATE (), ()
|
|
"""
|
|
When executing query:
|
|
"""
|
|
MATCH ()
|
|
MERGE (a:L)
|
|
ON MATCH SET a:M1
|
|
ON CREATE SET a:M2
|
|
"""
|
|
Then the result should be empty
|
|
And the side effects should be:
|
|
| +nodes | 1 |
|
|
| +labels | 3 |
|
|
|
|
Scenario: Should support updates while merging
|
|
Given an empty graph
|
|
And having executed:
|
|
"""
|
|
UNWIND [0, 1, 2] AS x
|
|
UNWIND [0, 1, 2] AS y
|
|
CREATE ({x: x, y: y})
|
|
"""
|
|
When executing query:
|
|
"""
|
|
MATCH (foo)
|
|
WITH foo.x AS x, foo.y AS y
|
|
MERGE (:N {x: x, y: y + 1})
|
|
MERGE (:N {x: x, y: y})
|
|
MERGE (:N {x: x + 1, y: y})
|
|
RETURN x, y
|
|
"""
|
|
Then the result should be:
|
|
| x | y |
|
|
| 0 | 0 |
|
|
| 0 | 1 |
|
|
| 0 | 2 |
|
|
| 1 | 0 |
|
|
| 1 | 1 |
|
|
| 1 | 2 |
|
|
| 2 | 0 |
|
|
| 2 | 1 |
|
|
| 2 | 2 |
|
|
And the side effects should be:
|
|
| +nodes | 15 |
|
|
| +labels | 15 |
|
|
| +properties | 30 |
|
|
|
|
Scenario: Merge must properly handle multiple labels
|
|
Given an empty graph
|
|
And having executed:
|
|
"""
|
|
CREATE (:L:A {prop: 42})
|
|
"""
|
|
When executing query:
|
|
"""
|
|
MERGE (test:L:B {prop: 42})
|
|
RETURN labels(test) AS labels
|
|
"""
|
|
Then the result should be:
|
|
| labels |
|
|
| ['L', 'B'] |
|
|
And the side effects should be:
|
|
| +nodes | 1 |
|
|
| +labels | 2 |
|
|
| +properties | 1 |
|
|
|
|
Scenario: Merge followed by multiple creates
|
|
Given an empty graph
|
|
When executing query:
|
|
"""
|
|
MERGE (t:T {id: 42})
|
|
CREATE (f:R)
|
|
CREATE (t)-[:REL]->(f)
|
|
"""
|
|
Then the result should be empty
|
|
And the side effects should be:
|
|
| +nodes | 2 |
|
|
| +relationships | 1 |
|
|
| +labels | 2 |
|
|
| +properties | 1 |
|
|
|
|
Scenario: Unwind combined with merge
|
|
Given an empty graph
|
|
When executing query:
|
|
"""
|
|
UNWIND [1, 2, 3, 4] AS int
|
|
MERGE (n {id: int})
|
|
RETURN count(*)
|
|
"""
|
|
Then the result should be:
|
|
| count(*) |
|
|
| 4 |
|
|
And the side effects should be:
|
|
| +nodes | 4 |
|
|
| +properties | 4 |
|
|
|
|
Scenario: Merges should not be able to match on deleted nodes
|
|
Given an empty graph
|
|
And having executed:
|
|
"""
|
|
CREATE (:A {value: 1}),
|
|
(:A {value: 2})
|
|
"""
|
|
When executing query:
|
|
"""
|
|
MATCH (a:A)
|
|
DELETE a
|
|
MERGE (a2:A)
|
|
RETURN a2.value
|
|
"""
|
|
Then the result should be:
|
|
| a2.value |
|
|
| null |
|
|
| null |
|
|
And the side effects should be:
|
|
| +nodes | 1 |
|
|
| -nodes | 2 |
|
|
| +labels | 1 |
|
|
|
|
Scenario: ON CREATE on created nodes
|
|
Given an empty graph
|
|
When executing query:
|
|
"""
|
|
MERGE (b)
|
|
ON CREATE SET b.created = 1
|
|
"""
|
|
Then the result should be empty
|
|
And the side effects should be:
|
|
| +nodes | 1 |
|
|
| +properties | 1 |
|
|
|