MCPcopy Create free account
hub / github.com/apache/kvrocks / RedisGenericCommand

Function RedisGenericCommand

src/storage/scripting.cc:771–903  ·  view source on GitHub ↗

TODO: we do not want to repeat same logic as Connection::ExecuteCommands, so the function need to be refactored

Source from the content-addressed store, hash-verified

769// TODO: we do not want to repeat same logic as Connection::ExecuteCommands,
770// so the function need to be refactored
771int RedisGenericCommand(lua_State *lua, int raise_error) {
772 auto *script_run_ctx = GetFromRegistry<ScriptRunCtx>(lua, REGISTRY_SCRIPT_RUN_CTX_NAME);
773 CHECK(script_run_ctx != nullptr);
774
775 int argc = lua_gettop(lua);
776 if (argc == 0) {
777 PushError(lua, "Please specify at least one argument for redis.call()");
778 return raise_error ? RaiseError(lua) : 1;
779 }
780
781 std::vector<std::string> args;
782 for (int j = 1; j <= argc; j++) {
783 if (lua_type(lua, j) == LUA_TNUMBER) {
784 lua_Number num = lua_tonumber(lua, j);
785 args.emplace_back(fmt::format("{:.17g}", static_cast<double>(num)));
786 } else {
787 size_t obj_len = 0;
788 const char *obj_s = lua_tolstring(lua, j, &obj_len);
789 if (obj_s == nullptr) {
790 PushError(lua, "Lua redis.call() command arguments must be strings or integers");
791 return raise_error ? RaiseError(lua) : 1;
792 }
793 args.emplace_back(obj_s, obj_len);
794 }
795 }
796
797 auto cmd_s = Server::LookupAndCreateCommand(args[0]);
798 if (!cmd_s) {
799 PushError(lua, "Unknown Redis command called from Lua script");
800 return raise_error ? RaiseError(lua) : 1;
801 }
802 auto cmd = *std::move(cmd_s);
803
804 auto attributes = cmd->GetAttributes();
805 if (!attributes->CheckArity(argc)) {
806 PushError(lua, "Wrong number of args while calling Redis command from Lua script");
807 return raise_error ? RaiseError(lua) : 1;
808 }
809
810 auto *conn = script_run_ctx->conn;
811 auto *srv = conn->GetServer();
812 Config *config = srv->GetConfig();
813
814 auto cmd_flags = attributes->GenerateFlags(args, *config);
815
816 if ((script_run_ctx->flags & ScriptFlagType::kScriptNoWrites) && !(cmd_flags & redis::kCmdReadOnly)) {
817 PushError(lua, "Write commands are not allowed from read-only scripts");
818 return raise_error ? RaiseError(lua) : 1;
819 }
820
821 if ((cmd_flags & redis::kCmdNoScript) || (cmd_flags & redis::kCmdExclusive)) {
822 PushError(lua, "This Redis command is not allowed from scripts");
823 return raise_error ? RaiseError(lua) : 1;
824 }
825
826 std::string cmd_name = attributes->name;
827 cmd->SetArgs(args);
828 auto s = cmd->Parse();

Callers 2

RedisCallCommandFunction · 0.85
RedisPCallCommandFunction · 0.85

Calls 15

PushErrorFunction · 0.85
RaiseErrorFunction · 0.85
StatusToRedisErrorMsgFunction · 0.85
RedisProtocolToLuaTypeFunction · 0.85
GetAttributesMethod · 0.80
CheckArityMethod · 0.80
GetServerMethod · 0.80
GenerateFlagsMethod · 0.80
SetArgsMethod · 0.80
ForEachKeyRangeMethod · 0.80
ForEachKeyMethod · 0.80
beginMethod · 0.80

Tested by

no test coverage detected