This is an automated email from the ASF dual-hosted git repository.

hulk pushed a commit to branch unstable
in repository https://gitbox.apache.org/repos/asf/kvrocks.git


The following commit(s) were added to refs/heads/unstable by this push:
     new 4404eb7e9 fix(string): add empty string value check for INCR to match 
Redis behavior (#3354)
4404eb7e9 is described below

commit 4404eb7e9662e92d2d3e304ada73322f50fa84a0
Author: sryan yuan <[email protected]>
AuthorDate: Thu Jan 29 19:43:00 2026 +0800

    fix(string): add empty string value check for INCR to match Redis behavior 
(#3354)
    
    ### Background
    Previously, Kvrocks allowed INCR on a key whose value was an empty
    string (""),
    treating it as zero and returning 1.
    
    In Redis, the same operation results in an error:
    ERR value is not an integer or out of range
    
    This difference caused inconsistent behavior between Kvrocks and Redis.
    
    ### Changes
    - Added check for empty string values before performing INCR
    - Return error when value is an empty string, matching Redis behavior
    
    ### Result
    Kvrocks now behaves consistently with Redis when performing INCR on
    empty string values,
    improving compatibility and reducing unexpected results in client
    applications.
    
    Co-authored-by: yxj25245 <[email protected]>
---
 src/types/redis_string.cc                | 4 ++++
 tests/gocase/unit/type/incr/incr_test.go | 5 +++++
 2 files changed, 9 insertions(+)

diff --git a/src/types/redis_string.cc b/src/types/redis_string.cc
index 4bd728535..e2d431303 100644
--- a/src/types/redis_string.cc
+++ b/src/types/redis_string.cc
@@ -373,6 +373,10 @@ rocksdb::Status String::IncrBy(engine::Context &ctx, const 
std::string &user_key
 
   size_t offset = Metadata::GetOffsetAfterExpire(raw_value[0]);
   std::string value = raw_value.substr(offset);
+  if (s.ok() && value.empty()) {
+    return rocksdb::Status::InvalidArgument("value is not an integer or out of 
range");
+  }
+
   int64_t n = 0;
   if (!value.empty()) {
     auto parse_result = ParseInt<int64_t>(value, 10);
diff --git a/tests/gocase/unit/type/incr/incr_test.go 
b/tests/gocase/unit/type/incr/incr_test.go
index 3b507ff5b..99a0c6b6b 100644
--- a/tests/gocase/unit/type/incr/incr_test.go
+++ b/tests/gocase/unit/type/incr/incr_test.go
@@ -84,6 +84,11 @@ func testIncr(t *testing.T, configs 
util.KvrocksServerConfigs) {
                require.EqualValues(t, 1, rdb.IncrBy(ctx, "expired-str", 
1).Val())
        })
 
+       t.Run("INCR fails against key with empty value", func(t *testing.T) {
+               require.NoError(t, rdb.Set(ctx, "novar", "", 0).Err())
+               util.ErrorRegexp(t, rdb.Incr(ctx, "novar").Err(), "ERR.*")
+       })
+
        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.*")

Reply via email to