Skip to content

Commit

Permalink
Fix issue apache#1398 - SET followed by DELETE does not delete (apach…
Browse files Browse the repository at this point in the history
…e#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.
  • Loading branch information
rafsun42 authored and Zainab-Saad committed Mar 6, 2024
1 parent 2960ca4 commit ef9a141
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 3 deletions.
75 changes: 72 additions & 3 deletions regress/expected/cypher_delete.out
Original file line number Diff line number Diff line change
Expand Up @@ -234,14 +234,17 @@ SELECT * FROM cypher('cypher_delete', $$CREATE (n:v)-[:e]->(:v)$$) AS (a agtype)
(0 rows)

SELECT * FROM cypher('cypher_delete', $$MATCH(n1)-[e]->() DELETE n1, e RETURN n1$$) AS (a agtype);
ERROR: Cannot delete a vertex that has edge(s). Delete the edge(s) first, or try DETACH DELETE.
a
-----------------------------------------------------------------
{"id": 844424930131990, "label": "v", "properties": {}}::vertex
(1 row)

--Cleanup
SELECT * FROM cypher('cypher_delete', $$MATCH(n) DETACH DELETE n RETURN n$$) AS (a agtype);
a
-----------------------------------------------------------------
{"id": 844424930131990, "label": "v", "properties": {}}::vertex
{"id": 844424930131991, "label": "v", "properties": {}}::vertex
(2 rows)
(1 row)

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

(1 row)

--
-- SET followed by DELETE
--
SELECT create_graph('setdelete');
NOTICE: graph "setdelete" has been created
create_graph
--------------

(1 row)

-- MATCH (x) SET x DELETE x
SELECT * FROM cypher('setdelete', $$ CREATE (:A), (:A), (:A) $$) as ("CREATE" agtype);
CREATE
--------
(0 rows)

SELECT * FROM cypher('setdelete', $$ MATCH (x:A) SET x.age = 24 DELETE x $$) as ("SET + DELETE" agtype);
SET + DELETE
--------------
(0 rows)

SELECT id as "expected: 0 rows" FROM setdelete._ag_label_vertex;
expected: 0 rows
------------------
(0 rows)

-- MATCH (n)-[e]->(m) SET e DETACH DELETE n
SELECT * FROM cypher('setdelete', $$ CREATE (:n)-[:e]->(:m), (:n)-[:e]->(:m) $$) AS ("CREATE" agtype);
CREATE
--------
(0 rows)

SELECT * FROM cypher('setdelete', $$ MATCH (n)-[e]->(m) SET e.i = 1 DETACH DELETE n RETURN id(m) $$) AS ("SET + DETACH DELETE" agtype);
SET + DETACH DELETE
---------------------
1688849860263937
1688849860263938
(2 rows)

SELECT id as "expected: 2 rows (m vertices)" FROM setdelete._ag_label_vertex;
expected: 2 rows (m vertices)
-------------------------------
1688849860263937
1688849860263938
(2 rows)

SELECT id as "expected: 0 rows" FROM setdelete._ag_label_edge;
expected: 0 rows
------------------
(0 rows)

-- clean up
SELECT drop_graph('setdelete', true);
NOTICE: drop cascades to 6 other objects
DETAIL: drop cascades to table setdelete._ag_label_vertex
drop cascades to table setdelete._ag_label_edge
drop cascades to table setdelete."A"
drop cascades to table setdelete.n
drop cascades to table setdelete.e
drop cascades to table setdelete.m
NOTICE: graph "setdelete" has been dropped
drop_graph
------------

(1 row)

--
-- Clean up
--
Expand Down
19 changes: 19 additions & 0 deletions regress/sql/cypher_delete.sql
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,25 @@ SELECT * FROM cypher('detach_delete', $$ MATCH ()-[e]->() RETURN e.name $$) as (

SELECT drop_graph('detach_delete', true);

--
-- SET followed by DELETE
--
SELECT create_graph('setdelete');

-- MATCH (x) SET x DELETE x
SELECT * FROM cypher('setdelete', $$ CREATE (:A), (:A), (:A) $$) as ("CREATE" agtype);
SELECT * FROM cypher('setdelete', $$ MATCH (x:A) SET x.age = 24 DELETE x $$) as ("SET + DELETE" agtype);
SELECT id as "expected: 0 rows" FROM setdelete._ag_label_vertex;

-- MATCH (n)-[e]->(m) SET e DETACH DELETE n
SELECT * FROM cypher('setdelete', $$ CREATE (:n)-[:e]->(:m), (:n)-[:e]->(:m) $$) AS ("CREATE" agtype);
SELECT * FROM cypher('setdelete', $$ MATCH (n)-[e]->(m) SET e.i = 1 DETACH DELETE n RETURN id(m) $$) AS ("SET + DETACH DELETE" agtype);
SELECT id as "expected: 2 rows (m vertices)" FROM setdelete._ag_label_vertex;
SELECT id as "expected: 0 rows" FROM setdelete._ag_label_edge;

-- clean up
SELECT drop_graph('setdelete', true);

--
-- Clean up
--
Expand Down
4 changes: 4 additions & 0 deletions src/backend/executor/cypher_delete.c
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,8 @@ static void process_delete_list(CustomScanState *node)
/*
* Setup the scan description, with the correct snapshot and scan keys.
*/
estate->es_snapshot->curcid = GetCurrentCommandId(false);
estate->es_output_cid = GetCurrentCommandId(false);
scan_desc = table_beginscan(resultRelInfo->ri_RelationDesc,
estate->es_snapshot, 1, scan_keys);

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

resultRelInfo = create_entity_result_rel_info(estate, graph_name,
label_name);
estate->es_snapshot->curcid = GetCurrentCommandId(false);
estate->es_output_cid = GetCurrentCommandId(false);
scan_desc = table_beginscan(resultRelInfo->ri_RelationDesc,
estate->es_snapshot, 0, NULL);
slot = ExecInitExtraTupleSlot(
Expand Down

0 comments on commit ef9a141

Please sign in to comment.