summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorOran Agra <oran@redislabs.com>2018-09-27 18:03:47 +0300
committerOran Agra <oran@redislabs.com>2019-03-20 17:06:22 +0200
commit747174388f305148b0832dd97b9754e2a64bdfef (patch)
tree18f53040c49e2891be5d1e6991cfe9e6e83050de /src
parent3eaa2cdc44a9b0742f0695f44911b92547995836 (diff)
downloadredis-747174388f305148b0832dd97b9754e2a64bdfef.tar.gz
change SORT and SPOP to use lookupKeyWrite rather than lookupKeyRead
like in SUNIONSTORE etc, commands that perform writes are expected to open all keys, even input keys, with lookupKeyWrite
Diffstat (limited to 'src')
-rw-r--r--src/sort.c55
-rw-r--r--src/t_set.c2
2 files changed, 32 insertions, 25 deletions
diff --git a/src/sort.c b/src/sort.c
index 8608cd8b3..db26da158 100644
--- a/src/sort.c
+++ b/src/sort.c
@@ -58,7 +58,7 @@ redisSortOperation *createSortOperation(int type, robj *pattern) {
*
* The returned object will always have its refcount increased by 1
* when it is non-NULL. */
-robj *lookupKeyByPattern(redisDb *db, robj *pattern, robj *subst) {
+robj *lookupKeyByPattern(redisDb *db, robj *pattern, robj *subst, int writeflag) {
char *p, *f, *k;
sds spat, ssub;
robj *keyobj, *fieldobj = NULL, *o;
@@ -106,7 +106,10 @@ robj *lookupKeyByPattern(redisDb *db, robj *pattern, robj *subst) {
decrRefCount(subst); /* Incremented by decodeObject() */
/* Lookup substituted key */
- o = lookupKeyRead(db,keyobj);
+ if (!writeflag)
+ o = lookupKeyRead(db,keyobj);
+ else
+ o = lookupKeyWrite(db,keyobj);
if (o == NULL) goto noobj;
if (fieldobj) {
@@ -198,30 +201,12 @@ void sortCommand(client *c) {
robj *sortval, *sortby = NULL, *storekey = NULL;
redisSortObject *vector; /* Resulting vector to sort */
- /* Lookup the key to sort. It must be of the right types */
- sortval = lookupKeyRead(c->db,c->argv[1]);
- if (sortval && sortval->type != OBJ_SET &&
- sortval->type != OBJ_LIST &&
- sortval->type != OBJ_ZSET)
- {
- addReply(c,shared.wrongtypeerr);
- return;
- }
-
/* Create a list of operations to perform for every sorted element.
* Operations can be GET */
operations = listCreate();
listSetFreeMethod(operations,zfree);
j = 2; /* options start at argv[2] */
- /* Now we need to protect sortval incrementing its count, in the future
- * SORT may have options able to overwrite/delete keys during the sorting
- * and the sorted key itself may get destroyed */
- if (sortval)
- incrRefCount(sortval);
- else
- sortval = createQuicklistObject();
-
/* The SORT command has an SQL-alike syntax, parse it */
while(j < c->argc) {
int leftargs = c->argc-j-1;
@@ -280,11 +265,33 @@ void sortCommand(client *c) {
/* Handle syntax errors set during options parsing. */
if (syntax_error) {
- decrRefCount(sortval);
listRelease(operations);
return;
}
+ /* Lookup the key to sort. It must be of the right types */
+ if (storekey)
+ sortval = lookupKeyRead(c->db,c->argv[1]);
+ else
+ sortval = lookupKeyWrite(c->db,c->argv[1]);
+ if (sortval && sortval->type != OBJ_SET &&
+ sortval->type != OBJ_LIST &&
+ sortval->type != OBJ_ZSET)
+ {
+ listRelease(operations);
+ addReply(c,shared.wrongtypeerr);
+ return;
+ }
+
+ /* Now we need to protect sortval incrementing its count, in the future
+ * SORT may have options able to overwrite/delete keys during the sorting
+ * and the sorted key itself may get destroyed */
+ if (sortval)
+ incrRefCount(sortval);
+ else
+ sortval = createQuicklistObject();
+
+
/* When sorting a set with no sort specified, we must sort the output
* so the result is consistent across scripting and replication.
*
@@ -452,7 +459,7 @@ void sortCommand(client *c) {
robj *byval;
if (sortby) {
/* lookup value to sort by */
- byval = lookupKeyByPattern(c->db,sortby,vector[j].obj);
+ byval = lookupKeyByPattern(c->db,sortby,vector[j].obj,storekey!=NULL);
if (!byval) continue;
} else {
/* use object itself to sort by */
@@ -515,7 +522,7 @@ void sortCommand(client *c) {
while((ln = listNext(&li))) {
redisSortOperation *sop = ln->value;
robj *val = lookupKeyByPattern(c->db,sop->pattern,
- vector[j].obj);
+ vector[j].obj,storekey!=NULL);
if (sop->type == SORT_OP_GET) {
if (!val) {
@@ -545,7 +552,7 @@ void sortCommand(client *c) {
while((ln = listNext(&li))) {
redisSortOperation *sop = ln->value;
robj *val = lookupKeyByPattern(c->db,sop->pattern,
- vector[j].obj);
+ vector[j].obj,storekey!=NULL);
if (sop->type == SORT_OP_GET) {
if (!val) val = createStringObject("",0);
diff --git a/src/t_set.c b/src/t_set.c
index cbe55aaa4..05d9ee243 100644
--- a/src/t_set.c
+++ b/src/t_set.c
@@ -415,7 +415,7 @@ void spopWithCountCommand(client *c) {
/* Make sure a key with the name inputted exists, and that it's type is
* indeed a set. Otherwise, return nil */
- if ((set = lookupKeyReadOrReply(c,c->argv[1],shared.null[c->resp]))
+ if ((set = lookupKeyWriteOrReply(c,c->argv[1],shared.null[c->resp]))
== NULL || checkType(c,set,OBJ_SET)) return;
/* If count is zero, serve an empty multibulk ASAP to avoid special