From a0a74ff35b05980241c5c52d9c233aa747db38bd Mon Sep 17 00:00:00 2001 From: Joel Bergstrand Date: Tue, 7 Jan 2025 12:12:50 +0100 Subject: [PATCH] Fixed issue with properties in CloneSubgraph --- build.gradle | 2 +- .../java/apoc/refactor/GraphRefactoring.java | 2 +- .../java/apoc/refactor/CloneSubgraphTest.java | 30 +++++++++++++++++++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 1b916b09a..13e29f99e 100644 --- a/build.gradle +++ b/build.gradle @@ -170,7 +170,7 @@ apply from: "licenses-source-header.gradle" ext { publicDir = "${project.rootDir}" - neo4jVersionEffective = project.hasProperty("neo4jVersionOverride") ? project.getProperty("neo4jVersionOverride") : "2025.01.0" + neo4jVersionEffective = project.hasProperty("neo4jVersionOverride") ? project.getProperty("neo4jVersionOverride") : "2025.01.0-SNAPSHOT" testContainersVersion = '1.20.2' apacheArrowVersion = '15.0.0' } diff --git a/core/src/main/java/apoc/refactor/GraphRefactoring.java b/core/src/main/java/apoc/refactor/GraphRefactoring.java index 9623f5f41..f7d6a768a 100644 --- a/core/src/main/java/apoc/refactor/GraphRefactoring.java +++ b/core/src/main/java/apoc/refactor/GraphRefactoring.java @@ -323,7 +323,7 @@ private static Node cloneNode(final Transaction tx, final Node node, final Set skipProps) { final var rel = from.createRelationshipTo(to, base.getType()); - rel.getAllProperties().forEach((k, v) -> { + base.getAllProperties().forEach((k, v) -> { if (skipProps.isEmpty() || !skipProps.contains(k)) rel.setProperty(k, v); }); } diff --git a/core/src/test/java/apoc/refactor/CloneSubgraphTest.java b/core/src/test/java/apoc/refactor/CloneSubgraphTest.java index 40a9facde..5cf1471bb 100644 --- a/core/src/test/java/apoc/refactor/CloneSubgraphTest.java +++ b/core/src/test/java/apoc/refactor/CloneSubgraphTest.java @@ -466,6 +466,36 @@ public void testCloneSubgraph_With_Standins_For_Node1_Should_Have_RootB() { }); } + @Test + public void testCloneSubgraph_With_Properties_On_Relationships_Preserved() { + try (final var tx = db.beginTx(); + final var clean = tx.execute("MATCH (n) DETACH DELETE n"); + final var create = tx.execute("CREATE (:A)-[:R{id:\"ID1\"}]->(:B)"); + final var clone = tx.execute( + """ + MATCH (n)-[r:R]->(oldB:B) + WITH oldB, COLLECT(DISTINCT n) AS nodes + CREATE (newB:B) + + WITH oldB, newB, nodes + MATCH (m)-[r]-(n) WHERE n IN nodes + + WITH oldB, newB, nodes, COLLECT(DISTINCT r) AS rels + MATCH (s) WHERE NOT s:B + + WITH oldB, newB, nodes, rels, COLLECT(DISTINCT [s, s]) + [[oldB, newB]] AS standinNodes + CALL apoc.refactor.cloneSubgraph(nodes, rels, {standinNodes:standinNodes}) + YIELD input, output + MATCH (old) WHERE ID(old) = input + CREATE (output)-[r:importedFrom{created_on:datetime()}]->(old) + + RETURN output + """); + final var res = tx.execute("MATCH (n)-[r]->(m) RETURN r.id AS id"); ) { + assertThat(res.stream()).containsExactlyInAnyOrder(Map.of("id", "ID1"), Map.of("id", "ID1")); + } + } + @Test public void testCloneSubgraph_With_Standins_For_RootA_And_Oddball_Should_Have_RootB_And_Use_Node_12_In_Place_Of_Oddball() {