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

git-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 5e79e7089 fix(set): return scalar for SRANDMEMBER without count (#3601)
5e79e7089 is described below

commit 5e79e7089b5b1bb56608a0f0331fbe760f5f2adf
Author: Raghav <[email protected]>
AuthorDate: Wed Sep 2 13:45:07 2026 +0100

    fix(set): return scalar for SRANDMEMBER without count (#3601)
    
    ## Summary
    
    - return a Redis-compatible bulk string for `SRANDMEMBER key`
    - return nil for a missing key when count is omitted
    - return a Redis-compatible array for `SRANDMEMBER key count` in both
    RESP2 and RESP3, including negative counts that may contain duplicates
    - add regression coverage for scalar, counted, missing-key, and raw
    RESP3 reply types
    
    Closes #2610.
    
    ## Testing
    
    - `./x.py build build-docker --unittest --ninja -j 4`
    - `./x.py check format`
    - `./x.py check tidy build-docker -j 4`
    - `./x.py check golangci-lint`
    - `./x.py test go build-docker`
    - `/workspace/build-docker/unittest` (623 passed, 1 skipped)
    - `/workspace/build-docker/unittest
    --gtest_filter=RedisSetTest.TakeWithoutPop`
    
    ---------
    
    Co-authored-by: Copilot Autofix powered by AI 
<[email protected]>
    Co-authored-by: hulk <[email protected]>
---
 src/commands/cmd_set.cc                     |  9 ++++++++-
 tests/gocase/unit/protocol/protocol_test.go | 20 ++++++++++++++++++++
 tests/gocase/unit/type/set/set_test.go      | 17 +++++++++++++++--
 3 files changed, 43 insertions(+), 3 deletions(-)

diff --git a/src/commands/cmd_set.cc b/src/commands/cmd_set.cc
index e80dcfe11..664eadedd 100644
--- a/src/commands/cmd_set.cc
+++ b/src/commands/cmd_set.cc
@@ -207,6 +207,7 @@ class CommandSRandMember : public Commander {
       }
 
       count_ = *parse_result;
+      with_count_ = true;
     }
     return Commander::Parse(args);
   }
@@ -219,12 +220,18 @@ class CommandSRandMember : public Commander {
     if (!s.ok()) {
       return {Status::RedisExecErr, s.ToString()};
     }
-    *output = conn->SetOfBulkStrings(members);
+
+    if (with_count_) {
+      *output = redis::ArrayOfBulkStrings(members);
+    } else {
+      *output = members.empty() ? conn->NilString() : 
redis::BulkString(members.front());
+    }
     return Status::OK();
   }
 
  private:
   int count_ = 1;
+  bool with_count_ = false;
 };
 
 class CommandSMove : public Commander {
diff --git a/tests/gocase/unit/protocol/protocol_test.go 
b/tests/gocase/unit/protocol/protocol_test.go
index fbf9f42c5..193223b01 100644
--- a/tests/gocase/unit/protocol/protocol_test.go
+++ b/tests/gocase/unit/protocol/protocol_test.go
@@ -298,6 +298,26 @@ func TestProtocolRESP3(t *testing.T) {
                }
        })
 
+       t.Run("SRANDMEMBER with count returns an array", func(t *testing.T) {
+               require.NoError(t, c.WriteArgs("SADD", "srandmember-resp3", 
"member"))
+               c.MustRead(t, ":1")
+
+               require.NoError(t, c.WriteArgs("SRANDMEMBER", 
"srandmember-resp3"))
+               c.MustReadBulkString(t, "member")
+
+               require.NoError(t, c.WriteArgs("SRANDMEMBER", 
"srandmember-resp3-missing"))
+               c.MustRead(t, "_")
+
+               require.NoError(t, c.WriteArgs("SRANDMEMBER", 
"srandmember-resp3-missing", "1"))
+               c.MustRead(t, "*0")
+
+               require.NoError(t, c.WriteArgs("SRANDMEMBER", 
"srandmember-resp3", "-2"))
+               c.MustRead(t, "*2")
+               for range 2 {
+                       c.MustReadBulkString(t, "member")
+               }
+       })
+
        t.Run("multi bulk strings with null", func(t *testing.T) {
                require.NoError(t, c.WriteArgs("HSET", "hash", "f1", "v1"))
                c.MustRead(t, ":1")
diff --git a/tests/gocase/unit/type/set/set_test.go 
b/tests/gocase/unit/type/set/set_test.go
index cb6670bfe..080e99224 100644
--- a/tests/gocase/unit/type/set/set_test.go
+++ b/tests/gocase/unit/type/set/set_test.go
@@ -664,8 +664,21 @@ var setTests = func(t *testing.T, configs 
util.KvrocksServerConfigs) {
                require.ErrorContains(t, rdb.Do(ctx, "spop", "myset", 1, 
1).Err(), "wrong number of arguments")
        })
 
-       t.Run("SRANDMEMBER with <count> against non existing key", func(t 
*testing.T) {
-               require.EqualValues(t, "", rdb.SRandMember(ctx, 
"nonexisting_key").Val())
+       t.Run("SRANDMEMBER result type depends on count", func(t *testing.T) {
+               CreateSet(t, rdb, ctx, "myset", []interface{}{"member"})
+
+               member := rdb.SRandMember(ctx, "myset")
+               require.NoError(t, member.Err())
+               require.Equal(t, "member", member.Val())
+
+               members := rdb.SRandMemberN(ctx, "myset", 1)
+               require.NoError(t, members.Err())
+               require.Equal(t, []string{"member"}, members.Val())
+
+               require.ErrorIs(t, rdb.SRandMember(ctx, 
"nonexisting_key").Err(), redis.Nil)
+               missingMembers := rdb.SRandMemberN(ctx, "nonexisting_key", 1)
+               require.NoError(t, missingMembers.Err())
+               require.Empty(t, missingMembers.Val())
        })
 
        t.Run("SRANDMEMBER the num of arguments is not 2 or 3", func(t 
*testing.T) {

Reply via email to