From e5a856ddf78cd48b569358525752cb2da8de6b83 Mon Sep 17 00:00:00 2001 From: FishYoung Date: Sat, 16 Nov 2024 10:30:22 +0800 Subject: [PATCH 1/2] fix(types): reset the value of expired key to prevent the following parsing and calculation. --- src/types/redis_string.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/types/redis_string.cc b/src/types/redis_string.cc index 7d7f476d878..85a3a95d9da 100644 --- a/src/types/redis_string.cc +++ b/src/types/redis_string.cc @@ -329,6 +329,7 @@ rocksdb::Status String::IncrBy(engine::Context &ctx, const std::string &user_key if (!s.ok() && !s.IsNotFound()) return s; if (s.IsNotFound()) { Metadata metadata(kRedisString, false); + raw_value.clear(); metadata.Encode(&raw_value); } @@ -367,6 +368,7 @@ rocksdb::Status String::IncrByFloat(engine::Context &ctx, const std::string &use if (s.IsNotFound()) { Metadata metadata(kRedisString, false); + raw_value.clear(); metadata.Encode(&raw_value); } size_t offset = Metadata::GetOffsetAfterExpire(raw_value[0]); From 80ffc13aba3e29f5a55f7b2c761bddf12d945a2c Mon Sep 17 00:00:00 2001 From: FishYoung Date: Mon, 18 Nov 2024 17:40:28 +0800 Subject: [PATCH 2/2] fix(tests): add test cases for INCRBY over expired keys. --- tests/gocase/unit/type/incr/incr_test.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/gocase/unit/type/incr/incr_test.go b/tests/gocase/unit/type/incr/incr_test.go index f8a1785cfb1..3b507ff5be9 100644 --- a/tests/gocase/unit/type/incr/incr_test.go +++ b/tests/gocase/unit/type/incr/incr_test.go @@ -22,6 +22,7 @@ package incr import ( "context" "testing" + "time" "github.com/apache/kvrocks/tests/gocase/util" "github.com/stretchr/testify/require" @@ -75,6 +76,14 @@ func testIncr(t *testing.T, configs util.KvrocksServerConfigs) { require.EqualValues(t, 34359738368, rdb.IncrBy(ctx, "novar", 17179869184).Val()) }) + t.Run("INCR over an expired key", func(t *testing.T) { + require.NoError(t, rdb.SetEx(ctx, "expired-foo", "1024", 2*time.Second).Err()) + require.NoError(t, rdb.SetEx(ctx, "expired-str", "value", 2*time.Second).Err()) + time.Sleep(3 * time.Second) + require.EqualValues(t, 1, rdb.IncrBy(ctx, "expired-foo", 1).Val()) + require.EqualValues(t, 1, rdb.IncrBy(ctx, "expired-str", 1).Val()) + }) + t.Run("INCR fails against key with spaces (left)", func(t *testing.T) { require.NoError(t, rdb.Set(ctx, "novar", " 11", 0).Err()) util.ErrorRegexp(t, rdb.Incr(ctx, "novar").Err(), "ERR.*") @@ -133,6 +142,12 @@ func testIncr(t *testing.T, configs util.KvrocksServerConfigs) { require.EqualValues(t, 34359738368, rdb.IncrByFloat(ctx, "novar", 17179869184).Val()) }) + t.Run("INCRBYFLOAT over an expired key", func(t *testing.T) { + require.NoError(t, rdb.SetEx(ctx, "expired-foo", "10.24", 2*time.Second).Err()) + time.Sleep(3 * time.Second) + require.EqualValues(t, 1, rdb.IncrBy(ctx, "expired-foo", 1.0).Val()) + }) + t.Run("INCRBYFLOAT fails against key with spaces (left)", func(t *testing.T) { require.NoError(t, rdb.Set(ctx, "novar", " 11", 0).Err()) util.ErrorRegexp(t, rdb.IncrByFloat(ctx, "novar", 1.0).Err(), "ERR.*valid.*")