diff --git a/src/observer/mysql/obmp_stmt_execute.cpp b/src/observer/mysql/obmp_stmt_execute.cpp index fede7f8345..b0e24022a4 100644 --- a/src/observer/mysql/obmp_stmt_execute.cpp +++ b/src/observer/mysql/obmp_stmt_execute.cpp @@ -2010,7 +2010,7 @@ int ObMPStmtExecute::get_package_type_by_name(ObIAllocator &allocator, CK (OB_NOT_NULL(ctx_.session_info_)); CK (OB_NOT_NULL(ctx_.session_info_->get_pl_engine())); if (OB_SUCC(ret) && OB_ISNULL(pl_type )) - OZ (schema_checker.init(*ctx_.schema_guard_)); + OZ (schema_checker.init(*ctx_.schema_guard_, ctx_.session_info_->get_sessid())); OZ (schema_checker.get_package_info(ctx_.session_info_->get_effective_tenant_id(), type_info->relation_name_, type_info->package_name_, diff --git a/src/pl/ob_pl.cpp b/src/pl/ob_pl.cpp index 6bc47c8ea2..2bcf6eb77e 100644 --- a/src/pl/ob_pl.cpp +++ b/src/pl/ob_pl.cpp @@ -43,6 +43,7 @@ #include "sql/privilege_check/ob_ora_priv_check.h" #include "sql/engine/expr/ob_expr_pl_integer_checker.h" #include "pl/pl_cache/ob_pl_cache_mgr.h" +#include "src/sql/engine/dml/ob_trigger_handler.h" namespace oceanbase { using namespace common; @@ -1777,7 +1778,7 @@ int ObPL::execute(ObExecContext &ctx, CK (OB_NOT_NULL(ctx.get_my_session())); OZ (ObPLContext::check_routine_legal(*routine, in_function, ctx.get_my_session()->is_for_trigger_package())); - + OZ (check_trigger_arg(params, *routine)); if (OB_SUCC(ret) && ctx.get_my_session()->is_pl_debug_on()) { int tmp_ret = OB_SUCCESS; bool need_check = true; @@ -2251,6 +2252,40 @@ int ObPL::insert_error_msg(int errcode) return ret; } +int ObPL::check_trigger_arg(const ParamStore ¶ms, const ObPLFunction &func) +{ + int ret = OB_SUCCESS; + if (ObTriggerInfo::is_trigger_body_package_id(func.get_package_id())) { + const int64_t param_cnt = TriggerHandle::get_routine_param_count(func.get_routine_id()); + OV (params.count() == param_cnt, OB_ERR_UNEXPECTED, K(params.count()), K(param_cnt)); + for (int64_t i = 0; OB_SUCC(ret) && i < param_cnt; i++) { + const ObPLDataType &data_type = func.get_variables().at(i); + CK (data_type.is_record_type()); + CK (params.at(i).is_ext()); + if (OB_SUCC(ret)) { + uint64_t udt_id = data_type.get_user_type_id(); + const ObUserDefinedType *udt = NULL; + OV (OB_INVALID_ID != udt_id); + for (int64_t j = 0; OB_SUCC(ret) && OB_ISNULL(udt) && j < func.get_type_table().count(); j++) { + OV (OB_NOT_NULL(func.get_type_table().at(j))); + if (OB_SUCC(ret) && func.get_type_table().at(j)->get_user_type_id() == udt_id) { + udt = func.get_type_table().at(j); + } + } + OV (OB_NOT_NULL(udt)); + OV (udt->is_record_type()); + if (OB_SUCC(ret)) { + ObPLRecord *record = reinterpret_cast(params.at(i).get_ext()); + CK (OB_NOT_NULL(record)); + CK (record->get_count() == (static_cast(udt))->get_member_count()); + } + } + } + LOG_DEBUG("checkout trigger routine arg end", K(ret), K(func), K(params)); + } + return ret; +} + ObPLExecState::~ObPLExecState() { } diff --git a/src/pl/ob_pl.h b/src/pl/ob_pl.h index 81f6010a96..ed61262964 100644 --- a/src/pl/ob_pl.h +++ b/src/pl/ob_pl.h @@ -1181,6 +1181,8 @@ public: static int simple_execute(ObPLExecCtx *ctx, int64_t argc, int64_t *argv); + static int check_trigger_arg(const ParamStore ¶ms, const ObPLFunction &func); + private: common::ObMySQLProxy *sql_proxy_; ObPLPackageManager package_manager_; diff --git a/src/pl/ob_pl_code_generator.cpp b/src/pl/ob_pl_code_generator.cpp index 7d7023ebf2..1d47fcfd0b 100644 --- a/src/pl/ob_pl_code_generator.cpp +++ b/src/pl/ob_pl_code_generator.cpp @@ -8100,6 +8100,9 @@ int ObPLCodeGenerator::generate_simple(ObPLFunction &pl_func) OZ (sql_info.generate(*sql_stmt, pl_func.get_expressions())); OZ (sql_infos.push_back(sql_info)); } + if (OB_SUCC(ret) && ObTriggerInfo::is_trigger_body_package_id(pl_func.get_package_id())) { + OZ (pl_func.set_types(get_ast().get_user_type_table())); + } return ret; } diff --git a/src/pl/ob_pl_resolver.cpp b/src/pl/ob_pl_resolver.cpp index 9ad795b7a7..4623d5bd24 100644 --- a/src/pl/ob_pl_resolver.cpp +++ b/src/pl/ob_pl_resolver.cpp @@ -1711,7 +1711,7 @@ int ObPLResolver::get_view_select_stmt( db_schema->get_database_name_str().length(), db_schema->get_database_name_str().ptr(), view_schema->get_table_name_str().length(), view_schema->get_table_name_str().ptr())); OZ (parser.parse(select_sql.string(), parse_result)); - OZ (schema_checker.init(ctx.schema_guard_)); + OZ (schema_checker.init(ctx.schema_guard_, ctx.session_info_.get_sessid())); OX (resolver_ctx.allocator_ = &(ctx.allocator_)); OX (resolver_ctx.schema_checker_ = &schema_checker); @@ -1785,7 +1785,7 @@ int ObPLResolver::build_record_type_by_view_schema(const ObPLResolveCtx &ctx, db_schema->get_database_name_str().length(), db_schema->get_database_name_str().ptr(), view_schema->get_table_name_str().length(), view_schema->get_table_name_str().ptr())); OZ (parser.parse(select_sql.string(), parse_result)); - OZ (schema_checker.init(ctx.schema_guard_)); + OZ (schema_checker.init(ctx.schema_guard_, ctx.session_info_.get_sessid())); OX (resolver_ctx.allocator_ = &(alloc)); OX (resolver_ctx.schema_checker_ = &schema_checker); @@ -5682,7 +5682,7 @@ int ObPLResolver::resolve_call(const ObStmtNodeTree *parse_tree, ObPLCallStmt *s if (OB_ISNULL(name_node)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("the children of parse tree is NULL", K(name_node), K(ret)); - } else if (OB_FAIL(schema_checker.init(resolve_ctx_.schema_guard_))) { + } else if (OB_FAIL(schema_checker.init(resolve_ctx_.schema_guard_, resolve_ctx_.session_info_.get_sessid()))) { LOG_ERROR("schema checker init failed", K(ret)); } else { ObString db_name; @@ -10163,7 +10163,7 @@ int ObPLResolver::resolve_udf_info( CK (OB_NOT_NULL(udf_info.ref_expr_)); CK (OB_NOT_NULL(current_block_)); OX (func.set_external_state()); - OZ (schema_checker.init(resolve_ctx_.schema_guard_)); + OZ (schema_checker.init(resolve_ctx_.schema_guard_, resolve_ctx_.session_info_.get_sessid())); OZ (ObRawExprUtils::rebuild_expr_params(udf_info, &expr_factory_, expr_params), K(udf_info), K(access_idxs)); { ObPLMockSelfArg self(access_idxs, expr_params, expr_factory_); @@ -10461,7 +10461,7 @@ int ObPLResolver::check_local_variable_read_only( ObSchemaChecker schema_checker; \ const ObTriggerInfo *trg_info = NULL; \ const uint64_t tenant_id = resolve_ctx_.session_info_.get_effective_tenant_id(); \ - OZ (schema_checker.init(resolve_ctx_.schema_guard_)); \ + OZ (schema_checker.init(resolve_ctx_.schema_guard_, resolve_ctx_.session_info_.get_sessid())); \ OZ (schema_checker.get_trigger_info(tenant_id, ns.get_db_name(), ns.get_package_name(), trg_info)); \ CK (OB_NOT_NULL(trg_info)); @@ -12603,7 +12603,7 @@ int ObPLResolver::resolve_condition(const ObStmtNodeTree *parse_tree, ObString db_name; ObString package_name; ObString condition_name; - OZ (schema_checker.init(resolve_ctx_.schema_guard_)); + OZ (schema_checker.init(resolve_ctx_.schema_guard_, resolve_ctx_.session_info_.get_sessid())); OZ (ObResolverUtils::resolve_sp_access_name(schema_checker, resolve_ctx_.session_info_.get_effective_tenant_id(), resolve_ctx_.session_info_.get_database_name(), @@ -13302,7 +13302,7 @@ int ObPLResolver::resolve_cursor( ObString db_name; ObString package_name; ObString cursor_name; - OZ (schema_checker.init(resolve_ctx_.schema_guard_)); + OZ (schema_checker.init(resolve_ctx_.schema_guard_, resolve_ctx_.session_info_.get_sessid())); OZ (ObResolverUtils::resolve_sp_access_name( schema_checker, resolve_ctx_.session_info_.get_effective_tenant_id(), resolve_ctx_.session_info_.get_database_name(), @@ -15209,7 +15209,7 @@ int ObPLResolver::check_var_type(ObString &name, uint64_t db_id, ObSchemaType &s ObSynonymChecker synonym_checker; uint64_t object_db_id = OB_INVALID_ID; ObString object_name; - if (OB_FAIL(schema_checker.init(schema_guard))) { + if (OB_FAIL(schema_checker.init(schema_guard, resolve_ctx_.session_info_.get_sessid()))) { LOG_WARN("failed to init schema_checker", K(ret)); } else if (OB_FAIL(ObResolverUtils::resolve_synonym_object_recursively( schema_checker, synonym_checker, tenant_id, @@ -15271,7 +15271,7 @@ int ObPLResolver::check_update_column(const ObPLBlockNS &ns, const ObIArray