diff --git a/src/server.c b/src/server.c index 0ae43d148..756fa5be8 100644 --- a/src/server.c +++ b/src/server.c @@ -789,6 +789,10 @@ struct redisCommand redisCommandTable[] = { "write use-memory @list @set @sortedset @dangerous", 0,sortGetKeys,1,1,1,0,0,0}, + {"sort_ro",sortroCommand,-2, + "read-only @list @set @sortedset @dangerous", + 0,NULL,1,1,1,0,0,0}, + {"info",infoCommand,-1, "ok-loading ok-stale random @dangerous", 0,NULL,0,0,0,0,0,0}, diff --git a/src/server.h b/src/server.h index e45558f8e..4f797d592 100644 --- a/src/server.h +++ b/src/server.h @@ -2606,6 +2606,7 @@ void syncCommand(client *c); void flushdbCommand(client *c); void flushallCommand(client *c); void sortCommand(client *c); +void sortroCommand(client *c); void lremCommand(client *c); void lposCommand(client *c); void rpoplpushCommand(client *c); diff --git a/src/sort.c b/src/sort.c index 53f9ef0cb..1eb61f83a 100644 --- a/src/sort.c +++ b/src/sort.c @@ -189,7 +189,7 @@ int sortCompare(const void *s1, const void *s2) { /* The SORT command is the most complex command in Redis. Warning: this code * is optimized for speed and a bit less for readability */ -void sortCommand(client *c) { +void sortCommandGeneric(client *c, int readonly) { list *operations; unsigned int outputlen = 0; int desc = 0, alpha = 0; @@ -226,7 +226,7 @@ void sortCommand(client *c) { break; } j+=2; - } else if (!strcasecmp(c->argv[j]->ptr,"store") && leftargs >= 1) { + } else if (readonly == 0 && !strcasecmp(c->argv[j]->ptr,"store") && leftargs >= 1) { storekey = c->argv[j+1]; j++; } else if (!strcasecmp(c->argv[j]->ptr,"by") && leftargs >= 1) { @@ -595,3 +595,12 @@ void sortCommand(client *c) { } zfree(vector); } + +/* SORT wrapper function for read-only mode. */ +void sortroCommand(client *c) { + sortCommandGeneric(c, 1); +} + +void sortCommand(client *c) { + sortCommandGeneric(c, 0); +} diff --git a/tests/unit/sort.tcl b/tests/unit/sort.tcl index a892c3a48..a9264eadf 100644 --- a/tests/unit/sort.tcl +++ b/tests/unit/sort.tcl @@ -263,6 +263,18 @@ start_server { r lrange testb 0 -1 } {5 3 4} {cluster:skip} + test "SORT_RO - Successful case" { + r del mylist + r lpush mylist a + r set x:a 100 + r sort_ro mylist by nosort get x:*-> + } {100} {cluster:skip} + + test "SORT_RO - Cannot run with STORE arg" { + catch {r sort_ro foolist STORE bar} e + set e + } {ERR syntax error} + tags {"slow"} { set num 100 set res [create_random_dataset $num lpush]