mirror of
https://github.com/redis/redis.git
synced 2026-05-28 04:02:46 -04:00
Merge 7264cf80f3 into 138263a1b4
This commit is contained in:
commit
afdee127a7
8 changed files with 295 additions and 20 deletions
|
|
@ -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},
|
||||
|
|
|
|||
|
|
@ -131,6 +131,13 @@
|
|||
"token": "WITHSCORES",
|
||||
"type": "pure-token",
|
||||
"optional": true
|
||||
},
|
||||
{
|
||||
"name": "withstatus",
|
||||
"token": "WITHSTATUS",
|
||||
"type": "pure-token",
|
||||
"optional": true,
|
||||
"since": "9.0.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -88,6 +88,13 @@
|
|||
"token": "WITHSCORES",
|
||||
"type": "pure-token",
|
||||
"optional": true
|
||||
},
|
||||
{
|
||||
"name": "withstatus",
|
||||
"token": "WITHSTATUS",
|
||||
"type": "pure-token",
|
||||
"optional": true,
|
||||
"since": "9.0.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
21
src/t_zset.c
21
src/t_zset.c
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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]"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue