ITS#8321 fix ambiguity in cursor_put fixup

After delete/add of a node, other nodes may no longer be
pointing at the data they intended. This can confuse subsequent
fixups.
mdb.RE/0.9
Howard Chu 9 years ago
parent e0316e0fae
commit 00aae125be
  1. 12
      libraries/liblmdb/mdb.c

@ -6683,22 +6683,28 @@ new_sub:
} else { } else {
/* There is room already in this leaf page. */ /* There is room already in this leaf page. */
rc = mdb_node_add(mc, mc->mc_ki[mc->mc_top], key, rdata, 0, nflags); rc = mdb_node_add(mc, mc->mc_ki[mc->mc_top], key, rdata, 0, nflags);
if (rc == 0 && insert_key) { if (rc == 0) {
/* Adjust other cursors pointing to mp */ /* Adjust other cursors pointing to mp */
MDB_cursor *m2, *m3; MDB_cursor *m2, *m3;
MDB_dbi dbi = mc->mc_dbi; MDB_dbi dbi = mc->mc_dbi;
unsigned i = mc->mc_top; unsigned i = mc->mc_top;
MDB_page *mp = mc->mc_pg[i]; MDB_page *mp = mc->mc_pg[i];
int nkeys = NUMKEYS(mp);
for (m2 = mc->mc_txn->mt_cursors[dbi]; m2; m2=m2->mc_next) { for (m2 = mc->mc_txn->mt_cursors[dbi]; m2; m2=m2->mc_next) {
if (mc->mc_flags & C_SUB) if (mc->mc_flags & C_SUB)
m3 = &m2->mc_xcursor->mx_cursor; m3 = &m2->mc_xcursor->mx_cursor;
else else
m3 = m2; m3 = m2;
if (m3 == mc || m3->mc_snum < mc->mc_snum) continue; if (m3 == mc || m3->mc_snum < mc->mc_snum || m3->mc_pg[i] != mp) continue;
if (m3->mc_pg[i] == mp && m3->mc_ki[i] >= mc->mc_ki[i]) { if (m3->mc_ki[i] >= mc->mc_ki[i] && insert_key) {
m3->mc_ki[i]++; m3->mc_ki[i]++;
} }
if (m3->mc_xcursor && (m3->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED)) {
MDB_node *n2 = NODEPTR(mp, m3->mc_ki[i]);
if ((n2->mn_flags & (F_SUBDATA|F_DUPDATA)) == F_DUPDATA)
m3->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(n2);
}
} }
} }
} }

Loading…
Cancel
Save