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 044b6fde Fix crash in zset store getkeys, fix zdiff/bzmpop range, add 
tests (#2051)
044b6fde is described below

commit 044b6fde4d34894b5ff0ba3534419b9631a34753
Author: Binbin <[email protected]>
AuthorDate: Thu Jan 25 19:11:03 2024 +0800

    Fix crash in zset store getkeys, fix zdiff/bzmpop range, add tests (#2051)
    
    These following cases will crash the server, the reason is that
    the index of numkeys is wrong:
    ```
    command getkeys zdiffstore dst 2 src1 src2
    command getkeys zinterstore dst 2 src1 src2
    command getkeys zunionstore dst 2 src1 src2
    ```
    
    These following getkeys output is wrong:
    ```
    > command getkeys zdiff 2 key1 key2
    1) "key1"
    2) "key2"
    3) (nil)
    
    > command getkeys bzmpop 0 2 key1 key2
    1) "key1"
    ```
    
    These are ok:
    ```
    command getkeys zinter 2 key1 key2
    command getkeys zunion 2 key1 key2
    command getkeys sintercard 2 key1 key2
    command getkeys zintercard 2 key1 key2
    command getkeys zmpop 2 key1 key2
    command getkeys lmpop 2 key1 key2
    command getkeys blmpop 0 2 key1 key2
    ```
    
    However, at present, there is still a problem with our zset store.
    We do not support returning dst key, but let's do it later...
    ```
    127.0.0.1:6379> command getkeys zinterstore dst 2 src1 src2
    1) "dst"
    2) "src1"
    3) "src2"
    
    127.0.0.1:6666> command getkeys zinterstore dst 2 src1 src2
    1) "src1"
    2) "src2"
    ```
---
 src/commands/cmd_zset.cc                  |  10 +--
 tests/gocase/unit/command/command_test.go | 108 ++++++++++++++++++++++++++++++
 2 files changed, 113 insertions(+), 5 deletions(-)

diff --git a/src/commands/cmd_zset.cc b/src/commands/cmd_zset.cc
index 7d80829d..12927fa6 100644
--- a/src/commands/cmd_zset.cc
+++ b/src/commands/cmd_zset.cc
@@ -561,7 +561,7 @@ class CommandBZMPop : public BlockingCommander {
 
   static CommandKeyRange Range(const std::vector<std::string> &args) {
     int num_key = *ParseInt<int>(args[2], 10);
-    return {3, 1 + num_key, 1};
+    return {3, 2 + num_key, 1};
   }
 
  private:
@@ -1223,7 +1223,7 @@ class CommandZUnionStore : public Commander {
   }
 
   static CommandKeyRange Range(const std::vector<std::string> &args) {
-    int num_key = *ParseInt<int>(args[1], 10);
+    int num_key = *ParseInt<int>(args[2], 10);
     return {3, 2 + num_key, 1};
   }
 
@@ -1250,7 +1250,7 @@ class CommandZInterStore : public CommandZUnionStore {
   }
 
   static CommandKeyRange Range(const std::vector<std::string> &args) {
-    int num_key = *ParseInt<int>(args[1], 10);
+    int num_key = *ParseInt<int>(args[2], 10);
     return {3, 2 + num_key, 1};
   }
 };
@@ -1464,7 +1464,7 @@ class CommandZDiff : public Commander {
 
   static CommandKeyRange Range(const std::vector<std::string> &args) {
     int num_key = *ParseInt<int>(args[1], 10);
-    return {2, 2 + num_key, 1};
+    return {2, 1 + num_key, 1};
   }
 
  protected:
@@ -1504,7 +1504,7 @@ class CommandZDiffStore : public Commander {
   }
 
   static CommandKeyRange Range(const std::vector<std::string> &args) {
-    int num_key = *ParseInt<int>(args[1], 10);
+    int num_key = *ParseInt<int>(args[2], 10);
     return {3, 2 + num_key, 1};
   }
 
diff --git a/tests/gocase/unit/command/command_test.go 
b/tests/gocase/unit/command/command_test.go
index 58b7589a..89d87a58 100644
--- a/tests/gocase/unit/command/command_test.go
+++ b/tests/gocase/unit/command/command_test.go
@@ -65,4 +65,112 @@ func TestCommand(t *testing.T) {
                require.Len(t, vs, 1)
                require.Equal(t, "test", vs[0])
        })
+
+       t.Run("COMMAND GETKEYS SINTERCARD", func(t *testing.T) {
+               r := rdb.Do(ctx, "COMMAND", "GETKEYS", "SINTERCARD", "2", 
"key1", "key2")
+               vs, err := r.Slice()
+               require.NoError(t, err)
+               require.Len(t, vs, 2)
+               require.Equal(t, "key1", vs[0])
+               require.Equal(t, "key2", vs[1])
+       })
+
+       t.Run("COMMAND GETKEYS ZINTER", func(t *testing.T) {
+               r := rdb.Do(ctx, "COMMAND", "GETKEYS", "ZINTER", "2", "key1", 
"key2")
+               vs, err := r.Slice()
+               require.NoError(t, err)
+               require.Len(t, vs, 2)
+               require.Equal(t, "key1", vs[0])
+               require.Equal(t, "key2", vs[1])
+       })
+
+       t.Run("COMMAND GETKEYS ZINTERSTORE", func(t *testing.T) {
+               r := rdb.Do(ctx, "COMMAND", "GETKEYS", "ZINTERSTORE", "dst", 
"2", "src1", "src2")
+               vs, err := r.Slice()
+               require.NoError(t, err)
+               require.Len(t, vs, 2)
+               require.Equal(t, "src1", vs[0])
+               require.Equal(t, "src2", vs[1])
+       })
+
+       t.Run("COMMAND GETKEYS ZINTERCARD", func(t *testing.T) {
+               r := rdb.Do(ctx, "COMMAND", "GETKEYS", "ZINTERCARD", "2", 
"key1", "key2")
+               vs, err := r.Slice()
+               require.NoError(t, err)
+               require.Len(t, vs, 2)
+               require.Equal(t, "key1", vs[0])
+               require.Equal(t, "key2", vs[1])
+       })
+
+       t.Run("COMMAND GETKEYS ZUNION", func(t *testing.T) {
+               r := rdb.Do(ctx, "COMMAND", "GETKEYS", "ZUNION", "2", "key1", 
"key2")
+               vs, err := r.Slice()
+               require.NoError(t, err)
+               require.Len(t, vs, 2)
+               require.Equal(t, "key1", vs[0])
+               require.Equal(t, "key2", vs[1])
+       })
+
+       t.Run("COMMAND GETKEYS ZUNIONSTORE", func(t *testing.T) {
+               r := rdb.Do(ctx, "COMMAND", "GETKEYS", "ZUNIONSTORE", "dst", 
"2", "src1", "src2")
+               vs, err := r.Slice()
+               require.NoError(t, err)
+               require.Len(t, vs, 2)
+               require.Equal(t, "src1", vs[0])
+               require.Equal(t, "src2", vs[1])
+       })
+
+       t.Run("COMMAND GETKEYS ZDIFF", func(t *testing.T) {
+               r := rdb.Do(ctx, "COMMAND", "GETKEYS", "ZDIFF", "2", "key1", 
"key2")
+               vs, err := r.Slice()
+               require.NoError(t, err)
+               require.Len(t, vs, 2)
+               require.Equal(t, "key1", vs[0])
+               require.Equal(t, "key2", vs[1])
+       })
+
+       t.Run("COMMAND GETKEYS ZDIFFSTORE", func(t *testing.T) {
+               r := rdb.Do(ctx, "COMMAND", "GETKEYS", "ZDIFFSTORE", "dst", 
"2", "src1", "src2")
+               vs, err := r.Slice()
+               require.NoError(t, err)
+               require.Len(t, vs, 2)
+               require.Equal(t, "src1", vs[0])
+               require.Equal(t, "src2", vs[1])
+       })
+
+       t.Run("COMMAND GETKEYS ZMPOP", func(t *testing.T) {
+               r := rdb.Do(ctx, "COMMAND", "GETKEYS", "ZMPOP", "2", "key1", 
"key2")
+               vs, err := r.Slice()
+               require.NoError(t, err)
+               require.Len(t, vs, 2)
+               require.Equal(t, "key1", vs[0])
+               require.Equal(t, "key2", vs[1])
+       })
+
+       t.Run("COMMAND GETKEYS BZMPOP", func(t *testing.T) {
+               r := rdb.Do(ctx, "COMMAND", "GETKEYS", "BZMPOP", "0", "2", 
"key1", "key2")
+               vs, err := r.Slice()
+               require.NoError(t, err)
+               require.Len(t, vs, 2)
+               require.Equal(t, "key1", vs[0])
+               require.Equal(t, "key2", vs[1])
+       })
+
+       t.Run("COMMAND GETKEYS LMPOP", func(t *testing.T) {
+               r := rdb.Do(ctx, "COMMAND", "GETKEYS", "LMPOP", "2", "key1", 
"key2")
+               vs, err := r.Slice()
+               require.NoError(t, err)
+               require.Len(t, vs, 2)
+               require.Equal(t, "key1", vs[0])
+               require.Equal(t, "key2", vs[1])
+       })
+
+       t.Run("COMMAND GETKEYS BLMPOP", func(t *testing.T) {
+               r := rdb.Do(ctx, "COMMAND", "GETKEYS", "BLMPOP", "0", "2", 
"key1", "key2")
+               vs, err := r.Slice()
+               require.NoError(t, err)
+               require.Len(t, vs, 2)
+               require.Equal(t, "key1", vs[0])
+               require.Equal(t, "key2", vs[1])
+       })
 }

Reply via email to