[Date Prev][Date Next] [Chronological] [Thread] [Top]

(ITS#8334) MDB_APPENDDUP does not catch overwrite(single item)



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;
}