Fix use of lookupKeyRead and lookupKeyWrite in zrangeGenericCommand, zunionInterDiffGenericCommand (#8316)

* Change zunionInterDiffGenericCommand to use lookupKeyRead if dstkey is null
* Change zrangeGenericCommand to use lookupKey Write if dstkey isn't null

ZRANGESTORE and UNION, ZINTER, ZDIFF are all new commands (6.2 RC1 and RC2).
In redis 6.0 the ZRANGE was using lookupKeyRead, and ZUNIONSTORE / ZINTERSTORE were using lookupKeyWrite.
So there bugs are introduced in 6.2 and will be resolved before it is released.

the implications of this bug are also not big:
The sole difference between LookupKeyRead and LookupKeyWrite is for command executed on a replica, which are not received from its master client. (for the master, and for the master client on the replica, these two functions behave the same)!
This commit is contained in:
sundb 2021-01-13 17:58:12 +08:00 committed by GitHub
parent 593cde16bc
commit 8a81ed1b5a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -2543,7 +2543,9 @@ void zunionInterDiffGenericCommand(client *c, robj *dstkey, int numkeysIndex, in
/* read keys to be used for input */ /* read keys to be used for input */
src = zcalloc(sizeof(zsetopsrc) * setnum); src = zcalloc(sizeof(zsetopsrc) * setnum);
for (i = 0, j = numkeysIndex+1; i < setnum; i++, j++) { for (i = 0, j = numkeysIndex+1; i < setnum; i++, j++) {
robj *obj = lookupKeyWrite(c->db,c->argv[j]); robj *obj = dstkey ?
lookupKeyWrite(c->db,c->argv[j]) :
lookupKeyRead(c->db,c->argv[j]);
if (obj != NULL) { if (obj != NULL) {
if (obj->type != OBJ_ZSET && obj->type != OBJ_SET) { if (obj->type != OBJ_ZSET && obj->type != OBJ_SET) {
zfree(src); zfree(src);
@ -3605,11 +3607,16 @@ void zrangeGenericCommand(zrange_result_handler *handler, int argc_start, int st
} }
/* Step 3: Lookup the key and get the range. */ /* Step 3: Lookup the key and get the range. */
if (((zobj = lookupKeyReadOrReply(c, key, shared.emptyarray)) == NULL) zobj = handler->dstkey ?
|| checkType(c, zobj, OBJ_ZSET)) { lookupKeyWrite(c->db,key) :
lookupKeyRead(c->db,key);
if (zobj == NULL) {
addReply(c,shared.emptyarray);
goto cleanup; goto cleanup;
} }
if (checkType(c,zobj,OBJ_ZSET)) goto cleanup;
/* Step 4: Pass this to the command-specific handler. */ /* Step 4: Pass this to the command-specific handler. */
switch (rangetype) { switch (rangetype) {
case ZRANGE_AUTO: case ZRANGE_AUTO: