Done, it works properly now.
-- KEYS: [key1, key2, ..., keyn, tempkey]
-- ARGV: [JSON([[min1, max1], [min2, max2], ...])]
local _ARGV = cjson.decode(ARGV[1])
local dest = KEYS[#KEYS]
for i = 1, #_ARGV do
local _a = _ARGV[i]; table.insert(_a, 'withscores')
local chunk = redis.call('ZRANGEBYSCORE', KEYS[i], unpack(_a))
if #chunk > 0 then
for j = 1, #chunk, 2 do
-- Hah, the inversion of ordering for scores and members in ZSET
-- reading vs. writing bites us in the butt.
chunk[j], chunk[j+1] = chunk[j+1], chunk[j]
-- Fixing the flaw
local _s = redis.call('ZSCORE', dest, chunk[j+1])
if _s then
chunk[j] = chunk[j] + tonumber(_s)
end
-- Done, but maybe there's a better way
end
redis.call('ZADD', dest, unpack(chunk))
end
end
local ret = redis.call('ZRANGE', dest, 0, -1, 'withscores')
redis.call('DEL', dest)
return ret
'''