This is an automated email from the ASF dual-hosted git repository.
mtaha pushed a commit to branch PG12
in repository https://gitbox.apache.org/repos/asf/age.git
The following commit(s) were added to refs/heads/PG12 by this push:
new e5c28a39 Fix Issue 1709 - MERGE creates incomplete vertices after the
first one (#1734)
e5c28a39 is described below
commit e5c28a394ea1d5bee7db90ee1de37f3e3673c41c
Author: John Gemignani <[email protected]>
AuthorDate: Sun Apr 7 20:09:35 2024 -0700
Fix Issue 1709 - MERGE creates incomplete vertices after the first one
(#1734)
Fixed issue 1709 where MERGE appears to create incomplete vertices after
the first one. However, the real issue was that SET wasn't seeing the
newly created tuples from MERGE. This was due to an incorrect cid when
performing the tuple insert in MERGE.
The issue was that the cid was being overwritten in the function
insert_entity_tuple_cid. Once this was corrected, everything worked fine.
Added regression tests.
---
regress/expected/cypher_merge.out | 141 +++++++++++++++++++++++++++++++++++-
regress/sql/cypher_merge.sql | 44 ++++++++++-
src/backend/executor/cypher_utils.c | 4 +-
3 files changed, 183 insertions(+), 6 deletions(-)
diff --git a/regress/expected/cypher_merge.out
b/regress/expected/cypher_merge.out
index 22399411..6ab42d54 100644
--- a/regress/expected/cypher_merge.out
+++ b/regress/expected/cypher_merge.out
@@ -1529,15 +1529,140 @@ SELECT * FROM cypher('issue_1691', $$MATCH (u) DELETE
u $$) AS (a agtype);
---
(0 rows)
+--
+-- Issue 1709 - MERGE creates incomplete vertices after the first one
+-- This is actually an issue with MERGE not using the correct
command id
+--
+SELECT * FROM create_graph('issue_1709');
+NOTICE: graph "issue_1709" has been created
+ create_graph
+--------------
+
+(1 row)
+
+SELECT * FROM cypher('issue_1709', $$ MATCH (u) RETURN u $$) AS (u agtype);
+ u
+---
+(0 rows)
+
+SELECT * FROM cypher('issue_1709', $$ UNWIND [{first: 'jon', last: 'snow'},
{first: 'ned', last: 'stark'}] AS map
+ MERGE (v:PERSON {first: map.first})
+ SET v=map
+ RETURN v $$) AS (v agtype);
+ v
+-----------------------------------------------------------------------------------------------------
+ {"id": 844424930131969, "label": "PERSON", "properties": {"last": "snow",
"first": "jon"}}::vertex
+ {"id": 844424930131970, "label": "PERSON", "properties": {"last": "stark",
"first": "ned"}}::vertex
+(2 rows)
+
+SELECT * FROM cypher('issue_1709', $$ MATCH (u) RETURN u $$) AS (u agtype);
+ u
+-----------------------------------------------------------------------------------------------------
+ {"id": 844424930131969, "label": "PERSON", "properties": {"last": "snow",
"first": "jon"}}::vertex
+ {"id": 844424930131970, "label": "PERSON", "properties": {"last": "stark",
"first": "ned"}}::vertex
+(2 rows)
+
+SELECT * FROM cypher('issue_1709', $$ MATCH (u) DELETE u $$) AS (a agtype);
+ a
+---
+(0 rows)
+
+SELECT * FROM cypher('issue_1709', $$ UNWIND [{first: 'jon', last: 'snow'},
{first: 'ned', last: 'stark', middle: 'jim'}, {first: 'jane', last: 'doe'},
{first: 'ned', last: 'flanders'}, {first: 'wanda', last: 'cosmo'}] AS map
+ MERGE (v:PERSON {first: map.first})
+ SET v=map
+ RETURN v $$) AS (v agtype);
+ v
+----------------------------------------------------------------------------------------------------------------------
+ {"id": 844424930131971, "label": "PERSON", "properties": {"last": "snow",
"first": "jon"}}::vertex
+ {"id": 844424930131972, "label": "PERSON", "properties": {"last": "stark",
"first": "ned", "middle": "jim"}}::vertex
+ {"id": 844424930131973, "label": "PERSON", "properties": {"last": "doe",
"first": "jane"}}::vertex
+ {"id": 844424930131972, "label": "PERSON", "properties": {"last": "flanders",
"first": "ned"}}::vertex
+ {"id": 844424930131974, "label": "PERSON", "properties": {"last": "cosmo",
"first": "wanda"}}::vertex
+(5 rows)
+
+SELECT * FROM cypher('issue_1709', $$ MATCH (u) RETURN u $$) AS (u agtype);
+ u
+--------------------------------------------------------------------------------------------------------
+ {"id": 844424930131971, "label": "PERSON", "properties": {"last": "snow",
"first": "jon"}}::vertex
+ {"id": 844424930131973, "label": "PERSON", "properties": {"last": "doe",
"first": "jane"}}::vertex
+ {"id": 844424930131972, "label": "PERSON", "properties": {"last": "flanders",
"first": "ned"}}::vertex
+ {"id": 844424930131974, "label": "PERSON", "properties": {"last": "cosmo",
"first": "wanda"}}::vertex
+(4 rows)
+
+SELECT * FROM cypher('issue_1709', $$ MATCH (u) DELETE u $$) AS (a agtype);
+ a
+---
+(0 rows)
+
+SELECT * FROM cypher('issue_1709', $$ UNWIND [{first: 'jon', last: 'snow'},
{first: 'ned', last: 'stark'}] AS map
+ MERGE (u: PERSON {last:
map.last})-[e:KNOWS]->(v:PERSON {first: map.first})
+ SET v=map
+ RETURN u,e,v $$) AS (u agtype, e agtype,
v agtype);
+ u
| e
|
v
+-------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------
+ {"id": 844424930131975, "label": "PERSON", "properties": {"last":
"snow"}}::vertex | {"id": 1125899906842625, "label": "KNOWS", "end_id":
844424930131976, "start_id": 844424930131975, "properties": {}}::edge | {"id":
844424930131976, "label": "PERSON", "properties": {"last": "snow", "first":
"jon"}}::vertex
+ {"id": 844424930131977, "label": "PERSON", "properties": {"last":
"stark"}}::vertex | {"id": 1125899906842626, "label": "KNOWS", "end_id":
844424930131978, "start_id": 844424930131977, "properties": {}}::edge | {"id":
844424930131978, "label": "PERSON", "properties": {"last": "stark", "first":
"ned"}}::vertex
+(2 rows)
+
+SELECT * FROM cypher('issue_1709', $$ MATCH (u)-[e]->(v) RETURN u,e,v $$) AS
(u agtype, e agtype, v agtype);
+ u
| e
|
v
+-------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------
+ {"id": 844424930131975, "label": "PERSON", "properties": {"last":
"snow"}}::vertex | {"id": 1125899906842625, "label": "KNOWS", "end_id":
844424930131976, "start_id": 844424930131975, "properties": {}}::edge | {"id":
844424930131976, "label": "PERSON", "properties": {"last": "snow", "first":
"jon"}}::vertex
+ {"id": 844424930131977, "label": "PERSON", "properties": {"last":
"stark"}}::vertex | {"id": 1125899906842626, "label": "KNOWS", "end_id":
844424930131978, "start_id": 844424930131977, "properties": {}}::edge | {"id":
844424930131978, "label": "PERSON", "properties": {"last": "stark", "first":
"ned"}}::vertex
+(2 rows)
+
+SELECT * FROM cypher('issue_1709', $$ MATCH ()-[e]->() DELETE e $$) AS (a
agtype);
+ a
+---
+(0 rows)
+
+SELECT * FROM cypher('issue_1709', $$ MATCH (u) DELETE u $$) AS (a agtype);
+ a
+---
+(0 rows)
+
+SELECT * FROM cypher('issue_1709', $$ UNWIND [{first: 'jon', last: 'snow'},
{first: 'ned', last: 'stark'}] AS map
+ MERGE (u: PERSON {last:
map.last})-[e:KNOWS]->(v:PERSON {first: map.first})
+ SET u=map SET v=map
+ RETURN u,e,v $$) AS (u agtype, e agtype,
v agtype);
+ u
|
e |
v
+-----------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------
+ {"id": 844424930131979, "label": "PERSON", "properties": {"last": "snow",
"first": "jon"}}::vertex | {"id": 1125899906842627, "label": "KNOWS",
"end_id": 844424930131980, "start_id": 844424930131979, "properties": {}}::edge
| {"id": 844424930131980, "label": "PERSON", "properties": {"last": "snow",
"first": "jon"}}::vertex
+ {"id": 844424930131981, "label": "PERSON", "properties": {"last": "stark",
"first": "ned"}}::vertex | {"id": 1125899906842628, "label": "KNOWS", "end_id":
844424930131982, "start_id": 844424930131981, "properties": {}}::edge | {"id":
844424930131982, "label": "PERSON", "properties": {"last": "stark", "first":
"ned"}}::vertex
+(2 rows)
+
+SELECT * FROM cypher('issue_1709', $$ MATCH (u)-[e]->(v) RETURN u,e,v $$) AS
(u agtype, e agtype, v agtype);
+ u
|
e |
v
+-----------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------
+ {"id": 844424930131979, "label": "PERSON", "properties": {"last": "snow",
"first": "jon"}}::vertex | {"id": 1125899906842627, "label": "KNOWS",
"end_id": 844424930131980, "start_id": 844424930131979, "properties": {}}::edge
| {"id": 844424930131980, "label": "PERSON", "properties": {"last": "snow",
"first": "jon"}}::vertex
+ {"id": 844424930131981, "label": "PERSON", "properties": {"last": "stark",
"first": "ned"}}::vertex | {"id": 1125899906842628, "label": "KNOWS", "end_id":
844424930131982, "start_id": 844424930131981, "properties": {}}::edge | {"id":
844424930131982, "label": "PERSON", "properties": {"last": "stark", "first":
"ned"}}::vertex
+(2 rows)
+
+SELECT * FROM cypher('issue_1709', $$ MATCH ()-[e]->() DELETE e $$) AS (a
agtype);
+ a
+---
+(0 rows)
+
+-- clean up
+SELECT * FROM cypher('issue_1709', $$ MATCH (u) DELETE u $$) AS (a agtype);
+ a
+---
+(0 rows)
+
--
-- clean up graphs
--
-SELECT * FROM cypher('cypher_merge', $$MATCH (n) DETACH DELETE n $$) AS (a
agtype);
+SELECT * FROM cypher('cypher_merge', $$ MATCH (n) DETACH DELETE n $$) AS (a
agtype);
a
---
(0 rows)
-SELECT * FROM cypher('issue_1630', $$MATCH (n) DETACH DELETE n $$) AS (a
agtype);
+SELECT * FROM cypher('issue_1630', $$ MATCH (n) DETACH DELETE n $$) AS (a
agtype);
+ a
+---
+(0 rows)
+
+SELECT * FROM cypher('issue_1709', $$ MATCH (n) DETACH DELETE n $$) AS (a
agtype);
a
---
(0 rows)
@@ -1595,6 +1720,18 @@ NOTICE: graph "issue_1691" has been dropped
(1 row)
+SELECT drop_graph('issue_1709', true);
+NOTICE: drop cascades to 4 other objects
+DETAIL: drop cascades to table issue_1709._ag_label_vertex
+drop cascades to table issue_1709._ag_label_edge
+drop cascades to table issue_1709."PERSON"
+drop cascades to table issue_1709."KNOWS"
+NOTICE: graph "issue_1709" has been dropped
+ drop_graph
+------------
+
+(1 row)
+
--
-- End
--
diff --git a/regress/sql/cypher_merge.sql b/regress/sql/cypher_merge.sql
index 555aff6b..59efad1b 100644
--- a/regress/sql/cypher_merge.sql
+++ b/regress/sql/cypher_merge.sql
@@ -722,11 +722,50 @@ SELECT * FROM cypher('issue_1691', $$ UNWIND ["foo",
"bar", "foo", "foo", "bar"]
SELECT * FROM cypher('issue_1691', $$MATCH ()-[e]->() DELETE e $$) AS (a
agtype);
SELECT * FROM cypher('issue_1691', $$MATCH (u) DELETE u $$) AS (a agtype);
+--
+-- Issue 1709 - MERGE creates incomplete vertices after the first one
+-- This is actually an issue with MERGE not using the correct
command id
+--
+SELECT * FROM create_graph('issue_1709');
+SELECT * FROM cypher('issue_1709', $$ MATCH (u) RETURN u $$) AS (u agtype);
+
+SELECT * FROM cypher('issue_1709', $$ UNWIND [{first: 'jon', last: 'snow'},
{first: 'ned', last: 'stark'}] AS map
+ MERGE (v:PERSON {first: map.first})
+ SET v=map
+ RETURN v $$) AS (v agtype);
+SELECT * FROM cypher('issue_1709', $$ MATCH (u) RETURN u $$) AS (u agtype);
+SELECT * FROM cypher('issue_1709', $$ MATCH (u) DELETE u $$) AS (a agtype);
+
+SELECT * FROM cypher('issue_1709', $$ UNWIND [{first: 'jon', last: 'snow'},
{first: 'ned', last: 'stark', middle: 'jim'}, {first: 'jane', last: 'doe'},
{first: 'ned', last: 'flanders'}, {first: 'wanda', last: 'cosmo'}] AS map
+ MERGE (v:PERSON {first: map.first})
+ SET v=map
+ RETURN v $$) AS (v agtype);
+SELECT * FROM cypher('issue_1709', $$ MATCH (u) RETURN u $$) AS (u agtype);
+SELECT * FROM cypher('issue_1709', $$ MATCH (u) DELETE u $$) AS (a agtype);
+
+SELECT * FROM cypher('issue_1709', $$ UNWIND [{first: 'jon', last: 'snow'},
{first: 'ned', last: 'stark'}] AS map
+ MERGE (u: PERSON {last:
map.last})-[e:KNOWS]->(v:PERSON {first: map.first})
+ SET v=map
+ RETURN u,e,v $$) AS (u agtype, e agtype,
v agtype);
+SELECT * FROM cypher('issue_1709', $$ MATCH (u)-[e]->(v) RETURN u,e,v $$) AS
(u agtype, e agtype, v agtype);
+SELECT * FROM cypher('issue_1709', $$ MATCH ()-[e]->() DELETE e $$) AS (a
agtype);
+SELECT * FROM cypher('issue_1709', $$ MATCH (u) DELETE u $$) AS (a agtype);
+
+SELECT * FROM cypher('issue_1709', $$ UNWIND [{first: 'jon', last: 'snow'},
{first: 'ned', last: 'stark'}] AS map
+ MERGE (u: PERSON {last:
map.last})-[e:KNOWS]->(v:PERSON {first: map.first})
+ SET u=map SET v=map
+ RETURN u,e,v $$) AS (u agtype, e agtype,
v agtype);
+SELECT * FROM cypher('issue_1709', $$ MATCH (u)-[e]->(v) RETURN u,e,v $$) AS
(u agtype, e agtype, v agtype);
+SELECT * FROM cypher('issue_1709', $$ MATCH ()-[e]->() DELETE e $$) AS (a
agtype);
+-- clean up
+SELECT * FROM cypher('issue_1709', $$ MATCH (u) DELETE u $$) AS (a agtype);
+
--
-- clean up graphs
--
-SELECT * FROM cypher('cypher_merge', $$MATCH (n) DETACH DELETE n $$) AS (a
agtype);
-SELECT * FROM cypher('issue_1630', $$MATCH (n) DETACH DELETE n $$) AS (a
agtype);
+SELECT * FROM cypher('cypher_merge', $$ MATCH (n) DETACH DELETE n $$) AS (a
agtype);
+SELECT * FROM cypher('issue_1630', $$ MATCH (n) DETACH DELETE n $$) AS (a
agtype);
+SELECT * FROM cypher('issue_1709', $$ MATCH (n) DETACH DELETE n $$) AS (a
agtype);
--
-- delete graphs
@@ -734,6 +773,7 @@ SELECT * FROM cypher('issue_1630', $$MATCH (n) DETACH
DELETE n $$) AS (a agtype)
SELECT drop_graph('cypher_merge', true);
SELECT drop_graph('issue_1630', true);
SELECT drop_graph('issue_1691', true);
+SELECT drop_graph('issue_1709', true);
--
-- End
diff --git a/src/backend/executor/cypher_utils.c
b/src/backend/executor/cypher_utils.c
index fdde7d08..2c19eabf 100644
--- a/src/backend/executor/cypher_utils.c
+++ b/src/backend/executor/cypher_utils.c
@@ -295,8 +295,8 @@ HeapTuple insert_entity_tuple_cid(ResultRelInfo
*resultRelInfo,
}
// Insert the tuple normally
- table_tuple_insert(resultRelInfo->ri_RelationDesc, elemTupleSlot,
- GetCurrentCommandId(true), 0, NULL);
+ table_tuple_insert(resultRelInfo->ri_RelationDesc, elemTupleSlot, cid, 0,
+ NULL);
// Insert index entries for the tuple
if (resultRelInfo->ri_NumIndices > 0)