diff --git a/fakeredis/_basefakesocket.py b/fakeredis/_basefakesocket.py index b8255b57..e3d09f86 100644 --- a/fakeredis/_basefakesocket.py +++ b/fakeredis/_basefakesocket.py @@ -190,7 +190,7 @@ def _process_command(self, fields: List[bytes]) -> None: cmd, cmd_arguments = _extract_command(fields) try: func, sig = self._name_to_func(cmd) - self._server.acl.validate_command(self._current_user, fields) # ACL check + self._server.acl.validate_command(self._current_user, self._client_info, fields) # ACL check with self._server.lock: # Clean out old connections while True: diff --git a/fakeredis/_msgs.py b/fakeredis/_msgs.py index 5dbe720a..f085904c 100644 --- a/fakeredis/_msgs.py +++ b/fakeredis/_msgs.py @@ -124,6 +124,7 @@ MISSING_ACLFILE_CONFIG = "ERR This Redis instance is not configured to use an ACL file. You may want to specify users via the ACL SETUSER command and then issue a CONFIG REWRITE (assuming you have a Redis configuration file set) in order to store users in the Redis configuration." NO_PERMISSION_ERROR = "NOPERM User {} has no permissions to run the '{}' command" +NO_PERMISSION_KEY_ERROR = "NOPERM No permissions to access a key" # Command flags FLAG_NO_SCRIPT = "s" # Command not allowed in scripts diff --git a/fakeredis/commands.json b/fakeredis/commands.json index a5762d2c..2a762c7f 100644 --- a/fakeredis/commands.json +++ b/fakeredis/commands.json @@ -1 +1 @@ -{"acl cat": ["acl|cat", -2, ["noscript", "loading", "stale"], 0, 0, 0, ["@slow"], [], [], []], "acl deluser": ["acl|deluser", -3, ["admin", "noscript", "loading", "stale"], 0, 0, 0, ["@admin", "@slow", "@dangerous"], [], [], []], "acl genpass": ["acl|genpass", -2, ["noscript", "loading", "stale"], 0, 0, 0, ["@slow"], [], [], []], "acl getuser": ["acl|getuser", 3, ["admin", "noscript", "loading", "stale"], 0, 0, 0, ["@admin", "@slow", "@dangerous"], [], [], []], "acl list": ["acl|list", 2, ["admin", "noscript", "loading", "stale"], 0, 0, 0, ["@admin", "@slow", "@dangerous"], [], [], []], "acl load": ["acl|load", 2, ["admin", "noscript", "loading", "stale"], 0, 0, 0, ["@admin", "@slow", "@dangerous"], [], [], []], "acl log": ["acl|log", -2, ["admin", "noscript", "loading", "stale"], 0, 0, 0, ["@admin", "@slow", "@dangerous"], [], [], []], "acl save": ["acl|save", 2, ["admin", "noscript", "loading", "stale"], 0, 0, 0, ["@admin", "@slow", "@dangerous"], [], [], []], "acl setuser": ["acl|setuser", -3, ["admin", "noscript", "loading", "stale"], 0, 0, 0, ["@admin", "@slow", "@dangerous"], [], [], []], "acl users": ["acl|users", 2, ["admin", "noscript", "loading", "stale"], 0, 0, 0, ["@admin", "@slow", "@dangerous"], [], [], []], "acl whoami": ["acl|whoami", 2, ["noscript", "loading", "stale"], 0, 0, 0, ["@slow"], [], [], []], "append": ["append", 3, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@string", "@fast"], [], [], []], "auth": ["auth", -2, ["noscript", "loading", "stale", "fast", "no_auth", "allow_busy"], 0, 0, 0, ["@fast", "@connection"], [], [], []], "bgsave": ["bgsave", -1, ["admin", "noscript", "no_async_loading"], 0, 0, 0, ["@admin", "@slow", "@dangerous"], [], [], []], "bitcount": ["bitcount", -2, ["readonly"], 1, 1, 1, ["@read", "@bitmap", "@slow"], [], [], []], "bitfield": ["bitfield", -2, ["write", "denyoom"], 1, 1, 1, ["@write", "@bitmap", "@slow"], [], [], [["bitfield_ro", -2, ["readonly", "fast"], 1, 1, 1, ["@read", "@bitmap", "@fast"], [], [], []]]], "bitop": ["bitop", -4, ["write", "denyoom"], 2, 3, 1, ["@write", "@bitmap", "@slow"], [], [], []], "bitpos": ["bitpos", -3, ["readonly"], 1, 1, 1, ["@read", "@bitmap", "@slow"], [], [], []], "blmove": ["blmove", 6, ["write", "denyoom", "blocking"], 1, 2, 1, ["@write", "@list", "@slow", "@blocking"], [], [], []], "blmpop": ["blmpop", -5, ["write", "blocking", "movablekeys"], 2, 2, 1, ["@write", "@list", "@slow", "@blocking"], [], [], []], "blpop": ["blpop", -3, ["write", "blocking"], 1, 1, 1, ["@write", "@list", "@slow", "@blocking"], [], [], []], "brpop": ["brpop", -3, ["write", "blocking"], 1, 1, 1, ["@write", "@list", "@slow", "@blocking"], [], [], [["brpoplpush", 4, ["write", "denyoom", "blocking"], 1, 2, 1, ["@write", "@list", "@slow", "@blocking"], [], [], []]]], "brpoplpush": ["brpoplpush", 4, ["write", "denyoom", "blocking"], 1, 2, 1, ["@write", "@list", "@slow", "@blocking"], [], [], []], "bzmpop": ["bzmpop", -5, ["write", "blocking", "movablekeys"], 2, 2, 1, ["@write", "@sortedset", "@slow", "@blocking"], [], [], []], "bzpopmax": ["bzpopmax", -3, ["write", "blocking", "fast"], 1, 1, 1, ["@write", "@sortedset", "@fast", "@blocking"], [], [], []], "bzpopmin": ["bzpopmin", -3, ["write", "blocking", "fast"], 1, 1, 1, ["@write", "@sortedset", "@fast", "@blocking"], [], [], []], "client setinfo": ["client|setinfo", 4, ["noscript", "loading", "stale"], 0, 0, 0, ["@slow", "@connection"], [], [], []], "command": ["command", -1, ["loading", "stale"], 0, 0, 0, ["@slow", "@connection"], [], [], [["command|count", 2, ["loading", "stale"], 0, 0, 0, ["@slow", "@connection"], [], [], []], ["command|docs", -2, ["loading", "stale"], 0, 0, 0, ["@slow", "@connection"], [], [], []], ["command|getkeys", -3, ["loading", "stale"], 0, 0, 0, ["@slow", "@connection"], [], [], [["command|getkeysandflags", -3, ["loading", "stale"], 0, 0, 0, ["@slow", "@connection"], [], [], []]]], ["command|getkeysandflags", -3, ["loading", "stale"], 0, 0, 0, ["@slow", "@connection"], [], [], []], ["command|help", 2, ["loading", "stale"], 0, 0, 0, ["@slow", "@connection"], [], [], []], ["command|info", -2, ["loading", "stale"], 0, 0, 0, ["@slow", "@connection"], [], [], []], ["command|list", -2, ["loading", "stale"], 0, 0, 0, ["@slow", "@connection"], [], [], []]]], "command count": ["command|count", 2, ["loading", "stale"], 0, 0, 0, ["@slow", "@connection"], [], [], []], "command info": ["command|info", -2, ["loading", "stale"], 0, 0, 0, ["@slow", "@connection"], [], [], []], "config set": ["config|set", -4, ["admin", "noscript", "loading", "stale"], 0, 0, 0, ["@admin", "@slow", "@dangerous"], [], [], []], "dbsize": ["dbsize", 1, ["readonly", "fast"], 0, 0, 0, ["@keyspace", "@read", "@fast"], [], [], []], "decr": ["decr", 2, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@string", "@fast"], [], [], [["decrby", 3, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@string", "@fast"], [], [], []]]], "decrby": ["decrby", 3, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@string", "@fast"], [], [], []], "del": ["del", -2, ["write"], 1, 1, 1, ["@keyspace", "@write", "@slow"], [], [], []], "discard": ["discard", 1, ["noscript", "loading", "stale", "fast", "allow_busy"], 0, 0, 0, ["@fast", "@transaction"], [], [], []], "dump": ["dump", 2, ["readonly"], 1, 1, 1, ["@keyspace", "@read", "@slow"], [], [], []], "echo": ["echo", 2, ["loading", "stale", "fast"], 0, 0, 0, ["@fast", "@connection"], [], [], []], "eval": ["eval", -3, ["noscript", "stale", "skip_monitor", "no_mandatory_keys", "movablekeys"], 2, 2, 1, ["@slow", "@scripting"], [], [], [["evalsha", -3, ["noscript", "stale", "skip_monitor", "no_mandatory_keys", "movablekeys"], 2, 2, 1, ["@slow", "@scripting"], [], [], [["evalsha_ro", -3, ["readonly", "noscript", "stale", "skip_monitor", "no_mandatory_keys", "movablekeys"], 2, 2, 1, ["@slow", "@scripting"], [], [], []]]], ["evalsha_ro", -3, ["readonly", "noscript", "stale", "skip_monitor", "no_mandatory_keys", "movablekeys"], 2, 2, 1, ["@slow", "@scripting"], [], [], []], ["eval_ro", -3, ["readonly", "noscript", "stale", "skip_monitor", "no_mandatory_keys", "movablekeys"], 2, 2, 1, ["@slow", "@scripting"], [], [], []]]], "evalsha": ["evalsha", -3, ["noscript", "stale", "skip_monitor", "no_mandatory_keys", "movablekeys"], 2, 2, 1, ["@slow", "@scripting"], [], [], [["evalsha_ro", -3, ["readonly", "noscript", "stale", "skip_monitor", "no_mandatory_keys", "movablekeys"], 2, 2, 1, ["@slow", "@scripting"], [], [], []]]], "exec": ["exec", 1, ["noscript", "loading", "stale", "skip_slowlog"], 0, 0, 0, ["@slow", "@transaction"], [], [], []], "exists": ["exists", -2, ["readonly", "fast"], 1, 1, 1, ["@keyspace", "@read", "@fast"], [], [], []], "expire": ["expire", -3, ["write", "fast"], 1, 1, 1, ["@keyspace", "@write", "@fast"], [], [], [["expireat", -3, ["write", "fast"], 1, 1, 1, ["@keyspace", "@write", "@fast"], [], [], []], ["expiretime", 2, ["readonly", "fast"], 1, 1, 1, ["@keyspace", "@read", "@fast"], [], [], []]]], "expireat": ["expireat", -3, ["write", "fast"], 1, 1, 1, ["@keyspace", "@write", "@fast"], [], [], []], "expiretime": ["expiretime", 2, ["readonly", "fast"], 1, 1, 1, ["@keyspace", "@read", "@fast"], [], [], []], "flushall": ["flushall", -1, ["write"], 0, 0, 0, ["@keyspace", "@write", "@slow", "@dangerous"], [], [], []], "flushdb": ["flushdb", -1, ["write"], 0, 0, 0, ["@keyspace", "@write", "@slow", "@dangerous"], [], [], []], "geoadd": ["geoadd", -5, ["write", "denyoom"], 1, 1, 1, ["@write", "@geo", "@slow"], [], [], []], "geodist": ["geodist", -4, ["readonly"], 1, 1, 1, ["@read", "@geo", "@slow"], [], [], []], "geohash": ["geohash", -2, ["readonly"], 1, 1, 1, ["@read", "@geo", "@slow"], [], [], []], "geopos": ["geopos", -2, ["readonly"], 1, 1, 1, ["@read", "@geo", "@slow"], [], [], []], "georadius": ["georadius", -6, ["write", "denyoom", "movablekeys"], 1, 0, 1, ["@write", "@geo", "@slow"], [], [], [["georadiusbymember", -5, ["write", "denyoom", "movablekeys"], 1, 0, 1, ["@write", "@geo", "@slow"], [], [], [["georadiusbymember_ro", -5, ["readonly"], 1, 1, 1, ["@read", "@geo", "@slow"], [], [], []]]], ["georadiusbymember_ro", -5, ["readonly"], 1, 1, 1, ["@read", "@geo", "@slow"], [], [], []], ["georadius_ro", -6, ["readonly"], 1, 1, 1, ["@read", "@geo", "@slow"], [], [], []]]], "georadiusbymember": ["georadiusbymember", -5, ["write", "denyoom", "movablekeys"], 1, 0, 1, ["@write", "@geo", "@slow"], [], [], [["georadiusbymember_ro", -5, ["readonly"], 1, 1, 1, ["@read", "@geo", "@slow"], [], [], []]]], "georadiusbymember_ro": ["georadiusbymember_ro", -5, ["readonly"], 1, 1, 1, ["@read", "@geo", "@slow"], [], [], []], "georadius_ro": ["georadius_ro", -6, ["readonly"], 1, 1, 1, ["@read", "@geo", "@slow"], [], [], []], "geosearch": ["geosearch", -7, ["readonly"], 1, 1, 1, ["@read", "@geo", "@slow"], [], [], [["geosearchstore", -8, ["write", "denyoom"], 1, 2, 1, ["@write", "@geo", "@slow"], [], [], []]]], "geosearchstore": ["geosearchstore", -8, ["write", "denyoom"], 1, 2, 1, ["@write", "@geo", "@slow"], [], [], []], "get": ["get", 2, ["readonly", "fast"], 1, 1, 1, ["@read", "@string", "@fast"], [], [], [["getbit", 3, ["readonly", "fast"], 1, 1, 1, ["@read", "@bitmap", "@fast"], [], [], []], ["getdel", 2, ["write", "fast"], 1, 1, 1, ["@write", "@string", "@fast"], [], [], []], ["getex", -2, ["write", "fast"], 1, 1, 1, ["@write", "@string", "@fast"], [], [], []], ["getrange", 4, ["readonly"], 1, 1, 1, ["@read", "@string", "@slow"], [], [], []], ["getset", 3, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@string", "@fast"], [], [], []]]], "getbit": ["getbit", 3, ["readonly", "fast"], 1, 1, 1, ["@read", "@bitmap", "@fast"], [], [], []], "getdel": ["getdel", 2, ["write", "fast"], 1, 1, 1, ["@write", "@string", "@fast"], [], [], []], "getex": ["getex", -2, ["write", "fast"], 1, 1, 1, ["@write", "@string", "@fast"], [], [], []], "getrange": ["getrange", 4, ["readonly"], 1, 1, 1, ["@read", "@string", "@slow"], [], [], []], "getset": ["getset", 3, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@string", "@fast"], [], [], []], "hdel": ["hdel", -3, ["write", "fast"], 1, 1, 1, ["@write", "@hash", "@fast"], [], [], []], "hexists": ["hexists", 3, ["readonly", "fast"], 1, 1, 1, ["@read", "@hash", "@fast"], [], [], []], "hexpire": ["hexpire", -5, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@hash", "@fast"], [], [], [["hexpireat", -5, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@hash", "@fast"], [], [], []], ["hexpiretime", -4, ["readonly", "fast"], 1, 1, 1, ["@read", "@hash", "@fast"], [], [], []]]], "hexpireat": ["hexpireat", -5, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@hash", "@fast"], [], [], []], "hexpiretime": ["hexpiretime", -4, ["readonly", "fast"], 1, 1, 1, ["@read", "@hash", "@fast"], [], [], []], "hget": ["hget", 3, ["readonly", "fast"], 1, 1, 1, ["@read", "@hash", "@fast"], [], [], [["hgetall", 2, ["readonly"], 1, 1, 1, ["@read", "@hash", "@slow"], [], [], []], ["hgetf", -5, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@hash", "@fast"], [], [], []]]], "hgetall": ["hgetall", 2, ["readonly"], 1, 1, 1, ["@read", "@hash", "@slow"], [], [], []], "hincrby": ["hincrby", 4, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@hash", "@fast"], [], [], [["hincrbyfloat", 4, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@hash", "@fast"], [], [], []]]], "hincrbyfloat": ["hincrbyfloat", 4, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@hash", "@fast"], [], [], []], "hkeys": ["hkeys", 2, ["readonly"], 1, 1, 1, ["@read", "@hash", "@slow"], [], [], []], "hlen": ["hlen", 2, ["readonly", "fast"], 1, 1, 1, ["@read", "@hash", "@fast"], [], [], []], "hmget": ["hmget", -3, ["readonly", "fast"], 1, 1, 1, ["@read", "@hash", "@fast"], [], [], []], "hmset": ["hmset", -4, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@hash", "@fast"], [], [], []], "hpersist": ["hpersist", -4, ["readonly", "fast"], 1, 1, 1, ["@read", "@hash", "@fast"], [], [], []], "hpexpire": ["hpexpire", -5, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@hash", "@fast"], [], [], [["hpexpireat", -5, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@hash", "@fast"], [], [], []], ["hpexpiretime", -4, ["readonly", "fast"], 1, 1, 1, ["@read", "@hash", "@fast"], [], [], []]]], "hpexpireat": ["hpexpireat", -5, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@hash", "@fast"], [], [], []], "hpexpiretime": ["hpexpiretime", -4, ["readonly", "fast"], 1, 1, 1, ["@read", "@hash", "@fast"], [], [], []], "hpttl": ["hpttl", -4, ["readonly", "fast"], 1, 1, 1, ["@read", "@hash", "@fast"], [], [], []], "hrandfield": ["hrandfield", -2, ["readonly"], 1, 1, 1, ["@read", "@hash", "@slow"], [], [], []], "hscan": ["hscan", -3, ["readonly"], 1, 1, 1, ["@read", "@hash", "@slow"], [], [], []], "hset": ["hset", -4, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@hash", "@fast"], [], [], [["hsetf", -6, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@hash", "@fast"], [], [], []], ["hsetnx", 4, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@hash", "@fast"], [], [], []]]], "hsetnx": ["hsetnx", 4, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@hash", "@fast"], [], [], []], "hstrlen": ["hstrlen", 3, ["readonly", "fast"], 1, 1, 1, ["@read", "@hash", "@fast"], [], [], []], "httl": ["httl", -4, ["readonly", "fast"], 1, 1, 1, ["@read", "@hash", "@fast"], [], [], []], "hvals": ["hvals", 2, ["readonly"], 1, 1, 1, ["@read", "@hash", "@slow"], [], [], []], "incr": ["incr", 2, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@string", "@fast"], [], [], [["incrby", 3, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@string", "@fast"], [], [], [["incrbyfloat", 3, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@string", "@fast"], [], [], []]]], ["incrbyfloat", 3, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@string", "@fast"], [], [], []]]], "incrby": ["incrby", 3, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@string", "@fast"], [], [], [["incrbyfloat", 3, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@string", "@fast"], [], [], []]]], "incrbyfloat": ["incrbyfloat", 3, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@string", "@fast"], [], [], []], "keys": ["keys", 2, ["readonly"], 0, 0, 0, ["@keyspace", "@read", "@slow", "@dangerous"], [], [], []], "lastsave": ["lastsave", 1, ["loading", "stale", "fast"], 0, 0, 0, ["@admin", "@fast", "@dangerous"], [], [], []], "lcs": ["lcs", -3, ["readonly"], 1, 1, 1, ["@read", "@string", "@slow"], [], [], []], "lindex": ["lindex", 3, ["readonly"], 1, 1, 1, ["@read", "@list", "@slow"], [], [], []], "linsert": ["linsert", 5, ["write", "denyoom"], 1, 1, 1, ["@write", "@list", "@slow"], [], [], []], "llen": ["llen", 2, ["readonly", "fast"], 1, 1, 1, ["@read", "@list", "@fast"], [], [], []], "lmove": ["lmove", 5, ["write", "denyoom"], 1, 2, 1, ["@write", "@list", "@slow"], [], [], []], "lmpop": ["lmpop", -4, ["write", "movablekeys"], 1, 1, 1, ["@write", "@list", "@slow"], [], [], []], "lpop": ["lpop", -2, ["write", "fast"], 1, 1, 1, ["@write", "@list", "@fast"], [], [], []], "lpos": ["lpos", -3, ["readonly"], 1, 1, 1, ["@read", "@list", "@slow"], [], [], []], "lpush": ["lpush", -3, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@list", "@fast"], [], [], [["lpushx", -3, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@list", "@fast"], [], [], []]]], "lpushx": ["lpushx", -3, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@list", "@fast"], [], [], []], "lrange": ["lrange", 4, ["readonly"], 1, 1, 1, ["@read", "@list", "@slow"], [], [], []], "lrem": ["lrem", 4, ["write"], 1, 1, 1, ["@write", "@list", "@slow"], [], [], []], "lset": ["lset", 4, ["write", "denyoom"], 1, 1, 1, ["@write", "@list", "@slow"], [], [], []], "ltrim": ["ltrim", 4, ["write"], 1, 1, 1, ["@write", "@list", "@slow"], [], [], []], "mget": ["mget", -2, ["readonly", "fast"], 1, 1, 1, ["@read", "@string", "@fast"], [], [], []], "move": ["move", 3, ["write", "fast"], 1, 1, 1, ["@keyspace", "@write", "@fast"], [], [], []], "mset": ["mset", -3, ["write", "denyoom"], 1, 1, 2, ["@write", "@string", "@slow"], [], [], [["msetnx", -3, ["write", "denyoom"], 1, 1, 2, ["@write", "@string", "@slow"], [], [], []]]], "msetnx": ["msetnx", -3, ["write", "denyoom"], 1, 1, 2, ["@write", "@string", "@slow"], [], [], []], "multi": ["multi", 1, ["noscript", "loading", "stale", "fast", "allow_busy"], 0, 0, 0, ["@fast", "@transaction"], [], [], []], "persist": ["persist", 2, ["write", "fast"], 1, 1, 1, ["@keyspace", "@write", "@fast"], [], [], []], "pexpire": ["pexpire", -3, ["write", "fast"], 1, 1, 1, ["@keyspace", "@write", "@fast"], [], [], [["pexpireat", -3, ["write", "fast"], 1, 1, 1, ["@keyspace", "@write", "@fast"], [], [], []], ["pexpiretime", 2, ["readonly", "fast"], 1, 1, 1, ["@keyspace", "@read", "@fast"], [], [], []]]], "pexpireat": ["pexpireat", -3, ["write", "fast"], 1, 1, 1, ["@keyspace", "@write", "@fast"], [], [], []], "pexpiretime": ["pexpiretime", 2, ["readonly", "fast"], 1, 1, 1, ["@keyspace", "@read", "@fast"], [], [], []], "pfadd": ["pfadd", -2, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@hyperloglog", "@fast"], [], [], []], "pfcount": ["pfcount", -2, ["readonly"], 1, 1, 1, ["@read", "@hyperloglog", "@slow"], [], [], []], "pfmerge": ["pfmerge", -2, ["write", "denyoom"], 1, 2, 1, ["@write", "@hyperloglog", "@slow"], [], [], []], "ping": ["ping", -1, ["fast"], 0, 0, 0, ["@fast", "@connection"], [], [], []], "psetex": ["psetex", 4, ["write", "denyoom"], 1, 1, 1, ["@write", "@string", "@slow"], [], [], []], "psubscribe": ["psubscribe", -2, ["pubsub", "noscript", "loading", "stale"], 0, 0, 0, ["@pubsub", "@slow"], [], [], []], "pttl": ["pttl", 2, ["readonly", "fast"], 1, 1, 1, ["@keyspace", "@read", "@fast"], [], [], []], "publish": ["publish", 3, ["pubsub", "loading", "stale", "fast"], 0, 0, 0, ["@pubsub", "@fast"], [], [], []], "pubsub": ["pubsub", -2, [], 0, 0, 0, ["@slow"], [], [], [["pubsub|channels", -2, ["pubsub", "loading", "stale"], 0, 0, 0, ["@pubsub", "@slow"], [], [], []], ["pubsub|help", 2, ["loading", "stale"], 0, 0, 0, ["@slow"], [], [], []], ["pubsub|numpat", 2, ["pubsub", "loading", "stale"], 0, 0, 0, ["@pubsub", "@slow"], [], [], []], ["pubsub|numsub", -2, ["pubsub", "loading", "stale"], 0, 0, 0, ["@pubsub", "@slow"], [], [], []], ["pubsub|shardchannels", -2, ["pubsub", "loading", "stale"], 0, 0, 0, ["@pubsub", "@slow"], [], [], []], ["pubsub|shardnumsub", -2, ["pubsub", "loading", "stale"], 0, 0, 0, ["@pubsub", "@slow"], [], [], []]]], "pubsub channels": ["pubsub|channels", -2, ["pubsub", "loading", "stale"], 0, 0, 0, ["@pubsub", "@slow"], [], [], []], "pubsub help": ["pubsub|help", 2, ["loading", "stale"], 0, 0, 0, ["@slow"], [], [], []], "pubsub numpat": ["pubsub|numpat", 2, ["pubsub", "loading", "stale"], 0, 0, 0, ["@pubsub", "@slow"], [], [], []], "pubsub numsub": ["pubsub|numsub", -2, ["pubsub", "loading", "stale"], 0, 0, 0, ["@pubsub", "@slow"], [], [], []], "pubsub shardchannels": ["pubsub|shardchannels", -2, ["pubsub", "loading", "stale"], 0, 0, 0, ["@pubsub", "@slow"], [], [], []], "pubsub shardnumsub": ["pubsub|shardnumsub", -2, ["pubsub", "loading", "stale"], 0, 0, 0, ["@pubsub", "@slow"], [], [], []], "punsubscribe": ["punsubscribe", -1, ["pubsub", "noscript", "loading", "stale"], 0, 0, 0, ["@pubsub", "@slow"], [], [], []], "randomkey": ["randomkey", 1, ["readonly"], 0, 0, 0, ["@keyspace", "@read", "@slow"], [], [], []], "rename": ["rename", 3, ["write"], 1, 2, 1, ["@keyspace", "@write", "@slow"], [], [], [["renamenx", 3, ["write", "fast"], 1, 2, 1, ["@keyspace", "@write", "@fast"], [], [], []]]], "renamenx": ["renamenx", 3, ["write", "fast"], 1, 2, 1, ["@keyspace", "@write", "@fast"], [], [], []], "restore": ["restore", -4, ["write", "denyoom"], 1, 1, 1, ["@keyspace", "@write", "@slow", "@dangerous"], [], [], [["restore-asking", -4, ["write", "denyoom", "asking"], 1, 1, 1, ["@keyspace", "@write", "@slow", "@dangerous"], [], [], []]]], "rpop": ["rpop", -2, ["write", "fast"], 1, 1, 1, ["@write", "@list", "@fast"], [], [], [["rpoplpush", 3, ["write", "denyoom"], 1, 2, 1, ["@write", "@list", "@slow"], [], [], []]]], "rpoplpush": ["rpoplpush", 3, ["write", "denyoom"], 1, 2, 1, ["@write", "@list", "@slow"], [], [], []], "rpush": ["rpush", -3, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@list", "@fast"], [], [], [["rpushx", -3, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@list", "@fast"], [], [], []]]], "rpushx": ["rpushx", -3, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@list", "@fast"], [], [], []], "sadd": ["sadd", -3, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@set", "@fast"], [], [], []], "save": ["save", 1, ["admin", "noscript", "no_async_loading", "no_multi"], 0, 0, 0, ["@admin", "@slow", "@dangerous"], [], [], []], "scan": ["scan", -2, ["readonly"], 0, 0, 0, ["@keyspace", "@read", "@slow"], [], [], []], "scard": ["scard", 2, ["readonly", "fast"], 1, 1, 1, ["@read", "@set", "@fast"], [], [], []], "script": ["script", -2, [], 0, 0, 0, ["@slow"], [], [], [["script|debug", 3, ["noscript"], 0, 0, 0, ["@slow", "@scripting"], [], [], []], ["script|exists", -3, ["noscript"], 0, 0, 0, ["@slow", "@scripting"], [], [], []], ["script|flush", -2, ["noscript"], 0, 0, 0, ["@slow", "@scripting"], [], [], []], ["script|help", 2, ["loading", "stale"], 0, 0, 0, ["@slow", "@scripting"], [], [], []], ["script|kill", 2, ["noscript", "allow_busy"], 0, 0, 0, ["@slow", "@scripting"], [], [], []], ["script|load", 3, ["noscript", "stale"], 0, 0, 0, ["@slow", "@scripting"], [], [], []]]], "script exists": ["script|exists", -3, ["noscript"], 0, 0, 0, ["@slow", "@scripting"], [], [], []], "script flush": ["script|flush", -2, ["noscript"], 0, 0, 0, ["@slow", "@scripting"], [], [], []], "script help": ["script|help", 2, ["loading", "stale"], 0, 0, 0, ["@slow", "@scripting"], [], [], []], "script load": ["script|load", 3, ["noscript", "stale"], 0, 0, 0, ["@slow", "@scripting"], [], [], []], "sdiff": ["sdiff", -2, ["readonly"], 1, 1, 1, ["@read", "@set", "@slow"], [], [], [["sdiffstore", -3, ["write", "denyoom"], 1, 2, 1, ["@write", "@set", "@slow"], [], [], []]]], "sdiffstore": ["sdiffstore", -3, ["write", "denyoom"], 1, 2, 1, ["@write", "@set", "@slow"], [], [], []], "select": ["select", 2, ["loading", "stale", "fast"], 0, 0, 0, ["@fast", "@connection"], [], [], []], "set": ["set", -3, ["write", "denyoom"], 1, 1, 1, ["@write", "@string", "@slow"], [], [], [["setbit", 4, ["write", "denyoom"], 1, 1, 1, ["@write", "@bitmap", "@slow"], [], [], []], ["setex", 4, ["write", "denyoom"], 1, 1, 1, ["@write", "@string", "@slow"], [], [], []], ["setnx", 3, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@string", "@fast"], [], [], []], ["setrange", 4, ["write", "denyoom"], 1, 1, 1, ["@write", "@string", "@slow"], [], [], []]]], "setbit": ["setbit", 4, ["write", "denyoom"], 1, 1, 1, ["@write", "@bitmap", "@slow"], [], [], []], "setex": ["setex", 4, ["write", "denyoom"], 1, 1, 1, ["@write", "@string", "@slow"], [], [], []], "setnx": ["setnx", 3, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@string", "@fast"], [], [], []], "setrange": ["setrange", 4, ["write", "denyoom"], 1, 1, 1, ["@write", "@string", "@slow"], [], [], []], "sinter": ["sinter", -2, ["readonly"], 1, 1, 1, ["@read", "@set", "@slow"], [], [], [["sintercard", -3, ["readonly", "movablekeys"], 1, 1, 1, ["@read", "@set", "@slow"], [], [], []], ["sinterstore", -3, ["write", "denyoom"], 1, 2, 1, ["@write", "@set", "@slow"], [], [], []]]], "sintercard": ["sintercard", -3, ["readonly", "movablekeys"], 1, 1, 1, ["@read", "@set", "@slow"], [], [], []], "sinterstore": ["sinterstore", -3, ["write", "denyoom"], 1, 2, 1, ["@write", "@set", "@slow"], [], [], []], "sismember": ["sismember", 3, ["readonly", "fast"], 1, 1, 1, ["@read", "@set", "@fast"], [], [], []], "smembers": ["smembers", 2, ["readonly"], 1, 1, 1, ["@read", "@set", "@slow"], [], [], []], "smismember": ["smismember", -3, ["readonly", "fast"], 1, 1, 1, ["@read", "@set", "@fast"], [], [], []], "smove": ["smove", 4, ["write", "fast"], 1, 2, 1, ["@write", "@set", "@fast"], [], [], []], "sort": ["sort", -2, ["write", "denyoom", "movablekeys"], 1, 0, 1, ["@write", "@set", "@sortedset", "@list", "@slow", "@dangerous"], [], [], [["sort_ro", -2, ["readonly", "movablekeys"], 1, 0, 1, ["@read", "@set", "@sortedset", "@list", "@slow", "@dangerous"], [], [], []]]], "sort_ro": ["sort_ro", -2, ["readonly", "movablekeys"], 1, 0, 1, ["@read", "@set", "@sortedset", "@list", "@slow", "@dangerous"], [], [], []], "spop": ["spop", -2, ["write", "fast"], 1, 1, 1, ["@write", "@set", "@fast"], [], [], []], "spublish": ["spublish", 3, ["pubsub", "loading", "stale", "fast"], 1, 1, 1, ["@pubsub", "@fast"], [], [], []], "srandmember": ["srandmember", -2, ["readonly"], 1, 1, 1, ["@read", "@set", "@slow"], [], [], []], "srem": ["srem", -3, ["write", "fast"], 1, 1, 1, ["@write", "@set", "@fast"], [], [], []], "sscan": ["sscan", -3, ["readonly"], 1, 1, 1, ["@read", "@set", "@slow"], [], [], []], "ssubscribe": ["ssubscribe", -2, ["pubsub", "noscript", "loading", "stale"], 1, 1, 1, ["@pubsub", "@slow"], [], [], []], "strlen": ["strlen", 2, ["readonly", "fast"], 1, 1, 1, ["@read", "@string", "@fast"], [], [], []], "subscribe": ["subscribe", -2, ["pubsub", "noscript", "loading", "stale"], 0, 0, 0, ["@pubsub", "@slow"], [], [], []], "substr": ["substr", 4, ["readonly"], 1, 1, 1, ["@read", "@string", "@slow"], [], [], []], "sunion": ["sunion", -2, ["readonly"], 1, 1, 1, ["@read", "@set", "@slow"], [], [], [["sunionstore", -3, ["write", "denyoom"], 1, 2, 1, ["@write", "@set", "@slow"], [], [], []]]], "sunionstore": ["sunionstore", -3, ["write", "denyoom"], 1, 2, 1, ["@write", "@set", "@slow"], [], [], []], "sunsubscribe": ["sunsubscribe", -1, ["pubsub", "noscript", "loading", "stale"], 1, 1, 1, ["@pubsub", "@slow"], [], [], []], "swapdb": ["swapdb", 3, ["write", "fast"], 0, 0, 0, ["@keyspace", "@write", "@fast", "@dangerous"], [], [], []], "time": ["time", 1, ["loading", "stale", "fast"], 0, 0, 0, ["@fast"], [], [], []], "ttl": ["ttl", 2, ["readonly", "fast"], 1, 1, 1, ["@keyspace", "@read", "@fast"], [], [], []], "type": ["type", 2, ["readonly", "fast"], 1, 1, 1, ["@keyspace", "@read", "@fast"], [], [], []], "unlink": ["unlink", -2, ["write", "fast"], 1, 1, 1, ["@keyspace", "@write", "@fast"], [], [], []], "unsubscribe": ["unsubscribe", -1, ["pubsub", "noscript", "loading", "stale"], 0, 0, 0, ["@pubsub", "@slow"], [], [], []], "unwatch": ["unwatch", 1, ["noscript", "loading", "stale", "fast", "allow_busy"], 0, 0, 0, ["@fast", "@transaction"], [], [], []], "watch": ["watch", -2, ["noscript", "loading", "stale", "fast", "allow_busy"], 1, 1, 1, ["@fast", "@transaction"], [], [], []], "xack": ["xack", -4, ["write", "fast"], 1, 1, 1, ["@write", "@stream", "@fast"], [], [], []], "xadd": ["xadd", -5, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@stream", "@fast"], [], [], []], "xautoclaim": ["xautoclaim", -6, ["write", "fast"], 1, 1, 1, ["@write", "@stream", "@fast"], [], [], []], "xclaim": ["xclaim", -6, ["write", "fast"], 1, 1, 1, ["@write", "@stream", "@fast"], [], [], []], "xdel": ["xdel", -3, ["write", "fast"], 1, 1, 1, ["@write", "@stream", "@fast"], [], [], []], "xgroup create": ["xgroup|create", -5, ["write", "denyoom"], 2, 2, 1, ["@write", "@stream", "@slow"], [], [], [["xgroup|createconsumer", 5, ["write", "denyoom"], 2, 2, 1, ["@write", "@stream", "@slow"], [], [], []]]], "xgroup createconsumer": ["xgroup|createconsumer", 5, ["write", "denyoom"], 2, 2, 1, ["@write", "@stream", "@slow"], [], [], []], "xgroup delconsumer": ["xgroup|delconsumer", 5, ["write"], 2, 2, 1, ["@write", "@stream", "@slow"], [], [], []], "xgroup destroy": ["xgroup|destroy", 4, ["write"], 2, 2, 1, ["@write", "@stream", "@slow"], [], [], []], "xgroup setid": ["xgroup|setid", -5, ["write"], 2, 2, 1, ["@write", "@stream", "@slow"], [], [], []], "xinfo consumers": ["xinfo|consumers", 4, ["readonly"], 2, 2, 1, ["@read", "@stream", "@slow"], [], [], []], "xinfo groups": ["xinfo|groups", 3, ["readonly"], 2, 2, 1, ["@read", "@stream", "@slow"], [], [], []], "xinfo stream": ["xinfo|stream", -3, ["readonly"], 2, 2, 1, ["@read", "@stream", "@slow"], [], [], []], "xlen": ["xlen", 2, ["readonly", "fast"], 1, 1, 1, ["@read", "@stream", "@fast"], [], [], []], "xpending": ["xpending", -3, ["readonly"], 1, 1, 1, ["@read", "@stream", "@slow"], [], [], []], "xrange": ["xrange", -4, ["readonly"], 1, 1, 1, ["@read", "@stream", "@slow"], [], [], []], "xread": ["xread", -4, ["readonly", "blocking", "movablekeys"], 0, 0, 1, ["@read", "@stream", "@slow", "@blocking"], [], [], [["xreadgroup", -7, ["write", "blocking", "movablekeys"], 0, 0, 1, ["@write", "@stream", "@slow", "@blocking"], [], [], []]]], "xreadgroup": ["xreadgroup", -7, ["write", "blocking", "movablekeys"], 0, 0, 1, ["@write", "@stream", "@slow", "@blocking"], [], [], []], "xrevrange": ["xrevrange", -4, ["readonly"], 1, 1, 1, ["@read", "@stream", "@slow"], [], [], []], "xtrim": ["xtrim", -4, ["write"], 1, 1, 1, ["@write", "@stream", "@slow"], [], [], []], "zadd": ["zadd", -4, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@sortedset", "@fast"], [], [], []], "zcard": ["zcard", 2, ["readonly", "fast"], 1, 1, 1, ["@read", "@sortedset", "@fast"], [], [], []], "zcount": ["zcount", 4, ["readonly", "fast"], 1, 1, 1, ["@read", "@sortedset", "@fast"], [], [], []], "zdiff": ["zdiff", -3, ["readonly", "movablekeys"], 1, 1, 1, ["@read", "@sortedset", "@slow"], [], [], [["zdiffstore", -4, ["write", "denyoom", "movablekeys"], 1, 2, 1, ["@write", "@sortedset", "@slow"], [], [], []]]], "zdiffstore": ["zdiffstore", -4, ["write", "denyoom", "movablekeys"], 1, 2, 1, ["@write", "@sortedset", "@slow"], [], [], []], "zincrby": ["zincrby", 4, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@sortedset", "@fast"], [], [], []], "zinter": ["zinter", -3, ["readonly", "movablekeys"], 1, 1, 1, ["@read", "@sortedset", "@slow"], [], [], [["zintercard", -3, ["readonly", "movablekeys"], 1, 1, 1, ["@read", "@sortedset", "@slow"], [], [], []], ["zinterstore", -4, ["write", "denyoom", "movablekeys"], 1, 2, 1, ["@write", "@sortedset", "@slow"], [], [], []]]], "zintercard": ["zintercard", -3, ["readonly", "movablekeys"], 1, 1, 1, ["@read", "@sortedset", "@slow"], [], [], []], "zinterstore": ["zinterstore", -4, ["write", "denyoom", "movablekeys"], 1, 2, 1, ["@write", "@sortedset", "@slow"], [], [], []], "zlexcount": ["zlexcount", 4, ["readonly", "fast"], 1, 1, 1, ["@read", "@sortedset", "@fast"], [], [], []], "zmpop": ["zmpop", -4, ["write", "movablekeys"], 1, 1, 1, ["@write", "@sortedset", "@slow"], [], [], []], "zmscore": ["zmscore", -3, ["readonly", "fast"], 1, 1, 1, ["@read", "@sortedset", "@fast"], [], [], []], "zpopmax": ["zpopmax", -2, ["write", "fast"], 1, 1, 1, ["@write", "@sortedset", "@fast"], [], [], []], "zpopmin": ["zpopmin", -2, ["write", "fast"], 1, 1, 1, ["@write", "@sortedset", "@fast"], [], [], []], "zrandmember": ["zrandmember", -2, ["readonly"], 1, 1, 1, ["@read", "@sortedset", "@slow"], [], [], []], "zrange": ["zrange", -4, ["readonly"], 1, 1, 1, ["@read", "@sortedset", "@slow"], [], [], [["zrangebylex", -4, ["readonly"], 1, 1, 1, ["@read", "@sortedset", "@slow"], [], [], []], ["zrangebyscore", -4, ["readonly"], 1, 1, 1, ["@read", "@sortedset", "@slow"], [], [], []], ["zrangestore", -5, ["write", "denyoom"], 1, 2, 1, ["@write", "@sortedset", "@slow"], [], [], []]]], "zrangebylex": ["zrangebylex", -4, ["readonly"], 1, 1, 1, ["@read", "@sortedset", "@slow"], [], [], []], "zrangebyscore": ["zrangebyscore", -4, ["readonly"], 1, 1, 1, ["@read", "@sortedset", "@slow"], [], [], []], "zrangestore": ["zrangestore", -5, ["write", "denyoom"], 1, 2, 1, ["@write", "@sortedset", "@slow"], [], [], []], "zrank": ["zrank", -3, ["readonly", "fast"], 1, 1, 1, ["@read", "@sortedset", "@fast"], [], [], []], "zrem": ["zrem", -3, ["write", "fast"], 1, 1, 1, ["@write", "@sortedset", "@fast"], [], [], [["zremrangebylex", 4, ["write"], 1, 1, 1, ["@write", "@sortedset", "@slow"], [], [], []], ["zremrangebyrank", 4, ["write"], 1, 1, 1, ["@write", "@sortedset", "@slow"], [], [], []], ["zremrangebyscore", 4, ["write"], 1, 1, 1, ["@write", "@sortedset", "@slow"], [], [], []]]], "zremrangebylex": ["zremrangebylex", 4, ["write"], 1, 1, 1, ["@write", "@sortedset", "@slow"], [], [], []], "zremrangebyrank": ["zremrangebyrank", 4, ["write"], 1, 1, 1, ["@write", "@sortedset", "@slow"], [], [], []], "zremrangebyscore": ["zremrangebyscore", 4, ["write"], 1, 1, 1, ["@write", "@sortedset", "@slow"], [], [], []], "zrevrange": ["zrevrange", -4, ["readonly"], 1, 1, 1, ["@read", "@sortedset", "@slow"], [], [], [["zrevrangebylex", -4, ["readonly"], 1, 1, 1, ["@read", "@sortedset", "@slow"], [], [], []], ["zrevrangebyscore", -4, ["readonly"], 1, 1, 1, ["@read", "@sortedset", "@slow"], [], [], []]]], "zrevrangebylex": ["zrevrangebylex", -4, ["readonly"], 1, 1, 1, ["@read", "@sortedset", "@slow"], [], [], []], "zrevrangebyscore": ["zrevrangebyscore", -4, ["readonly"], 1, 1, 1, ["@read", "@sortedset", "@slow"], [], [], []], "zrevrank": ["zrevrank", -3, ["readonly", "fast"], 1, 1, 1, ["@read", "@sortedset", "@fast"], [], [], []], "zscan": ["zscan", -3, ["readonly"], 1, 1, 1, ["@read", "@sortedset", "@slow"], [], [], []], "zscore": ["zscore", 3, ["readonly", "fast"], 1, 1, 1, ["@read", "@sortedset", "@fast"], [], [], []], "zunion": ["zunion", -3, ["readonly", "movablekeys"], 1, 1, 1, ["@read", "@sortedset", "@slow"], [], [], [["zunionstore", -4, ["write", "denyoom", "movablekeys"], 1, 2, 1, ["@write", "@sortedset", "@slow"], [], [], []]]], "zunionstore": ["zunionstore", -4, ["write", "denyoom", "movablekeys"], 1, 2, 1, ["@write", "@sortedset", "@slow"], [], [], []], "json.del": ["json.del", -1, [], 0, 0, 0, [], [], [], []], "json.forget": ["json.forget", -1, [], 0, 0, 0, [], [], [], []], "json.get": ["json.get", -1, [], 0, 0, 0, [], [], [], []], "json.toggle": ["json.toggle", -1, [], 0, 0, 0, [], [], [], []], "json.clear": ["json.clear", -1, [], 0, 0, 0, [], [], [], []], "json.set": ["json.set", -1, [], 0, 0, 0, [], [], [], []], "json.mset": ["json.mset", -1, [], 0, 0, 0, [], [], [], []], "json.merge": ["json.merge", -1, [], 0, 0, 0, [], [], [], []], "json.mget": ["json.mget", -1, [], 0, 0, 0, [], [], [], []], "json.numincrby": ["json.numincrby", -1, [], 0, 0, 0, [], [], [], []], "json.nummultby": ["json.nummultby", -1, [], 0, 0, 0, [], [], [], []], "json.strappend": ["json.strappend", -1, [], 0, 0, 0, [], [], [], []], "json.strlen": ["json.strlen", -1, [], 0, 0, 0, [], [], [], []], "json.arrappend": ["json.arrappend", -1, [], 0, 0, 0, [], [], [], []], "json.arrindex": ["json.arrindex", -1, [], 0, 0, 0, [], [], [], []], "json.arrinsert": ["json.arrinsert", -1, [], 0, 0, 0, [], [], [], []], "json.arrlen": ["json.arrlen", -1, [], 0, 0, 0, [], [], [], []], "json.arrpop": ["json.arrpop", -1, [], 0, 0, 0, [], [], [], []], "json.arrtrim": ["json.arrtrim", -1, [], 0, 0, 0, [], [], [], []], "json.objkeys": ["json.objkeys", -1, [], 0, 0, 0, [], [], [], []], "json.objlen": ["json.objlen", -1, [], 0, 0, 0, [], [], [], []], "json.type": ["json.type", -1, [], 0, 0, 0, [], [], [], []], "ts.create": ["ts.create", -1, [], 0, 0, 0, [], [], [], [["ts.createrule", -1, [], 0, 0, 0, [], [], [], []]]], "ts.del": ["ts.del", -1, [], 0, 0, 0, [], [], [], [["ts.deleterule", -1, [], 0, 0, 0, [], [], [], []]]], "ts.alter": ["ts.alter", -1, [], 0, 0, 0, [], [], [], []], "ts.add": ["ts.add", -1, [], 0, 0, 0, [], [], [], []], "ts.madd": ["ts.madd", -1, [], 0, 0, 0, [], [], [], []], "ts.incrby": ["ts.incrby", -1, [], 0, 0, 0, [], [], [], []], "ts.decrby": ["ts.decrby", -1, [], 0, 0, 0, [], [], [], []], "ts.createrule": ["ts.createrule", -1, [], 0, 0, 0, [], [], [], []], "ts.deleterule": ["ts.deleterule", -1, [], 0, 0, 0, [], [], [], []], "ts.range": ["ts.range", -1, [], 0, 0, 0, [], [], [], []], "ts.revrange": ["ts.revrange", -1, [], 0, 0, 0, [], [], [], []], "ts.mrange": ["ts.mrange", -1, [], 0, 0, 0, [], [], [], []], "ts.mrevrange": ["ts.mrevrange", -1, [], 0, 0, 0, [], [], [], []], "ts.get": ["ts.get", -1, [], 0, 0, 0, [], [], [], []], "ts.mget": ["ts.mget", -1, [], 0, 0, 0, [], [], [], []], "ts.info": ["ts.info", -1, [], 0, 0, 0, [], [], [], []], "ts.queryindex": ["ts.queryindex", -1, [], 0, 0, 0, [], [], [], []], "bf.reserve": ["bf.reserve", -1, [], 0, 0, 0, [], [], [], []], "bf.add": ["bf.add", -1, [], 0, 0, 0, [], [], [], []], "bf.madd": ["bf.madd", -1, [], 0, 0, 0, [], [], [], []], "bf.insert": ["bf.insert", -1, [], 0, 0, 0, [], [], [], []], "bf.exists": ["bf.exists", -1, [], 0, 0, 0, [], [], [], []], "bf.mexists": ["bf.mexists", -1, [], 0, 0, 0, [], [], [], []], "bf.scandump": ["bf.scandump", -1, [], 0, 0, 0, [], [], [], []], "bf.loadchunk": ["bf.loadchunk", -1, [], 0, 0, 0, [], [], [], []], "bf.info": ["bf.info", -1, [], 0, 0, 0, [], [], [], []], "bf.card": ["bf.card", -1, [], 0, 0, 0, [], [], [], []], "cf.reserve": ["cf.reserve", -1, [], 0, 0, 0, [], [], [], []], "cf.add": ["cf.add", -1, [], 0, 0, 0, [], [], [], [["cf.addnx", -1, [], 0, 0, 0, [], [], [], []]]], "cf.addnx": ["cf.addnx", -1, [], 0, 0, 0, [], [], [], []], "cf.insert": ["cf.insert", -1, [], 0, 0, 0, [], [], [], [["cf.insertnx", -1, [], 0, 0, 0, [], [], [], []]]], "cf.insertnx": ["cf.insertnx", -1, [], 0, 0, 0, [], [], [], []], "cf.exists": ["cf.exists", -1, [], 0, 0, 0, [], [], [], []], "cf.mexists": ["cf.mexists", -1, [], 0, 0, 0, [], [], [], []], "cf.del": ["cf.del", -1, [], 0, 0, 0, [], [], [], []], "cf.count": ["cf.count", -1, [], 0, 0, 0, [], [], [], []], "cf.scandump": ["cf.scandump", -1, [], 0, 0, 0, [], [], [], []], "cf.loadchunk": ["cf.loadchunk", -1, [], 0, 0, 0, [], [], [], []], "cf.info": ["cf.info", -1, [], 0, 0, 0, [], [], [], []], "cms.initbydim": ["cms.initbydim", -1, [], 0, 0, 0, [], [], [], []], "cms.initbyprob": ["cms.initbyprob", -1, [], 0, 0, 0, [], [], [], []], "cms.incrby": ["cms.incrby", -1, [], 0, 0, 0, [], [], [], []], "cms.query": ["cms.query", -1, [], 0, 0, 0, [], [], [], []], "cms.merge": ["cms.merge", -1, [], 0, 0, 0, [], [], [], []], "cms.info": ["cms.info", -1, [], 0, 0, 0, [], [], [], []], "topk.reserve": ["topk.reserve", -1, [], 0, 0, 0, [], [], [], []], "topk.add": ["topk.add", -1, [], 0, 0, 0, [], [], [], []], "topk.incrby": ["topk.incrby", -1, [], 0, 0, 0, [], [], [], []], "topk.query": ["topk.query", -1, [], 0, 0, 0, [], [], [], []], "topk.count": ["topk.count", -1, [], 0, 0, 0, [], [], [], []], "topk.list": ["topk.list", -1, [], 0, 0, 0, [], [], [], []], "topk.info": ["topk.info", -1, [], 0, 0, 0, [], [], [], []], "tdigest.create": ["tdigest.create", -1, [], 0, 0, 0, [], [], [], []], "tdigest.reset": ["tdigest.reset", -1, [], 0, 0, 0, [], [], [], []], "tdigest.add": ["tdigest.add", -1, [], 0, 0, 0, [], [], [], []], "tdigest.merge": ["tdigest.merge", -1, [], 0, 0, 0, [], [], [], []], "tdigest.min": ["tdigest.min", -1, [], 0, 0, 0, [], [], [], []], "tdigest.max": ["tdigest.max", -1, [], 0, 0, 0, [], [], [], []], "tdigest.quantile": ["tdigest.quantile", -1, [], 0, 0, 0, [], [], [], []], "tdigest.cdf": ["tdigest.cdf", -1, [], 0, 0, 0, [], [], [], []], "tdigest.trimmed_mean": ["tdigest.trimmed_mean", -1, [], 0, 0, 0, [], [], [], []], "tdigest.rank": ["tdigest.rank", -1, [], 0, 0, 0, [], [], [], []], "tdigest.revrank": ["tdigest.revrank", -1, [], 0, 0, 0, [], [], [], []], "tdigest.byrank": ["tdigest.byrank", -1, [], 0, 0, 0, [], [], [], []], "tdigest.byrevrank": ["tdigest.byrevrank", -1, [], 0, 0, 0, [], [], [], []], "tdigest.info": ["tdigest.info", -1, [], 0, 0, 0, [], [], [], []]} \ No newline at end of file +{"acl cat": ["acl|cat", -2, ["noscript", "loading", "stale"], 0, 0, 0, ["@slow"], [], [], []], "acl": ["acl", -1, [], 0, 0, 0, [], [], [], [["acl|cat", -2, ["noscript", "loading", "stale"], 0, 0, 0, ["@slow"], [], [], []], ["acl|deluser", -3, ["admin", "noscript", "loading", "stale"], 0, 0, 0, ["@admin", "@slow", "@dangerous"], [], [], []], ["acl|genpass", -2, ["noscript", "loading", "stale"], 0, 0, 0, ["@slow"], [], [], []], ["acl|getuser", 3, ["admin", "noscript", "loading", "stale"], 0, 0, 0, ["@admin", "@slow", "@dangerous"], [], [], []], ["acl|list", 2, ["admin", "noscript", "loading", "stale"], 0, 0, 0, ["@admin", "@slow", "@dangerous"], [], [], []], ["acl|load", 2, ["admin", "noscript", "loading", "stale"], 0, 0, 0, ["@admin", "@slow", "@dangerous"], [], [], []], ["acl|log", -2, ["admin", "noscript", "loading", "stale"], 0, 0, 0, ["@admin", "@slow", "@dangerous"], [], [], []], ["acl|save", 2, ["admin", "noscript", "loading", "stale"], 0, 0, 0, ["@admin", "@slow", "@dangerous"], [], [], []], ["acl|setuser", -3, ["admin", "noscript", "loading", "stale"], 0, 0, 0, ["@admin", "@slow", "@dangerous"], [], [], []], ["acl|users", 2, ["admin", "noscript", "loading", "stale"], 0, 0, 0, ["@admin", "@slow", "@dangerous"], [], [], []], ["acl|whoami", 2, ["noscript", "loading", "stale"], 0, 0, 0, ["@slow"], [], [], []]]], "acl deluser": ["acl|deluser", -3, ["admin", "noscript", "loading", "stale"], 0, 0, 0, ["@admin", "@slow", "@dangerous"], [], [], []], "acl genpass": ["acl|genpass", -2, ["noscript", "loading", "stale"], 0, 0, 0, ["@slow"], [], [], []], "acl getuser": ["acl|getuser", 3, ["admin", "noscript", "loading", "stale"], 0, 0, 0, ["@admin", "@slow", "@dangerous"], [], [], []], "acl list": ["acl|list", 2, ["admin", "noscript", "loading", "stale"], 0, 0, 0, ["@admin", "@slow", "@dangerous"], [], [], []], "acl load": ["acl|load", 2, ["admin", "noscript", "loading", "stale"], 0, 0, 0, ["@admin", "@slow", "@dangerous"], [], [], []], "acl log": ["acl|log", -2, ["admin", "noscript", "loading", "stale"], 0, 0, 0, ["@admin", "@slow", "@dangerous"], [], [], []], "acl save": ["acl|save", 2, ["admin", "noscript", "loading", "stale"], 0, 0, 0, ["@admin", "@slow", "@dangerous"], [], [], []], "acl setuser": ["acl|setuser", -3, ["admin", "noscript", "loading", "stale"], 0, 0, 0, ["@admin", "@slow", "@dangerous"], [], [], []], "acl users": ["acl|users", 2, ["admin", "noscript", "loading", "stale"], 0, 0, 0, ["@admin", "@slow", "@dangerous"], [], [], []], "acl whoami": ["acl|whoami", 2, ["noscript", "loading", "stale"], 0, 0, 0, ["@slow"], [], [], []], "append": ["append", 3, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@string", "@fast"], [], [], []], "auth": ["auth", -2, ["noscript", "loading", "stale", "fast", "no_auth", "allow_busy"], 0, 0, 0, ["@fast", "@connection"], [], [], []], "bgsave": ["bgsave", -1, ["admin", "noscript", "no_async_loading"], 0, 0, 0, ["@admin", "@slow", "@dangerous"], [], [], []], "bitcount": ["bitcount", -2, ["readonly"], 1, 1, 1, ["@read", "@bitmap", "@slow"], [], [], []], "bitfield": ["bitfield", -2, ["write", "denyoom"], 1, 1, 1, ["@write", "@bitmap", "@slow"], [], [], [["bitfield_ro", -2, ["readonly", "fast"], 1, 1, 1, ["@read", "@bitmap", "@fast"], [], [], []]]], "bitop": ["bitop", -4, ["write", "denyoom"], 2, 3, 1, ["@write", "@bitmap", "@slow"], [], [], []], "bitpos": ["bitpos", -3, ["readonly"], 1, 1, 1, ["@read", "@bitmap", "@slow"], [], [], []], "blmove": ["blmove", 6, ["write", "denyoom", "blocking"], 1, 2, 1, ["@write", "@list", "@slow", "@blocking"], [], [], []], "blmpop": ["blmpop", -5, ["write", "blocking", "movablekeys"], 2, 2, 1, ["@write", "@list", "@slow", "@blocking"], [], [], []], "blpop": ["blpop", -3, ["write", "blocking"], 1, 1, 1, ["@write", "@list", "@slow", "@blocking"], [], [], []], "brpop": ["brpop", -3, ["write", "blocking"], 1, 1, 1, ["@write", "@list", "@slow", "@blocking"], [], [], [["brpoplpush", 4, ["write", "denyoom", "blocking"], 1, 2, 1, ["@write", "@list", "@slow", "@blocking"], [], [], []]]], "brpoplpush": ["brpoplpush", 4, ["write", "denyoom", "blocking"], 1, 2, 1, ["@write", "@list", "@slow", "@blocking"], [], [], []], "bzmpop": ["bzmpop", -5, ["write", "blocking", "movablekeys"], 2, 2, 1, ["@write", "@sortedset", "@slow", "@blocking"], [], [], []], "bzpopmax": ["bzpopmax", -3, ["write", "blocking", "fast"], 1, 1, 1, ["@write", "@sortedset", "@fast", "@blocking"], [], [], []], "bzpopmin": ["bzpopmin", -3, ["write", "blocking", "fast"], 1, 1, 1, ["@write", "@sortedset", "@fast", "@blocking"], [], [], []], "client setinfo": ["client|setinfo", 4, ["noscript", "loading", "stale"], 0, 0, 0, ["@slow", "@connection"], [], [], []], "client": ["client", -1, [], 0, 0, 0, [], [], [], [["client|setinfo", 4, ["noscript", "loading", "stale"], 0, 0, 0, ["@slow", "@connection"], [], [], []]]], "command": ["command", -1, ["loading", "stale"], 0, 0, 0, ["@slow", "@connection"], [], [], [["command|count", 2, ["loading", "stale"], 0, 0, 0, ["@slow", "@connection"], [], [], []], ["command|docs", -2, ["loading", "stale"], 0, 0, 0, ["@slow", "@connection"], [], [], []], ["command|getkeys", -3, ["loading", "stale"], 0, 0, 0, ["@slow", "@connection"], [], [], [["command|getkeysandflags", -3, ["loading", "stale"], 0, 0, 0, ["@slow", "@connection"], [], [], []]]], ["command|getkeysandflags", -3, ["loading", "stale"], 0, 0, 0, ["@slow", "@connection"], [], [], []], ["command|help", 2, ["loading", "stale"], 0, 0, 0, ["@slow", "@connection"], [], [], []], ["command|info", -2, ["loading", "stale"], 0, 0, 0, ["@slow", "@connection"], [], [], []], ["command|list", -2, ["loading", "stale"], 0, 0, 0, ["@slow", "@connection"], [], [], []], ["command|count", 2, ["loading", "stale"], 0, 0, 0, ["@slow", "@connection"], [], [], []], ["command|info", -2, ["loading", "stale"], 0, 0, 0, ["@slow", "@connection"], [], [], []]]], "command count": ["command|count", 2, ["loading", "stale"], 0, 0, 0, ["@slow", "@connection"], [], [], []], "command info": ["command|info", -2, ["loading", "stale"], 0, 0, 0, ["@slow", "@connection"], [], [], []], "config set": ["config|set", -4, ["admin", "noscript", "loading", "stale"], 0, 0, 0, ["@admin", "@slow", "@dangerous"], [], [], []], "config": ["config", -1, [], 0, 0, 0, [], [], [], [["config|set", -4, ["admin", "noscript", "loading", "stale"], 0, 0, 0, ["@admin", "@slow", "@dangerous"], [], [], []]]], "dbsize": ["dbsize", 1, ["readonly", "fast"], 0, 0, 0, ["@keyspace", "@read", "@fast"], [], [], []], "decr": ["decr", 2, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@string", "@fast"], [], [], [["decrby", 3, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@string", "@fast"], [], [], []]]], "decrby": ["decrby", 3, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@string", "@fast"], [], [], []], "del": ["del", -2, ["write"], 1, 1, 1, ["@keyspace", "@write", "@slow"], [], [], []], "discard": ["discard", 1, ["noscript", "loading", "stale", "fast", "allow_busy"], 0, 0, 0, ["@fast", "@transaction"], [], [], []], "dump": ["dump", 2, ["readonly"], 1, 1, 1, ["@keyspace", "@read", "@slow"], [], [], []], "echo": ["echo", 2, ["loading", "stale", "fast"], 0, 0, 0, ["@fast", "@connection"], [], [], []], "eval": ["eval", -3, ["noscript", "stale", "skip_monitor", "no_mandatory_keys", "movablekeys"], 2, 2, 1, ["@slow", "@scripting"], [], [], [["evalsha", -3, ["noscript", "stale", "skip_monitor", "no_mandatory_keys", "movablekeys"], 2, 2, 1, ["@slow", "@scripting"], [], [], [["evalsha_ro", -3, ["readonly", "noscript", "stale", "skip_monitor", "no_mandatory_keys", "movablekeys"], 2, 2, 1, ["@slow", "@scripting"], [], [], []]]], ["evalsha_ro", -3, ["readonly", "noscript", "stale", "skip_monitor", "no_mandatory_keys", "movablekeys"], 2, 2, 1, ["@slow", "@scripting"], [], [], []], ["eval_ro", -3, ["readonly", "noscript", "stale", "skip_monitor", "no_mandatory_keys", "movablekeys"], 2, 2, 1, ["@slow", "@scripting"], [], [], []]]], "evalsha": ["evalsha", -3, ["noscript", "stale", "skip_monitor", "no_mandatory_keys", "movablekeys"], 2, 2, 1, ["@slow", "@scripting"], [], [], [["evalsha_ro", -3, ["readonly", "noscript", "stale", "skip_monitor", "no_mandatory_keys", "movablekeys"], 2, 2, 1, ["@slow", "@scripting"], [], [], []]]], "exec": ["exec", 1, ["noscript", "loading", "stale", "skip_slowlog"], 0, 0, 0, ["@slow", "@transaction"], [], [], []], "exists": ["exists", -2, ["readonly", "fast"], 1, 1, 1, ["@keyspace", "@read", "@fast"], [], [], []], "expire": ["expire", -3, ["write", "fast"], 1, 1, 1, ["@keyspace", "@write", "@fast"], [], [], [["expireat", -3, ["write", "fast"], 1, 1, 1, ["@keyspace", "@write", "@fast"], [], [], []], ["expiretime", 2, ["readonly", "fast"], 1, 1, 1, ["@keyspace", "@read", "@fast"], [], [], []]]], "expireat": ["expireat", -3, ["write", "fast"], 1, 1, 1, ["@keyspace", "@write", "@fast"], [], [], []], "expiretime": ["expiretime", 2, ["readonly", "fast"], 1, 1, 1, ["@keyspace", "@read", "@fast"], [], [], []], "flushall": ["flushall", -1, ["write"], 0, 0, 0, ["@keyspace", "@write", "@slow", "@dangerous"], [], [], []], "flushdb": ["flushdb", -1, ["write"], 0, 0, 0, ["@keyspace", "@write", "@slow", "@dangerous"], [], [], []], "geoadd": ["geoadd", -5, ["write", "denyoom"], 1, 1, 1, ["@write", "@geo", "@slow"], [], [], []], "geodist": ["geodist", -4, ["readonly"], 1, 1, 1, ["@read", "@geo", "@slow"], [], [], []], "geohash": ["geohash", -2, ["readonly"], 1, 1, 1, ["@read", "@geo", "@slow"], [], [], []], "geopos": ["geopos", -2, ["readonly"], 1, 1, 1, ["@read", "@geo", "@slow"], [], [], []], "georadius": ["georadius", -6, ["write", "denyoom", "movablekeys"], 1, 0, 1, ["@write", "@geo", "@slow"], [], [], [["georadiusbymember", -5, ["write", "denyoom", "movablekeys"], 1, 0, 1, ["@write", "@geo", "@slow"], [], [], [["georadiusbymember_ro", -5, ["readonly"], 1, 1, 1, ["@read", "@geo", "@slow"], [], [], []]]], ["georadiusbymember_ro", -5, ["readonly"], 1, 1, 1, ["@read", "@geo", "@slow"], [], [], []], ["georadius_ro", -6, ["readonly"], 1, 1, 1, ["@read", "@geo", "@slow"], [], [], []]]], "georadiusbymember": ["georadiusbymember", -5, ["write", "denyoom", "movablekeys"], 1, 0, 1, ["@write", "@geo", "@slow"], [], [], [["georadiusbymember_ro", -5, ["readonly"], 1, 1, 1, ["@read", "@geo", "@slow"], [], [], []]]], "georadiusbymember_ro": ["georadiusbymember_ro", -5, ["readonly"], 1, 1, 1, ["@read", "@geo", "@slow"], [], [], []], "georadius_ro": ["georadius_ro", -6, ["readonly"], 1, 1, 1, ["@read", "@geo", "@slow"], [], [], []], "geosearch": ["geosearch", -7, ["readonly"], 1, 1, 1, ["@read", "@geo", "@slow"], [], [], [["geosearchstore", -8, ["write", "denyoom"], 1, 2, 1, ["@write", "@geo", "@slow"], [], [], []]]], "geosearchstore": ["geosearchstore", -8, ["write", "denyoom"], 1, 2, 1, ["@write", "@geo", "@slow"], [], [], []], "get": ["get", 2, ["readonly", "fast"], 1, 1, 1, ["@read", "@string", "@fast"], [], [], [["getbit", 3, ["readonly", "fast"], 1, 1, 1, ["@read", "@bitmap", "@fast"], [], [], []], ["getdel", 2, ["write", "fast"], 1, 1, 1, ["@write", "@string", "@fast"], [], [], []], ["getex", -2, ["write", "fast"], 1, 1, 1, ["@write", "@string", "@fast"], [], [], []], ["getrange", 4, ["readonly"], 1, 1, 1, ["@read", "@string", "@slow"], [], [], []], ["getset", 3, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@string", "@fast"], [], [], []]]], "getbit": ["getbit", 3, ["readonly", "fast"], 1, 1, 1, ["@read", "@bitmap", "@fast"], [], [], []], "getdel": ["getdel", 2, ["write", "fast"], 1, 1, 1, ["@write", "@string", "@fast"], [], [], []], "getex": ["getex", -2, ["write", "fast"], 1, 1, 1, ["@write", "@string", "@fast"], [], [], []], "getrange": ["getrange", 4, ["readonly"], 1, 1, 1, ["@read", "@string", "@slow"], [], [], []], "getset": ["getset", 3, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@string", "@fast"], [], [], []], "hdel": ["hdel", -3, ["write", "fast"], 1, 1, 1, ["@write", "@hash", "@fast"], [], [], []], "hexists": ["hexists", 3, ["readonly", "fast"], 1, 1, 1, ["@read", "@hash", "@fast"], [], [], []], "hexpire": ["hexpire", -5, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@hash", "@fast"], [], [], [["hexpireat", -5, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@hash", "@fast"], [], [], []], ["hexpiretime", -4, ["readonly", "fast"], 1, 1, 1, ["@read", "@hash", "@fast"], [], [], []]]], "hexpireat": ["hexpireat", -5, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@hash", "@fast"], [], [], []], "hexpiretime": ["hexpiretime", -4, ["readonly", "fast"], 1, 1, 1, ["@read", "@hash", "@fast"], [], [], []], "hget": ["hget", 3, ["readonly", "fast"], 1, 1, 1, ["@read", "@hash", "@fast"], [], [], [["hgetall", 2, ["readonly"], 1, 1, 1, ["@read", "@hash", "@slow"], [], [], []], ["hgetf", -5, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@hash", "@fast"], [], [], []]]], "hgetall": ["hgetall", 2, ["readonly"], 1, 1, 1, ["@read", "@hash", "@slow"], [], [], []], "hincrby": ["hincrby", 4, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@hash", "@fast"], [], [], [["hincrbyfloat", 4, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@hash", "@fast"], [], [], []]]], "hincrbyfloat": ["hincrbyfloat", 4, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@hash", "@fast"], [], [], []], "hkeys": ["hkeys", 2, ["readonly"], 1, 1, 1, ["@read", "@hash", "@slow"], [], [], []], "hlen": ["hlen", 2, ["readonly", "fast"], 1, 1, 1, ["@read", "@hash", "@fast"], [], [], []], "hmget": ["hmget", -3, ["readonly", "fast"], 1, 1, 1, ["@read", "@hash", "@fast"], [], [], []], "hmset": ["hmset", -4, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@hash", "@fast"], [], [], []], "hpersist": ["hpersist", -4, ["readonly", "fast"], 1, 1, 1, ["@read", "@hash", "@fast"], [], [], []], "hpexpire": ["hpexpire", -5, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@hash", "@fast"], [], [], [["hpexpireat", -5, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@hash", "@fast"], [], [], []], ["hpexpiretime", -4, ["readonly", "fast"], 1, 1, 1, ["@read", "@hash", "@fast"], [], [], []]]], "hpexpireat": ["hpexpireat", -5, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@hash", "@fast"], [], [], []], "hpexpiretime": ["hpexpiretime", -4, ["readonly", "fast"], 1, 1, 1, ["@read", "@hash", "@fast"], [], [], []], "hpttl": ["hpttl", -4, ["readonly", "fast"], 1, 1, 1, ["@read", "@hash", "@fast"], [], [], []], "hrandfield": ["hrandfield", -2, ["readonly"], 1, 1, 1, ["@read", "@hash", "@slow"], [], [], []], "hscan": ["hscan", -3, ["readonly"], 1, 1, 1, ["@read", "@hash", "@slow"], [], [], []], "hset": ["hset", -4, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@hash", "@fast"], [], [], [["hsetf", -6, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@hash", "@fast"], [], [], []], ["hsetnx", 4, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@hash", "@fast"], [], [], []]]], "hsetnx": ["hsetnx", 4, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@hash", "@fast"], [], [], []], "hstrlen": ["hstrlen", 3, ["readonly", "fast"], 1, 1, 1, ["@read", "@hash", "@fast"], [], [], []], "httl": ["httl", -4, ["readonly", "fast"], 1, 1, 1, ["@read", "@hash", "@fast"], [], [], []], "hvals": ["hvals", 2, ["readonly"], 1, 1, 1, ["@read", "@hash", "@slow"], [], [], []], "incr": ["incr", 2, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@string", "@fast"], [], [], [["incrby", 3, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@string", "@fast"], [], [], [["incrbyfloat", 3, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@string", "@fast"], [], [], []]]], ["incrbyfloat", 3, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@string", "@fast"], [], [], []]]], "incrby": ["incrby", 3, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@string", "@fast"], [], [], [["incrbyfloat", 3, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@string", "@fast"], [], [], []]]], "incrbyfloat": ["incrbyfloat", 3, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@string", "@fast"], [], [], []], "keys": ["keys", 2, ["readonly"], 0, 0, 0, ["@keyspace", "@read", "@slow", "@dangerous"], [], [], []], "lastsave": ["lastsave", 1, ["loading", "stale", "fast"], 0, 0, 0, ["@admin", "@fast", "@dangerous"], [], [], []], "lcs": ["lcs", -3, ["readonly"], 1, 1, 1, ["@read", "@string", "@slow"], [], [], []], "lindex": ["lindex", 3, ["readonly"], 1, 1, 1, ["@read", "@list", "@slow"], [], [], []], "linsert": ["linsert", 5, ["write", "denyoom"], 1, 1, 1, ["@write", "@list", "@slow"], [], [], []], "llen": ["llen", 2, ["readonly", "fast"], 1, 1, 1, ["@read", "@list", "@fast"], [], [], []], "lmove": ["lmove", 5, ["write", "denyoom"], 1, 2, 1, ["@write", "@list", "@slow"], [], [], []], "lmpop": ["lmpop", -4, ["write", "movablekeys"], 1, 1, 1, ["@write", "@list", "@slow"], [], [], []], "lpop": ["lpop", -2, ["write", "fast"], 1, 1, 1, ["@write", "@list", "@fast"], [], [], []], "lpos": ["lpos", -3, ["readonly"], 1, 1, 1, ["@read", "@list", "@slow"], [], [], []], "lpush": ["lpush", -3, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@list", "@fast"], [], [], [["lpushx", -3, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@list", "@fast"], [], [], []]]], "lpushx": ["lpushx", -3, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@list", "@fast"], [], [], []], "lrange": ["lrange", 4, ["readonly"], 1, 1, 1, ["@read", "@list", "@slow"], [], [], []], "lrem": ["lrem", 4, ["write"], 1, 1, 1, ["@write", "@list", "@slow"], [], [], []], "lset": ["lset", 4, ["write", "denyoom"], 1, 1, 1, ["@write", "@list", "@slow"], [], [], []], "ltrim": ["ltrim", 4, ["write"], 1, 1, 1, ["@write", "@list", "@slow"], [], [], []], "mget": ["mget", -2, ["readonly", "fast"], 1, 1, 1, ["@read", "@string", "@fast"], [], [], []], "move": ["move", 3, ["write", "fast"], 1, 1, 1, ["@keyspace", "@write", "@fast"], [], [], []], "mset": ["mset", -3, ["write", "denyoom"], 1, 1, 2, ["@write", "@string", "@slow"], [], [], [["msetnx", -3, ["write", "denyoom"], 1, 1, 2, ["@write", "@string", "@slow"], [], [], []]]], "msetnx": ["msetnx", -3, ["write", "denyoom"], 1, 1, 2, ["@write", "@string", "@slow"], [], [], []], "multi": ["multi", 1, ["noscript", "loading", "stale", "fast", "allow_busy"], 0, 0, 0, ["@fast", "@transaction"], [], [], []], "persist": ["persist", 2, ["write", "fast"], 1, 1, 1, ["@keyspace", "@write", "@fast"], [], [], []], "pexpire": ["pexpire", -3, ["write", "fast"], 1, 1, 1, ["@keyspace", "@write", "@fast"], [], [], [["pexpireat", -3, ["write", "fast"], 1, 1, 1, ["@keyspace", "@write", "@fast"], [], [], []], ["pexpiretime", 2, ["readonly", "fast"], 1, 1, 1, ["@keyspace", "@read", "@fast"], [], [], []]]], "pexpireat": ["pexpireat", -3, ["write", "fast"], 1, 1, 1, ["@keyspace", "@write", "@fast"], [], [], []], "pexpiretime": ["pexpiretime", 2, ["readonly", "fast"], 1, 1, 1, ["@keyspace", "@read", "@fast"], [], [], []], "pfadd": ["pfadd", -2, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@hyperloglog", "@fast"], [], [], []], "pfcount": ["pfcount", -2, ["readonly"], 1, 1, 1, ["@read", "@hyperloglog", "@slow"], [], [], []], "pfmerge": ["pfmerge", -2, ["write", "denyoom"], 1, 2, 1, ["@write", "@hyperloglog", "@slow"], [], [], []], "ping": ["ping", -1, ["fast"], 0, 0, 0, ["@fast", "@connection"], [], [], []], "psetex": ["psetex", 4, ["write", "denyoom"], 1, 1, 1, ["@write", "@string", "@slow"], [], [], []], "psubscribe": ["psubscribe", -2, ["pubsub", "noscript", "loading", "stale"], 0, 0, 0, ["@pubsub", "@slow"], [], [], []], "pttl": ["pttl", 2, ["readonly", "fast"], 1, 1, 1, ["@keyspace", "@read", "@fast"], [], [], []], "publish": ["publish", 3, ["pubsub", "loading", "stale", "fast"], 0, 0, 0, ["@pubsub", "@fast"], [], [], []], "pubsub": ["pubsub", -2, [], 0, 0, 0, ["@slow"], [], [], [["pubsub|channels", -2, ["pubsub", "loading", "stale"], 0, 0, 0, ["@pubsub", "@slow"], [], [], []], ["pubsub|help", 2, ["loading", "stale"], 0, 0, 0, ["@slow"], [], [], []], ["pubsub|numpat", 2, ["pubsub", "loading", "stale"], 0, 0, 0, ["@pubsub", "@slow"], [], [], []], ["pubsub|numsub", -2, ["pubsub", "loading", "stale"], 0, 0, 0, ["@pubsub", "@slow"], [], [], []], ["pubsub|shardchannels", -2, ["pubsub", "loading", "stale"], 0, 0, 0, ["@pubsub", "@slow"], [], [], []], ["pubsub|shardnumsub", -2, ["pubsub", "loading", "stale"], 0, 0, 0, ["@pubsub", "@slow"], [], [], []], ["pubsub|channels", -2, ["pubsub", "loading", "stale"], 0, 0, 0, ["@pubsub", "@slow"], [], [], []], ["pubsub|help", 2, ["loading", "stale"], 0, 0, 0, ["@slow"], [], [], []], ["pubsub|numpat", 2, ["pubsub", "loading", "stale"], 0, 0, 0, ["@pubsub", "@slow"], [], [], []], ["pubsub|numsub", -2, ["pubsub", "loading", "stale"], 0, 0, 0, ["@pubsub", "@slow"], [], [], []], ["pubsub|shardchannels", -2, ["pubsub", "loading", "stale"], 0, 0, 0, ["@pubsub", "@slow"], [], [], []], ["pubsub|shardnumsub", -2, ["pubsub", "loading", "stale"], 0, 0, 0, ["@pubsub", "@slow"], [], [], []]]], "pubsub channels": ["pubsub|channels", -2, ["pubsub", "loading", "stale"], 0, 0, 0, ["@pubsub", "@slow"], [], [], []], "pubsub help": ["pubsub|help", 2, ["loading", "stale"], 0, 0, 0, ["@slow"], [], [], []], "pubsub numpat": ["pubsub|numpat", 2, ["pubsub", "loading", "stale"], 0, 0, 0, ["@pubsub", "@slow"], [], [], []], "pubsub numsub": ["pubsub|numsub", -2, ["pubsub", "loading", "stale"], 0, 0, 0, ["@pubsub", "@slow"], [], [], []], "pubsub shardchannels": ["pubsub|shardchannels", -2, ["pubsub", "loading", "stale"], 0, 0, 0, ["@pubsub", "@slow"], [], [], []], "pubsub shardnumsub": ["pubsub|shardnumsub", -2, ["pubsub", "loading", "stale"], 0, 0, 0, ["@pubsub", "@slow"], [], [], []], "punsubscribe": ["punsubscribe", -1, ["pubsub", "noscript", "loading", "stale"], 0, 0, 0, ["@pubsub", "@slow"], [], [], []], "randomkey": ["randomkey", 1, ["readonly"], 0, 0, 0, ["@keyspace", "@read", "@slow"], [], [], []], "rename": ["rename", 3, ["write"], 1, 2, 1, ["@keyspace", "@write", "@slow"], [], [], [["renamenx", 3, ["write", "fast"], 1, 2, 1, ["@keyspace", "@write", "@fast"], [], [], []]]], "renamenx": ["renamenx", 3, ["write", "fast"], 1, 2, 1, ["@keyspace", "@write", "@fast"], [], [], []], "restore": ["restore", -4, ["write", "denyoom"], 1, 1, 1, ["@keyspace", "@write", "@slow", "@dangerous"], [], [], [["restore-asking", -4, ["write", "denyoom", "asking"], 1, 1, 1, ["@keyspace", "@write", "@slow", "@dangerous"], [], [], []]]], "rpop": ["rpop", -2, ["write", "fast"], 1, 1, 1, ["@write", "@list", "@fast"], [], [], [["rpoplpush", 3, ["write", "denyoom"], 1, 2, 1, ["@write", "@list", "@slow"], [], [], []]]], "rpoplpush": ["rpoplpush", 3, ["write", "denyoom"], 1, 2, 1, ["@write", "@list", "@slow"], [], [], []], "rpush": ["rpush", -3, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@list", "@fast"], [], [], [["rpushx", -3, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@list", "@fast"], [], [], []]]], "rpushx": ["rpushx", -3, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@list", "@fast"], [], [], []], "sadd": ["sadd", -3, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@set", "@fast"], [], [], []], "save": ["save", 1, ["admin", "noscript", "no_async_loading", "no_multi"], 0, 0, 0, ["@admin", "@slow", "@dangerous"], [], [], []], "scan": ["scan", -2, ["readonly"], 0, 0, 0, ["@keyspace", "@read", "@slow"], [], [], []], "scard": ["scard", 2, ["readonly", "fast"], 1, 1, 1, ["@read", "@set", "@fast"], [], [], []], "script": ["script", -2, [], 0, 0, 0, ["@slow"], [], [], [["script|debug", 3, ["noscript"], 0, 0, 0, ["@slow", "@scripting"], [], [], []], ["script|exists", -3, ["noscript"], 0, 0, 0, ["@slow", "@scripting"], [], [], []], ["script|flush", -2, ["noscript"], 0, 0, 0, ["@slow", "@scripting"], [], [], []], ["script|help", 2, ["loading", "stale"], 0, 0, 0, ["@slow", "@scripting"], [], [], []], ["script|kill", 2, ["noscript", "allow_busy"], 0, 0, 0, ["@slow", "@scripting"], [], [], []], ["script|load", 3, ["noscript", "stale"], 0, 0, 0, ["@slow", "@scripting"], [], [], []], ["script|exists", -3, ["noscript"], 0, 0, 0, ["@slow", "@scripting"], [], [], []], ["script|flush", -2, ["noscript"], 0, 0, 0, ["@slow", "@scripting"], [], [], []], ["script|help", 2, ["loading", "stale"], 0, 0, 0, ["@slow", "@scripting"], [], [], []], ["script|load", 3, ["noscript", "stale"], 0, 0, 0, ["@slow", "@scripting"], [], [], []]]], "script exists": ["script|exists", -3, ["noscript"], 0, 0, 0, ["@slow", "@scripting"], [], [], []], "script flush": ["script|flush", -2, ["noscript"], 0, 0, 0, ["@slow", "@scripting"], [], [], []], "script help": ["script|help", 2, ["loading", "stale"], 0, 0, 0, ["@slow", "@scripting"], [], [], []], "script load": ["script|load", 3, ["noscript", "stale"], 0, 0, 0, ["@slow", "@scripting"], [], [], []], "sdiff": ["sdiff", -2, ["readonly"], 1, 1, 1, ["@read", "@set", "@slow"], [], [], [["sdiffstore", -3, ["write", "denyoom"], 1, 2, 1, ["@write", "@set", "@slow"], [], [], []]]], "sdiffstore": ["sdiffstore", -3, ["write", "denyoom"], 1, 2, 1, ["@write", "@set", "@slow"], [], [], []], "select": ["select", 2, ["loading", "stale", "fast"], 0, 0, 0, ["@fast", "@connection"], [], [], []], "set": ["set", -3, ["write", "denyoom"], 1, 1, 1, ["@write", "@string", "@slow"], [], [], [["setbit", 4, ["write", "denyoom"], 1, 1, 1, ["@write", "@bitmap", "@slow"], [], [], []], ["setex", 4, ["write", "denyoom"], 1, 1, 1, ["@write", "@string", "@slow"], [], [], []], ["setnx", 3, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@string", "@fast"], [], [], []], ["setrange", 4, ["write", "denyoom"], 1, 1, 1, ["@write", "@string", "@slow"], [], [], []]]], "setbit": ["setbit", 4, ["write", "denyoom"], 1, 1, 1, ["@write", "@bitmap", "@slow"], [], [], []], "setex": ["setex", 4, ["write", "denyoom"], 1, 1, 1, ["@write", "@string", "@slow"], [], [], []], "setnx": ["setnx", 3, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@string", "@fast"], [], [], []], "setrange": ["setrange", 4, ["write", "denyoom"], 1, 1, 1, ["@write", "@string", "@slow"], [], [], []], "sinter": ["sinter", -2, ["readonly"], 1, 1, 1, ["@read", "@set", "@slow"], [], [], [["sintercard", -3, ["readonly", "movablekeys"], 1, 1, 1, ["@read", "@set", "@slow"], [], [], []], ["sinterstore", -3, ["write", "denyoom"], 1, 2, 1, ["@write", "@set", "@slow"], [], [], []]]], "sintercard": ["sintercard", -3, ["readonly", "movablekeys"], 1, 1, 1, ["@read", "@set", "@slow"], [], [], []], "sinterstore": ["sinterstore", -3, ["write", "denyoom"], 1, 2, 1, ["@write", "@set", "@slow"], [], [], []], "sismember": ["sismember", 3, ["readonly", "fast"], 1, 1, 1, ["@read", "@set", "@fast"], [], [], []], "smembers": ["smembers", 2, ["readonly"], 1, 1, 1, ["@read", "@set", "@slow"], [], [], []], "smismember": ["smismember", -3, ["readonly", "fast"], 1, 1, 1, ["@read", "@set", "@fast"], [], [], []], "smove": ["smove", 4, ["write", "fast"], 1, 2, 1, ["@write", "@set", "@fast"], [], [], []], "sort": ["sort", -2, ["write", "denyoom", "movablekeys"], 1, 0, 1, ["@write", "@set", "@sortedset", "@list", "@slow", "@dangerous"], [], [], [["sort_ro", -2, ["readonly", "movablekeys"], 1, 0, 1, ["@read", "@set", "@sortedset", "@list", "@slow", "@dangerous"], [], [], []]]], "sort_ro": ["sort_ro", -2, ["readonly", "movablekeys"], 1, 0, 1, ["@read", "@set", "@sortedset", "@list", "@slow", "@dangerous"], [], [], []], "spop": ["spop", -2, ["write", "fast"], 1, 1, 1, ["@write", "@set", "@fast"], [], [], []], "spublish": ["spublish", 3, ["pubsub", "loading", "stale", "fast"], 1, 1, 1, ["@pubsub", "@fast"], [], [], []], "srandmember": ["srandmember", -2, ["readonly"], 1, 1, 1, ["@read", "@set", "@slow"], [], [], []], "srem": ["srem", -3, ["write", "fast"], 1, 1, 1, ["@write", "@set", "@fast"], [], [], []], "sscan": ["sscan", -3, ["readonly"], 1, 1, 1, ["@read", "@set", "@slow"], [], [], []], "ssubscribe": ["ssubscribe", -2, ["pubsub", "noscript", "loading", "stale"], 1, 1, 1, ["@pubsub", "@slow"], [], [], []], "strlen": ["strlen", 2, ["readonly", "fast"], 1, 1, 1, ["@read", "@string", "@fast"], [], [], []], "subscribe": ["subscribe", -2, ["pubsub", "noscript", "loading", "stale"], 0, 0, 0, ["@pubsub", "@slow"], [], [], []], "substr": ["substr", 4, ["readonly"], 1, 1, 1, ["@read", "@string", "@slow"], [], [], []], "sunion": ["sunion", -2, ["readonly"], 1, 1, 1, ["@read", "@set", "@slow"], [], [], [["sunionstore", -3, ["write", "denyoom"], 1, 2, 1, ["@write", "@set", "@slow"], [], [], []]]], "sunionstore": ["sunionstore", -3, ["write", "denyoom"], 1, 2, 1, ["@write", "@set", "@slow"], [], [], []], "sunsubscribe": ["sunsubscribe", -1, ["pubsub", "noscript", "loading", "stale"], 1, 1, 1, ["@pubsub", "@slow"], [], [], []], "swapdb": ["swapdb", 3, ["write", "fast"], 0, 0, 0, ["@keyspace", "@write", "@fast", "@dangerous"], [], [], []], "time": ["time", 1, ["loading", "stale", "fast"], 0, 0, 0, ["@fast"], [], [], []], "ttl": ["ttl", 2, ["readonly", "fast"], 1, 1, 1, ["@keyspace", "@read", "@fast"], [], [], []], "type": ["type", 2, ["readonly", "fast"], 1, 1, 1, ["@keyspace", "@read", "@fast"], [], [], []], "unlink": ["unlink", -2, ["write", "fast"], 1, 1, 1, ["@keyspace", "@write", "@fast"], [], [], []], "unsubscribe": ["unsubscribe", -1, ["pubsub", "noscript", "loading", "stale"], 0, 0, 0, ["@pubsub", "@slow"], [], [], []], "unwatch": ["unwatch", 1, ["noscript", "loading", "stale", "fast", "allow_busy"], 0, 0, 0, ["@fast", "@transaction"], [], [], []], "watch": ["watch", -2, ["noscript", "loading", "stale", "fast", "allow_busy"], 1, 1, 1, ["@fast", "@transaction"], [], [], []], "xack": ["xack", -4, ["write", "fast"], 1, 1, 1, ["@write", "@stream", "@fast"], [], [], []], "xadd": ["xadd", -5, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@stream", "@fast"], [], [], []], "xautoclaim": ["xautoclaim", -6, ["write", "fast"], 1, 1, 1, ["@write", "@stream", "@fast"], [], [], []], "xclaim": ["xclaim", -6, ["write", "fast"], 1, 1, 1, ["@write", "@stream", "@fast"], [], [], []], "xdel": ["xdel", -3, ["write", "fast"], 1, 1, 1, ["@write", "@stream", "@fast"], [], [], []], "xgroup create": ["xgroup|create", -5, ["write", "denyoom"], 2, 2, 1, ["@write", "@stream", "@slow"], [], [], [["xgroup|createconsumer", 5, ["write", "denyoom"], 2, 2, 1, ["@write", "@stream", "@slow"], [], [], []]]], "xgroup": ["xgroup", -1, [], 0, 0, 0, [], [], [], [["xgroup|create", -5, ["write", "denyoom"], 2, 2, 1, ["@write", "@stream", "@slow"], [], [], [["xgroup|createconsumer", 5, ["write", "denyoom"], 2, 2, 1, ["@write", "@stream", "@slow"], [], [], []]]], ["xgroup|createconsumer", 5, ["write", "denyoom"], 2, 2, 1, ["@write", "@stream", "@slow"], [], [], []], ["xgroup|delconsumer", 5, ["write"], 2, 2, 1, ["@write", "@stream", "@slow"], [], [], []], ["xgroup|destroy", 4, ["write"], 2, 2, 1, ["@write", "@stream", "@slow"], [], [], []], ["xgroup|setid", -5, ["write"], 2, 2, 1, ["@write", "@stream", "@slow"], [], [], []]]], "xgroup createconsumer": ["xgroup|createconsumer", 5, ["write", "denyoom"], 2, 2, 1, ["@write", "@stream", "@slow"], [], [], []], "xgroup delconsumer": ["xgroup|delconsumer", 5, ["write"], 2, 2, 1, ["@write", "@stream", "@slow"], [], [], []], "xgroup destroy": ["xgroup|destroy", 4, ["write"], 2, 2, 1, ["@write", "@stream", "@slow"], [], [], []], "xgroup setid": ["xgroup|setid", -5, ["write"], 2, 2, 1, ["@write", "@stream", "@slow"], [], [], []], "xinfo consumers": ["xinfo|consumers", 4, ["readonly"], 2, 2, 1, ["@read", "@stream", "@slow"], [], [], []], "xinfo": ["xinfo", -1, [], 0, 0, 0, [], [], [], [["xinfo|consumers", 4, ["readonly"], 2, 2, 1, ["@read", "@stream", "@slow"], [], [], []], ["xinfo|groups", 3, ["readonly"], 2, 2, 1, ["@read", "@stream", "@slow"], [], [], []], ["xinfo|stream", -3, ["readonly"], 2, 2, 1, ["@read", "@stream", "@slow"], [], [], []]]], "xinfo groups": ["xinfo|groups", 3, ["readonly"], 2, 2, 1, ["@read", "@stream", "@slow"], [], [], []], "xinfo stream": ["xinfo|stream", -3, ["readonly"], 2, 2, 1, ["@read", "@stream", "@slow"], [], [], []], "xlen": ["xlen", 2, ["readonly", "fast"], 1, 1, 1, ["@read", "@stream", "@fast"], [], [], []], "xpending": ["xpending", -3, ["readonly"], 1, 1, 1, ["@read", "@stream", "@slow"], [], [], []], "xrange": ["xrange", -4, ["readonly"], 1, 1, 1, ["@read", "@stream", "@slow"], [], [], []], "xread": ["xread", -4, ["readonly", "blocking", "movablekeys"], 0, 0, 1, ["@read", "@stream", "@slow", "@blocking"], [], [], [["xreadgroup", -7, ["write", "blocking", "movablekeys"], 0, 0, 1, ["@write", "@stream", "@slow", "@blocking"], [], [], []]]], "xreadgroup": ["xreadgroup", -7, ["write", "blocking", "movablekeys"], 0, 0, 1, ["@write", "@stream", "@slow", "@blocking"], [], [], []], "xrevrange": ["xrevrange", -4, ["readonly"], 1, 1, 1, ["@read", "@stream", "@slow"], [], [], []], "xtrim": ["xtrim", -4, ["write"], 1, 1, 1, ["@write", "@stream", "@slow"], [], [], []], "zadd": ["zadd", -4, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@sortedset", "@fast"], [], [], []], "zcard": ["zcard", 2, ["readonly", "fast"], 1, 1, 1, ["@read", "@sortedset", "@fast"], [], [], []], "zcount": ["zcount", 4, ["readonly", "fast"], 1, 1, 1, ["@read", "@sortedset", "@fast"], [], [], []], "zdiff": ["zdiff", -3, ["readonly", "movablekeys"], 1, 1, 1, ["@read", "@sortedset", "@slow"], [], [], [["zdiffstore", -4, ["write", "denyoom", "movablekeys"], 1, 2, 1, ["@write", "@sortedset", "@slow"], [], [], []]]], "zdiffstore": ["zdiffstore", -4, ["write", "denyoom", "movablekeys"], 1, 2, 1, ["@write", "@sortedset", "@slow"], [], [], []], "zincrby": ["zincrby", 4, ["write", "denyoom", "fast"], 1, 1, 1, ["@write", "@sortedset", "@fast"], [], [], []], "zinter": ["zinter", -3, ["readonly", "movablekeys"], 1, 1, 1, ["@read", "@sortedset", "@slow"], [], [], [["zintercard", -3, ["readonly", "movablekeys"], 1, 1, 1, ["@read", "@sortedset", "@slow"], [], [], []], ["zinterstore", -4, ["write", "denyoom", "movablekeys"], 1, 2, 1, ["@write", "@sortedset", "@slow"], [], [], []]]], "zintercard": ["zintercard", -3, ["readonly", "movablekeys"], 1, 1, 1, ["@read", "@sortedset", "@slow"], [], [], []], "zinterstore": ["zinterstore", -4, ["write", "denyoom", "movablekeys"], 1, 2, 1, ["@write", "@sortedset", "@slow"], [], [], []], "zlexcount": ["zlexcount", 4, ["readonly", "fast"], 1, 1, 1, ["@read", "@sortedset", "@fast"], [], [], []], "zmpop": ["zmpop", -4, ["write", "movablekeys"], 1, 1, 1, ["@write", "@sortedset", "@slow"], [], [], []], "zmscore": ["zmscore", -3, ["readonly", "fast"], 1, 1, 1, ["@read", "@sortedset", "@fast"], [], [], []], "zpopmax": ["zpopmax", -2, ["write", "fast"], 1, 1, 1, ["@write", "@sortedset", "@fast"], [], [], []], "zpopmin": ["zpopmin", -2, ["write", "fast"], 1, 1, 1, ["@write", "@sortedset", "@fast"], [], [], []], "zrandmember": ["zrandmember", -2, ["readonly"], 1, 1, 1, ["@read", "@sortedset", "@slow"], [], [], []], "zrange": ["zrange", -4, ["readonly"], 1, 1, 1, ["@read", "@sortedset", "@slow"], [], [], [["zrangebylex", -4, ["readonly"], 1, 1, 1, ["@read", "@sortedset", "@slow"], [], [], []], ["zrangebyscore", -4, ["readonly"], 1, 1, 1, ["@read", "@sortedset", "@slow"], [], [], []], ["zrangestore", -5, ["write", "denyoom"], 1, 2, 1, ["@write", "@sortedset", "@slow"], [], [], []]]], "zrangebylex": ["zrangebylex", -4, ["readonly"], 1, 1, 1, ["@read", "@sortedset", "@slow"], [], [], []], "zrangebyscore": ["zrangebyscore", -4, ["readonly"], 1, 1, 1, ["@read", "@sortedset", "@slow"], [], [], []], "zrangestore": ["zrangestore", -5, ["write", "denyoom"], 1, 2, 1, ["@write", "@sortedset", "@slow"], [], [], []], "zrank": ["zrank", -3, ["readonly", "fast"], 1, 1, 1, ["@read", "@sortedset", "@fast"], [], [], []], "zrem": ["zrem", -3, ["write", "fast"], 1, 1, 1, ["@write", "@sortedset", "@fast"], [], [], [["zremrangebylex", 4, ["write"], 1, 1, 1, ["@write", "@sortedset", "@slow"], [], [], []], ["zremrangebyrank", 4, ["write"], 1, 1, 1, ["@write", "@sortedset", "@slow"], [], [], []], ["zremrangebyscore", 4, ["write"], 1, 1, 1, ["@write", "@sortedset", "@slow"], [], [], []]]], "zremrangebylex": ["zremrangebylex", 4, ["write"], 1, 1, 1, ["@write", "@sortedset", "@slow"], [], [], []], "zremrangebyrank": ["zremrangebyrank", 4, ["write"], 1, 1, 1, ["@write", "@sortedset", "@slow"], [], [], []], "zremrangebyscore": ["zremrangebyscore", 4, ["write"], 1, 1, 1, ["@write", "@sortedset", "@slow"], [], [], []], "zrevrange": ["zrevrange", -4, ["readonly"], 1, 1, 1, ["@read", "@sortedset", "@slow"], [], [], [["zrevrangebylex", -4, ["readonly"], 1, 1, 1, ["@read", "@sortedset", "@slow"], [], [], []], ["zrevrangebyscore", -4, ["readonly"], 1, 1, 1, ["@read", "@sortedset", "@slow"], [], [], []]]], "zrevrangebylex": ["zrevrangebylex", -4, ["readonly"], 1, 1, 1, ["@read", "@sortedset", "@slow"], [], [], []], "zrevrangebyscore": ["zrevrangebyscore", -4, ["readonly"], 1, 1, 1, ["@read", "@sortedset", "@slow"], [], [], []], "zrevrank": ["zrevrank", -3, ["readonly", "fast"], 1, 1, 1, ["@read", "@sortedset", "@fast"], [], [], []], "zscan": ["zscan", -3, ["readonly"], 1, 1, 1, ["@read", "@sortedset", "@slow"], [], [], []], "zscore": ["zscore", 3, ["readonly", "fast"], 1, 1, 1, ["@read", "@sortedset", "@fast"], [], [], []], "zunion": ["zunion", -3, ["readonly", "movablekeys"], 1, 1, 1, ["@read", "@sortedset", "@slow"], [], [], [["zunionstore", -4, ["write", "denyoom", "movablekeys"], 1, 2, 1, ["@write", "@sortedset", "@slow"], [], [], []]]], "zunionstore": ["zunionstore", -4, ["write", "denyoom", "movablekeys"], 1, 2, 1, ["@write", "@sortedset", "@slow"], [], [], []], "json.del": ["json.del", -1, [], 0, 0, 0, [], [], [], []], "json.forget": ["json.forget", -1, [], 0, 0, 0, [], [], [], []], "json.get": ["json.get", -1, [], 0, 0, 0, [], [], [], []], "json.toggle": ["json.toggle", -1, [], 0, 0, 0, [], [], [], []], "json.clear": ["json.clear", -1, [], 0, 0, 0, [], [], [], []], "json.set": ["json.set", -1, [], 0, 0, 0, [], [], [], []], "json.mset": ["json.mset", -1, [], 0, 0, 0, [], [], [], []], "json.merge": ["json.merge", -1, [], 0, 0, 0, [], [], [], []], "json.mget": ["json.mget", -1, [], 0, 0, 0, [], [], [], []], "json.numincrby": ["json.numincrby", -1, [], 0, 0, 0, [], [], [], []], "json.nummultby": ["json.nummultby", -1, [], 0, 0, 0, [], [], [], []], "json.strappend": ["json.strappend", -1, [], 0, 0, 0, [], [], [], []], "json.strlen": ["json.strlen", -1, [], 0, 0, 0, [], [], [], []], "json.arrappend": ["json.arrappend", -1, [], 0, 0, 0, [], [], [], []], "json.arrindex": ["json.arrindex", -1, [], 0, 0, 0, [], [], [], []], "json.arrinsert": ["json.arrinsert", -1, [], 0, 0, 0, [], [], [], []], "json.arrlen": ["json.arrlen", -1, [], 0, 0, 0, [], [], [], []], "json.arrpop": ["json.arrpop", -1, [], 0, 0, 0, [], [], [], []], "json.arrtrim": ["json.arrtrim", -1, [], 0, 0, 0, [], [], [], []], "json.objkeys": ["json.objkeys", -1, [], 0, 0, 0, [], [], [], []], "json.objlen": ["json.objlen", -1, [], 0, 0, 0, [], [], [], []], "json.type": ["json.type", -1, [], 0, 0, 0, [], [], [], []], "ts.create": ["ts.create", -1, [], 0, 0, 0, [], [], [], [["ts.createrule", -1, [], 0, 0, 0, [], [], [], []]]], "ts.del": ["ts.del", -1, [], 0, 0, 0, [], [], [], [["ts.deleterule", -1, [], 0, 0, 0, [], [], [], []]]], "ts.alter": ["ts.alter", -1, [], 0, 0, 0, [], [], [], []], "ts.add": ["ts.add", -1, [], 0, 0, 0, [], [], [], []], "ts.madd": ["ts.madd", -1, [], 0, 0, 0, [], [], [], []], "ts.incrby": ["ts.incrby", -1, [], 0, 0, 0, [], [], [], []], "ts.decrby": ["ts.decrby", -1, [], 0, 0, 0, [], [], [], []], "ts.createrule": ["ts.createrule", -1, [], 0, 0, 0, [], [], [], []], "ts.deleterule": ["ts.deleterule", -1, [], 0, 0, 0, [], [], [], []], "ts.range": ["ts.range", -1, [], 0, 0, 0, [], [], [], []], "ts.revrange": ["ts.revrange", -1, [], 0, 0, 0, [], [], [], []], "ts.mrange": ["ts.mrange", -1, [], 0, 0, 0, [], [], [], []], "ts.mrevrange": ["ts.mrevrange", -1, [], 0, 0, 0, [], [], [], []], "ts.get": ["ts.get", -1, [], 0, 0, 0, [], [], [], []], "ts.mget": ["ts.mget", -1, [], 0, 0, 0, [], [], [], []], "ts.info": ["ts.info", -1, [], 0, 0, 0, [], [], [], []], "ts.queryindex": ["ts.queryindex", -1, [], 0, 0, 0, [], [], [], []], "bf.reserve": ["bf.reserve", -1, [], 0, 0, 0, [], [], [], []], "bf.add": ["bf.add", -1, [], 0, 0, 0, [], [], [], []], "bf.madd": ["bf.madd", -1, [], 0, 0, 0, [], [], [], []], "bf.insert": ["bf.insert", -1, [], 0, 0, 0, [], [], [], []], "bf.exists": ["bf.exists", -1, [], 0, 0, 0, [], [], [], []], "bf.mexists": ["bf.mexists", -1, [], 0, 0, 0, [], [], [], []], "bf.scandump": ["bf.scandump", -1, [], 0, 0, 0, [], [], [], []], "bf.loadchunk": ["bf.loadchunk", -1, [], 0, 0, 0, [], [], [], []], "bf.info": ["bf.info", -1, [], 0, 0, 0, [], [], [], []], "bf.card": ["bf.card", -1, [], 0, 0, 0, [], [], [], []], "cf.reserve": ["cf.reserve", -1, [], 0, 0, 0, [], [], [], []], "cf.add": ["cf.add", -1, [], 0, 0, 0, [], [], [], [["cf.addnx", -1, [], 0, 0, 0, [], [], [], []]]], "cf.addnx": ["cf.addnx", -1, [], 0, 0, 0, [], [], [], []], "cf.insert": ["cf.insert", -1, [], 0, 0, 0, [], [], [], [["cf.insertnx", -1, [], 0, 0, 0, [], [], [], []]]], "cf.insertnx": ["cf.insertnx", -1, [], 0, 0, 0, [], [], [], []], "cf.exists": ["cf.exists", -1, [], 0, 0, 0, [], [], [], []], "cf.mexists": ["cf.mexists", -1, [], 0, 0, 0, [], [], [], []], "cf.del": ["cf.del", -1, [], 0, 0, 0, [], [], [], []], "cf.count": ["cf.count", -1, [], 0, 0, 0, [], [], [], []], "cf.scandump": ["cf.scandump", -1, [], 0, 0, 0, [], [], [], []], "cf.loadchunk": ["cf.loadchunk", -1, [], 0, 0, 0, [], [], [], []], "cf.info": ["cf.info", -1, [], 0, 0, 0, [], [], [], []], "cms.initbydim": ["cms.initbydim", -1, [], 0, 0, 0, [], [], [], []], "cms.initbyprob": ["cms.initbyprob", -1, [], 0, 0, 0, [], [], [], []], "cms.incrby": ["cms.incrby", -1, [], 0, 0, 0, [], [], [], []], "cms.query": ["cms.query", -1, [], 0, 0, 0, [], [], [], []], "cms.merge": ["cms.merge", -1, [], 0, 0, 0, [], [], [], []], "cms.info": ["cms.info", -1, [], 0, 0, 0, [], [], [], []], "topk.reserve": ["topk.reserve", -1, [], 0, 0, 0, [], [], [], []], "topk.add": ["topk.add", -1, [], 0, 0, 0, [], [], [], []], "topk.incrby": ["topk.incrby", -1, [], 0, 0, 0, [], [], [], []], "topk.query": ["topk.query", -1, [], 0, 0, 0, [], [], [], []], "topk.count": ["topk.count", -1, [], 0, 0, 0, [], [], [], []], "topk.list": ["topk.list", -1, [], 0, 0, 0, [], [], [], []], "topk.info": ["topk.info", -1, [], 0, 0, 0, [], [], [], []], "tdigest.create": ["tdigest.create", -1, [], 0, 0, 0, [], [], [], []], "tdigest.reset": ["tdigest.reset", -1, [], 0, 0, 0, [], [], [], []], "tdigest.add": ["tdigest.add", -1, [], 0, 0, 0, [], [], [], []], "tdigest.merge": ["tdigest.merge", -1, [], 0, 0, 0, [], [], [], []], "tdigest.min": ["tdigest.min", -1, [], 0, 0, 0, [], [], [], []], "tdigest.max": ["tdigest.max", -1, [], 0, 0, 0, [], [], [], []], "tdigest.quantile": ["tdigest.quantile", -1, [], 0, 0, 0, [], [], [], []], "tdigest.cdf": ["tdigest.cdf", -1, [], 0, 0, 0, [], [], [], []], "tdigest.trimmed_mean": ["tdigest.trimmed_mean", -1, [], 0, 0, 0, [], [], [], []], "tdigest.rank": ["tdigest.rank", -1, [], 0, 0, 0, [], [], [], []], "tdigest.revrank": ["tdigest.revrank", -1, [], 0, 0, 0, [], [], [], []], "tdigest.byrank": ["tdigest.byrank", -1, [], 0, 0, 0, [], [], [], []], "tdigest.byrevrank": ["tdigest.byrevrank", -1, [], 0, 0, 0, [], [], [], []], "tdigest.info": ["tdigest.info", -1, [], 0, 0, 0, [], [], [], []]} \ No newline at end of file diff --git a/fakeredis/model/_acl.py b/fakeredis/model/_acl.py index aa975d54..d0bdf2e7 100644 --- a/fakeredis/model/_acl.py +++ b/fakeredis/model/_acl.py @@ -1,5 +1,6 @@ +import fnmatch import hashlib -from typing import Dict, Set, List, Union, Optional +from typing import Dict, Set, List, Union, Optional, Sequence from fakeredis import _msgs as msgs from ._command_info import get_commands_by_category, get_command_info @@ -62,17 +63,43 @@ def reset(self): self._channel_patterns.clear() self._selectors.clear() - def command_allowed(self, command: bytes) -> bool: - command = command.lower() - res = command == b"auth" or self._commands.get(command, False) - res = res or self._commands.get(b"@all", False) + @staticmethod + def _get_command_info(fields: List[bytes]): + command = fields[0].lower() command_info = get_command_info(command) + if not command_info and len(fields) > 1: + command = command + b" " + fields[1].lower() + command_info = get_command_info(command) + return command_info + + def command_allowed(self, fields: List[bytes]) -> bool: + res = fields[0].lower() == b"auth" or self._commands.get(fields[0].lower(), False) + res = res or self._commands.get(b"@all", False) + command_info = self._get_command_info(fields) if not command_info: return res for category in command_info[6]: res = res or self._commands.get(category, False) return res + def _get_keys(self, fields: List[bytes]) -> List[bytes]: + command_info = self._get_command_info(fields) + if not command_info: + return [] + first_key, last_key, step = command_info[3:6] + if first_key == 0: + return [] + last_key = (last_key + 1) if last_key >= 0 else last_key + step = step + 1 + return fields[first_key : last_key + 1 : step] + + def keys_not_allowed(self, fields: List[bytes]) -> List[bytes]: + keys = self._get_keys(fields) + res = set() + for pat in self._key_patterns: + res = res.union(fnmatch.filter(keys, pat)) + return list(set(keys) - res) + def set_nopass(self) -> None: self._nopass = True self._passwords.clear() @@ -306,15 +333,18 @@ def add_log_record( ) self._log.append(entry) - def validate_command(self, username: bytes, fields: List[bytes]): + def validate_command(self, username: bytes, client_info: bytes, fields: List[bytes]): if username not in self._user_acl: return user_acl = self._user_acl[username] if not user_acl.enabled: raise SimpleError("User disabled") - command, args = fields[0], fields[1:] - - if not user_acl.command_allowed(command): - raise SimpleError(msgs.NO_PERMISSION_ERROR.format(username.decode(), command.lower().decode())) + if not user_acl.command_allowed(fields): + self.add_log_record(b"command", b"toplevel", fields[0], username, client_info) + raise SimpleError(msgs.NO_PERMISSION_ERROR.format(username.decode(), fields[0].lower().decode())) + keys_not_allowed = user_acl.keys_not_allowed(fields) + if len(keys_not_allowed) > 0: + self.add_log_record(b"key", b"toplevel", keys_not_allowed[0], username, client_info) + raise SimpleError(msgs.NO_PERMISSION_KEY_ERROR) # todo diff --git a/scripts/generate_command_info.py b/scripts/generate_command_info.py index b39f7ea5..f9dea2bd 100644 --- a/scripts/generate_command_info.py +++ b/scripts/generate_command_info.py @@ -98,6 +98,14 @@ def get_command_info(cmd_name: str, all_commands: Dict[str, Any]) -> List[Any]: if cmd not in implemented: continue command_info_dict[cmd] = get_command_info(cmd, cmds) + subcommand = cmd.split(" ") + if len(subcommand) > 1: + ( + command_info_dict.setdefault(subcommand[0], [subcommand[0], -1, [], 0, 0, 0, [], [], [], []])[ + 9 + ].append(command_info_dict[cmd]) + ) + print(command_info_dict[cmd]) with open(os.path.join(os.path.dirname(__file__), "..", "fakeredis", "commands.json"), "w") as f: json.dump(command_info_dict, f) diff --git a/test/test_mixins/test_acl_commands.py b/test/test_mixins/test_acl_commands.py index 16aad3df..08022a58 100644 --- a/test/test_mixins/test_acl_commands.py +++ b/test/test_mixins/test_acl_commands.py @@ -317,15 +317,17 @@ def teardown(): assert r.get("cache:0") == b"1" # Invalid operation - with pytest.raises(exceptions.NoPermissionError) as command_not_permitted: + with pytest.raises(exceptions.NoPermissionError) as ctx: r.hset("cache:0", "hkey", "hval") - assert str(command_not_permitted.value) == "User fredis-py-user has no permissions to run the 'hset' command" + assert str(ctx.value) == "User fredis-py-user has no permissions to run the 'hset' command" # Invalid key - with pytest.raises(exceptions.NoPermissionError): + with pytest.raises(exceptions.NoPermissionError) as ctx: r.get("violated_cache:0") + assert str(ctx.value) == "No permissions to access a key" + r.auth("", "default") log = r.acl_log() assert isinstance(log, list)