Repository: valkey-io/valkey
File: src/t_hash.c (C)

Code before:
 * Keyspace Notifications (if enabled):
 * - "hset"      — Emitted when fields are added or updated.
 * - "hexpire"   — Emitted when expiration is set on fields.
 * - "hexpired"  — Emitted when fields are immediately expired and deleted.
 * - "del"       — Emitted if the entire key is removed (empty hash).
 *
 *
 * Client Reply:
 * - Integer reply: 1 if all changes succeeded, 0 if no changes occurred. */
void hsetexCommand(client *c) {
    robj *o;
    robj *expire = NULL;
    robj *comparison = NULL;
    int unit = UNIT_SECONDS;
    int flags = ARGS_NO_FLAGS;
    int fields_index = 0;
    long long num_fields = 0;
    long long when = EXPIRY_NONE;
    int i = 0;
    int set_flags = HASH_SET_COPY, set_expired = 0;
    int changes = 0;
    robj **new_argv = NULL;
    int new_argc = 0;
    int need_rewrite_argv = 0;

    robj **keepttl_fields = NULL;
    int expired_overitten = 0;

    for (; fields_index < c->argc - 1; fields_index++) {
        if (!strcasecmp(objectGetVal(c->argv[fields_index]), "fields")) {
            /* checking optional flags */
            if (parseExtendedCommandArgumentsOrReply(c, &flags, &unit, &expire, &comparison, COMMAND_HSET, fields_index++) != C_OK) return;
            if (getLongLongFromObjectOrReply(c, c->argv[fields_index++], &num_fields, NULL) != C_OK) return;
            break;
        }
    }
    /* Check that the parsed fields number matches the real provided number of fields */
    if (!num_fields || num_fields > LLONG_MAX / 2 || (num_fields * 2) != (c->argc - fields_index)) {
        addReplyError(c, "numfields should be greater than 0 and match the provided number of fields");
        return;
    }

    o = lookupKeyWrite(c->db, c->argv[1]);
    if (checkType(c, o, OBJ_HASH))
        return;

    if (flags & (ARGS_SET_NX | ARGS_SET_XX | ARGS_SET_FNX | ARGS_SET_FXX | ARGS_EX | ARGS_PX | ARGS_EXAT)) {
        need_rewrite_argv = 1;
    }

    /* Check NX/XX key-level conditions before creating a new object */

Review comment (suggestion):
```suggestion
    robj **keepttl_fields = NULL;
    int expired_overitten = 0;

```

Code after:
 * - "hset"      — Emitted when fields are added or updated.
 * - "hexpire"   — Emitted when expiration is set on fields.
 * - "hexpired"  — Emitted when fields are immediately expired and deleted.
 * - "del"       — Emitted if the entire key is removed (empty hash).
 *
 *
 * Client Reply:
 * - Integer reply: 1 if all changes succeeded, 0 if no changes occurred. */
void hsetexCommand(client *c) {
    robj *o;
    robj *expire = NULL;
    robj *comparison = NULL;
    int unit = UNIT_SECONDS;
    int flags = ARGS_NO_FLAGS;
    int fields_index = 0;
    long long num_fields = 0;
    long long when = EXPIRY_NONE;
    int i = 0;
    int set_flags = HASH_SET_COPY, set_expired = 0;
    int changes = 0;
    robj **new_argv = NULL;
    int new_argc = 0;
    int need_rewrite_argv = 0;
    robj **keepttl_fields = NULL;
    int expired_overwritten = 0;

    for (; fields_index < c->argc - 1; fields_index++) {
        if (!strcasecmp(objectGetVal(c->argv[fields_index]), "fields")) {
            /* checking optional flags */
            if (parseExtendedCommandArgumentsOrReply(c, &flags, &unit, &expire, &comparison, COMMAND_HSET, fields_index++) != C_OK) return;
            if (getLongLongFromObjectOrReply(c, c->argv[fields_index++], &num_fields, NULL) != C_OK) return;
            break;
        }
    }
    /* Check that the parsed fields number matches the real provided number of fields */
    if (!num_fields || num_fields > LLONG_MAX / 2 || (num_fields * 2) != (c->argc - fields_index)) {
        addReplyError(c, "numfields should be greater than 0 and match the provided number of fields");
        return;
    }

    o = lookupKeyWrite(c->db, c->argv[1]);
    if (checkType(c, o, OBJ_HASH))
        return;

    if (flags & (ARGS_SET_NX | ARGS_SET_XX | ARGS_SET_FNX | ARGS_SET_FXX | ARGS_EX | ARGS_PX | ARGS_EXAT)) {
        need_rewrite_argv = 1;
    }

    /* Check NX/XX key-level conditions before creating a new object */
    if (((flags & ARGS_SET_NX) && o != NULL) ||
        ((flags & ARGS_SET_XX) && o == NULL)) {