RESP3: fix cases of NULL reported instead of empty aggregate.
This commit is contained in:
parent
b12ccc840e
commit
06d490342f
10
src/server.c
10
src/server.c
@ -2161,6 +2161,16 @@ void createSharedObjects(void) {
|
||||
shared.nullarray[2] = createObject(OBJ_STRING,sdsnew("*-1\r\n"));
|
||||
shared.nullarray[3] = createObject(OBJ_STRING,sdsnew("_\r\n"));
|
||||
|
||||
shared.emptymap[0] = NULL;
|
||||
shared.emptymap[1] = NULL;
|
||||
shared.emptymap[2] = createObject(OBJ_STRING,sdsnew("*0\r\n"));
|
||||
shared.emptymap[3] = createObject(OBJ_STRING,sdsnew("%0\r\n"));
|
||||
|
||||
shared.emptyset[0] = NULL;
|
||||
shared.emptyset[1] = NULL;
|
||||
shared.emptyset[2] = createObject(OBJ_STRING,sdsnew("*0\r\n"));
|
||||
shared.emptyset[3] = createObject(OBJ_STRING,sdsnew("~0\r\n"));
|
||||
|
||||
for (j = 0; j < PROTO_SHARED_SELECT_CMDS; j++) {
|
||||
char dictid_str[64];
|
||||
int dictid_len;
|
||||
|
@ -897,7 +897,7 @@ struct moduleLoadQueueEntry {
|
||||
|
||||
struct sharedObjectsStruct {
|
||||
robj *crlf, *ok, *err, *emptybulk, *czero, *cone, *pong, *space,
|
||||
*colon, *queued, *null[4], *nullarray[4],
|
||||
*colon, *queued, *null[4], *nullarray[4], *emptymap[4], *emptyset[4],
|
||||
*emptyarray, *wrongtypeerr, *nokeyerr, *syntaxerr, *sameobjecterr,
|
||||
*outofrangeerr, *noscripterr, *loadingerr, *slowscripterr, *bgsaveerr,
|
||||
*masterdownerr, *roslaveerr, *execaborterr, *noautherr, *noreplicaserr,
|
||||
|
@ -772,8 +772,8 @@ void genericHgetallCommand(client *c, int flags) {
|
||||
hashTypeIterator *hi;
|
||||
int length, count = 0;
|
||||
|
||||
if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.null[c->resp])) == NULL
|
||||
|| checkType(c,o,OBJ_HASH)) return;
|
||||
if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.emptymap[c->resp]))
|
||||
== NULL || checkType(c,o,OBJ_HASH)) return;
|
||||
|
||||
/* We return a map if the user requested keys and values, like in the
|
||||
* HGETALL case. Otherwise to use a flat array makes more sense. */
|
||||
|
@ -402,7 +402,7 @@ void lrangeCommand(client *c) {
|
||||
if ((getLongFromObjectOrReply(c, c->argv[2], &start, NULL) != C_OK) ||
|
||||
(getLongFromObjectOrReply(c, c->argv[3], &end, NULL) != C_OK)) return;
|
||||
|
||||
if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.null[c->resp])) == NULL
|
||||
if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.emptyarray)) == NULL
|
||||
|| checkType(c,o,OBJ_LIST)) return;
|
||||
llen = listTypeLength(o);
|
||||
|
||||
@ -414,7 +414,7 @@ void lrangeCommand(client *c) {
|
||||
/* Invariant: start >= 0, so this test will be true when end < 0.
|
||||
* The range is empty when start > end or start >= length. */
|
||||
if (start > end || start >= llen) {
|
||||
addReplyNull(c);
|
||||
addReply(c,shared.emptyarray);
|
||||
return;
|
||||
}
|
||||
if (end >= llen) end = llen-1;
|
||||
|
10
src/t_set.c
10
src/t_set.c
@ -418,10 +418,10 @@ void spopWithCountCommand(client *c) {
|
||||
if ((set = lookupKeyWriteOrReply(c,c->argv[1],shared.null[c->resp]))
|
||||
== NULL || checkType(c,set,OBJ_SET)) return;
|
||||
|
||||
/* If count is zero, serve an empty multibulk ASAP to avoid special
|
||||
/* If count is zero, serve an empty set ASAP to avoid special
|
||||
* cases later. */
|
||||
if (count == 0) {
|
||||
addReplyNull(c);
|
||||
addReply(c,shared.emptyset[c->resp]);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -632,13 +632,13 @@ void srandmemberWithCountCommand(client *c) {
|
||||
uniq = 0;
|
||||
}
|
||||
|
||||
if ((set = lookupKeyReadOrReply(c,c->argv[1],shared.null[c->resp]))
|
||||
if ((set = lookupKeyReadOrReply(c,c->argv[1],shared.emptyset[c->resp]))
|
||||
== NULL || checkType(c,set,OBJ_SET)) return;
|
||||
size = setTypeSize(set);
|
||||
|
||||
/* If count is zero, serve it ASAP to avoid special cases later. */
|
||||
if (count == 0) {
|
||||
addReplyNull(c);
|
||||
addReply(c,shared.emptyset[c->resp]);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -813,7 +813,7 @@ void sinterGenericCommand(client *c, robj **setkeys,
|
||||
}
|
||||
addReply(c,shared.czero);
|
||||
} else {
|
||||
addReplyNull(c);
|
||||
addReply(c,shared.emptyset[c->resp]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
18
src/t_zset.c
18
src/t_zset.c
@ -2426,7 +2426,7 @@ void zrangeGenericCommand(client *c, int reverse) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((zobj = lookupKeyReadOrReply(c,key,shared.null[c->resp])) == NULL
|
||||
if ((zobj = lookupKeyReadOrReply(c,key,shared.emptyarray)) == NULL
|
||||
|| checkType(c,zobj,OBJ_ZSET)) return;
|
||||
|
||||
/* Sanitize indexes. */
|
||||
@ -2438,7 +2438,7 @@ void zrangeGenericCommand(client *c, int reverse) {
|
||||
/* Invariant: start >= 0, so this test will be true when end < 0.
|
||||
* The range is empty when start > end or start >= length. */
|
||||
if (start > end || start >= llen) {
|
||||
addReplyNull(c);
|
||||
addReply(c,shared.emptyarray);
|
||||
return;
|
||||
}
|
||||
if (end >= llen) end = llen-1;
|
||||
@ -2574,7 +2574,7 @@ void genericZrangebyscoreCommand(client *c, int reverse) {
|
||||
}
|
||||
|
||||
/* Ok, lookup the key and get the range */
|
||||
if ((zobj = lookupKeyReadOrReply(c,key,shared.null[c->resp])) == NULL ||
|
||||
if ((zobj = lookupKeyReadOrReply(c,key,shared.emptyarray)) == NULL ||
|
||||
checkType(c,zobj,OBJ_ZSET)) return;
|
||||
|
||||
if (zobj->encoding == OBJ_ENCODING_ZIPLIST) {
|
||||
@ -2594,7 +2594,7 @@ void genericZrangebyscoreCommand(client *c, int reverse) {
|
||||
|
||||
/* No "first" element in the specified interval. */
|
||||
if (eptr == NULL) {
|
||||
addReplyNull(c);
|
||||
addReply(c,shared.emptyarray);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2661,7 +2661,7 @@ void genericZrangebyscoreCommand(client *c, int reverse) {
|
||||
|
||||
/* No "first" element in the specified interval. */
|
||||
if (ln == NULL) {
|
||||
addReplyNull(c);
|
||||
addReply(c,shared.emptyarray);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2919,7 +2919,7 @@ void genericZrangebylexCommand(client *c, int reverse) {
|
||||
}
|
||||
|
||||
/* Ok, lookup the key and get the range */
|
||||
if ((zobj = lookupKeyReadOrReply(c,key,shared.null[c->resp])) == NULL ||
|
||||
if ((zobj = lookupKeyReadOrReply(c,key,shared.emptyarray)) == NULL ||
|
||||
checkType(c,zobj,OBJ_ZSET))
|
||||
{
|
||||
zslFreeLexRange(&range);
|
||||
@ -2942,7 +2942,7 @@ void genericZrangebylexCommand(client *c, int reverse) {
|
||||
|
||||
/* No "first" element in the specified interval. */
|
||||
if (eptr == NULL) {
|
||||
addReplyNull(c);
|
||||
addReply(c,shared.emptyarray);
|
||||
zslFreeLexRange(&range);
|
||||
return;
|
||||
}
|
||||
@ -3006,7 +3006,7 @@ void genericZrangebylexCommand(client *c, int reverse) {
|
||||
|
||||
/* No "first" element in the specified interval. */
|
||||
if (ln == NULL) {
|
||||
addReplyNull(c);
|
||||
addReply(c,shared.emptyarray);
|
||||
zslFreeLexRange(&range);
|
||||
return;
|
||||
}
|
||||
@ -3160,7 +3160,7 @@ void genericZpopCommand(client *c, robj **keyv, int keyc, int where, int emitkey
|
||||
|
||||
/* No candidate for zpopping, return empty. */
|
||||
if (!zobj) {
|
||||
addReplyNull(c);
|
||||
addReply(c,shared.emptyarray);
|
||||
return;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user