diff --git a/redis.c b/redis.c index 90fe5e80d1a1e27a9d60b5a3a4cc1c54247e06c6..75159e4ec3b6ea83ace0713581f9aac0cffd625f 100644 --- a/redis.c +++ b/redis.c @@ -6068,6 +6068,14 @@ static void hashTryConversion(robj *subject, robj **argv, int start, int end) { } } +/* Encode given objects in-place when the hash uses a dict. */ +static void hashTryObjectEncoding(robj *subject, robj **o1, robj **o2) { + if (subject->encoding == REDIS_ENCODING_HT) { + *o1 = tryObjectEncoding(*o1); + *o2 = tryObjectEncoding(*o2); + } +} + /* Get the value from a hash identified by key. Returns either a string * object or NULL if the value cannot be found. The refcount of the object * is always increased by 1 when the value was found. */ @@ -6126,7 +6134,6 @@ static int hashSet(robj *o, robj *key, robj *value) { if (zipmapLen(o->ptr) > server.hash_max_zipmap_entries) convertToRealHash(o); } else { - value = tryObjectEncoding(value); if (dictReplace(o->ptr,key,value)) { /* Insert */ incrRefCount(key); @@ -6250,6 +6257,7 @@ static void hsetCommand(redisClient *c) { if ((o = hashLookupWriteOrCreate(c,c->argv[1])) == NULL) return; hashTryConversion(o,c->argv,2,3); + hashTryObjectEncoding(o,&c->argv[2], &c->argv[3]); update = hashSet(o,c->argv[2],c->argv[3]); addReply(c, update ? shared.czero : shared.cone); server.dirty++; @@ -6263,6 +6271,7 @@ static void hsetnxCommand(redisClient *c) { if (hashExists(o, c->argv[2])) { addReply(c, shared.czero); } else { + hashTryObjectEncoding(o,&c->argv[2], &c->argv[3]); hashSet(o,c->argv[2],c->argv[3]); addReply(c, shared.cone); server.dirty++; @@ -6281,6 +6290,7 @@ static void hmsetCommand(redisClient *c) { if ((o = hashLookupWriteOrCreate(c,c->argv[1])) == NULL) return; hashTryConversion(o,c->argv,2,c->argc-1); for (i = 2; i < c->argc; i += 2) { + hashTryObjectEncoding(o,&c->argv[i], &c->argv[i+1]); hashSet(o,c->argv[i],c->argv[i+1]); } addReply(c, shared.ok);