Skip to content

Commit 5fbe064

Browse files
authored
Fix issue #1398 - SET followed by DELETE does not delete (#1412)
In the DELETE executor, tuples were being locked\deleted using the command ID returned by GetCurrentCommandId(). However, the original tuples were retrieved using a command ID stored in the estate. To fix it- before the retrieval of a tuple, estate command IDs are set using GetCurrentCommandId() so it matches if the tuple is to be deleted later. Additional changes: ------------------- Fixed an incorrect cypher_delete test. The query `MATCH (n1)-[e]->() DELETE n1, e RETURN n1` should be able to delete n1 and e without requiring DETACH DELETE. TODO: ----- It may be a good idea to audit the executors for any inconsistent use of command IDs.
1 parent f6e6af7 commit 5fbe064

File tree

3 files changed

+95
-3
lines changed

3 files changed

+95
-3
lines changed

regress/expected/cypher_delete.out

Lines changed: 72 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -234,14 +234,17 @@ SELECT * FROM cypher('cypher_delete', $$CREATE (n:v)-[:e]->(:v)$$) AS (a agtype)
234234
(0 rows)
235235

236236
SELECT * FROM cypher('cypher_delete', $$MATCH(n1)-[e]->() DELETE n1, e RETURN n1$$) AS (a agtype);
237-
ERROR: Cannot delete a vertex that has edge(s). Delete the edge(s) first, or try DETACH DELETE.
237+
a
238+
-----------------------------------------------------------------
239+
{"id": 844424930131990, "label": "v", "properties": {}}::vertex
240+
(1 row)
241+
238242
--Cleanup
239243
SELECT * FROM cypher('cypher_delete', $$MATCH(n) DETACH DELETE n RETURN n$$) AS (a agtype);
240244
a
241245
-----------------------------------------------------------------
242-
{"id": 844424930131990, "label": "v", "properties": {}}::vertex
243246
{"id": 844424930131991, "label": "v", "properties": {}}::vertex
244-
(2 rows)
247+
(1 row)
245248

246249
SELECT * FROM cypher('cypher_delete', $$MATCH(n) RETURN n$$) AS (a agtype);
247250
a
@@ -758,6 +761,72 @@ NOTICE: graph "detach_delete" has been dropped
758761

759762
(1 row)
760763

764+
--
765+
-- SET followed by DELETE
766+
--
767+
SELECT create_graph('setdelete');
768+
NOTICE: graph "setdelete" has been created
769+
create_graph
770+
--------------
771+
772+
(1 row)
773+
774+
-- MATCH (x) SET x DELETE x
775+
SELECT * FROM cypher('setdelete', $$ CREATE (:A), (:A), (:A) $$) as ("CREATE" agtype);
776+
CREATE
777+
--------
778+
(0 rows)
779+
780+
SELECT * FROM cypher('setdelete', $$ MATCH (x:A) SET x.age = 24 DELETE x $$) as ("SET + DELETE" agtype);
781+
SET + DELETE
782+
--------------
783+
(0 rows)
784+
785+
SELECT id as "expected: 0 rows" FROM setdelete._ag_label_vertex;
786+
expected: 0 rows
787+
------------------
788+
(0 rows)
789+
790+
-- MATCH (n)-[e]->(m) SET e DETACH DELETE n
791+
SELECT * FROM cypher('setdelete', $$ CREATE (:n)-[:e]->(:m), (:n)-[:e]->(:m) $$) AS ("CREATE" agtype);
792+
CREATE
793+
--------
794+
(0 rows)
795+
796+
SELECT * FROM cypher('setdelete', $$ MATCH (n)-[e]->(m) SET e.i = 1 DETACH DELETE n RETURN id(m) $$) AS ("SET + DETACH DELETE" agtype);
797+
SET + DETACH DELETE
798+
---------------------
799+
1688849860263937
800+
1688849860263938
801+
(2 rows)
802+
803+
SELECT id as "expected: 2 rows (m vertices)" FROM setdelete._ag_label_vertex;
804+
expected: 2 rows (m vertices)
805+
-------------------------------
806+
1688849860263937
807+
1688849860263938
808+
(2 rows)
809+
810+
SELECT id as "expected: 0 rows" FROM setdelete._ag_label_edge;
811+
expected: 0 rows
812+
------------------
813+
(0 rows)
814+
815+
-- clean up
816+
SELECT drop_graph('setdelete', true);
817+
NOTICE: drop cascades to 6 other objects
818+
DETAIL: drop cascades to table setdelete._ag_label_vertex
819+
drop cascades to table setdelete._ag_label_edge
820+
drop cascades to table setdelete."A"
821+
drop cascades to table setdelete.n
822+
drop cascades to table setdelete.e
823+
drop cascades to table setdelete.m
824+
NOTICE: graph "setdelete" has been dropped
825+
drop_graph
826+
------------
827+
828+
(1 row)
829+
761830
--
762831
-- Clean up
763832
--

regress/sql/cypher_delete.sql

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,25 @@ SELECT * FROM cypher('detach_delete', $$ MATCH ()-[e]->() RETURN e.name $$) as (
283283

284284
SELECT drop_graph('detach_delete', true);
285285

286+
--
287+
-- SET followed by DELETE
288+
--
289+
SELECT create_graph('setdelete');
290+
291+
-- MATCH (x) SET x DELETE x
292+
SELECT * FROM cypher('setdelete', $$ CREATE (:A), (:A), (:A) $$) as ("CREATE" agtype);
293+
SELECT * FROM cypher('setdelete', $$ MATCH (x:A) SET x.age = 24 DELETE x $$) as ("SET + DELETE" agtype);
294+
SELECT id as "expected: 0 rows" FROM setdelete._ag_label_vertex;
295+
296+
-- MATCH (n)-[e]->(m) SET e DETACH DELETE n
297+
SELECT * FROM cypher('setdelete', $$ CREATE (:n)-[:e]->(:m), (:n)-[:e]->(:m) $$) AS ("CREATE" agtype);
298+
SELECT * FROM cypher('setdelete', $$ MATCH (n)-[e]->(m) SET e.i = 1 DETACH DELETE n RETURN id(m) $$) AS ("SET + DETACH DELETE" agtype);
299+
SELECT id as "expected: 2 rows (m vertices)" FROM setdelete._ag_label_vertex;
300+
SELECT id as "expected: 0 rows" FROM setdelete._ag_label_edge;
301+
302+
-- clean up
303+
SELECT drop_graph('setdelete', true);
304+
286305
--
287306
-- Clean up
288307
--

src/backend/executor/cypher_delete.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,8 @@ static void process_delete_list(CustomScanState *node)
437437
/*
438438
* Setup the scan description, with the correct snapshot and scan keys.
439439
*/
440+
estate->es_snapshot->curcid = GetCurrentCommandId(false);
441+
estate->es_output_cid = GetCurrentCommandId(false);
440442
scan_desc = table_beginscan(resultRelInfo->ri_RelationDesc,
441443
estate->es_snapshot, 1, scan_keys);
442444

@@ -501,6 +503,8 @@ static void check_for_connected_edges(CustomScanState *node)
501503

502504
resultRelInfo = create_entity_result_rel_info(estate, graph_name,
503505
label_name);
506+
estate->es_snapshot->curcid = GetCurrentCommandId(false);
507+
estate->es_output_cid = GetCurrentCommandId(false);
504508
scan_desc = table_beginscan(resultRelInfo->ri_RelationDesc,
505509
estate->es_snapshot, 0, NULL);
506510
slot = ExecInitExtraTupleSlot(

0 commit comments

Comments
 (0)