X-Git-Url: https://git.saurik.com/redis.git/blobdiff_plain/12d293ca6edab6cc94cbd90840c629a535a12aef..01e95705f8d4b0d21cf892748eaf153f16fbf947:/src/t_string.c diff --git a/src/t_string.c b/src/t_string.c index ce6233a9..2bd1646e 100644 --- a/src/t_string.c +++ b/src/t_string.c @@ -1,4 +1,5 @@ #include "redis.h" +#include /* isnan(), isinf() */ /*----------------------------------------------------------------------------- * String Commands @@ -382,6 +383,39 @@ void decrbyCommand(redisClient *c) { incrDecrCommand(c,-incr); } +void incrbyfloatCommand(redisClient *c) { + long double incr, value; + robj *o, *new, *aux; + + o = lookupKeyWrite(c->db,c->argv[1]); + if (o != NULL && checkType(c,o,REDIS_STRING)) return; + if (getLongDoubleFromObjectOrReply(c,o,&value,NULL) != REDIS_OK || + getLongDoubleFromObjectOrReply(c,c->argv[2],&incr,NULL) != REDIS_OK) + return; + + value += incr; + if (isnan(value) || isinf(value)) { + addReplyError(c,"increment would produce NaN or Infinity"); + return; + } + new = createStringObjectFromLongDouble(value); + if (o) + dbOverwrite(c->db,c->argv[1],new); + else + dbAdd(c->db,c->argv[1],new); + signalModifiedKey(c->db,c->argv[1]); + server.dirty++; + addReplyBulk(c,new); + + /* Always replicate INCRBYFLOAT as a SET command with the final value + * in order to make sure that differences in float pricision or formatting + * will not create differences in replicas or after an AOF restart. */ + aux = createStringObject("SET",3); + rewriteClientCommandArgument(c,0,aux); + decrRefCount(aux); + rewriteClientCommandArgument(c,2,new); +} + void appendCommand(redisClient *c) { size_t totlen; robj *o, *append;