GEOADD - add [CH] [NX|XX] options (#8227)

New command flags similar to what SADD already has.

Co-authored-by: huangwei03 <huangwei03@kuaishou.com>
Co-authored-by: Itamar Haber <itamar@redislabs.com>
Co-authored-by: Oran Agra <oran@redislabs.com>
This commit is contained in:
kukey 2021-01-03 23:13:37 +08:00 committed by GitHub
parent 91690a2920
commit 33fb617053
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 71 additions and 14 deletions

View File

@ -428,31 +428,45 @@ static int sort_gp_desc(const void *a, const void *b) {
* Commands
* ==================================================================== */
/* GEOADD key long lat name [long2 lat2 name2 ... longN latN nameN] */
/* GEOADD key [CH] [NX|XX] long lat name [long2 lat2 name2 ... longN latN nameN] */
void geoaddCommand(client *c) {
/* Check arguments number for sanity. */
if ((c->argc - 2) % 3 != 0) {
int xx = 0, nx = 0, longidx = 2;
int i;
/* Parse options. At the end 'longidx' is set to the argument position
* of the longitude of the first element. */
while (longidx < c->argc) {
char *opt = c->argv[longidx]->ptr;
if (!strcasecmp(opt,"nx")) nx = 1;
else if (!strcasecmp(opt,"xx")) xx = 1;
else if (!strcasecmp(opt,"ch")) {}
else break;
longidx++;
}
if ((c->argc - longidx) % 3 || (xx && nx)) {
/* Need an odd number of arguments if we got this far... */
addReplyError(c, "syntax error. Try GEOADD key [x1] [y1] [name1] "
"[x2] [y2] [name2] ... ");
addReplyErrorObject(c,shared.syntaxerr);
return;
}
int elements = (c->argc - 2) / 3;
int argc = 2+elements*2; /* ZADD key score ele ... */
/* Set up the vector for calling ZADD. */
int elements = (c->argc - longidx) / 3;
int argc = longidx+elements*2; /* ZADD key [CH] [NX|XX] score ele ... */
robj **argv = zcalloc(argc*sizeof(robj*));
argv[0] = createRawStringObject("zadd",4);
argv[1] = c->argv[1]; /* key */
incrRefCount(argv[1]);
for (i = 1; i < longidx; i++) {
argv[i] = c->argv[i];
incrRefCount(argv[i]);
}
/* Create the argument vector to call ZADD in order to add all
* the score,value pairs to the requested zset, where score is actually
* an encoded version of lat,long. */
int i;
for (i = 0; i < elements; i++) {
double xy[2];
if (extractLongLatOrReply(c, (c->argv+2)+(i*3),xy) == C_ERR) {
if (extractLongLatOrReply(c, (c->argv+longidx)+(i*3),xy) == C_ERR) {
for (i = 0; i < argc; i++)
if (argv[i]) decrRefCount(argv[i]);
zfree(argv);
@ -464,9 +478,9 @@ void geoaddCommand(client *c) {
geohashEncodeWGS84(xy[0], xy[1], GEO_STEP_MAX, &hash);
GeoHashFix52Bits bits = geohashAlign52Bits(hash);
robj *score = createObject(OBJ_STRING, sdsfromlonglong(bits));
robj *val = c->argv[2 + i * 3 + 2];
argv[2+i*2] = score;
argv[3+i*2] = val;
robj *val = c->argv[longidx + i * 3 + 2];
argv[longidx+i*2] = score;
argv[longidx+1+i*2] = val;
incrRefCount(val);
}

View File

@ -74,6 +74,49 @@ start_server {tags {"geo"}} {
r geoadd nyc -73.9454966 40.747533 "lic market"
} {0}
test {GEOADD update with CH option} {
assert_equal 1 [r geoadd nyc CH 40.747533 -73.9454966 "lic market"]
lassign [lindex [r geopos nyc "lic market"] 0] x1 y1
assert {abs($x1) - 40.747 < 0.001}
assert {abs($y1) - 73.945 < 0.001}
} {}
test {GEOADD update with NX option} {
assert_equal 0 [r geoadd nyc NX -73.9454966 40.747533 "lic market"]
lassign [lindex [r geopos nyc "lic market"] 0] x1 y1
assert {abs($x1) - 40.747 < 0.001}
assert {abs($y1) - 73.945 < 0.001}
} {}
test {GEOADD update with XX option} {
assert_equal 0 [r geoadd nyc XX -83.9454966 40.747533 "lic market"]
lassign [lindex [r geopos nyc "lic market"] 0] x1 y1
assert {abs($x1) - 83.945 < 0.001}
assert {abs($y1) - 40.747 < 0.001}
} {}
test {GEOADD update with CH NX option} {
r geoadd nyc CH NX -73.9454966 40.747533 "lic market"
} {0}
test {GEOADD update with CH XX option} {
r geoadd nyc CH XX -73.9454966 40.747533 "lic market"
} {1}
test {GEOADD update with XX NX option will return syntax error} {
catch {
r geoadd nyc xx nx -73.9454966 40.747533 "lic market"
} err
set err
} {ERR*syntax*}
test {GEOADD update with invalid option} {
catch {
r geoadd nyc ch xx foo -73.9454966 40.747533 "lic market"
} err
set err
} {ERR*syntax*}
test {GEOADD invalid coordinates} {
catch {
r geoadd nyc -73.9454966 40.747533 "lic market" \