diff --git a/src/server.c b/src/server.c index 5b3b434df..fb308e5f8 100644 --- a/src/server.c +++ b/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; diff --git a/src/server.h b/src/server.h index d003ce59a..31d253066 100644 --- a/src/server.h +++ b/src/server.h @@ -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, diff --git a/src/t_hash.c b/src/t_hash.c index bc70e4051..e6ed33819 100644 --- a/src/t_hash.c +++ b/src/t_hash.c @@ -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. */ diff --git a/src/t_list.c b/src/t_list.c index 54e4959b9..601ea8899 100644 --- a/src/t_list.c +++ b/src/t_list.c @@ -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; diff --git a/src/t_set.c b/src/t_set.c index 05d9ee243..abbf82fde 100644 --- a/src/t_set.c +++ b/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; } diff --git a/src/t_zset.c b/src/t_zset.c index 2680e76a9..ea6f4b848 100644 --- a/src/t_zset.c +++ b/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; }