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

Code before:
    /* For migrating and importing slots, we need to go over all the keys to
     * count existing keys and missing keys that we need for TRYAGAIN and ASK
     * redirects. Skip this if we're not importing or migrating. */
    if (!migrating_slot && !importing_slot) goto after_checking_each_key;

    /* We handle all the cases as if they were EXEC commands, so we have
     * a common code path for everything */
    if (c->cmd->proc == execCommand) {
        /* If CLIENT_MULTI flag is not set EXEC is just going to return an
         * error. */
        if (!c->flag.multi) return myself;
        ms = c->mstate;
    } else {
        /* In order to have a single codepath create a fake Multi State
         * structure if the client is not in MULTI/EXEC state, this way
         * we have a single codepath below. */
        ms = &_ms;
        _ms.commands = &mc;
        _ms.count = 1;
        mc.argv = c->argv;
        mc.argc = c->argc;
        mc.cmd = c->cmd;
    }

    serverDb *currentDb = c->db;

    /* Check for multiple keys, existing keys, missing keys. */
    for (i = 0; i < ms->count; i++) {
        struct serverCommand *mcmd;
        robj **margv;
        int margc, numkeys, j;
        keyReference *keyindex;

        mcmd = ms->commands[i].cmd;
        margc = ms->commands[i].argc;
        margv = ms->commands[i].argv;

        getKeysResult result;
        initGetKeysResult(&result);
        numkeys = getKeysFromCommand(mcmd, margv, margc, &result);
        keyindex = result.keys;

        if (mcmd->proc == selectCommand) {
            /* Failed SELECT is ignored since it doesn't modify the database. */
            serverDb *origDb = currentDb;
            long long id;
            if (getLongLongFromObject(margv[1], &id) == C_OK && selectDb(c, id) == C_OK) {
                currentDb = c->db;
                selectDb(c, origDb->id);
            }
        }

Review comment (suggestion):
```suggestion
        mc.argv = argv;
        mc.argc = argc;
        mc.cmd = cmd;
```

Code after:
    /* If we're importing or migrating the slot, we need to do some more checks:
     *
     *   1. Go over all the keys to count existing keys and missing keys that we
     *      need for TRYAGAIN and ASK redirects.
     *   2. Check for some commands that are forbiddedn during slot migration.
     *
     * Skip this if we're not importing or migrating this slot. */
    if (!migrating_slot && !importing_slot) goto after_checking_each_key;

    /* We handle all the cases as if they were EXEC commands, so we have
     * a common code path for everything */
    if (c->cmd->proc == execCommand) {
        /* If CLIENT_MULTI flag is not set EXEC is just going to return an
         * error. */
        if (!c->flag.multi) return myself;
        ms = c->mstate;
    } else {
        /* In order to have a single codepath create a fake Multi State
         * structure if the client is not in MULTI/EXEC state, this way
         * we have a single codepath below. */
        ms = &_ms;
        _ms.commands = &mc;
        _ms.count = 1;
        mc.argv = c->argv;
        mc.argc = c->argc;
        mc.cmd = c->cmd;
    }

    serverDb *currentDb = c->db;

    /* Check for multiple keys, existing keys, missing keys. */
    for (i = 0; i < ms->count; i++) {
        struct serverCommand *mcmd;
        robj **margv;
        int margc, numkeys, j;
        keyReference *keyindex;

        mcmd = ms->commands[i].cmd;
        margc = ms->commands[i].argc;
        margv = ms->commands[i].argv;

        getKeysResult result;
        initGetKeysResult(&result);
        numkeys = getKeysFromCommand(mcmd, margv, margc, &result);
        keyindex = result.keys;

        if (mcmd->proc == selectCommand) {
            /* Failed SELECT is ignored since it doesn't modify the database. */
            serverDb *origDb = currentDb;
            long long id;
            if (getLongLongFromObject(margv[1], &id) == C_OK && selectDb(c, id) == C_OK) {