Full_Name: Hallvard B Furuseth
Version: LMDB 0.9.17
OS: Linux x86_64
URL: 
Submission from: (NULL) (81.191.45.31)
Submitted by: hallvard


mdb_put(,, key of non-F_DUPDATA node, old data, MDB_APPENDDUP)
succeeds in an MDB_DUPSORT database.  It should return MDB_KEYEXIST:
It should not matter whether a lone item is inside a sub-DB/sub-page.

Fix:

diff --git a/libraries/liblmdb/mdb.c b/libraries/liblmdb/mdb.c
index 96c859e..2b7cd6b 100644
--- a/libraries/liblmdb/mdb.c
+++ b/libraries/liblmdb/mdb.c
@@ -6483,3 +6483,3 @@ more:
                                if (!dcmp(data, &olddata)) {
-                                       if (flags & MDB_NODUPDATA)
+                                       if (flags &
(MDB_NODUPDATA|MDB_APPENDDUP))
                                                return MDB_KEYEXIST;

Demo program:

#include "lmdb.h"
#include <stdio.h>
#include <stdlib.h>
#define E(expr) CHECK((rc = (expr)) == MDB_SUCCESS, #expr)
#define CHECK(test, msg) ((test) ? (void)0 : ((void)fprintf(stderr, \
        "%s:%d: %s: %s\n", __FILE__, __LINE__, msg, mdb_strerror(rc)), abort()))

int main(void)
{
        int rc;
        MDB_env *env;
        B_txtxn *txn;
        MDB_dbi dbi;
        MDB_val key = {2, "k"}, data = {2, "d"};

        E(mdb_env_create(&env));
        E(mdb_env_open(env, "./testdb", 0, 0664));
        E(mdb_txn_begin(env, NULL, 0, &txn));
        E(mdb_dbi_open(txn, NULL, MDB_DUPSORT, &dbi));%%0       E(mdb_drop(txn, 
dbi, 0));
   
        E(mdb_put(txn, dbi, &key, &data, 0));
        rc = mdb_put(txn, dbi, &key, &data, MDB_APPENDDUP);
        CHECK(rc == MDB_KEYEXIST, "MDB_APPENDDUP expected MDB_KEYEXIST");

        mdb_txn_abort(txn);
        mdb_env_close(env);
        return 0;
}


Reply via email to