diff --git a/src/server.c b/src/server.c index afe5094c5..9d915ac3b 100644 --- a/src/server.c +++ b/src/server.c @@ -470,6 +470,10 @@ struct redisCommand redisCommandTable[] = { "read-only fast @sortedset", 0,NULL,1,1,1,0,0,0}, + {"zmscore",zmscoreCommand,-3, + "read-only fast @sortedset", + 0,NULL,1,1,1,0,0,0}, + {"zrank",zrankCommand,3, "read-only fast @sortedset", 0,NULL,1,1,1,0,0,0}, diff --git a/src/server.h b/src/server.h index adfac3293..018dd4607 100644 --- a/src/server.h +++ b/src/server.h @@ -2321,6 +2321,7 @@ void zrevrangeCommand(client *c); void zcardCommand(client *c); void zremCommand(client *c); void zscoreCommand(client *c); +void zmscoreCommand(client *c); void zremrangebyscoreCommand(client *c); void zremrangebylexCommand(client *c); void zpopminCommand(client *c); diff --git a/src/t_zset.c b/src/t_zset.c index 16131ee85..87a5a882e 100644 --- a/src/t_zset.c +++ b/src/t_zset.c @@ -3082,6 +3082,24 @@ void zscoreCommand(client *c) { } } +void zmscoreCommand(client *c) { + robj *key = c->argv[1]; + robj *zobj; + double score; + zobj = lookupKeyRead(c->db,key); + if (zobj != NULL && checkType(c,zobj,OBJ_ZSET)) return; + + addReplyArrayLen(c,c->argc - 2); + for (int j = 2; j < c->argc; j++) { + /* Treat a missing set the same way as an empty set */ + if (zobj == NULL || zsetScore(zobj,c->argv[j]->ptr,&score) == C_ERR) { + addReplyNull(c); + } else { + addReplyDouble(c,score); + } + } +} + void zrankGenericCommand(client *c, int reverse) { robj *key = c->argv[1]; robj *ele = c->argv[2]; diff --git a/tests/support/cluster.tcl b/tests/support/cluster.tcl index 64b079ff8..dced8d864 100644 --- a/tests/support/cluster.tcl +++ b/tests/support/cluster.tcl @@ -27,7 +27,7 @@ set ::redis_cluster::plain_commands { sadd srem sismember scard spop srandmember smembers sscan zadd zincrby zrem zremrangebyscore zremrangebyrank zremrangebylex zrange zrangebyscore zrevrangebyscore zrangebylex zrevrangebylex zcount - zlexcount zrevrange zcard zscore zrank zrevrank zscan hset hsetnx + zlexcount zrevrange zcard zscore zmscore zrank zrevrank zscan hset hsetnx hget hmset hmget hincrby hincrbyfloat hdel hlen hkeys hvals hgetall hexists hscan incrby decrby incrbyfloat getset move expire expireat pexpire pexpireat type ttl pttl persist restore diff --git a/tests/unit/type/zset.tcl b/tests/unit/type/zset.tcl index a8c817f6e..d098840b0 100644 --- a/tests/unit/type/zset.tcl +++ b/tests/unit/type/zset.tcl @@ -780,6 +780,44 @@ start_server {tags {"zset"}} { set oldscore $score } } + + test {ZMSCORE retrieve} { + r del zmscoretest + r zadd zmscoretest 10 x + r zadd zmscoretest 20 y + + r zmscore zmscoretest x y + } {10 20} + + test {ZMSCORE retrieve from empty set} { + r del zmscoretest + + r zmscore zmscoretest x y + } {{} {}} + + test {ZMSCORE retrieve with missing member} { + r del zmscoretest + r zadd zmscoretest 10 x + + r zmscore zmscoretest x y + } {10 {}} + + test {ZMSCORE retrieve single member} { + r del zmscoretest + r zadd zmscoretest 10 x + r zadd zmscoretest 20 y + + r zmscore zmscoretest x + } {10} + + test {ZMSCORE retrieve requires one or more members} { + r del zmscoretest + r zadd zmscoretest 10 x + r zadd zmscoretest 20 y + + catch {r zmscore zmscoretest} e + assert_match {*ERR*wrong*number*arg*} $e + } test "ZSET commands don't accept the empty strings as valid score" { assert_error "*not*float*" {r zadd myzset "" abc} @@ -815,6 +853,21 @@ start_server {tags {"zset"}} { } } + test "ZMSCORE - $encoding" { + r del zscoretest + set aux {} + for {set i 0} {$i < $elements} {incr i} { + set score [expr rand()] + lappend aux $score + r zadd zscoretest $score $i + } + + assert_encoding $encoding zscoretest + for {set i 0} {$i < $elements} {incr i} { + assert_equal [lindex $aux $i] [r zmscore zscoretest $i] + } + } + test "ZSCORE after a DEBUG RELOAD - $encoding" { r del zscoretest set aux {}