Commit f529a01c authored by antirez's avatar antirez
Browse files

MOVE now can move TTL metadata as well.

MOVE was not able to move the TTL: when a key was moved into a different
database number, it became persistent like if PERSIST was used.

In some incredible way (I guess almost nobody uses Redis MOVE) this bug
remained unnoticed inside Redis internals for many years.
Finally Andy Grunwald discovered it and opened an issue.

This commit fixes the bug and adds a regression test.

Close #2765.
parent 33769f84
...@@ -743,7 +743,7 @@ void moveCommand(client *c) { ...@@ -743,7 +743,7 @@ void moveCommand(client *c) {
robj *o; robj *o;
redisDb *src, *dst; redisDb *src, *dst;
int srcid; int srcid;
long long dbid; long long dbid, expire;
if (server.cluster_enabled) { if (server.cluster_enabled) {
addReplyError(c,"MOVE is not allowed in cluster mode"); addReplyError(c,"MOVE is not allowed in cluster mode");
...@@ -777,6 +777,7 @@ void moveCommand(client *c) { ...@@ -777,6 +777,7 @@ void moveCommand(client *c) {
addReply(c,shared.czero); addReply(c,shared.czero);
return; return;
} }
expire = getExpire(c->db,c->argv[1]);
/* Return zero if the key already exists in the target DB */ /* Return zero if the key already exists in the target DB */
if (lookupKeyWrite(dst,c->argv[1]) != NULL) { if (lookupKeyWrite(dst,c->argv[1]) != NULL) {
...@@ -784,6 +785,7 @@ void moveCommand(client *c) { ...@@ -784,6 +785,7 @@ void moveCommand(client *c) {
return; return;
} }
dbAdd(dst,c->argv[1],o); dbAdd(dst,c->argv[1],o);
if (expire) setExpire(dst,c->argv[1],expire);
incrRefCount(o); incrRefCount(o);
/* OK! key moved, free the entry in the source DB */ /* OK! key moved, free the entry in the source DB */
......
...@@ -193,6 +193,19 @@ start_server {tags {"keyspace"}} { ...@@ -193,6 +193,19 @@ start_server {tags {"keyspace"}} {
set e set e
} {*ERR*index out of range} } {*ERR*index out of range}
test {MOVE can move key expire metadata as well} {
r select 10
r flushdb
r select 9
r set mykey foo ex 100
r move mykey 10
assert {[r ttl mykey] == -2}
r select 10
assert {[r ttl mykey] > 0 && [r ttl mykey] <= 100}
assert {[r get mykey] eq "foo"}
r select 9
}
test {SET/GET keys in different DBs} { test {SET/GET keys in different DBs} {
r set a hello r set a hello
r set b world r set b world
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment