mdbx: исправление put(MDBX_UPSERT+MDBX_ALLDUPS) для случая замены всех значений в subDb.

Fixed cursor_put_nochecklen() internals for case when dupsort'ed named subDb
contains a single key with multiple values (aka duplicates), which are replaced
with a single value by put-operation with the `MDBX_UPSERT+MDBX_ALLDUPS` flags.

In this case, the database becomes completely empty, without any pages.
However exactly this condition was not considered and
thus wasn't handled correctly.

Fixes https://gitflic.ru/project/erthink/libmdbx/issue/8

Thanks Masatoshi Fukunaga <https://gitflic.ru/user/mah0x211> for reporting.
This commit is contained in:
Леонид Юрьев (Leonid Yuriev) 2023-02-01 01:03:51 +03:00
parent 209f784ee7
commit fb827959a9
2 changed files with 11 additions and 2 deletions

View File

@ -10,7 +10,10 @@ and [by Yandex](https://translated.turbopages.org/proxy_u/ru-en.en/https/gitflic
- Max <maxc0d3r@protonmail.com> за сообщение о проблеме ERROR_SHARING_VIOLATION
в режиме MDBX_EXCLUSIVE на Windows.
- Alisher Ashyrov https://t.me/a1is43ras4 за сообщение о проблеме с assert-проверкой и содействие в отладке.
- Alisher Ashyrov <https://t.me/a1is43ras4> за сообщение о проблеме
с assert-проверкой и содействие в отладке.
- Masatoshi Fukunaga <https://gitflic.ru/user/mah0x211> за сообщение о проблеме
`put(MDBX_UPSERT+MDBX_ALLDUPS)` для случая замены всех значений в subDb.
Исправления (без корректировок новых функций):
@ -31,6 +34,12 @@ and [by Yandex](https://translated.turbopages.org/proxy_u/ru-en.en/https/gitflic
- Исправление copy&paste опечатки в разделе "Getting started" документации.
- Устранение проблемы `put(MDBX_UPSERT+MDBX_ALLDUPS)` для случая замены
всех значений единственного ключа в subDb. В ходе этой операции subDb
становится полностью пустой, без каких-либо страниц и именно эта
ситуация не была учтена в коде, что приводило к повреждению БД
при фиксации такой транзакции.
Ликвидация технических долгов и мелочи:
- Исправление опечаток.

View File

@ -17275,7 +17275,7 @@ static __hot int cursor_put_nochecklen(MDBX_cursor *mc, const MDBX_val *key,
if (unlikely(err != MDBX_SUCCESS))
return err;
flags -= MDBX_ALLDUPS;
rc = MDBX_NOTFOUND;
rc = mc->mc_snum ? MDBX_NOTFOUND : MDBX_NO_ROOT;
exact = false;
} else if (!(flags & (MDBX_RESERVE | MDBX_MULTIPLE))) {
/* checking for early exit without dirtying pages */