1
0
Fork 0
mirror of https://github.com/dragonflydb/dragonfly.git synced 2024-12-14 11:58:02 +00:00

Fix GETRANGE exception. Fix SETRANGE case with empty value and non-existing key.

This commit is contained in:
Roman Gershman 2022-04-03 15:58:29 +03:00
parent 167f949c5a
commit 579ba3149b
2 changed files with 27 additions and 1 deletions

View file

@ -519,10 +519,15 @@ void StringFamily::GetRange(CmdArgList args, ConnectionContext* cntx) {
}
const CompactObj& co = it_res.value()->second;
size_t strlen = co.Size();
if (start < 0)
start = strlen + start;
else if (size_t(start) >= strlen)
return OpStatus::OK;
if (end < 0)
end = strlen + end;
if (start < 0)
start = 0;
if (end < 0)
@ -565,7 +570,17 @@ void StringFamily::SetRange(CmdArgList args, ConnectionContext* cntx) {
}
auto cb = [&](Transaction* t, EngineShard* shard) -> OpResult<uint32_t> {
if (min_size == 0) {
auto it_res = shard->db_slice().Find(t->db_index(), key, OBJ_STRING);
if (it_res) {
return it_res.value()->second.Size();
} else {
return it_res.status();
}
}
auto [it, added] = shard->db_slice().AddOrFind(t->db_index(), key);
string s;
s.reserve(min_size);

View file

@ -265,13 +265,24 @@ TEST_F(StringFamilyTest, SetEx) {
ASSERT_THAT(Run({"setex", "key", "0", "val"}), ElementsAre(ErrArg("invalid expire time")));
}
TEST_F(StringFamilyTest, SetRange) {
TEST_F(StringFamilyTest, Range) {
Run({"set", "key1", "Hello World"});
Run({"SETRANGE", "key1", "6", "Earth"});
EXPECT_THAT(Run({"get", "key1"}), RespEq("Hello Earth"));
Run({"SETRANGE", "key2", "2", "Earth"});
EXPECT_THAT(Run({"get", "key2"}), RespEq(string_view("\000\000Earth", 7)));
Run({"SETRANGE", "key3", "0", ""});
EXPECT_EQ(0, CheckedInt({"exists", "key3"}));
Run({"SETRANGE", "key3", "0", "abc"});
EXPECT_EQ(1, CheckedInt({"exists", "key3"}));
Run({"SET", "key3", "123"});
EXPECT_THAT(Run({"getrange", "key3", "2", "3"}), RespEq("3"));
EXPECT_THAT(Run({"getrange", "key3", "3", "3"}), RespEq(""));
EXPECT_THAT(Run({"getrange", "key3", "4", "5"}), RespEq(""));
}
} // namespace dfly