CouchDB
  1. CouchDB
  2. COUCHDB-188

_bulk_docs fails when deleting and adding a doc with the same id

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Blocker Blocker
    • Resolution: Fixed
    • Affects Version/s: 0.9
    • Fix Version/s: 1.3
    • Component/s: Database Core
    • Labels:
      None
    • Environment:

      CouchDB revision 730414.

    • Skill Level:
      Regular Contributors Level (Easy to Medium)

      Description

      CouchDB returns a "412 Precondition Failed" when the list of changes sent to _bulk_docs deletes a document and later creates a document with the same id as the deleted document:

      {"docs": [

      {"_id": "docid", "_rev": "<rev>", "_deleted": true}

      ,

      {"_id": "docid"}

      ]}

      Once fixed, the response JSON document will return the same docid twice in the list but it's presumably ordered consistently with the request data so any client should be able to understand the response.

      Demonstrating the problem using curl is easy enough:

      $ curl -X PUT http://localhost:5984/test

      {"ok":true}

      $ curl -X PUT -d "{}" http://localhost:5984/test/docid

      {"ok":true,"id":"docid","rev":"4140747751"}

      $ curl -X POST -d '{"docs": [

      {"_id": "docid", "_rev": "4140747751", "_deleted": true}

      ,

      {"_id": "docid"}

      ]}' http://localhost:5984/test/_bulk_docs

      {"error":"conflict","reason":"Document update conflict."}

      Note: this is likely related to COUCHDB-172.

        Activity

        Hide
        Jan Lehnardt added a comment -

        bulk update will get a new behaviour in 0.9. Closing

        Show
        Jan Lehnardt added a comment - bulk update will get a new behaviour in 0.9. Closing
        Hide
        Matt Goodall added a comment -

        Agh, sorry! I'll repost to the list.

        • Matt

        [...]

        Show
        Matt Goodall added a comment - Agh, sorry! I'll repost to the list. Matt [...]
        Hide
        Matt Goodall added a comment -

        Hi,

        I'm a bit confused why this was closed. Perhaps a description of the
        "new behaviour" is available somewhere?

        The only mention of anything related to a change in _bulk_docs I've
        noticed is about not failing everything in the list of updates
        (might be nice if that was optional, actually) and the associated
        error reporting. However, that doesn't necessarily fix the problem I
        described.

        Can anyone explain how the planned change fixes things?

        Thanks, Matt

        Show
        Matt Goodall added a comment - Hi, I'm a bit confused why this was closed. Perhaps a description of the "new behaviour" is available somewhere? The only mention of anything related to a change in _bulk_docs I've noticed is about not failing everything in the list of updates (might be nice if that was optional, actually) and the associated error reporting. However, that doesn't necessarily fix the problem I described. Can anyone explain how the planned change fixes things? Thanks, Matt
        Hide
        Matt Goodall added a comment -

        Testing against trunk shows that the new behaviour still has the same error. I think the following test shows the problem.

        couchTests.bulkdocs_delete_create = function(debug) {

        var db = new CouchDB("test_suite_db");
        db.deleteDb();
        db.createDb();

        var results = db.bulkSave([{_id: 'foo'}]);
        var orig_rev = results[0].rev;
        var results = db.bulkSave([{_id: 'foo', _rev: orig_rev, _deleted: true}, {_id: 'foo'}]);
        T(!results[0].error);
        T(results[1].rev != orig_rev);
        T(!results[1].error);
        T(results[1].rev != orig_rev);
        };

        Show
        Matt Goodall added a comment - Testing against trunk shows that the new behaviour still has the same error. I think the following test shows the problem. couchTests.bulkdocs_delete_create = function(debug) { var db = new CouchDB("test_suite_db"); db.deleteDb(); db.createDb(); var results = db.bulkSave( [{_id: 'foo'}] ); var orig_rev = results [0] .rev; var results = db.bulkSave( [{_id: 'foo', _rev: orig_rev, _deleted: true}, {_id: 'foo'}] ); T(!results [0] .error); T(results [1] .rev != orig_rev); T(!results [1] .error); T(results [1] .rev != orig_rev); };
        Hide
        Matt Goodall added a comment -

        Just came across this issue and tested against the 0.10 branch. It's still happening, I don't believe it should ever have been closed.

        Show
        Matt Goodall added a comment - Just came across this issue and tested against the 0.10 branch. It's still happening, I don't believe it should ever have been closed.
        Hide
        Paul Joseph Davis added a comment -

        couchTests.custom_test = function(debug) {
        var db = new CouchDB("test_suite_db",

        {"X-Couch-Full-Commit":"false"}

        );
        db.deleteDb();
        db.createDb();

        var results = db.bulkSave([{_id: 'foo'}]);
        var orig_rev = results[0].rev;
        results = db.bulkSave([
        {_id: 'foo', _rev: "2-eec205a9d413992850a6e32678485900"},
        {_id: 'foo', _rev: orig_rev, _deleted: true}
        ]);
        alert(JSON.stringify(results));
        T(results[0].error === undefined);
        T(results[1].error === undefined);
        };

        Slightly interesting, the order of updates is backwards. Also, it works if we specify what the _rev would be after the delete call.

        Show
        Paul Joseph Davis added a comment - couchTests.custom_test = function(debug) { var db = new CouchDB("test_suite_db", {"X-Couch-Full-Commit":"false"} ); db.deleteDb(); db.createDb(); var results = db.bulkSave( [{_id: 'foo'}] ); var orig_rev = results [0] .rev; results = db.bulkSave([ {_id: 'foo', _rev: "2-eec205a9d413992850a6e32678485900"}, {_id: 'foo', _rev: orig_rev, _deleted: true} ]); alert(JSON.stringify(results)); T(results [0] .error === undefined); T(results [1] .error === undefined); }; Slightly interesting, the order of updates is backwards. Also, it works if we specify what the _rev would be after the delete call.
        Hide
        Jan Lehnardt added a comment -

        Bump to 0.11 and set blocking.

        Show
        Jan Lehnardt added a comment - Bump to 0.11 and set blocking.
        Hide
        Filipe Manana added a comment -

        Attaching patch which fixes this issue against master.
        Part of the fix was already done in COUCHDB-911.

        Show
        Filipe Manana added a comment - Attaching patch which fixes this issue against master. Part of the fix was already done in COUCHDB-911 .
        Hide
        Jan Lehnardt added a comment -

        Bump to 1.3.x

        Show
        Jan Lehnardt added a comment - Bump to 1.3.x
        Hide
        Filipe Manana added a comment -

        Fix applied to master (6d1d23b7d0eba4de3c4097907adc37b09191196e).

        Show
        Filipe Manana added a comment - Fix applied to master (6d1d23b7d0eba4de3c4097907adc37b09191196e).

          People

          • Assignee:
            Filipe Manana
            Reporter:
            Matt Goodall
          • Votes:
            1 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development