-
Notifications
You must be signed in to change notification settings - Fork 24.5k
Description
Redis branch: latest unstable at commit c552fad
Issue statement
It appears that redis module API RedisModule_HashSet() was returning 0 for the creation of a new hash type key which did not previously exist. It however returns the number of fields updated for a hash type key which previsouly existed.
Since a return value of 0 is currently considered an error by RedisModule_HashSet(), it becomes confusing to determine whether the HashSet is successful or not based on the return value.
Expected behavior
The return value for a successful new hash key creation by RedisModule_HashSet() shoud differ from the error return code.
To reproduce the issue
int ret;
RedisModuleKey *hash_key_ptr = RedisModule_OpenKey(ctx, hash_key,
REDISMODULE_READ|REDISMODULE_WRITE);
keytype = RedisModule_KeyType(hash_key_ptr);
if (keytype != REDISMODULE_KEYTYPE_HASH &&
keytype != REDISMODULE_KEYTYPE_EMPTY)
{
RedisModule_CloseKey(hash_key_ptr);
return RedisModule_ReplyWithError(ctx,REDISMODULE_ERRORMSG_WRONGTYPE);
}
ret = RedisModule_HashSet(hash_key_ptr, REDISMODULE_HASH_CFIELDS,
"field1", value1,
"field2", value2,
"field3", value3,
NULL);
Return value ret was found to be 0.
The hash key was found to be written successfully.
Root cause analysis
module.c
int RM_HashSet(RedisModuleKey *key, int flags, ...) {
...
2783 int updated = 0;
...
2823 robj *argv[2] = {field,value};
2824 hashTypeTryConversion(key->value,argv,0,1);
2825 updated += hashTypeSet(key->value, field->ptr, value->ptr, low_flags);
...
2836 return updated;
hashTypeSet() returns the number of updated fields ONLY (i.e. the field must previsously exist).
If the field is new (in the case of creating a new hash key), hashTypeSet returns 0 even though the field is created.
Hence for RM_HashSet(), variable "updated" was not incremented for any field when creating a new hash key and 0 is returned to caller, although the hash key creation was successful.