]> git.sur5r.net Git - openldap/blobdiff - libraries/liblmdb/mdb.c
Tweaks for MDB_MULTIPLE
[openldap] / libraries / liblmdb / mdb.c
index 0badbbbf690ba5f53586cce6ea7f32aa65ca6178..149a893208193e6684556a589f4ab3f29c7ac585 100644 (file)
@@ -4969,7 +4969,7 @@ mdb_cursor_put(MDB_cursor *mc, MDB_val *key, MDB_val *data,
        MDB_page        *fp;
        MDB_db dummy;
        int do_sub = 0, insert = 0;
-       unsigned int mcount = 0;
+       unsigned int mcount = 0, dcount;
        size_t nsize;
        int rc, rc2;
        MDB_pagebuf pbuf;
@@ -4977,6 +4977,16 @@ mdb_cursor_put(MDB_cursor *mc, MDB_val *key, MDB_val *data,
        unsigned int nflags;
        DKBUF;
 
+       /* Check this first so counter will always be zero on any
+        * early failures.
+        */
+       if (flags & MDB_MULTIPLE) {
+               dcount = data[1].mv_size;
+               data[1].mv_size = 0;
+               if (!F_ISSET(mc->mc_db->md_flags, MDB_DUPFIXED))
+                       return EINVAL;
+       }
+
        if (F_ISSET(mc->mc_txn->mt_flags, MDB_TXN_RDONLY))
                return EACCES;
 
@@ -5340,8 +5350,8 @@ put_sub:
                                                }
                                        }
                                }
-                                /* we've done our job */
-                                dkey.mv_size = 0;
+                               /* we've done our job */
+                               dkey.mv_size = 0;
                        }
                        if (flags & MDB_APPENDDUP)
                                xflags |= MDB_APPEND;
@@ -5357,12 +5367,16 @@ put_sub:
                if (!rc && !(flags & MDB_CURRENT))
                        mc->mc_db->md_entries++;
                if (flags & MDB_MULTIPLE) {
-                       mcount++;
-                       if (mcount < data[1].mv_size) {
-                               data[0].mv_data = (char *)data[0].mv_data + data[0].mv_size;
-                               leaf = NODEPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]);
-                               goto more;
+                       if (!rc) {
+                               mcount++;
+                               if (mcount < dcount) {
+                                       data[0].mv_data = (char *)data[0].mv_data + data[0].mv_size;
+                                       leaf = NODEPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]);
+                                       goto more;
+                               }
                        }
+                       /* let caller know how many succeeded, if any */
+                       data[1].mv_size = mcount;
                }
        }
 done: