mail@arnedebruijn.nl wrote:
Full_Name: Arne de Bruijn Version: mdb.master a93810c OS: Linux URL: ftp://ftp.openldap.org/incoming/ Submission from: (NULL) (94.210.130.16)
MDB_GET_BOTH seems to unexpectedly return success if a data-value before the first data-value for a key is requested.
Thanks for the report. This appears to have been broken due to commit 18a07eb7c2dc33372455a6040984cd6b699b41a5 for ITS#7681. Fixed now in mdb.master
The example program sets 1:b and 1:c and requests 1:a. It prints: get_both: key=1 val=b
While I would expect: get_both: err=MDB_NOTFOUND: No matching key/data pair found
(curiously it works when it only sets 1:b)
#include <stdlib.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include "lmdb.h"
void set_val(MDB_val *v, char *s) { v->mv_size = strlen(s); v->mv_data = s; }
int main() { int rc; MDB_env *menv = NULL; MDB_dbi mdbi; MDB_txn *mtxn = NULL; MDB_val key, val; MDB_cursor *mc;
if ((rc = mdb_env_create(&menv))) goto err; if ((rc = unlink("testdb"))) goto err; if ((rc = mdb_env_open(menv, "testdb", MDB_NOSUBDIR, 0666))) goto err; if ((rc = mdb_txn_begin(menv, NULL, 0, &mtxn))) goto err; if ((rc = mdb_dbi_open(mtxn, NULL, MDB_DUPSORT | MDB_CREATE, &mdbi))) goto err; set_val(&key, "1"); set_val(&val, "b"); if ((rc = mdb_put(mtxn, mdbi, &key, &val, 0))) goto err; set_val(&key, "1"); set_val(&val, "c"); if ((rc = mdb_put(mtxn, mdbi, &key, &val, 0))) goto err;
if ((rc = mdb_cursor_open(mtxn, mdbi, &mc))) goto err;
set_val(&key, "1"); set_val(&val, "a"); rc = mdb_cursor_get(mc, &key, &val, MDB_GET_BOTH); if (rc) printf("get_both: err=%s\n", mdb_strerror(rc)); else printf("get_both: key=%.*s val=%.*s\n", key.mv_size, (char *)key.mv_data, val.mv_size, (char *)val.mv_data);
mdb_cursor_close(mc);
if ((rc = mdb_txn_commit(mtxn))) { mdb_dbi_close(menv, mdbi); goto err; } mdb_env_close(menv); return 0; err: if (mtxn) mdb_txn_abort(mtxn); if (menv) mdb_env_close(menv); fprintf(stderr, "Error: %s\n", mdb_strerror(rc)); return 1; }