diff --git a/src/rootserver/ob_ddl_operator.cpp b/src/rootserver/ob_ddl_operator.cpp index a46c2e9f8a..1ccfb73e87 100644 --- a/src/rootserver/ob_ddl_operator.cpp +++ b/src/rootserver/ob_ddl_operator.cpp @@ -8717,11 +8717,12 @@ int ObDDLOperator::alter_package(const ObPackageInfo &package_info, OZ (schema_service_impl->get_routine_sql_service().update_routine(routine_info, &trans)); } } - OZ (new_package_info.assign(package_info)); - OZ (schema_service_.gen_new_schema_version(tenant_id, new_schema_version)); - OX (new_package_info.set_schema_version(new_schema_version)); - OZ (schema_service_impl->get_routine_sql_service().alter_package(new_package_info, &trans, ddl_stmt_str)); } + // if alter package, we need push up schema version, because we need update package state + OZ (new_package_info.assign(package_info)); + OZ (schema_service_.gen_new_schema_version(tenant_id, new_schema_version)); + OX (new_package_info.set_schema_version(new_schema_version)); + OZ (schema_service_impl->get_routine_sql_service().alter_package(new_package_info, &trans, ddl_stmt_str)); } OZ (error_info.handle_error_info(trans, &package_info)); return ret; diff --git a/src/rootserver/ob_root_service.cpp b/src/rootserver/ob_root_service.cpp index bfac724e54..2ac45cd375 100755 --- a/src/rootserver/ob_root_service.cpp +++ b/src/rootserver/ob_root_service.cpp @@ -7270,15 +7270,17 @@ int ObRootService::create_package(const obrpc::ObCreatePackageArg &arg) ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid arg", K(arg), K(ret)); } else { - ObPackageInfo new_package_info = arg.package_info_; + ObPackageInfo new_package_info; const ObPackageInfo *old_package_info = NULL; - uint64_t tenant_id = new_package_info.get_tenant_id(); + uint64_t tenant_id = arg.package_info_.get_tenant_id(); ObString database_name = arg.db_name_; ObSchemaGetterGuard schema_guard; const ObDatabaseSchema *db_schema = NULL; const ObUserInfo *user_info = NULL; bool is_oracle_mode = false; - if (OB_FAIL(ObCompatModeGetter::check_is_oracle_mode_with_tenant_id( + if (OB_FAIL(new_package_info.assign(arg.package_info_))) { + LOG_WARN("fail to assign package info", K(ret)); + } else if (OB_FAIL(ObCompatModeGetter::check_is_oracle_mode_with_tenant_id( tenant_id, is_oracle_mode))) { LOG_WARN("fail to check is oracle mode", K(ret)); } else if (OB_FAIL(ddl_service_.get_tenant_schema_guard_with_version_in_inner_table(tenant_id, schema_guard))) { @@ -7424,12 +7426,34 @@ int ObRootService::alter_package(const obrpc::ObAlterPackageArg &arg) } else if (OB_ISNULL(package_info)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("package info is null", K(db_schema->get_database_id()), K(package_name), K(package_type), K(ret)); - } else if (OB_FAIL(ddl_service_.alter_package(schema_guard, - *package_info, - public_routine_infos, - const_cast(arg.error_info_), - &arg.ddl_stmt_str_))) { - LOG_WARN("drop package failed", K(ret), K(package_name)); + } + if (OB_SUCC(ret)) { + if (GET_MIN_CLUSTER_VERSION() < CLUSTER_VERSION_4_3_1_0) { + if (OB_FAIL(ddl_service_.alter_package(schema_guard, + *package_info, + public_routine_infos, + const_cast(arg.error_info_), + &arg.ddl_stmt_str_))) { + LOG_WARN("drop package failed", K(ret), K(package_name)); + } + } else { + ObSArray &dep_infos = + const_cast &>(arg.dependency_infos_); + ObPackageInfo new_package_info; + if (OB_FAIL(new_package_info.assign(*package_info))) { + LOG_WARN("failed to copy new package info", K(ret)); + } else if (OB_FAIL(new_package_info.set_exec_env(arg.exec_env_))) { + LOG_WARN("fail to set exec env", K(ret)); + } else if (OB_FAIL(ddl_service_.create_package(schema_guard, + package_info, + new_package_info, + public_routine_infos, + const_cast(arg.error_info_), + dep_infos, + &arg.ddl_stmt_str_))) { + LOG_WARN("create package failed", K(ret), K(new_package_info)); + } + } } } else { ret = OB_ERR_PACKAGE_DOSE_NOT_EXIST; diff --git a/src/share/ob_rpc_struct.cpp b/src/share/ob_rpc_struct.cpp index ade8b6bf0b..113752de0e 100755 --- a/src/share/ob_rpc_struct.cpp +++ b/src/share/ob_rpc_struct.cpp @@ -5849,18 +5849,21 @@ int ObAlterPackageArg::assign(const ObAlterPackageArg &other) LOG_WARN("fail to assign array", K(ret)); } else if (OB_FAIL(error_info_.assign(other.error_info_))) { LOG_WARN("failed to copy error info", K(ret)); + } else if (OB_FAIL(dependency_infos_.assign(other.dependency_infos_))) { + LOG_WARN("failed to copy dependency info", K(ret)); } else { tenant_id_ = other.tenant_id_; db_name_ = other.db_name_; package_name_ = other.package_name_; package_type_ = other.package_type_; compatible_mode_ = other.compatible_mode_; + exec_env_ = other.exec_env_; } return ret; } OB_SERIALIZE_MEMBER((ObAlterPackageArg, ObDDLArg), tenant_id_, db_name_, package_name_, package_type_, - compatible_mode_, public_routine_infos_, error_info_); + compatible_mode_, public_routine_infos_, error_info_, exec_env_, dependency_infos_); bool ObDropPackageArg::is_valid() const { diff --git a/src/share/ob_rpc_struct.h b/src/share/ob_rpc_struct.h index 50b295e054..5b6b44e800 100755 --- a/src/share/ob_rpc_struct.h +++ b/src/share/ob_rpc_struct.h @@ -6857,13 +6857,16 @@ public: package_type_(share::schema::INVALID_PACKAGE_TYPE), compatible_mode_(-1), public_routine_infos_(), - error_info_() + error_info_(), + exec_env_(), + dependency_infos_() {} virtual ~ObAlterPackageArg() {} bool is_valid() const; int assign(const ObAlterPackageArg &other); TO_STRING_KV(K_(tenant_id), K_(db_name), K_(package_name), K_(package_type), - K_(compatible_mode), K_(public_routine_infos), K_(error_info)); + K_(compatible_mode), K_(public_routine_infos), K_(error_info), + K_(exec_env), K_(dependency_infos)); uint64_t tenant_id_; common::ObString db_name_; @@ -6872,6 +6875,8 @@ public: int64_t compatible_mode_; common::ObSArray public_routine_infos_; share::schema::ObErrorInfo error_info_; + common::ObString exec_env_; + common::ObSArray dependency_infos_; }; struct ObDropPackageArg : public ObDDLArg diff --git a/src/share/schema/ob_package_info.cpp b/src/share/schema/ob_package_info.cpp index 0575a9b349..ef6c8fbf32 100644 --- a/src/share/schema/ob_package_info.cpp +++ b/src/share/schema/ob_package_info.cpp @@ -21,11 +21,12 @@ namespace share { namespace schema { -ObPackageInfo &ObPackageInfo::operator =(const ObPackageInfo &package_info) + +int ObPackageInfo::assign(const ObPackageInfo &package_info) { + int ret = OB_SUCCESS; if (this != &package_info) { reset(); - int &ret = error_ret_; set_tenant_id(package_info.get_tenant_id()); database_id_ = package_info.database_id_; owner_id_ = package_info.owner_id_; @@ -48,15 +49,8 @@ ObPackageInfo &ObPackageInfo::operator =(const ObPackageInfo &package_info) }else { // do nothing } + this->error_ret_ = ret; } - return *this; -} - -int ObPackageInfo::assign(const ObPackageInfo &other) -{ - int ret = OB_SUCCESS; - this->operator=(other); - ret = this->error_ret_; return ret; } diff --git a/src/share/schema/ob_package_info.h b/src/share/schema/ob_package_info.h index 186e753c41..97db534c37 100644 --- a/src/share/schema/ob_package_info.h +++ b/src/share/schema/ob_package_info.h @@ -51,15 +51,9 @@ public: reset(); } - ObPackageInfo(const ObPackageInfo &package_info) - : ObSchema() - { - reset(); - *this = package_info; - } + DISABLE_COPY_ASSIGN(ObPackageInfo); virtual ~ObPackageInfo() {} - ObPackageInfo &operator=(const ObPackageInfo &package_info); int assign(const ObPackageInfo &other); bool is_valid() const; void reset(); diff --git a/src/share/schema/ob_routine_sql_service.cpp b/src/share/schema/ob_routine_sql_service.cpp index 4ead36ab86..0cbbe524a8 100644 --- a/src/share/schema/ob_routine_sql_service.cpp +++ b/src/share/schema/ob_routine_sql_service.cpp @@ -49,7 +49,7 @@ int ObRoutineSqlService::create_package(ObPackageInfo &package_info, opt.tenant_id_ = package_info.get_tenant_id(); opt.database_id_ = package_info.get_database_id(); opt.table_id_ = package_info.get_package_id(); - opt.op_type_ = OB_DDL_CREATE_PACKAGE; + opt.op_type_ = is_replace ? OB_DDL_ALTER_PACKAGE : OB_DDL_CREATE_PACKAGE; opt.schema_version_ = package_info.get_schema_version(); opt.ddl_stmt_str_ = (NULL != ddl_stmt_str) ? *ddl_stmt_str : ObString(); if (OB_FAIL(log_operation(opt, *sql_client))) { diff --git a/src/sql/resolver/ddl/ob_alter_package_resolver.cpp b/src/sql/resolver/ddl/ob_alter_package_resolver.cpp index 99c6348db1..d839ba51e4 100644 --- a/src/sql/resolver/ddl/ob_alter_package_resolver.cpp +++ b/src/sql/resolver/ddl/ob_alter_package_resolver.cpp @@ -159,6 +159,10 @@ int ObAlterPackageResolver::compile_package(const ObString& db_name, package_guard, *(params_.sql_proxy_)); bool has_error = false; + char buf[OB_MAX_PROC_ENV_LENGTH]; + int64_t pos = 0; + OZ (ObExecEnv::gen_exec_env(*session_info_, buf, OB_MAX_PROC_ENV_LENGTH, pos)); + OZ (ob_write_string(*allocator_, ObString(pos, buf), pkg_arg.exec_env_)); OZ (package_guard.init()); OZ (schema_checker_->get_package_info(session_info_->get_effective_tenant_id(), db_name, @@ -242,32 +246,48 @@ int ObAlterPackageResolver::compile_package(const ObString& db_name, &package_spec_ast)); OZ (analyze_package(compiler, &(package_spec_ast.get_body()->get_namespace()), package_body_ast, db_name, package_body_info, error_info, has_error)); - if (OB_SUCC(ret) && !has_error) { - // if has_error, don't need to update routine route sql + if (OB_SUCC(ret)) { ObArray routine_infos; - ObSEArray routine_spec_infos; - ObPLRoutineTable &spec_routine_table = package_spec_ast.get_routine_table(); - ObPLRoutineTable &body_routine_table = package_body_ast.get_routine_table(); OZ (schema_checker_->get_schema_guard()->get_routine_infos_in_package( - session_info_->get_effective_tenant_id(), - package_spec_info->get_package_id(), - routine_infos)); - if (OB_SUCC(ret) && routine_infos.empty() && spec_routine_table.get_count() > 1) { - OZ (ObCreatePackageResolver::resolve_functions_spec( - *package_spec_info, routine_spec_infos, spec_routine_table)); - CK (routine_spec_infos.count() > 0); - for (int64_t i = 0; OB_SUCC(ret) && i < routine_spec_infos.count(); ++i) { - OZ (routine_infos.push_back(&routine_spec_infos.at(i))); + session_info_->get_effective_tenant_id(), + package_spec_info->get_package_id(), + routine_infos)); + if (OB_FAIL(ret)) { + } else if (!has_error) { + // if has_error, don't need to update routine route sql + ObSEArray routine_spec_infos; + ObPLRoutineTable &spec_routine_table = package_spec_ast.get_routine_table(); + ObPLRoutineTable &body_routine_table = package_body_ast.get_routine_table(); + if (OB_SUCC(ret) && routine_infos.empty() && spec_routine_table.get_count() > 1) { + OZ (ObCreatePackageResolver::resolve_functions_spec( + *package_spec_info, routine_spec_infos, spec_routine_table)); + CK (routine_spec_infos.count() > 0); + for (int64_t i = 0; OB_SUCC(ret) && i < routine_spec_infos.count(); ++i) { + OZ (routine_infos.push_back(&routine_spec_infos.at(i))); + } + } + OZ (ObCreatePackageBodyResolver::update_routine_route_sql(*allocator_, + *session_info_, + pkg_arg.public_routine_infos_, + spec_routine_table, + body_routine_table, + routine_infos)); + if (OB_FAIL(ret)) { + pkg_arg.public_routine_infos_.reset(); + } + } else if (0 != package_body_info->get_exec_env().case_compare(pkg_arg.exec_env_)) { + for (int64_t i = 0; OB_SUCC(ret) && i < routine_infos.count(); ++i) { + OZ (pkg_arg.public_routine_infos_.push_back(*routine_infos.at(i))); } } - OZ (ObCreatePackageBodyResolver::update_routine_route_sql(*allocator_, - *session_info_, - pkg_arg.public_routine_infos_, - spec_routine_table, - body_routine_table, - routine_infos)); - if (OB_FAIL(ret)) { - pkg_arg.public_routine_infos_.reset(); + // TODO:actually,“alter package compile” should replace package spec and package body + // but if we will alter package body, it only send package body info rpc, so we can only collect package body dep + if (OB_SUCC(ret)) { + ObString dep_attr; + OZ (ObDependencyInfo::collect_dep_infos(package_body_ast.get_dependency_table(), + pkg_arg.dependency_infos_, + ObObjectType::PACKAGE_BODY, + 0, dep_attr, dep_attr)); } } COLLECT_PACKAGE_INFO(pkg_arg, package_body_info);