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.*")