diff --git a/src/redis.c b/src/redis.c index a4ab9a964..025394efc 100644 --- a/src/redis.c +++ b/src/redis.c @@ -222,7 +222,7 @@ struct redisCommand redisCommandTable[] = { {"replconf",replconfCommand,-1,"ars",0,NULL,0,0,0,0,0}, {"flushdb",flushdbCommand,1,"w",0,NULL,0,0,0,0,0}, {"flushall",flushallCommand,1,"w",0,NULL,0,0,0,0,0}, - {"sort",sortCommand,-2,"wmS",0,NULL,1,1,1,0,0}, + {"sort",sortCommand,-2,"wm",0,NULL,1,1,1,0,0}, {"info",infoCommand,-1,"rlt",0,NULL,0,0,0,0,0}, {"monitor",monitorCommand,1,"ars",0,NULL,0,0,0,0,0}, {"ttl",ttlCommand,2,"r",0,NULL,1,1,1,0,0}, diff --git a/src/redis.h b/src/redis.h index 34afd0f88..5e4ee844c 100644 --- a/src/redis.h +++ b/src/redis.h @@ -705,7 +705,6 @@ struct redisServer { list *unblocked_clients; /* list of clients to unblock before next loop */ /* Sort parameters - qsort_r() is only available under BSD so we * have to take this state global, in order to pass it to sortCompare() */ - int sort_dontsort; int sort_desc; int sort_alpha; int sort_bypattern; diff --git a/src/scripting.c b/src/scripting.c index be52a1141..35b654f77 100644 --- a/src/scripting.c +++ b/src/scripting.c @@ -282,8 +282,6 @@ int luaRedisGenericCommand(lua_State *lua, int raise_error) { * reply as expected. */ if ((cmd->flags & REDIS_CMD_SORT_FOR_SCRIPT) && (reply[0] == '*' && reply[1] != '-')) { - /* Skip this step if command is SORT but output was already sorted */ - if (cmd->proc != sortCommand || server.sort_dontsort) luaSortArray(lua); } sdsfree(reply); diff --git a/src/sort.c b/src/sort.c index c1ed5517f..e5178cd0d 100644 --- a/src/sort.c +++ b/src/sort.c @@ -215,8 +215,11 @@ void sortCommand(redisClient *c) { /* If we have STORE we need to force sorting for deterministic output * and replication. We use alpha sorting since this is guaranteed to - * work with any input. */ - if (storekey && dontsort) { + * work with any input. + * + * We also want determinism when SORT is called from Lua scripts, so + * in this case we also force alpha sorting. */ + if ((storekey || c->flags & REDIS_LUA_CLIENT) && dontsort) { dontsort = 0; alpha = 1; sortby = NULL; @@ -326,7 +329,6 @@ void sortCommand(redisClient *c) { } if (end >= vectorlen) end = vectorlen-1; - server.sort_dontsort = dontsort; if (dontsort == 0) { server.sort_desc = desc; server.sort_alpha = alpha; diff --git a/tests/unit/scripting.tcl b/tests/unit/scripting.tcl index 6d60e4198..057918716 100644 --- a/tests/unit/scripting.tcl +++ b/tests/unit/scripting.tcl @@ -203,23 +203,23 @@ start_server {tags {"scripting"}} { r eval {return redis.call('smembers','myset')} 0 } {a aa aaa azz b c d e f g h i l m n o p q r s t u v z} - test "SORT is normally not re-ordered by the scripting engine" { + test "SORT is normally not alpha re-ordered for the scripting engine" { r del myset r sadd myset 1 2 3 4 10 r eval {return redis.call('sort','myset','desc')} 0 } {10 4 3 2 1} - test "SORT BY output gets ordered by scripting" { + test "SORT BY output gets ordered for scripting" { r del myset r sadd myset a b c d e f g h i l m n o p q r s t u v z aa aaa azz r eval {return redis.call('sort','myset','by','_')} 0 } {a aa aaa azz b c d e f g h i l m n o p q r s t u v z} - test "SORT output containing NULLs is well handled by scripting" { + test "SORT BY with GET gets ordered for scripting" { r del myset r sadd myset a b c r eval {return redis.call('sort','myset','by','_','get','#','get','_:*')} 0 - } {{} {} {} a b c} + } {a {} b {} c {}} test "redis.sha1hex() implementation" { list [r eval {return redis.sha1hex('')} 0] \