From 913070a9e85170e89176e5dc9488263cc7327085 Mon Sep 17 00:00:00 2001 From: antirez Date: Tue, 20 Dec 2016 10:12:38 +0100 Subject: Geo: fix edge case return values for uniformity. There were two cases outlined in issue #3512 and PR #3551 where the Geo API returned unexpected results: empty strings where NULL replies were expected, or a single null reply where an array was expected. This violates the Redis principle that Redis replies for existing keys or elements should be indistinguishable. This is technically an API breakage so will be merged only into 4.0 and specified in the changelog in the list of breaking compatibilities, even if it is not very likely that actual code will be affected, hopefully, since with the past behavior basically there was to acconut for *both* the possibilities, and the new behavior is always one of the two, but in a consistent way. --- src/geo.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/geo.c b/src/geo.c index 46022bdde..e1d026f1e 100644 --- a/src/geo.c +++ b/src/geo.c @@ -161,7 +161,7 @@ double extractDistanceOrReply(client *c, robj **argv, addReplyError(c,"radius cannot be negative"); return -1; } - + double to_meters = extractUnitOrReply(c,argv[1]); if (to_meters < 0) { return -1; @@ -738,16 +738,15 @@ void geoposCommand(client *c) { int j; /* Look up the requested zset */ - robj *zobj = NULL; - if ((zobj = lookupKeyReadOrReply(c, c->argv[1], shared.emptymultibulk)) - == NULL || checkType(c, zobj, OBJ_ZSET)) return; + robj *zobj = lookupKeyRead(c->db, c->argv[1]); + if (zobj && checkType(c, zobj, OBJ_ZSET)) return; /* Report elements one after the other, using a null bulk reply for * missing elements. */ addReplyMultiBulkLen(c,c->argc-2); for (j = 2; j < c->argc; j++) { double score; - if (zsetScore(zobj, c->argv[j]->ptr, &score) == C_ERR) { + if (!zobj || zsetScore(zobj, c->argv[j]->ptr, &score) == C_ERR) { addReply(c,shared.nullmultibulk); } else { /* Decode... */ @@ -782,7 +781,7 @@ void geodistCommand(client *c) { /* Look up the requested zset */ robj *zobj = NULL; - if ((zobj = lookupKeyReadOrReply(c, c->argv[1], shared.emptybulk)) + if ((zobj = lookupKeyReadOrReply(c, c->argv[1], shared.nullbulk)) == NULL || checkType(c, zobj, OBJ_ZSET)) return; /* Get the scores. We need both otherwise NULL is returned. */ -- cgit v1.2.1