10
votes

I am attempting to use the Redis TYPE command inside a Lua script (executed via EVAL)

local key_type = redis.call("TYPE", key)

According to the Redis documentation, this should return a string of "none", "zset" etc.

However the type of the returned value is a lua table. Comparing the value to a string always returns false.

I've managed to get around the problem by changing the call to

local key_type = redis.call("TYPE", key)["ok"]

This value is indeed a string and does work in string comparison commands. I am worried that this is a bug in my particular version of Redis and it will break in future versions when I upgrade.

Does anyone know if this is expected behaviour, or a bug?

1

1 Answers

12
votes

The TYPE command returns a status reply (a.k.a simple string), e.g "+list\r\n".

On Redis scripting side, call is implemented by luaRedisCallCommand which performs the real Redis command behind the scenes.

Once successfully executed, this function converts the command result with redisProtocolToLuaType.

When a status reply is encountered, this function creates a Lua table with "ok" as key, and the status reply as value (see redisProtocolToLuaType_Status). So:

  • there is no bug,
  • this is why redis.call("TYPE", key) is a table (and thus you need to get the value for the "ok" key as you did, to get key's type as a string).

Note: when you directly return the table, Redis takes care to get the value associated to the "ok" key, and returns it as a status reply, e.g:

> EVAL 'return redis.call("TYPE", "foo")' 
set

See this code section for more details.