diff options
author | Eduardo Semprebon <eduardobr@gmail.com> | 2021-08-09 08:40:29 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-09 09:40:29 +0300 |
commit | d3356bf614155f2a4352a0630065d715ce073b8a (patch) | |
tree | 8bdad343594943673ca7336e784a000c54df7569 | |
parent | e8eeba7bee6add5286afc4d59db074a924fb9209 (diff) | |
download | redis-d3356bf614155f2a4352a0630065d715ce073b8a.tar.gz |
Add SORT_RO command (#9299)
Add a readonly variant of the STORE command, so it can be used on
read-only workloads (replica, ACL, etc)
-rw-r--r-- | src/server.c | 4 | ||||
-rw-r--r-- | src/server.h | 1 | ||||
-rw-r--r-- | src/sort.c | 13 | ||||
-rw-r--r-- | tests/unit/sort.tcl | 12 |
4 files changed, 28 insertions, 2 deletions
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] |