Error in Lua script (ZUNIONSTORE + unpack(KEYS) + AGGREGATE MIN) - Redis 2.6

550 views
Skip to first unread message

vicmargar

unread,
Apr 27, 2012, 9:50:24 PM4/27/12
to Redis DB
Hello, I've been trying to implement a use case for Redis sorted sets
using Lua scripting in Redis 2.6 and after a lot of time without being
able to make it work I've managed to reproduce my problem in a simple
scenario. I'm still not sure if I'm doing something wrong but
basically I can't get ZUNIONSTORE to work if i'm using unpack and
'AGGREGATE' 'MIN' at the same time:


redis 127.0.0.1:6379> zadd set1 1 key1
(integer) 1
redis 127.0.0.1:6379> zadd set1 1 key2
(integer) 1
redis 127.0.0.1:6379> zadd set2 2 key1
(integer) 1
redis 127.0.0.1:6379> zadd set2 1 key3
(integer) 1
redis 127.0.0.1:6379> eval "return redis.call('zunionstore', 'tmp', 3,
unpack(KEYS))" 3 set1 set2 set3
(integer) 3
redis 127.0.0.1:6379> zrange tmp 0 -1 WITHSCORES
1) "key2"
2) "1"
3) "key3"
4) "1"
5) "key1"
6) "3"
redis 127.0.0.1:6379> eval "return redis.call('zunionstore', 'tmp', 3,
unpack(KEYS), 'AGGREGATE', 'MIN')" 3 set1 set2 set3
(integer) 2
redis 127.0.0.1:6379> zrange tmp 0 -1 WITHSCORES
1) "key1"
2) "1"
3) "key2"
4) "1"
redis 127.0.0.1:6379> eval "return redis.call('zunionstore', 'tmp', 3,
'set1', 'set2', 'set3', 'AGGREGATE', 'MIN')" 0
(integer) 3
redis 127.0.0.1:6379> zrange tmp 0 -1 WITHSCORES
1) "key1"
2) "1"
3) "key2"
4) "1"
5) "key3"
6) "1"

Thank you for your help!

Javier Guerra Giraldez

unread,
Jul 23, 2012, 10:20:46 AM7/23/12
to redi...@googlegroups.com
On Sun, Jul 22, 2012 at 6:14 PM, Ziyan Zhou <ziya...@gmail.com> wrote:
> I am not sure why lua is so retarded.

to keep consistency to the arguments list.

the (fixed) 'AGGREGATE' and 'MIN' arguments are guaranteed to stay at
the same position, that is fifth and sixth.

multiple-returns are only allowed to expand fully at the end of an
argument list, so that subsequent arguments are not pushed around
unpredictably

--
Javier

Ziyan Zhou

unread,
Jul 24, 2012, 4:57:52 PM7/24/12
to redi...@googlegroups.com
Problem is there is no clear indication of what went wrong, it is hard to debug especially in vicmargar's case where the number of arguments stayed the same. His bug caused strange outcome, yet there is nothing to indicate an error, just hard to debug in general.

Also the code can be changed to:

local args = {'zunionstore', 'tmp', #KEYS, unpack(KEYS)}
args[#args + 1] = 'AGGREGATE'
args[#args + 1] = 'MIN'
redis.call(unpack(args))

To accommodate any number of KEYS, so 'AGGREGATE' and 'MIN' are not guaranteed to stay at 5th or 6th, instead, they are guaranteed to stay at the end.

Javier Guerra Giraldez

unread,
Jul 24, 2012, 5:07:36 PM7/24/12
to redi...@googlegroups.com
On Tue, Jul 24, 2012 at 3:57 PM, Ziyan Zhou <ziya...@gmail.com> wrote:
> Also the code can be changed to:
>
> local args = {'zunionstore', 'tmp', #KEYS, unpack(KEYS)}
> args[#args + 1] = 'AGGREGATE'
> args[#args + 1] = 'MIN'
> redis.call(unpack(args))

sure, that's the way to do it


> To accommodate any number of KEYS, so 'AGGREGATE' and 'MIN' are not
> guaranteed to stay at 5th or 6th, instead, they are guaranteed to stay at
> the end.

this is appropriate for a command line, or a data description language
(like Redis commands); but for a programming language, functions tend
to pick arguments at fixed positions in the arguments list, and that's
why Lua is designed like this.

--
Javier
Reply all
Reply to author
Forward
0 new messages