mdbx: исправление регресса состояния dupsort-курсора после cursor_put(APPEND).

При добавлении нового ключа в append-режиме, в случае когда в текущей
(последней) позиции с ключом связаны несколько значений и
(соответственно) вложенный dupsort-курсор инициализирован, вставка
происходила без сброса вложенного курсора.

В результате вложенный курсор логически оставался стоять на
multivalue-данных связанных с предыдущей позицией основного курсора,
т.е. переходил в неконсистентное состояние.

Ошибка проявлялась возвратом неверных значений из mdbx_cursor_count()
или срабатывание assert-проверки в отладочных сборках.
This commit is contained in:
Леонид Юрьев (Leonid Yuriev) 2024-12-15 22:17:12 +03:00
parent c66dac50c3
commit a845522db7

View File

@ -898,7 +898,9 @@ __hot int cursor_put(MDBX_cursor *mc, const MDBX_val *key, MDBX_val *data, unsig
if (insert_key) { if (insert_key) {
/* The key does not exist */ /* The key does not exist */
DEBUG("inserting key at index %i", mc->ki[mc->top]); DEBUG("inserting key at index %i", mc->ki[mc->top]);
if ((mc->tree->flags & MDBX_DUPSORT) && node_size(key, data) > env->leaf_nodemax) { if (mc->tree->flags & MDBX_DUPSORT) {
inner_gone(mc);
if (node_size(key, data) > env->leaf_nodemax) {
/* Too big for a node, insert in sub-DB. Set up an empty /* Too big for a node, insert in sub-DB. Set up an empty
* "old sub-page" for convert_to_subtree to expand to a full page. */ * "old sub-page" for convert_to_subtree to expand to a full page. */
fp->dupfix_ksize = (mc->tree->flags & MDBX_DUPFIXED) ? (uint16_t)data->iov_len : 0; fp->dupfix_ksize = (mc->tree->flags & MDBX_DUPFIXED) ? (uint16_t)data->iov_len : 0;
@ -906,6 +908,7 @@ __hot int cursor_put(MDBX_cursor *mc, const MDBX_val *key, MDBX_val *data, unsig
old_data.iov_len = PAGEHDRSZ; old_data.iov_len = PAGEHDRSZ;
goto convert_to_subtree; goto convert_to_subtree;
} }
}
} else { } else {
/* there's only a key anyway, so this is a no-op */ /* there's only a key anyway, so this is a no-op */
if (is_dupfix_leaf(mc->pg[mc->top])) { if (is_dupfix_leaf(mc->pg[mc->top])) {