Skip to content

Commit

Permalink
Fixes #2699: The apoc.refactor.mergeNodes remove entities if a list w…
Browse files Browse the repository at this point in the history
…ith 2 equal nodes is passed
  • Loading branch information
vga91 authored and nadja-muller committed May 23, 2022
1 parent 72866a9 commit 2ac45f4
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 4 deletions.
8 changes: 5 additions & 3 deletions core/src/main/java/apoc/refactor/GraphRefactoring.java
Original file line number Diff line number Diff line change
Expand Up @@ -278,8 +278,9 @@ private Map<Node, Node> generateStandinMap(List<List<Node>> standins) {
public Stream<NodeResult> mergeNodes(@Name("nodes") List<Node> nodes, @Name(value = "config", defaultValue = "{}") Map<String, Object> config) {
if (nodes == null || nodes.isEmpty()) return Stream.empty();
RefactorConfig conf = new RefactorConfig(config);
Set<Node> nodesSet = new LinkedHashSet<>(nodes);
// grab write locks upfront consistently ordered
nodes.stream().distinct().sorted(Comparator.comparingLong(Node::getId)).forEach(tx::acquireWriteLock);
nodesSet.stream().sorted(Comparator.comparingLong(Node::getId)).forEach(tx::acquireWriteLock);

final Node first = nodes.get(0);
final List<Long> existingSelfRelIds = conf.isPreservingExistingSelfRels()
Expand All @@ -288,7 +289,7 @@ public Stream<NodeResult> mergeNodes(@Name("nodes") List<Node> nodes, @Name(valu
.collect(Collectors.toList())
: Collections.emptyList();

nodes.stream().skip(1).distinct().forEach(node -> mergeNodes(node, first, conf, existingSelfRelIds));
nodesSet.stream().skip(1).forEach(node -> mergeNodes(node, first, conf, existingSelfRelIds));
return Stream.of(new NodeResult(first));
}

Expand All @@ -300,8 +301,9 @@ public Stream<NodeResult> mergeNodes(@Name("nodes") List<Node> nodes, @Name(valu
@Description("apoc.refactor.mergeRelationships([rel1,rel2]) merge relationships onto first in list")
public Stream<RelationshipResult> mergeRelationships(@Name("rels") List<Relationship> relationships, @Name(value = "config", defaultValue = "{}") Map<String, Object> config) {
if (relationships == null || relationships.isEmpty()) return Stream.empty();
Set<Relationship> relationshipsSet = new LinkedHashSet<>(relationships);
RefactorConfig conf = new RefactorConfig(config);
Iterator<Relationship> it = relationships.iterator();
Iterator<Relationship> it = relationshipsSet.iterator();
Relationship first = it.next();
while (it.hasNext()) {
Relationship other = it.next();
Expand Down
19 changes: 18 additions & 1 deletion core/src/test/java/apoc/refactor/GraphRefactoringTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

import static apoc.util.MapUtil.map;
import static apoc.util.TestUtil.testCall;
import static apoc.util.TestUtil.testCallCount;
import static apoc.util.TestUtil.testCallEmpty;
import static apoc.util.TestUtil.testResult;
import static apoc.util.Util.isSelfRel;
Expand Down Expand Up @@ -523,7 +524,23 @@ public void testInvertRelationship() throws Exception {
assertEquals(1L, rel.getProperty("a"));
});
}


@Test
public void testRefactorWithSameEntities() {
Node node = db.executeTransactionally("CREATE (n:SingleNode) RETURN n", emptyMap(),
r -> Iterators.single(r.columnAs("n")));
testCall(db, "MATCH (n:SingleNode) CALL apoc.refactor.mergeNodes([n,n]) yield node return node",
r -> assertEquals(node, r.get("node")));
testCallCount(db, "MATCH (n:SingleNode) RETURN n", 1);

Relationship rel = db.executeTransactionally("CREATE (n:Start)-[r:REL_TO_MERGE]->(:End) RETURN r", emptyMap(),
r -> Iterators.single(r.columnAs("r")));
testCall(db, "MATCH (n:Start)-[r:REL_TO_MERGE]->(:End) CALL apoc.refactor.mergeRelationships([r,r]) yield rel return rel", r -> {
assertEquals(rel, r.get("rel"));
});
testCallCount(db, "MATCH (n:Start)-[r:REL_TO_MERGE]->(:End) RETURN r", 1);
}

@Test
public void testCollapseNode() throws Exception {
Long id = db.executeTransactionally("CREATE (f:Foo)-[:FOO {a:1}]->(b:Bar {c:3})-[:BAR {b:2}]->(f) RETURN id(b) as id", emptyMap(), result -> Iterators.single(result.columnAs("id")));
Expand Down

0 comments on commit 2ac45f4

Please sign in to comment.