Support by/get options for sort(_ro) in cluster mode when pattern implies slot. (#12728)
The by/get options of sort/sort_ro command used to be forbidden in cluster mode, since we are not sure which slot the pattern may be in. As the optimization done in #12536, patterns now can be mapped to slots, we should allow by/get options in cluster mode when the pattern maps to the same slot as the key.
This commit is contained in:
parent
3c0fd25201
commit
e95a5d4831
19
src/sort.c
19
src/sort.c
@ -32,6 +32,7 @@
|
||||
#include "server.h"
|
||||
#include "pqsort.h" /* Partial qsort for SORT+LIMIT */
|
||||
#include <math.h> /* isnan() */
|
||||
#include "cluster.h"
|
||||
|
||||
zskiplistNode* zslGetElementByRank(zskiplist *zsl, unsigned long rank);
|
||||
|
||||
@ -235,10 +236,12 @@ void sortCommandGeneric(client *c, int readonly) {
|
||||
if (strchr(c->argv[j+1]->ptr,'*') == NULL) {
|
||||
dontsort = 1;
|
||||
} else {
|
||||
/* If BY is specified with a real pattern, we can't accept
|
||||
* it in cluster mode. */
|
||||
if (server.cluster_enabled) {
|
||||
addReplyError(c,"BY option of SORT denied in Cluster mode.");
|
||||
/* If BY is specified with a real pattern, we can't accept it in cluster mode,
|
||||
* unless we can make sure the keys formed by the pattern are in the same slot
|
||||
* as the key to sort. */
|
||||
if (server.cluster_enabled && patternHashSlot(sortby->ptr, sdslen(sortby->ptr)) != c->slot) {
|
||||
addReplyError(c, "BY option of SORT denied in Cluster mode when "
|
||||
"keys formed by the pattern may be in different slots.");
|
||||
syntax_error++;
|
||||
break;
|
||||
}
|
||||
@ -252,8 +255,12 @@ void sortCommandGeneric(client *c, int readonly) {
|
||||
}
|
||||
j++;
|
||||
} else if (!strcasecmp(c->argv[j]->ptr,"get") && leftargs >= 1) {
|
||||
if (server.cluster_enabled) {
|
||||
addReplyError(c,"GET option of SORT denied in Cluster mode.");
|
||||
/* If GET is specified with a real pattern, we can't accept it in cluster mode,
|
||||
* unless we can make sure the keys formed by the pattern are in the same slot
|
||||
* as the key to sort. */
|
||||
if (server.cluster_enabled && patternHashSlot(c->argv[j+1]->ptr, sdslen(c->argv[j+1]->ptr)) != c->slot) {
|
||||
addReplyError(c, "GET option of SORT denied in Cluster mode when "
|
||||
"keys formed by the pattern may be in different slots.");
|
||||
syntax_error++;
|
||||
break;
|
||||
}
|
||||
|
@ -357,3 +357,39 @@ foreach command {SORT SORT_RO} {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
start_cluster 1 0 {tags {"external:skip cluster sort"}} {
|
||||
|
||||
r flushall
|
||||
r lpush "{a}mylist" 1 2 3
|
||||
r set "{a}by1" 20
|
||||
r set "{a}by2" 30
|
||||
r set "{a}by3" 0
|
||||
r set "{a}get1" 200
|
||||
r set "{a}get2" 100
|
||||
r set "{a}get3" 30
|
||||
|
||||
test "sort by in cluster mode" {
|
||||
catch {r sort "{a}mylist" by by*} e
|
||||
assert_match {ERR BY option of SORT denied in Cluster mode when *} $e
|
||||
r sort "{a}mylist" by "{a}by*"
|
||||
} {3 1 2}
|
||||
|
||||
test "sort get in cluster mode" {
|
||||
catch {r sort "{a}mylist" by "{a}by*" get get*} e
|
||||
assert_match {ERR GET option of SORT denied in Cluster mode when *} $e
|
||||
r sort "{a}mylist" by "{a}by*" get "{a}get*"
|
||||
} {30 200 100}
|
||||
|
||||
test "sort_ro by in cluster mode" {
|
||||
catch {r sort_ro "{a}mylist" by by*} e
|
||||
assert_match {ERR BY option of SORT denied in Cluster mode when *} $e
|
||||
r sort_ro "{a}mylist" by "{a}by*"
|
||||
} {3 1 2}
|
||||
|
||||
test "sort_ro get in cluster mode" {
|
||||
catch {r sort_ro "{a}mylist" by "{a}by*" get get*} e
|
||||
assert_match {ERR GET option of SORT denied in Cluster mode when *} $e
|
||||
r sort_ro "{a}mylist" by "{a}by*" get "{a}get*"
|
||||
} {30 200 100}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user