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

Function EvalGenericCommand

src/storage/scripting.cc:648–757  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

646}
647
648Status EvalGenericCommand(redis::Connection *conn, engine::Context *ctx, const std::string &body_or_sha,
649 const std::vector<std::string> &keys, const std::vector<std::string> &argv, bool evalsha,
650 std::string *output, bool read_only) {
651 Server *srv = conn->GetServer();
652 // Use the worker's private Lua VM when entering the read-only mode
653 lua_State *lua = conn->Owner()->Lua();
654
655 /* We obtain the script SHA1, then check if this function is already
656 * defined into the Lua state */
657 char funcname[2 + 40 + 1] = {};
658 memcpy(funcname, REDIS_LUA_FUNC_SHA_PREFIX, sizeof(REDIS_LUA_FUNC_SHA_PREFIX));
659
660 if (!evalsha) {
661 SHA1Hex(funcname + 2, body_or_sha.c_str(), body_or_sha.size());
662 } else {
663 for (int j = 0; j < 40; j++) {
664 funcname[j + 2] = static_cast<char>(tolower(body_or_sha[j]));
665 }
666 }
667
668 /* Push the pcall error handler function on the stack. */
669 lua_getglobal(lua, "__redis__err__handler");
670
671 /* Try to lookup the Lua function */
672 lua_getglobal(lua, funcname);
673 if (lua_isnil(lua, -1)) {
674 lua_pop(lua, 1); /* remove the nil from the stack */
675 std::string body;
676 if (evalsha) {
677 auto s = srv->ScriptGet(funcname + 2, &body);
678 if (!s.IsOK()) {
679 lua_pop(lua, 1); /* remove the error handler from the stack. */
680 return {Status::RedisNoScript, redis::errNoMatchingScript};
681 }
682 } else {
683 body = body_or_sha;
684 }
685
686 std::string sha = funcname + 2;
687 auto s = CreateFunction(srv, body, &sha, lua, false);
688 if (!s.IsOK()) {
689 lua_pop(lua, 1); /* remove the error handler from the stack. */
690 return s;
691 }
692 /* Now the following is guaranteed to return non nil */
693 lua_getglobal(lua, funcname);
694 }
695
696 ScriptRunCtx current_script_run_ctx;
697 current_script_run_ctx.conn = conn;
698 current_script_run_ctx.ctx = ctx;
699 current_script_run_ctx.flags = read_only ? ScriptFlagType::kScriptNoWrites : 0;
700 lua_getglobal(lua, fmt::format(REDIS_LUA_FUNC_SHA_FLAGS, funcname + 2).c_str());
701 if (!lua_isnil(lua, -1)) {
702 // It should be ensured that the conversion is successful
703 auto script_flags = lua_tointeger(lua, -1);
704 current_script_run_ctx.flags |= script_flags;
705 }

Callers 1

ExecuteMethod · 0.85

Calls 14

SHA1HexFunction · 0.85
CreateFunctionFunction · 0.85
SaveOnRegistryFunction · 0.85
SetGlobalArrayFunction · 0.85
ErrorFunction · 0.85
ReplyToRedisReplyFunction · 0.85
RemoveFromRegistryFunction · 0.85
GetServerMethod · 0.80
LuaMethod · 0.80
OwnerMethod · 0.80
ScriptGetMethod · 0.80
GetProtocolVersionMethod · 0.80

Tested by

no test coverage detected