summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2015-02-23 11:24:24 +0100
committerantirez <antirez@gmail.com>2015-02-23 11:24:24 +0100
commitfc365a3a001d0ec55e6bde914708911aa1b524c4 (patch)
tree9884ddc5761432b60d04557c06500665c3600465
parent0aa5acc8f31a45ba4ee625227bae80e125fd8bdb (diff)
downloadredis-fc365a3a001d0ec55e6bde914708911aa1b524c4.tar.gz
Change RENAME behavior when src and dst keys are the same.
Fixes issue #2392.
-rw-r--r--src/db.c14
-rw-r--r--tests/unit/basic.tcl13
2 files changed, 21 insertions, 6 deletions
diff --git a/src/db.c b/src/db.c
index 69d1a7768..36650318a 100644
--- a/src/db.c
+++ b/src/db.c
@@ -688,16 +688,20 @@ void shutdownCommand(redisClient *c) {
void renameGenericCommand(redisClient *c, int nx) {
robj *o;
long long expire;
+ int samekey = 0;
- /* To use the same key as src and dst is probably an error */
- if (sdscmp(c->argv[1]->ptr,c->argv[2]->ptr) == 0) {
- addReply(c,shared.sameobjecterr);
- return;
- }
+ /* When source and dest key is the same, no operation is performed,
+ * if the key exists, however we still return an error on unexisting key. */
+ if (sdscmp(c->argv[1]->ptr,c->argv[2]->ptr) == 0) samekey = 1;
if ((o = lookupKeyWriteOrReply(c,c->argv[1],shared.nokeyerr)) == NULL)
return;
+ if (samekey) {
+ addReply(c,nx ? shared.czero : shared.ok);
+ return;
+ }
+
incrRefCount(o);
expire = getExpire(c->db,c->argv[1]);
if (lookupKeyWrite(c->db,c->argv[2]) != NULL) {
diff --git a/tests/unit/basic.tcl b/tests/unit/basic.tcl
index b0b3b9bac..fec0df5ec 100644
--- a/tests/unit/basic.tcl
+++ b/tests/unit/basic.tcl
@@ -368,7 +368,18 @@ start_server {tags {"basic"}} {
format $err
} {ERR*}
- test {RENAME where source and dest key is the same} {
+ test {RENAME where source and dest key are the same (existing)} {
+ r set mykey foo
+ r rename mykey mykey
+ } {OK}
+
+ test {RENAMENX where source and dest key are the same (existing)} {
+ r set mykey foo
+ r renamenx mykey mykey
+ } {0}
+
+ test {RENAME where source and dest key are the same (non existing)} {
+ r del mykey
catch {r rename mykey mykey} err
format $err
} {ERR*}