From 47ac5a4254fdfcaed02bf8f7591fc8ae1f8cf830 Mon Sep 17 00:00:00 2001 From: 0xacc Date: Wed, 7 Feb 2024 20:16:18 +0000 Subject: [PATCH] [to #53705973] fix name resolve of SQL SECURITY INVOKER routines --- src/pl/ob_pl.cpp | 11 ++++++++++- src/pl/ob_pl_compile.cpp | 22 ++++++++++++++++++++-- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/pl/ob_pl.cpp b/src/pl/ob_pl.cpp index bec050fd5..5459ce75d 100644 --- a/src/pl/ob_pl.cpp +++ b/src/pl/ob_pl.cpp @@ -1229,8 +1229,17 @@ int ObPLContext::set_default_database(ObPLFunction &routine, int ret = OB_SUCCESS; bool is_special_ir = false; const uint64_t tenant_id = routine.get_tenant_id(); + bool need_set_db = true; + + // in mysql mode, only system packages with invoker's right do not need set db + // in oracle mode, set db by if the routine is invoker's right + if (lib::is_oracle_mode() + || get_tenant_id_by_object_id(routine.get_package_id()) == OB_SYS_TENANT_ID) { + need_set_db = !routine.is_invoker_right(); + } + OZ (routine.is_special_pkg_invoke_right(guard, is_special_ir)); - if (!routine.is_invoker_right() + if (need_set_db && !is_special_ir && routine.get_proc_type() != NESTED_FUNCTION && routine.get_proc_type() != NESTED_PROCEDURE diff --git a/src/pl/ob_pl_compile.cpp b/src/pl/ob_pl_compile.cpp index 2f43ad801..470f2b52d 100644 --- a/src/pl/ob_pl_compile.cpp +++ b/src/pl/ob_pl_compile.cpp @@ -297,6 +297,7 @@ int ObPLCompiler::compile(const uint64_t id, ObPLFunction &func) uint64_t old_db_id = OB_INVALID_ID; bool need_reset_exec_env = false; bool need_reset_default_database = false; + bool need_set_db = true; //Step 1:根据id从schema取出pl信息,并构造ObPLFunctionAST int64_t init_start = ObTimeUtility::current_time(); @@ -327,8 +328,16 @@ int ObPLCompiler::compile(const uint64_t id, ObPLFunction &func) CK (OB_UNLIKELY(OB_NOT_NULL(proc))); OZ (schema_guard_.get_database_schema(proc->get_tenant_id(), proc->get_database_id(), db)); CK (OB_UNLIKELY(OB_NOT_NULL(db))); + // in mysql mode, only system packages with invoker's right do not need set db + // in oracle mode, set db by if the routine is invoker's right if (OB_SUCC(ret) - && !proc->is_invoker_right() + && (lib::is_oracle_mode() + || get_tenant_id_by_object_id(proc->get_package_id()) == OB_SYS_TENANT_ID)) { + need_set_db = !proc->is_invoker_right(); + } + + if (OB_SUCC(ret) + && need_set_db && proc->get_database_id() != old_db_id) { old_db_id = session_info_.get_database_id(); if (OB_FAIL(old_db_name.append(session_info_.get_database_name()))) { @@ -1400,6 +1409,7 @@ template void ObPLCompilerEnvGuard::init(const Info &info, ObSQLSessionInfo &session_info, share::schema::ObSchemaGetterGuard &schema_guard, int &ret) { ObExecEnv env; + bool need_set_db = true; OX (need_reset_exec_env_ = false); OX (need_reset_default_database_ = false); OZ (old_exec_env_.load(session_info_)); @@ -1408,8 +1418,16 @@ void ObPLCompilerEnvGuard::init(const Info &info, ObSQLSessionInfo &session_info OZ (env.store(session_info_)); OX (need_reset_exec_env_ = true); } + + // in mysql mode, only system packages with invoker's right do not need set db + // in oracle mode, set db by if the routine is invoker's right if (OB_SUCC(ret) - && !info.is_invoker_right() + && (lib::is_oracle_mode() + || get_tenant_id_by_object_id(info.get_package_id()) == OB_SYS_TENANT_ID)) { + need_set_db = !info.is_invoker_right(); + } + if (OB_SUCC(ret) + && need_set_db && info.get_database_id() != session_info_.get_database_id()) { const share::schema::ObDatabaseSchema *db_schema = NULL; old_db_id_ = session_info_.get_database_id();