Repository: microsoft/garnet
File: libs/server/Resp/Objects/SetCommands.cs (C#)

Code before:
            int? limit = null;

            if ((parseState.Count - 1) < nKeys)
            {
                while (!RespWriteUtils.WriteError(CmdStrings.RESP_SYNTAX_ERROR, ref dcurr, dend))
                    SendAndReset();
                return true;
            }

            for (var i = 1; i <= nKeys; i++)
            {
                keys[i - 1] = parseState.GetArgSliceByRef(i);
            }

            // Optional LIMIT argument
            if (parseState.Count > nKeys + 1)
            {
                var limitArg = parseState.GetArgSliceByRef(nKeys + 1);
                if (!limitArg.ReadOnlySpan.EqualsUpperCaseSpanIgnoringCase(CmdStrings.LIMIT))
                {
                    while (!RespWriteUtils.WriteError(CmdStrings.RESP_SYNTAX_ERROR, ref dcurr, dend))
                        SendAndReset();
                    return true;
                }

                if (parseState.Count != nKeys + 3 || !parseState.TryGetInt(nKeys + 2, out var limitVal))
                {
                    while (!RespWriteUtils.WriteError(CmdStrings.RESP_ERR_GENERIC_VALUE_IS_NOT_INTEGER, ref dcurr, dend))
                        SendAndReset();
                    return true;
                }

                limit = limitVal;
            }

            var status = storageApi.SetIntersectCard(keys, limit, out var result);
            switch (status)
            {
                case GarnetStatus.OK:
                    while (!RespWriteUtils.WriteInteger(result, ref dcurr, dend))
                        SendAndReset();
                    break;
                case GarnetStatus.WRONGTYPE:
                    while (!RespWriteUtils.WriteError(CmdStrings.RESP_ERR_WRONG_TYPE, ref dcurr, dend))
                        SendAndReset();
                    break;
            }

            return true;
        }


Review comment (suggestion):
Need to check that limit is non-negative. Error should be `ERR LIMIT can't be negative`.

Code after:
                return AbortWithErrorMessage(Encoding.ASCII.GetBytes(string.Format(CmdStrings.GenericErrShouldBeGreaterThanZero, "numkeys")));
            }

            var keys = parseState.Parameters.Slice(1, nKeys);

            // Optional LIMIT argument
            int? limit = null;
            if (parseState.Count > nKeys + 1)
            {
                var limitArg = parseState.GetArgSliceByRef(nKeys + 1);
                if (!limitArg.ReadOnlySpan.EqualsUpperCaseSpanIgnoringCase(CmdStrings.LIMIT) || parseState.Count != nKeys + 3)
                {
                    return AbortWithErrorMessage(CmdStrings.RESP_SYNTAX_ERROR);
                }

                if (!parseState.TryGetInt(nKeys + 2, out var limitVal))
                {
                    return AbortWithErrorMessage(CmdStrings.RESP_ERR_GENERIC_VALUE_IS_NOT_INTEGER);
                }

                if (limitVal < 0)
                {
                    return AbortWithErrorMessage(Encoding.ASCII.GetBytes(string.Format(CmdStrings.GenericErrCantBeNegative, "LIMIT")));
                }

                limit = limitVal;
            }

            var status = storageApi.SetIntersectLength(keys, limit, out var result);
            switch (status)
            {
                case GarnetStatus.OK:
                    while (!RespWriteUtils.WriteInteger(result, ref dcurr, dend))
                        SendAndReset();
                    break;
                case GarnetStatus.WRONGTYPE:
                    while (!RespWriteUtils.WriteError(CmdStrings.RESP_ERR_WRONG_TYPE, ref dcurr, dend))
                        SendAndReset();
                    break;
            }

            return true;
        }

        /// <summary>
        /// Returns the members of the set resulting from the union of all the given sets.
        /// Keys that do not exist are considered to be empty sets.
        /// </summary>
        /// <param name="storageApi"></param>
        /// <typeparam name="TGarnetApi"></typeparam>
        /// <returns></returns>