diff options
author | Jason Elbaum <jason.elbaum@gmail.com> | 2021-06-16 09:29:57 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-16 09:29:57 +0300 |
commit | 7f342020dcbdf9abe754d6b666efdeded7063870 (patch) | |
tree | f8df3fee44bde136817fe4c03d2f639fd0fc6ff8 /src/t_zset.c | |
parent | c7e502a07bdeec29c2be41da70b483b2156d36db (diff) | |
download | redis-7f342020dcbdf9abe754d6b666efdeded7063870.tar.gz |
Change return value type for ZPOPMAX/MIN in RESP3 (#8981)
When using RESP3, ZPOPMAX/ZPOPMIN should return nested arrays for consistency
with other commands (e.g. ZRANGE).
We do that only when COUNT argument is present (similarly to how LPOP behaves).
for reasoning see https://github.com/redis/redis/issues/8824#issuecomment-855427955
This is a breaking change only when RESP3 is used, and COUNT argument is present!
Diffstat (limited to 'src/t_zset.c')
-rw-r--r-- | src/t_zset.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/src/t_zset.c b/src/t_zset.c index 08c00909a..8dbbfd32a 100644 --- a/src/t_zset.c +++ b/src/t_zset.c @@ -3817,11 +3817,16 @@ void genericZpopCommand(client *c, robj **keyv, int keyc, int where, int emitkey } void *arraylen_ptr = addReplyDeferredLen(c); - long arraylen = 0; + long result_count = 0; /* We emit the key only for the blocking variant. */ if (emitkey) addReplyBulk(c,key); + /* Respond with a single (flat) array in RESP2 or if countarg is not + * provided (returning a single element). In RESP3, when countarg is + * provided, use nested array. */ + int use_nested_array = c->resp > 2 && countarg != NULL; + /* Remove the element. */ do { if (zobj->encoding == OBJ_ENCODING_ZIPLIST) { @@ -3864,16 +3869,19 @@ void genericZpopCommand(client *c, robj **keyv, int keyc, int where, int emitkey serverAssertWithInfo(c,zobj,zsetDel(zobj,ele)); server.dirty++; - if (arraylen == 0) { /* Do this only for the first iteration. */ + if (result_count == 0) { /* Do this only for the first iteration. */ char *events[2] = {"zpopmin","zpopmax"}; notifyKeyspaceEvent(NOTIFY_ZSET,events[where],key,c->db->id); signalModifiedKey(c,c->db,key); } + if (use_nested_array) { + addReplyArrayLen(c,2); + } addReplyBulkCBuffer(c,ele,sdslen(ele)); addReplyDouble(c,score); sdsfree(ele); - arraylen += 2; + ++result_count; /* Remove the key, if indeed needed. */ if (zsetLength(zobj) == 0) { @@ -3883,7 +3891,10 @@ void genericZpopCommand(client *c, robj **keyv, int keyc, int where, int emitkey } } while(--count); - setDeferredArrayLen(c,arraylen_ptr,arraylen + (emitkey != 0)); + if (!use_nested_array) { + result_count *= 2; + } + setDeferredArrayLen(c,arraylen_ptr,result_count + (emitkey != 0)); } /* ZPOPMIN key [<count>] */ |