From 7ed769e9c6d12d643816424b5d576f8bdb2239de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Thu, 20 Mar 2025 01:51:37 +0300 Subject: [PATCH] =?UTF-8?q?mdbx:=20=D0=BF=D0=BE=D0=B4=D0=B4=D0=B5=D1=80?= =?UTF-8?q?=D0=B6=D0=BA=D0=B0=20`MDBX=5FMULTIPLE`=20=D1=81=20=D0=BD=D1=83?= =?UTF-8?q?=D0=BB=D0=B5=D0=B2=D1=8B=D0=BC=20=D1=80=D0=B0=D0=B7=D0=BC=D0=B5?= =?UTF-8?q?=D1=80=D0=BE=D0=BC=20=D0=B4=D0=B0=D0=BD=D0=BD=D1=8B=D1=85=20(ba?= =?UTF-8?q?ckport).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/cursor.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/cursor.c b/src/cursor.c index 036ab123..632aecc7 100644 --- a/src/cursor.c +++ b/src/cursor.c @@ -731,8 +731,17 @@ __hot int cursor_put(MDBX_cursor *mc, const MDBX_val *key, MDBX_val *data, unsig if (mc->clc->k.cmp(key, ¤t_key) != 0) return MDBX_EKEYMISMATCH; - if (unlikely((flags & MDBX_MULTIPLE))) - goto drop_current; + if (unlikely((flags & MDBX_MULTIPLE))) { + if (unlikely(!mc->subcur)) + return MDBX_EINVAL; + err = cursor_del(mc, flags & MDBX_ALLDUPS); + if (unlikely(err != MDBX_SUCCESS)) + return err; + if (unlikely(data[1].iov_len == 0)) + return MDBX_SUCCESS; + flags -= MDBX_CURRENT; + goto skip_check_samedata; + } if (mc->subcur) { node_t *node = page_node(mc->pg[mc->top], mc->ki[mc->top]); @@ -742,7 +751,6 @@ __hot int cursor_put(MDBX_cursor *mc, const MDBX_val *key, MDBX_val *data, unsig * отличается, то вместо обновления требуется удаление и * последующая вставка. */ if (mc->subcur->nested_tree.items > 1 || current_data.iov_len != data->iov_len) { - drop_current: err = cursor_del(mc, flags & MDBX_ALLDUPS); if (unlikely(err != MDBX_SUCCESS)) return err; @@ -847,6 +855,8 @@ __hot int cursor_put(MDBX_cursor *mc, const MDBX_val *key, MDBX_val *data, unsig size_t *batch_dupfix_done = nullptr, batch_dupfix_given = 0; if (unlikely(flags & MDBX_MULTIPLE)) { batch_dupfix_given = data[1].iov_len; + if (unlikely(data[1].iov_len == 0)) + return /* nothing todo */ MDBX_SUCCESS; batch_dupfix_done = &data[1].iov_len; *batch_dupfix_done = 0; }