This commit is contained in:
youngmore1024 2026-05-27 10:37:49 +00:00 committed by GitHub
commit afdee127a7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 295 additions and 20 deletions

View file

@ -10005,6 +10005,7 @@ struct COMMAND_ARG ZRANGE_Args[] = {
{MAKE_ARG("rev",ARG_TYPE_PURE_TOKEN,-1,"REV",NULL,"6.2.0",CMD_ARG_OPTIONAL,0,NULL)},
{MAKE_ARG("limit",ARG_TYPE_BLOCK,-1,"LIMIT",NULL,"6.2.0",CMD_ARG_OPTIONAL,2,NULL),.subargs=ZRANGE_limit_Subargs},
{MAKE_ARG("withscores",ARG_TYPE_PURE_TOKEN,-1,"WITHSCORES",NULL,NULL,CMD_ARG_OPTIONAL,0,NULL)},
{MAKE_ARG("withstatus",ARG_TYPE_PURE_TOKEN,-1,"WITHSTATUS",NULL,"9.0.0",CMD_ARG_OPTIONAL,0,NULL)},
};
/********** ZRANGEBYLEX ********************/
@ -10073,6 +10074,7 @@ struct COMMAND_ARG ZRANGEBYSCORE_Args[] = {
{MAKE_ARG("min",ARG_TYPE_DOUBLE,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
{MAKE_ARG("max",ARG_TYPE_DOUBLE,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
{MAKE_ARG("withscores",ARG_TYPE_PURE_TOKEN,-1,"WITHSCORES",NULL,"2.0.0",CMD_ARG_OPTIONAL,0,NULL)},
{MAKE_ARG("withstatus",ARG_TYPE_PURE_TOKEN,-1,"WITHSTATUS",NULL,"9.0.0",CMD_ARG_OPTIONAL,0,NULL)},
{MAKE_ARG("limit",ARG_TYPE_BLOCK,-1,"LIMIT",NULL,NULL,CMD_ARG_OPTIONAL,2,NULL),.subargs=ZRANGEBYSCORE_limit_Subargs},
};
@ -10276,6 +10278,7 @@ struct COMMAND_ARG ZREVRANGE_Args[] = {
{MAKE_ARG("start",ARG_TYPE_INTEGER,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
{MAKE_ARG("stop",ARG_TYPE_INTEGER,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
{MAKE_ARG("withscores",ARG_TYPE_PURE_TOKEN,-1,"WITHSCORES",NULL,NULL,CMD_ARG_OPTIONAL,0,NULL)},
{MAKE_ARG("withstatus",ARG_TYPE_PURE_TOKEN,-1,"WITHSTATUS",NULL,"9.0.0",CMD_ARG_OPTIONAL,0,NULL)},
};
/********** ZREVRANGEBYLEX ********************/
@ -10344,6 +10347,7 @@ struct COMMAND_ARG ZREVRANGEBYSCORE_Args[] = {
{MAKE_ARG("max",ARG_TYPE_DOUBLE,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
{MAKE_ARG("min",ARG_TYPE_DOUBLE,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
{MAKE_ARG("withscores",ARG_TYPE_PURE_TOKEN,-1,"WITHSCORES",NULL,NULL,CMD_ARG_OPTIONAL,0,NULL)},
{MAKE_ARG("withstatus",ARG_TYPE_PURE_TOKEN,-1,"WITHSTATUS",NULL,"9.0.0",CMD_ARG_OPTIONAL,0,NULL)},
{MAKE_ARG("limit",ARG_TYPE_BLOCK,-1,"LIMIT",NULL,NULL,CMD_ARG_OPTIONAL,2,NULL),.subargs=ZREVRANGEBYSCORE_limit_Subargs},
};
@ -12578,18 +12582,18 @@ struct COMMAND_STRUCT redisCommandTable[] = {
{MAKE_CMD("zpopmax","Returns the highest-scoring members from a sorted set after removing them. Deletes the sorted set if the last member was popped.","O(log(N)*M) with N being the number of elements in the sorted set, and M being the number of elements popped.","5.0.0",CMD_DOC_NONE,NULL,NULL,"sorted_set",COMMAND_GROUP_SORTED_SET,ZPOPMAX_History,0,ZPOPMAX_Tips,0,zpopmaxCommand,-2,CMD_WRITE|CMD_FAST,ACL_CATEGORY_SORTEDSET,ZPOPMAX_Keyspecs,1,NULL,2),.args=ZPOPMAX_Args},
{MAKE_CMD("zpopmin","Returns the lowest-scoring members from a sorted set after removing them. Deletes the sorted set if the last member was popped.","O(log(N)*M) with N being the number of elements in the sorted set, and M being the number of elements popped.","5.0.0",CMD_DOC_NONE,NULL,NULL,"sorted_set",COMMAND_GROUP_SORTED_SET,ZPOPMIN_History,0,ZPOPMIN_Tips,0,zpopminCommand,-2,CMD_WRITE|CMD_FAST,ACL_CATEGORY_SORTEDSET,ZPOPMIN_Keyspecs,1,NULL,2),.args=ZPOPMIN_Args},
{MAKE_CMD("zrandmember","Returns one or more random members from a sorted set.","O(N) where N is the number of members returned","6.2.0",CMD_DOC_NONE,NULL,NULL,"sorted_set",COMMAND_GROUP_SORTED_SET,ZRANDMEMBER_History,0,ZRANDMEMBER_Tips,1,zrandmemberCommand,-2,CMD_READONLY,ACL_CATEGORY_SORTEDSET,ZRANDMEMBER_Keyspecs,1,NULL,2),.args=ZRANDMEMBER_Args},
{MAKE_CMD("zrange","Returns members in a sorted set within a range of indexes.","O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements returned.","1.2.0",CMD_DOC_NONE,NULL,NULL,"sorted_set",COMMAND_GROUP_SORTED_SET,ZRANGE_History,1,ZRANGE_Tips,0,zrangeCommand,-4,CMD_READONLY,ACL_CATEGORY_SORTEDSET,ZRANGE_Keyspecs,1,NULL,7),.args=ZRANGE_Args},
{MAKE_CMD("zrange","Returns members in a sorted set within a range of indexes.","O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements returned.","1.2.0",CMD_DOC_NONE,NULL,NULL,"sorted_set",COMMAND_GROUP_SORTED_SET,ZRANGE_History,1,ZRANGE_Tips,0,zrangeCommand,-4,CMD_READONLY,ACL_CATEGORY_SORTEDSET,ZRANGE_Keyspecs,1,NULL,8),.args=ZRANGE_Args},
{MAKE_CMD("zrangebylex","Returns members in a sorted set within a lexicographical range.","O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements being returned. If M is constant (e.g. always asking for the first 10 elements with LIMIT), you can consider it O(log(N)).","2.8.9",CMD_DOC_DEPRECATED,"`ZRANGE` with the `BYLEX` argument","6.2.0","sorted_set",COMMAND_GROUP_SORTED_SET,ZRANGEBYLEX_History,0,ZRANGEBYLEX_Tips,0,zrangebylexCommand,-4,CMD_READONLY,ACL_CATEGORY_SORTEDSET,ZRANGEBYLEX_Keyspecs,1,NULL,4),.args=ZRANGEBYLEX_Args},
{MAKE_CMD("zrangebyscore","Returns members in a sorted set within a range of scores.","O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements being returned. If M is constant (e.g. always asking for the first 10 elements with LIMIT), you can consider it O(log(N)).","1.0.5",CMD_DOC_DEPRECATED,"`ZRANGE` with the `BYSCORE` argument","6.2.0","sorted_set",COMMAND_GROUP_SORTED_SET,ZRANGEBYSCORE_History,1,ZRANGEBYSCORE_Tips,0,zrangebyscoreCommand,-4,CMD_READONLY,ACL_CATEGORY_SORTEDSET,ZRANGEBYSCORE_Keyspecs,1,NULL,5),.args=ZRANGEBYSCORE_Args},
{MAKE_CMD("zrangebyscore","Returns members in a sorted set within a range of scores.","O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements being returned. If M is constant (e.g. always asking for the first 10 elements with LIMIT), you can consider it O(log(N)).","1.0.5",CMD_DOC_DEPRECATED,"`ZRANGE` with the `BYSCORE` argument","6.2.0","sorted_set",COMMAND_GROUP_SORTED_SET,ZRANGEBYSCORE_History,1,ZRANGEBYSCORE_Tips,0,zrangebyscoreCommand,-4,CMD_READONLY,ACL_CATEGORY_SORTEDSET,ZRANGEBYSCORE_Keyspecs,1,NULL,6),.args=ZRANGEBYSCORE_Args},
{MAKE_CMD("zrangestore","Stores a range of members from sorted set in a key.","O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements stored into the destination key.","6.2.0",CMD_DOC_NONE,NULL,NULL,"sorted_set",COMMAND_GROUP_SORTED_SET,ZRANGESTORE_History,0,ZRANGESTORE_Tips,0,zrangestoreCommand,-5,CMD_WRITE|CMD_DENYOOM,ACL_CATEGORY_SORTEDSET,ZRANGESTORE_Keyspecs,2,NULL,7),.args=ZRANGESTORE_Args},
{MAKE_CMD("zrank","Returns the index of a member in a sorted set ordered by ascending scores.","O(log(N))","2.0.0",CMD_DOC_NONE,NULL,NULL,"sorted_set",COMMAND_GROUP_SORTED_SET,ZRANK_History,1,ZRANK_Tips,0,zrankCommand,-3,CMD_READONLY|CMD_FAST,ACL_CATEGORY_SORTEDSET,ZRANK_Keyspecs,1,NULL,3),.args=ZRANK_Args},
{MAKE_CMD("zrem","Removes one or more members from a sorted set. Deletes the sorted set if all members were removed.","O(M*log(N)) with N being the number of elements in the sorted set and M the number of elements to be removed.","1.2.0",CMD_DOC_NONE,NULL,NULL,"sorted_set",COMMAND_GROUP_SORTED_SET,ZREM_History,1,ZREM_Tips,0,zremCommand,-3,CMD_WRITE|CMD_FAST,ACL_CATEGORY_SORTEDSET,ZREM_Keyspecs,1,NULL,2),.args=ZREM_Args},
{MAKE_CMD("zremrangebylex","Removes members in a sorted set within a lexicographical range. Deletes the sorted set if all members were removed.","O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements removed by the operation.","2.8.9",CMD_DOC_NONE,NULL,NULL,"sorted_set",COMMAND_GROUP_SORTED_SET,ZREMRANGEBYLEX_History,0,ZREMRANGEBYLEX_Tips,0,zremrangebylexCommand,4,CMD_WRITE,ACL_CATEGORY_SORTEDSET,ZREMRANGEBYLEX_Keyspecs,1,NULL,3),.args=ZREMRANGEBYLEX_Args},
{MAKE_CMD("zremrangebyrank","Removes members in a sorted set within a range of indexes. Deletes the sorted set if all members were removed.","O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements removed by the operation.","2.0.0",CMD_DOC_NONE,NULL,NULL,"sorted_set",COMMAND_GROUP_SORTED_SET,ZREMRANGEBYRANK_History,0,ZREMRANGEBYRANK_Tips,0,zremrangebyrankCommand,4,CMD_WRITE,ACL_CATEGORY_SORTEDSET,ZREMRANGEBYRANK_Keyspecs,1,NULL,3),.args=ZREMRANGEBYRANK_Args},
{MAKE_CMD("zremrangebyscore","Removes members in a sorted set within a range of scores. Deletes the sorted set if all members were removed.","O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements removed by the operation.","1.2.0",CMD_DOC_NONE,NULL,NULL,"sorted_set",COMMAND_GROUP_SORTED_SET,ZREMRANGEBYSCORE_History,0,ZREMRANGEBYSCORE_Tips,0,zremrangebyscoreCommand,4,CMD_WRITE,ACL_CATEGORY_SORTEDSET,ZREMRANGEBYSCORE_Keyspecs,1,NULL,3),.args=ZREMRANGEBYSCORE_Args},
{MAKE_CMD("zrevrange","Returns members in a sorted set within a range of indexes in reverse order.","O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements returned.","1.2.0",CMD_DOC_DEPRECATED,"`ZRANGE` with the `REV` argument","6.2.0","sorted_set",COMMAND_GROUP_SORTED_SET,ZREVRANGE_History,0,ZREVRANGE_Tips,0,zrevrangeCommand,-4,CMD_READONLY,ACL_CATEGORY_SORTEDSET,ZREVRANGE_Keyspecs,1,NULL,4),.args=ZREVRANGE_Args},
{MAKE_CMD("zrevrange","Returns members in a sorted set within a range of indexes in reverse order.","O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements returned.","1.2.0",CMD_DOC_DEPRECATED,"`ZRANGE` with the `REV` argument","6.2.0","sorted_set",COMMAND_GROUP_SORTED_SET,ZREVRANGE_History,0,ZREVRANGE_Tips,0,zrevrangeCommand,-4,CMD_READONLY,ACL_CATEGORY_SORTEDSET,ZREVRANGE_Keyspecs,1,NULL,5),.args=ZREVRANGE_Args},
{MAKE_CMD("zrevrangebylex","Returns members in a sorted set within a lexicographical range in reverse order.","O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements being returned. If M is constant (e.g. always asking for the first 10 elements with LIMIT), you can consider it O(log(N)).","2.8.9",CMD_DOC_DEPRECATED,"`ZRANGE` with the `REV` and `BYLEX` arguments","6.2.0","sorted_set",COMMAND_GROUP_SORTED_SET,ZREVRANGEBYLEX_History,0,ZREVRANGEBYLEX_Tips,0,zrevrangebylexCommand,-4,CMD_READONLY,ACL_CATEGORY_SORTEDSET,ZREVRANGEBYLEX_Keyspecs,1,NULL,4),.args=ZREVRANGEBYLEX_Args},
{MAKE_CMD("zrevrangebyscore","Returns members in a sorted set within a range of scores in reverse order.","O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements being returned. If M is constant (e.g. always asking for the first 10 elements with LIMIT), you can consider it O(log(N)).","2.2.0",CMD_DOC_DEPRECATED,"`ZRANGE` with the `REV` and `BYSCORE` arguments","6.2.0","sorted_set",COMMAND_GROUP_SORTED_SET,ZREVRANGEBYSCORE_History,1,ZREVRANGEBYSCORE_Tips,0,zrevrangebyscoreCommand,-4,CMD_READONLY,ACL_CATEGORY_SORTEDSET,ZREVRANGEBYSCORE_Keyspecs,1,NULL,5),.args=ZREVRANGEBYSCORE_Args},
{MAKE_CMD("zrevrangebyscore","Returns members in a sorted set within a range of scores in reverse order.","O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements being returned. If M is constant (e.g. always asking for the first 10 elements with LIMIT), you can consider it O(log(N)).","2.2.0",CMD_DOC_DEPRECATED,"`ZRANGE` with the `REV` and `BYSCORE` arguments","6.2.0","sorted_set",COMMAND_GROUP_SORTED_SET,ZREVRANGEBYSCORE_History,1,ZREVRANGEBYSCORE_Tips,0,zrevrangebyscoreCommand,-4,CMD_READONLY,ACL_CATEGORY_SORTEDSET,ZREVRANGEBYSCORE_Keyspecs,1,NULL,6),.args=ZREVRANGEBYSCORE_Args},
{MAKE_CMD("zrevrank","Returns the index of a member in a sorted set ordered by descending scores.","O(log(N))","2.0.0",CMD_DOC_NONE,NULL,NULL,"sorted_set",COMMAND_GROUP_SORTED_SET,ZREVRANK_History,1,ZREVRANK_Tips,0,zrevrankCommand,-3,CMD_READONLY|CMD_FAST,ACL_CATEGORY_SORTEDSET,ZREVRANK_Keyspecs,1,NULL,3),.args=ZREVRANK_Args},
{MAKE_CMD("zscan","Iterates over members and scores of a sorted set.","O(1) for every call. O(N) for a complete iteration, including enough command calls for the cursor to return back to 0. N is the number of elements inside the collection.","2.8.0",CMD_DOC_NONE,NULL,NULL,"sorted_set",COMMAND_GROUP_SORTED_SET,ZSCAN_History,0,ZSCAN_Tips,1,zscanCommand,-3,CMD_READONLY,ACL_CATEGORY_SORTEDSET,ZSCAN_Keyspecs,1,NULL,4),.args=ZSCAN_Args},
{MAKE_CMD("zscore","Returns the score of a member in a sorted set.","O(1)","1.2.0",CMD_DOC_NONE,NULL,NULL,"sorted_set",COMMAND_GROUP_SORTED_SET,ZSCORE_History,0,ZSCORE_Tips,0,zscoreCommand,3,CMD_READONLY|CMD_FAST,ACL_CATEGORY_SORTEDSET,ZSCORE_Keyspecs,1,NULL,2),.args=ZSCORE_Args},

View file

@ -131,6 +131,13 @@
"token": "WITHSCORES",
"type": "pure-token",
"optional": true
},
{
"name": "withstatus",
"token": "WITHSTATUS",
"type": "pure-token",
"optional": true,
"since": "9.0.0"
}
]
}

View file

@ -98,6 +98,13 @@
"optional": true,
"since": "2.0.0"
},
{
"name": "withstatus",
"token": "WITHSTATUS",
"type": "pure-token",
"optional": true,
"since": "9.0.0"
},
{
"token": "LIMIT",
"name": "limit",

View file

@ -88,6 +88,13 @@
"token": "WITHSCORES",
"type": "pure-token",
"optional": true
},
{
"name": "withstatus",
"token": "WITHSTATUS",
"type": "pure-token",
"optional": true,
"since": "9.0.0"
}
]
}

View file

@ -97,6 +97,13 @@
"type": "pure-token",
"optional": true
},
{
"name": "withstatus",
"token": "WITHSTATUS",
"type": "pure-token",
"optional": true,
"since": "9.0.0"
},
{
"token": "LIMIT",
"name": "limit",

View file

@ -3510,14 +3510,14 @@ void zrangestoreCommand (client *c) {
zrangeGenericCommand(&handler, 2, 1, ZRANGE_AUTO, ZRANGE_DIRECTION_AUTO);
}
/* ZRANGE <key> <min> <max> [BYSCORE | BYLEX] [REV] [WITHSCORES] [LIMIT offset count] */
/* ZRANGE <key> <min> <max> [BYSCORE | BYLEX] [REV] [WITHSCORES] [WITHSTATUS] [LIMIT offset count] */
void zrangeCommand(client *c) {
zrange_result_handler handler;
zrangeResultHandlerInit(&handler, c, ZRANGE_CONSUMER_TYPE_CLIENT);
zrangeGenericCommand(&handler, 1, 0, ZRANGE_AUTO, ZRANGE_DIRECTION_AUTO);
}
/* ZREVRANGE <key> <start> <stop> [WITHSCORES] */
/* ZREVRANGE <key> <start> <stop> [WITHSCORES] [WITHSTATUS] */
void zrevrangeCommand(client *c) {
zrange_result_handler handler;
zrangeResultHandlerInit(&handler, c, ZRANGE_CONSUMER_TYPE_CLIENT);
@ -3629,14 +3629,14 @@ void genericZrangebyscoreCommand(zrange_result_handler *handler,
handler->finalizeResultEmission(handler, rangelen);
}
/* ZRANGEBYSCORE <key> <min> <max> [WITHSCORES] [LIMIT offset count] */
/* ZRANGEBYSCORE <key> <min> <max> [WITHSCORES] [WITHSTATUS] [LIMIT offset count] */
void zrangebyscoreCommand(client *c) {
zrange_result_handler handler;
zrangeResultHandlerInit(&handler, c, ZRANGE_CONSUMER_TYPE_CLIENT);
zrangeGenericCommand(&handler, 1, 0, ZRANGE_SCORE, ZRANGE_DIRECTION_FORWARD);
}
/* ZREVRANGEBYSCORE <key> <max> <min> [WITHSCORES] [LIMIT offset count] */
/* ZREVRANGEBYSCORE <key> <max> <min> [WITHSCORES] [WITHSTATUS] [LIMIT offset count] */
void zrevrangebyscoreCommand(client *c) {
zrange_result_handler handler;
zrangeResultHandlerInit(&handler, c, ZRANGE_CONSUMER_TYPE_CLIENT);
@ -3903,14 +3903,14 @@ void genericZrangebylexCommand(zrange_result_handler *handler,
handler->finalizeResultEmission(handler, rangelen);
}
/* ZRANGEBYLEX <key> <min> <max> [LIMIT offset count] */
/* ZRANGEBYLEX <key> <min> <max> [LIMIT offset count] [WITHSTATUS] */
void zrangebylexCommand(client *c) {
zrange_result_handler handler;
zrangeResultHandlerInit(&handler, c, ZRANGE_CONSUMER_TYPE_CLIENT);
zrangeGenericCommand(&handler, 1, 0, ZRANGE_LEX, ZRANGE_DIRECTION_FORWARD);
}
/* ZREVRANGEBYLEX <key> <max> <min> [LIMIT offset count] */
/* ZREVRANGEBYLEX <key> <max> <min> [LIMIT offset count] [WITHSTATUS] */
void zrevrangebylexCommand(client *c) {
zrange_result_handler handler;
zrangeResultHandlerInit(&handler, c, ZRANGE_CONSUMER_TYPE_CLIENT);
@ -3925,7 +3925,7 @@ void zrevrangebylexCommand(client *c) {
* other command pass explicit value.
*
* The argc_start points to the src key argument, so following syntax is like:
* <src> <min> <max> [BYSCORE | BYLEX] [REV] [WITHSCORES] [LIMIT offset count]
* <src> <min> <max> [BYSCORE | BYLEX] [REV] [WITHSCORES] [WITHSTATUS] [LIMIT offset count]
*/
void zrangeGenericCommand(zrange_result_handler *handler, int argc_start, int store,
zrange_type rangetype, zrange_direction direction)
@ -3942,6 +3942,7 @@ void zrangeGenericCommand(zrange_result_handler *handler, int argc_start, int st
long opt_start = 0;
long opt_end = 0;
int opt_withscores = 0;
int opt_withstatus = 0;
long opt_offset = 0;
long opt_limit = -1;
@ -3950,6 +3951,8 @@ void zrangeGenericCommand(zrange_result_handler *handler, int argc_start, int st
int leftargs = c->argc-j-1;
if (!store && !strcasecmp(c->argv[j]->ptr,"withscores")) {
opt_withscores = 1;
} else if (!store && !strcasecmp(c->argv[j]->ptr,"withstatus")) {
opt_withstatus = 1;
} else if (!strcasecmp(c->argv[j]->ptr,"limit") && leftargs >= 2) {
if ((getLongFromObjectOrReply(c, c->argv[j+1], &opt_offset, NULL) != C_OK) ||
(getLongFromObjectOrReply(c, c->argv[j+2], &opt_limit, NULL) != C_OK))
@ -4039,8 +4042,10 @@ void zrangeGenericCommand(zrange_result_handler *handler, int argc_start, int st
if (store) {
handler->beginResultEmission(handler, -1);
handler->finalizeResultEmission(handler, 0);
} else if (opt_withstatus) {
addReply(c, shared.nullarray[c->resp]);
} else {
addReply(c, shared.emptyarray);
addReply(c,shared.emptyarray);
}
goto cleanup;
}

View file

@ -58,14 +58,14 @@
# One-of choices: BLMOVE source destination LEFT|RIGHT LEFT|RIGHT timeout
"BLMOVE src dst LEFT " "LEFT|RIGHT timeout"
# Optional args can be in any order: ZRANGE key min max [BYSCORE|BYLEX] [REV] [LIMIT offset count] [WITHSCORES]
"ZRANGE k 1 2 " "[BYSCORE|BYLEX] [REV] [LIMIT offset count] [WITHSCORES]"
"ZRANGE k 1 2 bylex " "[REV] [LIMIT offset count] [WITHSCORES]"
"ZRANGE k 1 2 bylex rev " "[LIMIT offset count] [WITHSCORES]"
"ZRANGE k 1 2 limit 2 4 " "[BYSCORE|BYLEX] [REV] [WITHSCORES]"
"ZRANGE k 1 2 bylex rev limit 2 4 WITHSCORES " ""
"ZRANGE k 1 2 rev " "[BYSCORE|BYLEX] [LIMIT offset count] [WITHSCORES]"
"ZRANGE k 1 2 WITHSCORES " "[BYSCORE|BYLEX] [REV] [LIMIT offset count]"
# Optional args can be in any order: ZRANGE key min max [BYSCORE|BYLEX] [REV] [LIMIT offset count] [WITHSCORES] [WITHSTATUS]
"ZRANGE k 1 2 " "[BYSCORE|BYLEX] [REV] [LIMIT offset count] [WITHSCORES] [WITHSTATUS]"
"ZRANGE k 1 2 bylex " "[REV] [LIMIT offset count] [WITHSCORES] [WITHSTATUS]"
"ZRANGE k 1 2 bylex rev " "[LIMIT offset count] [WITHSCORES] [WITHSTATUS]"
"ZRANGE k 1 2 limit 2 4 " "[BYSCORE|BYLEX] [REV] [WITHSCORES] [WITHSTATUS]"
"ZRANGE k 1 2 bylex rev limit 2 4 WITHSCORES WITHSTATUS " ""
"ZRANGE k 1 2 rev " "[BYSCORE|BYLEX] [LIMIT offset count] [WITHSCORES] [WITHSTATUS]"
"ZRANGE k 1 2 WITHSCORES " "[BYSCORE|BYLEX] [REV] [LIMIT offset count] [WITHSTATUS]"
# Optional one-of args with parameters: SET key value [NX|XX|IFEQ ifeq-value|IFNE ifne-value|IFDEQ ifdeq-digest|IFDNE ifdne-digest] [GET] [EX seconds|PX milliseconds|EXAT unix-time-seconds|PXAT unix-time-milliseconds|KEEPTTL]
"SET key value " "[NX|XX|IFEQ ifeq-value|IFNE ifne-value|IFDEQ ifdeq-digest|IFDNE ifdne-digest] [GET] [EX seconds|PX milliseconds|EXAT unix-time-seconds|PXAT unix-time-milliseconds|KEEPTTL]"

View file

@ -454,6 +454,62 @@ start_server {tags {"zset"}} {
assert_equal {d 4 c 3 b 2 a 1} [r zrevrange ztmp 0 -1 withscores]
}
test "ZREVRANGE with/without WITHSTATUS - $encoding" {
r del ztmp
r zadd ztmp 1 a 2 b 3 c 4 d
# Test WITHSTATUS when key exists and has elements
assert_equal {d c b a} [r zrevrange ztmp 0 -1 WITHSTATUS]
# Test WITHSTATUS when key exists but is empty (no elements in range)
assert_equal {} [r zrevrange ztmp 10 20 WITHSTATUS]
# Test WITHSTATUS with WITHSCORES
assert_equal {d 4 c 3 b 2 a 1} [r zrevrange ztmp 0 -1 WITHSCORES WITHSTATUS]
# Test WITHSTATUS with ZREVRANGE and LIMIT
assert_equal {d c} [r zrevrange ztmp 0 1 WITHSTATUS]
# Test key does not exist - should return nullarray
assert_equal {} [r zrevrange non_existent_key 0 -1 WITHSTATUS]
# Test key exists but has no matching elements in range
assert_equal {} [r zrevrange ztmp 10 20 WITHSTATUS]
# Test nullarray vs emptyarray distinction in RESP3
r hello 3
r readraw 1
# Test nullarray (key does not exist) in RESP3
set null_res [r zrevrange non_existent_key 0 -1 WITHSTATUS]
assert_equal {_} $null_res
# Test emptyarray (key exists but no matching elements) in RESP3
set empty_res [r zrevrange ztmp 10 20 WITHSTATUS]
assert_equal {*0} $empty_res
r readraw 0
r hello 2
r readraw 1
# Test nullarray (key does not exist) in RESP2
set null_res [r zrevrange non_existent_key 0 -1 WITHSTATUS]
assert_equal {*-1} $null_res
# Test emptyarray (key exists but no matching elements) in RESP2
set empty_res [r zrevrange ztmp 10 20 WITHSTATUS]
assert_equal {*0} $empty_res
r readraw 0
# Test WITHSTATUS with LIMIT (using BYSCORE)
assert_equal {d c} [r zrevrangebyscore ztmp +inf -inf LIMIT 0 2 WITHSTATUS]
# Test WITHSTATUS with multiple modifiers
assert_equal {d 4 c 3} [r zrevrangebyscore ztmp +inf -inf LIMIT 0 2 WITHSCORES WITHSTATUS]
}
test "ZRANK/ZREVRANK basics - $encoding" {
set nullres {$-1}
if {$::force_resp3} {
@ -628,6 +684,64 @@ start_server {tags {"zset"}} {
assert_equal {} [r zrangebyscore zset 2 5 LIMIT 12 13 WITHSCORES]
}
test "ZRANGEBYSCORE with/without WITHSTATUS - $encoding" {
create_default_zset
# Test WITHSTATUS when key exists and has elements
assert_equal {b c d} [r zrangebyscore zset 0 3 WITHSTATUS]
# Test WITHSTATUS when key exists but is empty (no elements in range)
assert_equal {} [r zrangebyscore zset 10 20 WITHSTATUS]
# Test WITHSTATUS with WITHSCORES
assert_equal {b 1 c 2 d 3} [r zrangebyscore zset 0 3 WITHSCORES WITHSTATUS]
# Test WITHSTATUS with LIMIT
assert_equal {b c} [r zrangebyscore zset 0 3 LIMIT 0 2 WITHSTATUS]
# Test key does not exist - should return nullarray
assert_equal {} [r zrangebyscore non_existent_key 0 10 WITHSTATUS]
# Test nullarray vs emptyarray distinction in RESP3
r hello 3
r readraw 1
# Test nullarray (key does not exist) in RESP3
set null_res [r zrangebyscore non_existent_key 0 10 WITHSTATUS]
assert_equal {_} $null_res
# Test emptyarray (key exists but no matching elements) in RESP3
set empty_res [r zrangebyscore zset 10 20 WITHSTATUS]
assert_equal {*0} $empty_res
r readraw 0
r hello 2
r readraw 1
# Test nullarray (key does not exist) in RESP2
set null_res [r zrangebyscore non_existent_key 0 10 WITHSTATUS]
assert_equal {*-1} $null_res
# Test emptyarray (key exists but no matching elements) in RESP2
set empty_res [r zrangebyscore zset 10 20 WITHSTATUS]
assert_equal {*0} $empty_res
r readraw 0
# Test WITHSTATUS with ZREVRANGEBYSCORE
assert_equal {d c b} [r zrevrangebyscore zset 3 0 WITHSTATUS]
# Test WITHSTATUS with ZREVRANGEBYSCORE and WITHSCORES
assert_equal {d 3 c 2 b 1} [r zrevrangebyscore zset 3 0 WITHSCORES WITHSTATUS]
# Test WITHSTATUS with ZREVRANGEBYSCORE and LIMIT
assert_equal {d c} [r zrevrangebyscore zset 3 0 LIMIT 0 2 WITHSTATUS]
# Test WITHSTATUS with ZREVRANGEBYSCORE and LIMIT
assert_equal {d c} [r zrevrangebyscore zset 3 0 LIMIT 0 2 WITHSTATUS]
}
test "ZRANGEBYSCORE with non-value min or max - $encoding" {
assert_error "*not*float*" {r zrangebyscore fooz str 1}
assert_error "*not*float*" {r zrangebyscore fooz 1 str}
@ -726,6 +840,58 @@ start_server {tags {"zset"}} {
assert_equal {} [r zrevrangebylex zset + \[o LIMIT -1 5]
}
test "ZRANGEBYLEX with/without WITHSTATUS - $encoding" {
create_default_lex_zset
# Test WITHSTATUS when key exists and has elements
assert_equal {alpha bar cool} [r zrangebylex zset - \[cool WITHSTATUS]
# Test WITHSTATUS when key exists but is empty (no elements in range)
assert_equal {} [r zrangebylex zset \[zzz + WITHSTATUS]
# Test WITHSTATUS with LIMIT
assert_equal {alpha bar} [r zrangebylex zset - \[cool LIMIT 0 2 WITHSTATUS]
# Test key does not exist - should return nullarray
assert_equal {} [r zrangebylex non_existent_key - + WITHSTATUS]
# Test nullarray vs emptyarray distinction in RESP3
r hello 3
r readraw 1
# Test nullarray (key does not exist) in RESP3
set null_res [r zrangebylex non_existent_key - + WITHSTATUS]
assert_equal {_} $null_res
# Test emptyarray (key exists but no matching elements) in RESP3
set empty_res [r zrangebylex zset \[zzz + WITHSTATUS]
assert_equal {*0} $empty_res
r readraw 0
r hello 2
r readraw 1
# Test nullarray (key does not exist) in RESP2
set null_res [r zrangebylex non_existent_key - + WITHSTATUS]
assert_equal {*-1} $null_res
# Test emptyarray (key exists but no matching elements) in RESP2
set empty_res [r zrangebylex zset \[zzz + WITHSTATUS]
assert_equal {*0} $empty_res
r readraw 0
# Test WITHSTATUS with ZREVRANGEBYLEX
assert_equal {omega hill great} [r zrevrangebylex zset + \[g WITHSTATUS]
# Test WITHSTATUS with ZREVRANGEBYLEX and LIMIT
assert_equal {omega hill} [r zrevrangebylex zset + \[g LIMIT 0 2 WITHSTATUS]
# Test WITHSTATUS with ZREVRANGEBYLEX and LIMIT
assert_equal {omega hill} [r zrevrangebylex zset + \[g LIMIT 0 2 WITHSTATUS]
}
test "ZRANGEBYLEX with invalid lex range specifiers - $encoding" {
assert_error "*not*string*" {r zrangebylex fooz foo bar}
assert_error "*not*string*" {r zrangebylex fooz \[foo bar}
@ -2507,6 +2673,78 @@ start_server {tags {"zset"}} {
r config set zset-max-listpack-entries $original_max
}
test {ZRANGE with/without WITHSTATUS} {
# Test basic functionality with WITHSTATUS parameter
r zadd zset_withstatus 1 a 2 b 3 c
# Test WITHSTATUS when key exists and has elements
assert_equal {a b c} [r zrange zset_withstatus 0 -1 WITHSTATUS]
# Test WITHSTATUS when key exists but is empty (no elements in range)
r zadd zset_empty 1 a 2 b 3 c
assert_equal {} [r zrange zset_empty 10 20 WITHSTATUS]
# Test WITHSTATUS with WITHSCORES
assert_equal {a 1 b 2 c 3} [r zrange zset_withstatus 0 -1 WITHSCORES WITHSTATUS]
# Test WITHSTATUS with BYSCORE
assert_equal {a b c} [r zrange zset_withstatus 0 5 BYSCORE WITHSTATUS]
# Test WITHSTATUS with BYLEX
r zadd zset_lex 0 alpha 0 bar 0 cool
assert_equal {alpha bar} [r zrange zset_lex - \[bar BYLEX WITHSTATUS]
# Test WITHSTATUS with REV
assert_equal {c b a} [r zrange zset_withstatus 0 -1 REV WITHSTATUS]
# Test WITHSTATUS with LIMIT (only works with BYSCORE or BYLEX)
assert_equal {a b} [r zrange zset_withstatus 0 5 BYSCORE LIMIT 0 2 WITHSTATUS]
# Test WITHSTATUS with multiple modifiers
assert_equal {a 1 b 2} [r zrange zset_withstatus 0 5 BYSCORE LIMIT 0 2 WITHSCORES WITHSTATUS]
# Test key does not exist - should return nullarray
assert_equal {} [r zrange non_existent_key 0 -1 WITHSTATUS]
# Note: In RESP2, nullarray is represented as an empty array in the test framework
# but the actual protocol response would be different
# Test key exists but has no matching elements in range
assert_equal {} [r zrange zset_withstatus 10 20 WITHSTATUS]
# Test nullarray vs emptyarray distinction in RESP3
r hello 3
r readraw 1
# Test nullarray (key does not exist) in RESP3
set null_res [r zrange non_existent_key 0 -1 WITHSTATUS]
assert_equal {_} $null_res
# Test emptyarray (key exists but no matching elements) in RESP3
set empty_res [r zrange zset_withstatus 10 20 WITHSTATUS]
assert_equal {*0} $empty_res
r readraw 0
r hello 2
r readraw 1
# Test nullarray (key does not exist) in RESP2
set null_res [r zrange non_existent_key 0 -1 WITHSTATUS]
assert_equal {*-1} $null_res
# Test emptyarray (key exists but no matching elements) in RESP2
set empty_res [r zrange zset_withstatus 10 20 WITHSTATUS]
assert_equal {*0} $empty_res
r readraw 0
# Test WITHSTATUS without other parameters (should work like normal ZRANGE)
assert_equal {a b c} [r zrange zset_withstatus 0 -1 WITHSTATUS]
# Test WITHSTATUS with WITHSCORES (should work together)
assert_equal {a 1 b 2 c 3} [r zrange zset_withstatus 0 -1 WITHSCORES WITHSTATUS]
}
test {ZRANGE invalid syntax} {
catch {r zrange z1{t} 0 -1 limit 1 2} err
assert_match "*syntax*" $err