diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b9bebf2e2..2578b8b99 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,9 +38,14 @@ jobs: run: | sudo apt-get -y install tcl8.5 ./runtest --clients 2 --verbose +<<<<<<< HEAD - name: module tests run: | ./runtest-moduleapi +======= + - name: module api test + run: ./runtest-moduleapi --clients 2 --verbose +>>>>>>> 024c380b9da02bc4112822c0f5f9ac1388b4205b build-ubuntu-old: runs-on: ubuntu-16.04 diff --git a/src/db.cpp b/src/db.cpp index 81e32f849..0e4d96277 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -314,7 +314,7 @@ int dbMerge(redisDb *db, robj *key, robj *val, int fReplace) * unless 'keepttl' is true. * * All the new keys in the database should be created via this interface. */ -void genericSetKey(redisDb *db, robj *key, robj *val, int keepttl) { +void genericSetKey(redisDb *db, robj *key, robj *val, int keepttl, int signal) { dictEntry *de = dictFind(db->pdict, ptrFromObj(key)); if (de == NULL) { dbAdd(db,key,val); @@ -323,12 +323,12 @@ void genericSetKey(redisDb *db, robj *key, robj *val, int keepttl) { dbOverwriteCore(db,de,key,val,!!g_pserver->fActiveReplica,!keepttl); } incrRefCount(val); - signalModifiedKey(db,key); + if (signal) signalModifiedKey(db,key); } /* Common case for genericSetKey() where the TTL is not retained. */ void setKey(redisDb *db, robj *key, robj *val) { - genericSetKey(db,key,val,0); + genericSetKey(db,key,val,0,1); } /* Return true if the specified key exists in the specified database. diff --git a/src/module.cpp b/src/module.cpp index 0c59ee48d..b57dc55b1 100644 --- a/src/module.cpp +++ b/src/module.cpp @@ -2231,7 +2231,7 @@ RedisModuleString *RM_RandomKey(RedisModuleCtx *ctx) { int RM_StringSet(RedisModuleKey *key, RedisModuleString *str) { if (!(key->mode & REDISMODULE_WRITE) || key->iter) return REDISMODULE_ERR; RM_DeleteKey(key); - setKey(key->db,key->key,str); + genericSetKey(key->db,key->key,str,0,0); key->value = str; return REDISMODULE_OK; } @@ -2311,7 +2311,7 @@ int RM_StringTruncate(RedisModuleKey *key, size_t newlen) { if (key->value == NULL) { /* Empty key: create it with the new size. */ robj *o = createObject(OBJ_STRING,sdsnewlen(NULL, newlen)); - setKey(key->db,key->key,o); + genericSetKey(key->db,key->key,o,0,0); key->value = o; decrRefCount(o); } else { @@ -3701,7 +3701,7 @@ int RM_ModuleTypeSetValue(RedisModuleKey *key, moduleType *mt, void *value) { if (!(key->mode & REDISMODULE_WRITE) || key->iter) return REDISMODULE_ERR; RM_DeleteKey(key); robj *o = createModuleObject(mt,value); - setKey(key->db,key->key,o); + genericSetKey(key->db,key->key,o,0,0); decrRefCount(o); key->value = o; return REDISMODULE_OK; @@ -6107,7 +6107,7 @@ sds modulesCollectInfo(sds info, const char *section, int for_crash_report, int struct RedisModule *module = (RedisModule*)dictGetVal(de); if (!module->info_cb) continue; - RedisModuleInfoCtx info_ctx = {module, section, info, sections, 0}; + RedisModuleInfoCtx info_ctx = {module, section, info, sections, 0, 0}; module->info_cb(&info_ctx, for_crash_report); /* Implicitly end dicts (no way to handle errors, and we must add the newline). */ if (info_ctx.in_dict_field) diff --git a/src/server.h b/src/server.h index 85da1fe9b..e911034d2 100644 --- a/src/server.h +++ b/src/server.h @@ -2646,7 +2646,7 @@ int objectSetLRUOrLFU(robj *val, long long lfu_freq, long long lru_idle, void dbAdd(redisDb *db, robj *key, robj *val); void dbOverwrite(redisDb *db, robj *key, robj *val); int dbMerge(redisDb *db, robj *key, robj *val, int fReplace); -void genericSetKey(redisDb *db, robj *key, robj *val, int keepttl); +void genericSetKey(redisDb *db, robj *key, robj *val, int keepttl, int signal); void setKey(redisDb *db, robj *key, robj *val); int dbExists(redisDb *db, robj *key); robj *dbRandomKey(redisDb *db); diff --git a/src/t_string.cpp b/src/t_string.cpp index 6868b4168..c9c6ed729 100644 --- a/src/t_string.cpp +++ b/src/t_string.cpp @@ -84,7 +84,7 @@ void setGenericCommand(client *c, int flags, robj *key, robj *val, robj *expire, addReply(c, abort_reply ? abort_reply : shared.null[c->resp]); return; } - genericSetKey(c->db,key,val,flags & OBJ_SET_KEEPTTL); + genericSetKey(c->db,key,val,flags & OBJ_SET_KEEPTTL,1); g_pserver->dirty++; if (expire) setExpire(c,c->db,key,nullptr,mstime()+milliseconds); notifyKeyspaceEvent(NOTIFY_STRING,"set",key,c->db->id); diff --git a/src/util.c b/src/util.c index 2be42a0df..bd8f0fb98 100644 --- a/src/util.c +++ b/src/util.c @@ -602,6 +602,10 @@ int ld2string(char *buf, size_t len, long double value, ld2string_mode mode) { } if (*p == '.') l--; } + if (l == 2 && buf[0] == '-' && buf[1] == '0') { + buf[0] = '0'; + l = 1; + } break; default: return 0; /* Invalid mode. */ } diff --git a/tests/unit/type/incr.tcl b/tests/unit/type/incr.tcl index a58710d39..b7a135203 100644 --- a/tests/unit/type/incr.tcl +++ b/tests/unit/type/incr.tcl @@ -151,4 +151,11 @@ start_server {tags {"incr"}} { catch {r incrbyfloat foo 1} err format $err } {ERR*valid*} + + test {No negative zero} { + r del foo + r incrbyfloat foo [expr double(1)/41] + r incrbyfloat foo [expr double(-1)/41] + r get foo + } {0} }