Describe the bug
Lua Script returns value for a key but cant perform basic arithmetic operation
To reproduce
Value is set in redis with following code:
client.getBucket(keyX).set(2000);
I could fetch the same value with
client.getBucket(keyX).get();
Bu fails on basic arithmetic operation (adding 5 to the number). Throws error - unable to perform arithmetic operation on string.
String script="local limit=redis.call('GET','keyX'); return limit+5;";
String script="local limit=redis.call('GET','keyX'); return tonumber(limit)+5;";
But if for the same key, I just return value limit without any operation it returns value.
String script="local limit=redis.call('GET','keyX'); return limit;";
Similarly, If I just try to return value converting it with tonumber, fails. Throws error - unable to perform arithmetic operation on nil value.
String script="local limit=redis.call('GET','keyX'); return tonumber(limit);";
For all above scenarios, I have tried it using redis-cli & redis java client redisson. Both are giving same error.
With redis-cli, running command as follows:
eval "script" 0
With redisson java client, code is as follows:
RScript rScript = client.getScript();
String scriptSHA = rScript.scriptLoad(script);
Object quotaObj = rScript.evalSha(RScript.Mode.READ_WRITE, scriptSHA, RScript.ReturnType.VALUE);
Expected behavior
It should return a value with arithmetic operation, at least after using tonumber function
Additional information
Client is with redis cluster mode config. Redis-cli version 7.0.0 Redisson 3.21.0 Redis is deployed in master-slave mode with 3 masters & 3 slaves.
Comment From: itamarhaber
Hello @Abhijeet104,
I cannot reproduce this, works as expected:
127.0.0.1:6379> SET keyX 2000
OK
127.0.0.1:6379> GET keyX
"2000"
(integer) 2005
127.0.0.1:6379> EVAL "local limit=redis.call('GET','keyX'); return limit;" 0
"2000"
127.0.0.1:6379> EVAL "local limit=redis.call('GET','keyX'); return limit+5;" 0
(integer) 2005
127.0.0.1:6379> EVAL "local limit=redis.call('GET','keyX'); return tonumber(limit)+5;" 0
(integer) 2005
Note that the "unable to perform arithmetic operation on string" error is probably due to having a non-number value stored at keyX. Similarly, the "unable to perform arithmetic operation on nil value" error is because keyX doesn't exist. Your experience is most likely due to not setting up keyX with a number value in some of your tests.
Comment From: Abhijeet104
As I told in the question, value was being set using redisson client & for some calculation Lua script was used.
Found the problem.
Redisson encodes while setting value by default, that was causing issue. Since value for keyX was encoded, so even if value was some number & after encoding it became some random string, which could not be converted into number at Redis during Lua script execution. Hence the error.
Problem got solved after changing the value set code as follows(using some codec)
client.getBucket(keyX,StringCodec.INSTANCE).set(2000);
and get the value in same fashion.