From 9142f00e21fa41f669a9992502203ababd38a195 Mon Sep 17 00:00:00 2001 From: obdev Date: Wed, 22 May 2024 07:36:06 +0000 Subject: [PATCH] [CP] [to #56772630] fix serval pl/sql bugs --- src/pl/ob_pl.cpp | 57 ++++++++++++++++--- src/pl/ob_pl.h | 6 +- src/pl/ob_pl_stmt.cpp | 6 +- src/pl/ob_pl_stmt.h | 2 + .../expr/ob_raw_expr_resolver_impl.cpp | 23 ++++++++ src/sql/resolver/ob_resolver_utils.cpp | 3 +- 6 files changed, 82 insertions(+), 15 deletions(-) diff --git a/src/pl/ob_pl.cpp b/src/pl/ob_pl.cpp index df09504bb..8bc4f8894 100644 --- a/src/pl/ob_pl.cpp +++ b/src/pl/ob_pl.cpp @@ -2873,6 +2873,17 @@ int ObPLExecCtx::get_user_type(uint64_t type_id, return ret; } +int ObPLExecCtx::calc_expr(uint64_t package_id, int64_t expr_idx, ObObjParam &result) +{ + int ret = OB_SUCCESS; + if (OB_INVALID_ID == package_id) { + OZ (ObSPIService::spi_calc_expr_at_idx(this, expr_idx, OB_INVALID_INDEX, &result)); + } else { + OZ (ObSPIService::spi_calc_package_expr(this, package_id, expr_idx, &result)); + } + return ret; +} + int ObPLExecState::final(int ret) { int tmp_ret = OB_SUCCESS; @@ -3971,7 +3982,8 @@ int ObPLExecState::check_pl_execute_priv(ObSchemaGetterGuard &guard, OBJ_PRIV_ID_EXECUTE, CHECK_FLAG_NORMAL, obj_owner_id, - role_id_array)); + role_id_array), + K(obj_tenant_id), K(user_id), K(database_name), K(obj_id), K(obj_owner_id), K(role_id_array)); } if (ROUTINE_SCHEMA == schema_type && ret == OB_TABLE_NOT_EXIST) { ret = OB_WRONG_COLUMN_NAME; @@ -4453,11 +4465,18 @@ int ObPLFunction::is_special_pkg_invoke_right(ObSchemaGetterGuard &guard, bool & return ret; } +int ObPLINS::calc_expr(uint64_t package_id, int64_t expr_idx, ObObjParam &result) +{ + int ret = OB_NOT_SUPPORTED; + LOG_USER_WARN(OB_NOT_SUPPORTED, "call expr on base class ObIPLNS"); + return ret; +} + int ObPLINS::init_complex_obj(ObIAllocator &allocator, const ObPLDataType &pl_type, common::ObObjParam &obj, bool set_allocator, - bool set_null) const + bool set_null) { int ret = OB_SUCCESS; int64_t init_size = 0; @@ -4489,16 +4508,36 @@ int ObPLINS::init_complex_obj(ObIAllocator &allocator, OX (record = reinterpret_cast(ptr)); for (int64_t i = 0; OB_SUCC(ret) && i < record_type->get_member_count(); ++i) { CK (OB_NOT_NULL(record_type->get_member(i))); + CK (OB_NOT_NULL(record_type->get_record_member(i))); OZ (record->get_element(i, member)); CK (OB_NOT_NULL(member)); - if (record_type->get_member(i)->is_obj_type()) { - OX (new (member) ObObj(ObNullType)); + OX (new (member) ObObj(ObNullType)); + if (OB_FAIL(ret)) { + } else if (record_type->get_record_member(i)->get_default() != OB_INVALID_INDEX) { + ObObjParam default_v; + if (record_type->is_package_type()) { + OZ (calc_expr(extract_package_id(pl_type.get_user_type_id()), + record_type->get_record_member(i)->get_default(), + default_v)); + } else { + OZ (calc_expr(OB_INVALID_ID, + record_type->get_record_member(i)->get_default(), + default_v)); + } + if (OB_FAIL(ret)) { + } else if (record_type->get_member(i)->is_obj_type()) { + OZ (deep_copy_obj(allocator, default_v, *member)); + } else { + OZ (ObUserDefinedType::deep_copy_obj(allocator, default_v, *member)); + } } else { - int64_t init_size = OB_INVALID_SIZE; - int64_t member_ptr = 0; - OZ (record_type->get_member(i)->get_size(PL_TYPE_INIT_SIZE, init_size)); - OZ (record_type->get_member(i)->newx(allocator, this, member_ptr)); - OX (member->set_extend(member_ptr, record_type->get_member(i)->get_type(), init_size)); + if (!record_type->get_member(i)->is_obj_type()) { + int64_t init_size = OB_INVALID_SIZE; + int64_t member_ptr = 0; + OZ (record_type->get_member(i)->get_size(PL_TYPE_INIT_SIZE, init_size)); + OZ (record_type->get_member(i)->newx(allocator, this, member_ptr)); + OX (member->set_extend(member_ptr, record_type->get_member(i)->get_type(), init_size)); + } } } // f(self object_type, p1 out object_type), p1 will be init here, we have to set it null diff --git a/src/pl/ob_pl.h b/src/pl/ob_pl.h index 6f2cbaa71..316b88f01 100644 --- a/src/pl/ob_pl.h +++ b/src/pl/ob_pl.h @@ -95,7 +95,9 @@ public: const ObPLDataType &pl_type, common::ObObjParam &obj, bool set_allocator = false, - bool set_null = true) const; + bool set_null = true); + + virtual int calc_expr(uint64_t package_id, int64_t expr_idx, ObObjParam &result); }; class ObPLFunctionBase @@ -645,8 +647,8 @@ struct ObPLExecCtx : public ObPLINS virtual int get_user_type(uint64_t type_id, const ObUserDefinedType *&user_type, ObIAllocator *allocator = NULL) const; + virtual int calc_expr(uint64_t package_id, int64_t expr_idx, ObObjParam &result); - //Note: 不实现虚函数,省得llvm解析的时候需要处理vtable麻烦 common::ObIAllocator *allocator_; sql::ObExecContext *exec_ctx_; ParamStore *params_; // param stroe, 对应PL Function的符号表 diff --git a/src/pl/ob_pl_stmt.cpp b/src/pl/ob_pl_stmt.cpp index 6b1acdd5e..511d106b5 100644 --- a/src/pl/ob_pl_stmt.cpp +++ b/src/pl/ob_pl_stmt.cpp @@ -2217,9 +2217,9 @@ int ObPLExternalNS::resolve_external_routine(const ObString &db_name, LOG_WARN("add dependency object failed", "package_id", schema_routine_info->get_package_id(), K(ret)); } else if (synonym_checker.has_synonym()) { if (OB_FAIL(ObResolverUtils::add_dependency_synonym_object(&resolve_ctx_.schema_guard_, - &resolve_ctx_.session_info_, - synonym_checker, - *get_dependency_table()))) { + &resolve_ctx_.session_info_, + synonym_checker, + *get_dependency_table()))) { LOG_WARN("add dependency synonym failed", K(ret)); } } diff --git a/src/pl/ob_pl_stmt.h b/src/pl/ob_pl_stmt.h index 5bc45fe3a..b32327408 100644 --- a/src/pl/ob_pl_stmt.h +++ b/src/pl/ob_pl_stmt.h @@ -1208,6 +1208,8 @@ public: inline const ObPLBlockNS *get_parent_ns() const { return parent_ns_; } inline const ObPLResolveCtx &get_resolve_ctx() { return resolve_ctx_; } inline const ObPLDependencyTable *get_dependency_table() const { return dependency_table_; } + + inline ObPLDependencyTable *get_dependency_table() { return dependency_table_; } inline void set_dependency_table(ObPLDependencyTable *dependency_table) { dependency_table_ = dependency_table; } int add_dependency_object(const share::schema::ObSchemaObjVersion &obj_version) const; diff --git a/src/sql/resolver/expr/ob_raw_expr_resolver_impl.cpp b/src/sql/resolver/expr/ob_raw_expr_resolver_impl.cpp index 6cdcd3c22..f0e1cfbd9 100644 --- a/src/sql/resolver/expr/ob_raw_expr_resolver_impl.cpp +++ b/src/sql/resolver/expr/ob_raw_expr_resolver_impl.cpp @@ -2195,11 +2195,34 @@ int ObRawExprResolverImpl::check_pl_variable(ObQualifiedName &q_name, bool &is_p if (NULL == ctx_.secondary_namespace_) { // do nothing ... } else { + +class ObPLDependencyGuard +{ +public: + ObPLDependencyGuard(pl::ObPLDependencyTable *dependency_table) + : dependency_table_(dependency_table), count_(0) { + if (OB_NOT_NULL(dependency_table_)) { + count_ = dependency_table_->count(); + } + } + ~ObPLDependencyGuard() { + if (OB_NOT_NULL(dependency_table_)) { + while (dependency_table_->count() > count_) { + dependency_table_->pop_back(); + } + } + } +private: + pl::ObPLDependencyTable *dependency_table_; + int64_t count_; +}; + SET_LOG_CHECK_MODE(); CK(OB_NOT_NULL(ctx_.secondary_namespace_->get_external_ns())); if (OB_SUCC(ret)) { ObArray fake_columns; ObArray fake_exprs; + ObPLDependencyGuard dep_guard(ctx_.secondary_namespace_->get_external_ns()->get_dependency_table()); if (OB_FAIL(ObResolverUtils::resolve_external_symbol(allocator, expr_factory, ctx_.secondary_namespace_->get_external_ns()->get_resolve_ctx().session_info_, diff --git a/src/sql/resolver/ob_resolver_utils.cpp b/src/sql/resolver/ob_resolver_utils.cpp index 5a6fed0d8..ec281d88b 100644 --- a/src/sql/resolver/ob_resolver_utils.cpp +++ b/src/sql/resolver/ob_resolver_utils.cpp @@ -7409,6 +7409,7 @@ int ObResolverUtils::resolve_external_symbol(common::ObIAllocator &allocator, } } } + if (OB_SUCC(ret)) { pl::ObPLResolver pl_resolver(allocator, session_info, @@ -7446,7 +7447,7 @@ int ObResolverUtils::resolve_external_symbol(common::ObIAllocator &allocator, && T_FUN_PL_GET_CURSOR_ATTR != expr->get_expr_type()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("expr type is invalid", K(expr->get_expr_type())); - } else if (OB_NOT_NULL(ns) && OB_NOT_NULL(ns->get_external_ns())) { + } else if (OB_NOT_NULL(ns) && OB_NOT_NULL(ns->get_external_ns()) && !is_check_mode) { ObPLDependencyTable &src_dep_tbl = func_ast.get_dependency_table(); for (int64_t i = 0; OB_SUCC(ret) && i < src_dep_tbl.count(); ++i) { OZ (ns->get_external_ns()->add_dependency_object(src_dep_tbl.at(i)));