File 0418-Fix-delete_object-and-write-convergence-in-transacti.patch of Package erlang

From e052249e6ce4da0c6a022bb8da0186cd678e1054 Mon Sep 17 00:00:00 2001
From: Daniil Fedotov <hairyhum@gmail.com>
Date: Fri, 29 Jun 2018 14:54:32 -0400
Subject: [PATCH] Fix delete_object and write convergence in transaction.

Fix a bug, when delete_object was deleting the record if it was written
in the same transaction even if it was written to a different value.

To verify:
%% Create a set table
mnesia:create_table(foo, []).

%% Write and delete_object in transaction
mnesia:transaction(fun() ->
    mnesia:write({foo, bar, one}),
    mnesia:delete_object({foo, bar, not_one})
end).

{atomic, [{foo, bar, one}]} = mnesia:transaction(fun() -> mnesia:read(foo, bar) end).

Added a section to isolation tests to check for non-matching delete_object
requests.
---
 lib/mnesia/src/mnesia.erl                 | 16 ++++++++++------
 lib/mnesia/test/mnesia_isolation_test.erl | 11 ++++++++++-
 2 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/lib/mnesia/src/mnesia.erl b/lib/mnesia/src/mnesia.erl
index e298904e2a..df3a2dfe6f 100644
--- a/lib/mnesia/src/mnesia.erl
+++ b/lib/mnesia/src/mnesia.erl
@@ -779,12 +779,16 @@ do_delete_object(Tid, Ts, Tab, Val, LockKind) ->
 		      ?ets_insert(Store, {Oid, Val, delete_object});
 		  _ ->
 		      case ?ets_match_object(Store, {Oid, '_', write}) of
-			  [] ->
-			      ?ets_match_delete(Store, {Oid, Val, '_'}),
-			      ?ets_insert(Store, {Oid, Val, delete_object});
-			  _  ->
-			      ?ets_delete(Store, Oid),
-			      ?ets_insert(Store, {Oid, Oid, delete})
+			      [] ->
+			          ?ets_match_delete(Store, {Oid, Val, '_'}),
+			          ?ets_insert(Store, {Oid, Val, delete_object});
+			      Ops  ->
+			          case lists:member({Oid, Val, write}, Ops) of
+			              true ->
+			                  ?ets_delete(Store, Oid),
+			                  ?ets_insert(Store, {Oid, Oid, delete});
+			              false -> ok
+			          end
 		      end
 	      end,
 	      ok;
diff --git a/lib/mnesia/test/mnesia_isolation_test.erl b/lib/mnesia/test/mnesia_isolation_test.erl
index b2eea2390b..49bcec14af 100644
--- a/lib/mnesia/test/mnesia_isolation_test.erl
+++ b/lib/mnesia/test/mnesia_isolation_test.erl
@@ -1563,7 +1563,8 @@ trans_update_visible_inside_trans(Config) when is_list(Config) ->
     ?match({atomic, ok},  mnesia:create_table([{name, Tab}, 
 					     {ram_copies, [Node1]}])), 
     ValPos = 3, 
-    RecA = {Tab, a, 1}, 
+    RecA = {Tab, a, 1},
+    RecA2 = {Tab, a, 2},
     PatA = {Tab, '$1', 1}, 
     RecB = {Tab, b, 3}, 
     PatB = {Tab, '$1', 3}, 
@@ -1598,6 +1599,14 @@ trans_update_visible_inside_trans(Config) when is_list(Config) ->
 		  ?match([], mnesia:index_read(Tab, 3, ValPos)), 
 
 		  %% delete_object
+		  ?match(ok, mnesia:delete_object(RecA2)),
+		  ?match([RecA], mnesia:read({Tab, a})),
+		  ?match([RecA], mnesia:wread({Tab, a})),
+		  ?match([RecA], mnesia:match_object(PatA)),
+		  ?match([a], mnesia:all_keys(Tab)),
+		  ?match([RecA], mnesia:index_match_object(PatA, ValPos)),
+		  ?match([RecA], mnesia:index_read(Tab, 1, ValPos)),
+
 		  ?match(ok, mnesia:delete_object(RecA)), 
 		  ?match([], mnesia:read({Tab, a})), 
 		  ?match([], mnesia:wread({Tab, a})), 
-- 
2.16.4

openSUSE Build Service is sponsored by