https://bugs.openldap.org/show_bug.cgi?id=8447
--- Comment #3 from [email protected] --- I can reproduce this without using any cursors. I am using the lmdb++ header for simplicity (https://github.com/hoytech/lmdbxx), but it also reproduces using the plain C API. Full repro: #include <iostream> #include <stdlib.h> #include "lmdb++.h" #define PROJECT_NAME "mdb-dup-bug" static int compare_state_key(const MDB_val *a, const MDB_val *b) { auto get_skey = [](const MDB_val *v) { std::string_view data(static_cast<const char *>(v->mv_data), v->mv_size); return data.substr(0, data.find(',')); }; return get_skey(a).compare(get_skey(b)); } int main(int argc, char **argv) { if(argc != 1) { std::cout << argv[0] << "takes no arguments.\n"; return 1; } std::cout << "This is project " << PROJECT_NAME << ".\n"; auto env = lmdb::env::create(); env.set_max_dbs(10); char dirname[] = "/tmp/lmdb-bug.XXXXXX"; env.open(mkdtemp(dirname)); lmdb::dbi db; { auto txn = lmdb::txn::begin(env); db = lmdb::dbi::open( txn, std::string("dupsort").c_str(), MDB_CREATE | MDB_DUPSORT); lmdb::dbi_set_dupsort(txn, db, compare_state_key); db.put(txn, "abcd", "ab,cdef"); db.put(txn, "abcd", "a,abc"); txn.commit(); } { auto txn = lmdb::txn::begin(env); std::string_view data; db.get(txn, "abcd", data); std::cout << "Data size: " << data.size() << " expected: 5, data: '" << data << "', expected: 'a,abc'\n"; txn.commit(); } { auto txn = lmdb::txn::begin(env); db.put(txn, "abcd", "a,12"); txn.commit(); } { auto txn = lmdb::txn::begin(env); std::string_view data; db.get(txn, "abcd", data); std::cout << "Data size: " << data.size() << " expected: 4, data: '" << data << "', expected: 'a,12'\n"; txn.commit(); } { auto txn = lmdb::txn::begin(env); db.put(txn, "abcd", "a,x"); txn.commit(); } { auto txn = lmdb::txn::begin(env); std::string_view data; db.get(txn, "abcd", data); std::cout << "Data size: " << data.size() << " expected: 3, data: '" << data << "', expected: 'a,x'\n"; txn.commit(); } return 0; } This prints the following output: This is project mdb-dup-bug. Data size: 5 expected: 5, data: 'a,abc', expected: 'a,abc' Data size: 5 expected: 4, data: 'a,12c', expected: 'a,12' Data size: 5 expected: 3, data: 'a,x2c', expected: 'a,x' Commenting out the first put with the different data-key resolves the issue, but certainly you would expect that replacing a duplicate replaces the size too. Doing explicit delete before the put works around this issue. -- You are receiving this mail because: You are on the CC list for the issue.
