summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/db.c6
-rw-r--r--src/module.c6
-rw-r--r--src/quicklist.c4
-rw-r--r--src/server.c10
-rw-r--r--src/server.h2
-rw-r--r--src/t_stream.c5
-rw-r--r--src/t_string.c2
-rw-r--r--tests/unit/scripting.tcl11
-rw-r--r--tests/unit/type/incr.tcl1
9 files changed, 32 insertions, 15 deletions
diff --git a/src/db.c b/src/db.c
index 211bb978d..cadfeb77b 100644
--- a/src/db.c
+++ b/src/db.c
@@ -221,7 +221,7 @@ void dbOverwrite(redisDb *db, robj *key, robj *val) {
* 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) {
if (lookupKeyWrite(db,key) == NULL) {
dbAdd(db,key,val);
} else {
@@ -229,12 +229,12 @@ void genericSetKey(redisDb *db, robj *key, robj *val, int keepttl) {
}
incrRefCount(val);
if (!keepttl) removeExpire(db,key);
- 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.c b/src/module.c
index 64f274e78..4d3d9e1af 100644
--- a/src/module.c
+++ b/src/module.c
@@ -2157,7 +2157,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;
}
@@ -2237,7 +2237,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 {
@@ -3625,7 +3625,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;
diff --git a/src/quicklist.c b/src/quicklist.c
index ae183ffd8..52e3988f5 100644
--- a/src/quicklist.c
+++ b/src/quicklist.c
@@ -110,7 +110,7 @@ quicklist *quicklistCreate(void) {
return quicklist;
}
-#define COMPRESS_MAX (1 << QL_COMP_BITS)
+#define COMPRESS_MAX ((1 << QL_COMP_BITS)-1)
void quicklistSetCompressDepth(quicklist *quicklist, int compress) {
if (compress > COMPRESS_MAX) {
compress = COMPRESS_MAX;
@@ -120,7 +120,7 @@ void quicklistSetCompressDepth(quicklist *quicklist, int compress) {
quicklist->compress = compress;
}
-#define FILL_MAX (1 << (QL_FILL_BITS-1))
+#define FILL_MAX ((1 << (QL_FILL_BITS-1))-1)
void quicklistSetFill(quicklist *quicklist, int fill) {
if (fill > FILL_MAX) {
fill = FILL_MAX;
diff --git a/src/server.c b/src/server.c
index c89e9c075..9ebf0ee6b 100644
--- a/src/server.c
+++ b/src/server.c
@@ -672,15 +672,15 @@ struct redisCommand redisCommandTable[] = {
0,NULL,1,1,1,0,0,0},
{"multi",multiCommand,1,
- "no-script fast @transaction",
+ "no-script fast ok-loading ok-stale @transaction",
0,NULL,0,0,0,0,0,0},
{"exec",execCommand,1,
- "no-script no-monitor no-slowlog @transaction",
+ "no-script no-monitor no-slowlog ok-loading ok-stale @transaction",
0,NULL,0,0,0,0,0,0},
{"discard",discardCommand,1,
- "no-script fast @transaction",
+ "no-script fast ok-loading ok-stale @transaction",
0,NULL,0,0,0,0,0,0},
{"sync",syncCommand,1,
@@ -947,11 +947,11 @@ struct redisCommand redisCommandTable[] = {
0,NULL,1,1,1,0,0,0},
{"xread",xreadCommand,-4,
- "read-only no-script @stream @blocking",
+ "read-only @stream @blocking",
0,xreadGetKeys,1,1,1,0,0,0},
{"xreadgroup",xreadCommand,-7,
- "write no-script @stream @blocking",
+ "write @stream @blocking",
0,xreadGetKeys,1,1,1,0,0,0},
{"xgroup",xgroupCommand,-2,
diff --git a/src/server.h b/src/server.h
index c4db4278e..dbd72281f 100644
--- a/src/server.h
+++ b/src/server.h
@@ -2057,7 +2057,7 @@ int objectSetLRUOrLFU(robj *val, long long lfu_freq, long long lru_idle,
#define LOOKUP_NOTOUCH (1<<0)
void dbAdd(redisDb *db, robj *key, robj *val);
void dbOverwrite(redisDb *db, robj *key, robj *val);
-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_stream.c b/src/t_stream.c
index 3f8cbfcfa..e0af87f97 100644
--- a/src/t_stream.c
+++ b/src/t_stream.c
@@ -1374,6 +1374,11 @@ void xreadCommand(client *c) {
int moreargs = c->argc-i-1;
char *o = c->argv[i]->ptr;
if (!strcasecmp(o,"BLOCK") && moreargs) {
+ if (c->flags & CLIENT_LUA) {
+ /* There is no sense to use BLOCK option within LUA */
+ addReplyErrorFormat(c, "%s command is not allowed with BLOCK option from scripts", (char *)c->argv[0]->ptr);
+ return;
+ }
i++;
if (getTimeoutFromObjectOrReply(c,c->argv[i],&timeout,
UNIT_MILLISECONDS) != C_OK) return;
diff --git a/src/t_string.c b/src/t_string.c
index 8ccd69eb9..3174e9ccd 100644
--- a/src/t_string.c
+++ b/src/t_string.c
@@ -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);
server.dirty++;
if (expire) setExpire(c,c->db,key,mstime()+milliseconds);
notifyKeyspaceEvent(NOTIFY_STRING,"set",key,c->db->id);
diff --git a/tests/unit/scripting.tcl b/tests/unit/scripting.tcl
index fb36d0b80..8b364b287 100644
--- a/tests/unit/scripting.tcl
+++ b/tests/unit/scripting.tcl
@@ -146,6 +146,17 @@ start_server {tags {"scripting"}} {
set e
} {*not allowed*}
+ test {EVAL - Scripts can't run XREAD and XREADGROUP with BLOCK option} {
+ r del s
+ r xgroup create s g $ MKSTREAM
+ set res [r eval {return redis.pcall('xread','STREAMS','s','$')} 1 s]
+ assert {$res eq {}}
+ assert_error "*xread command is not allowed with BLOCK option from scripts" {r eval {return redis.pcall('xread','BLOCK',0,'STREAMS','s','$')} 1 s}
+ set res [r eval {return redis.pcall('xreadgroup','group','g','c','STREAMS','s','>')} 1 s]
+ assert {$res eq {}}
+ assert_error "*xreadgroup command is not allowed with BLOCK option from scripts" {r eval {return redis.pcall('xreadgroup','group','g','c','BLOCK',0,'STREAMS','s','>')} 1 s}
+ }
+
test {EVAL - Scripts can't run certain commands} {
set e {}
r debug lua-always-replicate-commands 0
diff --git a/tests/unit/type/incr.tcl b/tests/unit/type/incr.tcl
index 63bf2e116..b7a135203 100644
--- a/tests/unit/type/incr.tcl
+++ b/tests/unit/type/incr.tcl
@@ -153,6 +153,7 @@ start_server {tags {"incr"}} {
} {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