You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ko...@apache.org on 2015/07/18 13:29:11 UTC

couchdb commit: updated refs/heads/1.6.x to fb696d7

Repository: couchdb
Updated Branches:
  refs/heads/1.6.x 95cb436be -> fb696d71b


Preserve bucket ordering during validation

Document buckets are sorted by docid, but the validation code was
reversing the buckets. If multiple clients send concurrent updates for
the same document the broken sorting can result in duplicate documents.

COUCHDB-2735


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/fb696d71
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/fb696d71
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/fb696d71

Branch: refs/heads/1.6.x
Commit: fb696d71b45f4448cdd956262a01f7e39231e5d8
Parents: 95cb436
Author: Adam Kocoloski <ad...@cloudant.com>
Authored: Wed Jul 15 17:06:18 2015 -0400
Committer: Adam Kocoloski <ad...@cloudant.com>
Committed: Wed Jul 15 17:06:18 2015 -0400

----------------------------------------------------------------------
 src/couchdb/couch_db.erl | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/fb696d71/src/couchdb/couch_db.erl
----------------------------------------------------------------------
diff --git a/src/couchdb/couch_db.erl b/src/couchdb/couch_db.erl
index 11ea0fd..2957818 100644
--- a/src/couchdb/couch_db.erl
+++ b/src/couchdb/couch_db.erl
@@ -517,7 +517,8 @@ prep_and_validate_update(Db, #doc{id=Id,revs={RevStart, Revs}}=Doc,
 
 prep_and_validate_updates(_Db, [], [], _AllowConflict, AccPrepped,
         AccFatalErrors) ->
-   {AccPrepped, AccFatalErrors};
+   AccPrepped2 = lists:reverse(lists:map(fun lists:reverse/1, AccPrepped)),
+   {AccPrepped2, AccFatalErrors};
 prep_and_validate_updates(Db, [DocBucket|RestBuckets], [not_found|RestLookups],
         AllowConflict, AccPrepped, AccErrors) ->
     {PreppedBucket, AccErrors3} = lists:foldl(
@@ -543,7 +544,7 @@ prep_and_validate_updates(Db, [DocBucket|RestBuckets], [not_found|RestLookups],
         {[], AccErrors}, DocBucket),
 
     prep_and_validate_updates(Db, RestBuckets, RestLookups, AllowConflict,
-            [lists:reverse(PreppedBucket) | AccPrepped], AccErrors3);
+            [PreppedBucket | AccPrepped], AccErrors3);
 prep_and_validate_updates(Db, [DocBucket|RestBuckets],
         [{ok, #full_doc_info{rev_tree=OldRevTree}=OldFullDocInfo}|RestLookups],
         AllowConflict, AccPrepped, AccErrors) ->
@@ -579,7 +580,8 @@ update_docs(Db, Docs, Options) ->
 prep_and_validate_replicated_updates(_Db, [], [], AccPrepped, AccErrors) ->
     Errors2 = [{{Id, {Pos, Rev}}, Error} ||
             {#doc{id=Id,revs={Pos,[Rev|_]}}, Error} <- AccErrors],
-    {lists:reverse(AccPrepped), lists:reverse(Errors2)};
+    AccPrepped2 = lists:reverse(lists:map(fun lists:reverse/1, AccPrepped)),
+    {AccPrepped2, lists:reverse(Errors2)};
 prep_and_validate_replicated_updates(Db, [Bucket|RestBuckets], [OldInfo|RestOldInfo], AccPrepped, AccErrors) ->
     case OldInfo of
     not_found ->