[CP] [to #53286756] refactor(ddl): alter package compile error if the package does not have a body
This commit is contained in:
@ -81,8 +81,6 @@ int ObAlterPackageResolver::resolve_alter_compile_clause(const ParseNode &alter_
|
|||||||
obrpc::ObAlterPackageArg &pkg_arg)
|
obrpc::ObAlterPackageArg &pkg_arg)
|
||||||
{
|
{
|
||||||
int ret = OB_SUCCESS;
|
int ret = OB_SUCCESS;
|
||||||
bool compile_spec = false;
|
|
||||||
bool compile_body = false;
|
|
||||||
CK (OB_LIKELY(T_PACKAGE_ALTER_OPTIONS == alter_clause.type_));
|
CK (OB_LIKELY(T_PACKAGE_ALTER_OPTIONS == alter_clause.type_));
|
||||||
CK (OB_LIKELY(PACKAGE_ALTER_COMPILE == alter_clause.int16_values_[0]));
|
CK (OB_LIKELY(PACKAGE_ALTER_COMPILE == alter_clause.int16_values_[0]));
|
||||||
if (OB_FAIL(ret)) {
|
if (OB_FAIL(ret)) {
|
||||||
@ -90,64 +88,68 @@ int ObAlterPackageResolver::resolve_alter_compile_clause(const ParseNode &alter_
|
|||||||
ret = OB_NOT_SUPPORTED;
|
ret = OB_NOT_SUPPORTED;
|
||||||
LOG_WARN("alter package with reuse_setting not supported yet!", K(ret));
|
LOG_WARN("alter package with reuse_setting not supported yet!", K(ret));
|
||||||
LOG_USER_ERROR(OB_NOT_SUPPORTED, "alter package with reuse setting");
|
LOG_USER_ERROR(OB_NOT_SUPPORTED, "alter package with reuse setting");
|
||||||
} else if (PACKAGE_UNIT_BODY == alter_clause.int16_values_[2]) {
|
|
||||||
compile_body = true;
|
|
||||||
} else if (PACKAGE_UNIT_SPECIFICATION == alter_clause.int16_values_[2]) {
|
|
||||||
compile_spec = true;
|
|
||||||
}
|
}
|
||||||
OZ (compile_package(db_name, package_name, compile_spec, compile_body, pkg_arg));
|
OZ (compile_package(db_name, package_name, alter_clause.int16_values_[2], pkg_arg));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ObAlterPackageResolver::analyze_package(ObPLCompiler &compiler,
|
int ObAlterPackageResolver::analyze_package(ObPLCompiler &compiler,
|
||||||
const ObString &source,
|
|
||||||
const ObPLBlockNS *parent_ns,
|
const ObPLBlockNS *parent_ns,
|
||||||
ObPLPackageAST &package_ast,
|
ObPLPackageAST &package_ast,
|
||||||
bool is_for_trigger,
|
|
||||||
bool is_package,
|
|
||||||
const ObString& db_name,
|
const ObString& db_name,
|
||||||
const ObString &package_name,
|
|
||||||
const ObPackageInfo *package_info,
|
const ObPackageInfo *package_info,
|
||||||
share::schema::ObErrorInfo &error_info,
|
share::schema::ObErrorInfo &error_info,
|
||||||
bool &has_error)
|
bool &has_error)
|
||||||
{
|
{
|
||||||
int ret = OB_SUCCESS;
|
int ret = OB_SUCCESS;
|
||||||
int tmp_ret = OB_SUCCESS;
|
ObString source;
|
||||||
if (OB_FAIL(compiler.analyze_package(source, parent_ns, package_ast, is_for_trigger))) {
|
ObString package_name;
|
||||||
|
|
||||||
|
CK (OB_NOT_NULL(package_info));
|
||||||
|
CK (package_info->is_package() || package_info->is_package_body());
|
||||||
|
OX (package_name = package_info->get_package_name());
|
||||||
|
OX (source = package_info->get_source());
|
||||||
|
OZ (ObSQLUtils::convert_sql_text_from_schema_for_resolve(
|
||||||
|
*allocator_, session_info_->get_dtc_params(), source));
|
||||||
|
|
||||||
|
if (OB_FAIL(ret)) {
|
||||||
|
} else if (OB_FAIL(compiler.analyze_package(source, parent_ns, package_ast,
|
||||||
|
false /* is_for_trigger */))) {
|
||||||
ObPL::insert_error_msg(ret);
|
ObPL::insert_error_msg(ret);
|
||||||
switch (ret) {
|
switch (ret) {
|
||||||
case OB_ERR_PACKAGE_DOSE_NOT_EXIST:
|
case OB_ERR_PACKAGE_DOSE_NOT_EXIST:
|
||||||
LOG_USER_WARN(OB_ERR_PACKAGE_DOSE_NOT_EXIST, is_package ? "PACKAGE" : "PACKAGE BODY",
|
LOG_USER_WARN(OB_ERR_PACKAGE_DOSE_NOT_EXIST,
|
||||||
|
package_info->is_package() ? "PACKAGE" : "PACKAGE BODY",
|
||||||
db_name.length(), db_name.ptr(), package_name.length(), package_name.ptr());
|
db_name.length(), db_name.ptr(), package_name.length(), package_name.ptr());
|
||||||
break;
|
break;
|
||||||
case OB_ERR_BAD_DATABASE:
|
case OB_ERR_BAD_DATABASE:
|
||||||
LOG_USER_WARN(OB_ERR_BAD_DATABASE, db_name.length(), db_name.ptr());
|
LOG_USER_WARN(OB_ERR_BAD_DATABASE, db_name.length(), db_name.ptr());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOG_USER_WARN(OB_ERR_PACKAGE_COMPILE_ERROR, is_package ? "PACKAGE" : "PACKAGE BODY",
|
LOG_USER_WARN(OB_ERR_PACKAGE_COMPILE_ERROR,
|
||||||
|
package_info->is_package() ? "PACKAGE" : "PACKAGE BODY",
|
||||||
db_name.length(), db_name.ptr(), package_name.length(), package_name.ptr());
|
db_name.length(), db_name.ptr(), package_name.length(), package_name.ptr());
|
||||||
has_error = true;
|
has_error = true;
|
||||||
ret = OB_SUCCESS;
|
ret = OB_SUCCESS;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tmp_ret = error_info.collect_error_info(package_info);
|
OZ (error_info.collect_error_info(package_info));
|
||||||
ret = OB_SUCCESS == ret ? tmp_ret : ret;
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ObAlterPackageResolver::compile_package(const ObString& db_name,
|
int ObAlterPackageResolver::compile_package(const ObString& db_name,
|
||||||
const ObString &package_name,
|
const ObString &package_name,
|
||||||
bool compile_spec,
|
int16_t compile_flag,
|
||||||
bool compile_body,
|
|
||||||
obrpc::ObAlterPackageArg &pkg_arg)
|
obrpc::ObAlterPackageArg &pkg_arg)
|
||||||
{
|
{
|
||||||
int ret = OB_SUCCESS;
|
int ret = OB_SUCCESS;
|
||||||
const ObPackageInfo *package_spec_info = NULL;
|
const ObPackageInfo *package_spec_info = nullptr;
|
||||||
const ObPackageInfo *package_body_info = NULL;
|
const ObPackageInfo *package_body_info = nullptr;
|
||||||
int64_t compatible_mode = lib::is_oracle_mode() ? COMPATIBLE_ORACLE_MODE
|
int64_t compatible_mode = lib::is_oracle_mode() ? COMPATIBLE_ORACLE_MODE
|
||||||
: COMPATIBLE_MYSQL_MODE;
|
: COMPATIBLE_MYSQL_MODE;
|
||||||
share::schema::ObErrorInfo &error_info = pkg_arg.error_info_;
|
share::schema::ObErrorInfo &error_info = pkg_arg.error_info_;
|
||||||
|
|
||||||
HEAP_VARS_2((ObPLPackageAST, package_spec_ast, *allocator_),
|
HEAP_VARS_2((ObPLPackageAST, package_spec_ast, *allocator_),
|
||||||
(ObPLPackageAST, package_body_ast, *allocator_)) {
|
(ObPLPackageAST, package_body_ast, *allocator_)) {
|
||||||
ObPLPackageGuard package_guard(session_info_->get_effective_tenant_id());
|
ObPLPackageGuard package_guard(session_info_->get_effective_tenant_id());
|
||||||
@ -156,7 +158,6 @@ int ObAlterPackageResolver::compile_package(const ObString& db_name,
|
|||||||
*(schema_checker_->get_schema_guard()),
|
*(schema_checker_->get_schema_guard()),
|
||||||
package_guard,
|
package_guard,
|
||||||
*(params_.sql_proxy_));
|
*(params_.sql_proxy_));
|
||||||
ObString source;
|
|
||||||
bool has_error = false;
|
bool has_error = false;
|
||||||
OZ (package_guard.init());
|
OZ (package_guard.init());
|
||||||
OZ (schema_checker_->get_package_info(session_info_->get_effective_tenant_id(),
|
OZ (schema_checker_->get_package_info(session_info_->get_effective_tenant_id(),
|
||||||
@ -171,78 +172,67 @@ int ObAlterPackageResolver::compile_package(const ObString& db_name,
|
|||||||
package_spec_info->get_database_id(),
|
package_spec_info->get_database_id(),
|
||||||
package_spec_info->get_package_id(),
|
package_spec_info->get_package_id(),
|
||||||
package_spec_info->get_schema_version(),
|
package_spec_info->get_schema_version(),
|
||||||
NULL));
|
nullptr));
|
||||||
OX (source = package_spec_info->get_source());
|
OZ (analyze_package(compiler, nullptr, package_spec_ast, db_name, package_spec_info,
|
||||||
OZ (ObSQLUtils::convert_sql_text_from_schema_for_resolve(
|
error_info, has_error));
|
||||||
*allocator_, session_info_->get_dtc_params(), source));
|
|
||||||
OZ (analyze_package(compiler, source, NULL, package_spec_ast, false, true,
|
bool collect_package_body_info = false;
|
||||||
db_name, package_name, package_spec_info, error_info, has_error));
|
if (OB_SUCC(ret)) {
|
||||||
if (OB_FAIL(ret)) {
|
switch (compile_flag) {
|
||||||
// error msg has fixed in analyze_package
|
case PACKAGE_UNIT_SPECIFICATION: {
|
||||||
} else if (1 == package_spec_ast.get_routine_table().get_count()
|
collect_package_body_info = false; // compile package spec
|
||||||
&& !compile_body && !compile_spec) {
|
} break;
|
||||||
OZ (schema_checker_->get_package_info(session_info_->get_effective_tenant_id(),
|
case PACKAGE_UNIT_PACKAGE: {
|
||||||
db_name,
|
|
||||||
package_name,
|
|
||||||
PACKAGE_BODY_TYPE,
|
|
||||||
compatible_mode,
|
|
||||||
package_body_info),
|
|
||||||
package_spec_ast.get_routine_table().get_count(),
|
|
||||||
compile_body);
|
|
||||||
if (OB_SUCC(ret)) {
|
|
||||||
ObString source;
|
|
||||||
OZ (schema_checker_->get_package_info(session_info_->get_effective_tenant_id(),
|
OZ (schema_checker_->get_package_info(session_info_->get_effective_tenant_id(),
|
||||||
db_name,
|
db_name,
|
||||||
package_name,
|
package_name,
|
||||||
PACKAGE_BODY_TYPE,
|
PACKAGE_BODY_TYPE,
|
||||||
compatible_mode,
|
compatible_mode,
|
||||||
package_body_info));
|
package_body_info));
|
||||||
OX (source = package_body_info->get_source());
|
if (OB_ERR_PACKAGE_DOSE_NOT_EXIST == ret) {
|
||||||
OZ (ObSQLUtils::convert_sql_text_from_schema_for_resolve(
|
ret = OB_SUCCESS;
|
||||||
*allocator_, session_info_->get_dtc_params(), source));
|
collect_package_body_info = false; // compile package spec
|
||||||
OZ (package_body_ast.init(db_name,
|
} else if (OB_SUCC(ret) && OB_NOT_NULL(package_body_info)) {
|
||||||
package_name,
|
collect_package_body_info = true; // compile package body
|
||||||
PL_PACKAGE_BODY,
|
} else {
|
||||||
OB_INVALID_ID,
|
LOG_WARN("failed to get package body info", K(ret), K(package_body_info));
|
||||||
OB_INVALID_ID,
|
}
|
||||||
OB_INVALID_VERSION,
|
} break;
|
||||||
&package_spec_ast));
|
case PACKAGE_UNIT_BODY: {
|
||||||
OZ (analyze_package(compiler, source, &(package_spec_ast.get_body()->get_namespace()),
|
OZ (schema_checker_->get_package_info(session_info_->get_effective_tenant_id(),
|
||||||
package_body_ast, false, false, db_name, package_name, package_body_info, error_info, has_error));
|
db_name,
|
||||||
} else if (OB_ERR_PACKAGE_DOSE_NOT_EXIST == ret) {
|
package_name,
|
||||||
ret = OB_SUCCESS;
|
PACKAGE_BODY_TYPE,
|
||||||
OZ (error_info.delete_error(package_spec_info));
|
compatible_mode,
|
||||||
}
|
package_body_info));
|
||||||
} else if (package_spec_ast.get_routine_table().get_count() > 1 && !compile_body) {
|
if (OB_ERR_PACKAGE_DOSE_NOT_EXIST == ret) {
|
||||||
// 如果不需要compile body, 仅check body是否存在
|
LOG_WARN("package body not found", K(ret), K(db_name), K(package_name));
|
||||||
OZ (schema_checker_->get_package_info(session_info_->get_effective_tenant_id(),
|
} else if (OB_SUCC(ret) && OB_NOT_NULL(package_body_info)) {
|
||||||
db_name,
|
collect_package_body_info = true; // compile package body
|
||||||
package_name,
|
} else {
|
||||||
PACKAGE_BODY_TYPE,
|
LOG_WARN("failed to get package body info", K(ret), K(package_body_info));
|
||||||
compatible_mode,
|
}
|
||||||
package_body_info),
|
} break;
|
||||||
package_spec_ast.get_routine_table().get_count(),
|
default: {
|
||||||
compile_body);
|
ret = OB_INVALID_ARGUMENT;
|
||||||
if (OB_ERR_PACKAGE_DOSE_NOT_EXIST == ret) {
|
LOG_WARN("invalid alter package compile flag", K(ret), K(compile_flag));
|
||||||
ret = OB_SUCCESS;
|
} break;
|
||||||
LOG_USER_WARN(OB_ERR_PACKAGE_COMPILE_ERROR, "PACKAGE",
|
|
||||||
db_name.length(), db_name.ptr(),
|
|
||||||
package_name.length(), package_name.ptr());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define COLLECT_PACKAGE_INFO(alt_pkg_arg, package_info) \
|
||||||
|
do { \
|
||||||
|
OV(OB_NOT_NULL(package_info), OB_INVALID_ARGUMENT); \
|
||||||
|
OX(alt_pkg_arg.tenant_id_ = package_info->get_tenant_id()); \
|
||||||
|
OX(alt_pkg_arg.package_type_ = package_info->get_type()); \
|
||||||
|
OX(alt_pkg_arg.compatible_mode_ = package_info->get_compatibility_mode()); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
if (OB_FAIL(ret)) {
|
if (OB_FAIL(ret)) {
|
||||||
} else if (compile_body || (!compile_body && !compile_spec)) {
|
} else if (!collect_package_body_info) {
|
||||||
ObString source;
|
COLLECT_PACKAGE_INFO(pkg_arg, package_spec_info);
|
||||||
has_error = false;
|
} else {
|
||||||
OZ (schema_checker_->get_package_info(session_info_->get_effective_tenant_id(),
|
bool has_error = false;
|
||||||
db_name,
|
|
||||||
package_name,
|
|
||||||
PACKAGE_BODY_TYPE,
|
|
||||||
compatible_mode,
|
|
||||||
package_body_info));
|
|
||||||
OX (source = package_body_info->get_source());
|
|
||||||
OZ (ObSQLUtils::convert_sql_text_from_schema_for_resolve(
|
|
||||||
*allocator_, session_info_->get_dtc_params(), source));
|
|
||||||
OZ (package_body_ast.init(db_name,
|
OZ (package_body_ast.init(db_name,
|
||||||
package_name,
|
package_name,
|
||||||
PL_PACKAGE_BODY,
|
PL_PACKAGE_BODY,
|
||||||
@ -250,38 +240,41 @@ int ObAlterPackageResolver::compile_package(const ObString& db_name,
|
|||||||
OB_INVALID_ID,
|
OB_INVALID_ID,
|
||||||
OB_INVALID_VERSION,
|
OB_INVALID_VERSION,
|
||||||
&package_spec_ast));
|
&package_spec_ast));
|
||||||
OZ (analyze_package(compiler, source, &(package_spec_ast.get_body()->get_namespace()),
|
OZ (analyze_package(compiler, &(package_spec_ast.get_body()->get_namespace()),
|
||||||
package_body_ast, false, false, db_name, package_name, package_body_info, error_info, has_error));
|
package_body_ast, db_name, package_body_info, error_info, has_error));
|
||||||
OX (pkg_arg.tenant_id_ = package_body_info->get_tenant_id());
|
|
||||||
OX (pkg_arg.package_type_ = package_body_info->get_type());
|
|
||||||
OX (pkg_arg.compatible_mode_ = package_body_info->get_compatibility_mode());
|
|
||||||
if (OB_SUCC(ret) && !has_error) {
|
if (OB_SUCC(ret) && !has_error) {
|
||||||
// if has_error, don't need to update routine route sql
|
// if has_error, don't need to update routine route sql
|
||||||
ObArray<const ObRoutineInfo *> routine_infos;
|
ObArray<const ObRoutineInfo *> routine_infos;
|
||||||
|
ObSEArray<ObRoutineInfo, 2> routine_spec_infos;
|
||||||
ObPLRoutineTable &spec_routine_table = package_spec_ast.get_routine_table();
|
ObPLRoutineTable &spec_routine_table = package_spec_ast.get_routine_table();
|
||||||
ObPLRoutineTable &body_routine_table = package_body_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(
|
OZ (schema_checker_->get_schema_guard()->get_routine_infos_in_package(
|
||||||
session_info_->get_effective_tenant_id(),
|
session_info_->get_effective_tenant_id(),
|
||||||
package_spec_info->get_package_id(),
|
package_spec_info->get_package_id(),
|
||||||
routine_infos));
|
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)));
|
||||||
|
}
|
||||||
|
}
|
||||||
OZ (ObCreatePackageBodyResolver::update_routine_route_sql(*allocator_,
|
OZ (ObCreatePackageBodyResolver::update_routine_route_sql(*allocator_,
|
||||||
*session_info_,
|
*session_info_,
|
||||||
pkg_arg.public_routine_infos_,
|
pkg_arg.public_routine_infos_,
|
||||||
spec_routine_table,
|
spec_routine_table,
|
||||||
body_routine_table,
|
body_routine_table,
|
||||||
routine_infos));
|
routine_infos));
|
||||||
|
if (OB_FAIL(ret)) {
|
||||||
|
pkg_arg.public_routine_infos_.reset();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
COLLECT_PACKAGE_INFO(pkg_arg, package_body_info);
|
||||||
}
|
}
|
||||||
if (OB_SUCC(ret)) {
|
|
||||||
if (!(compile_body || (!compile_body && !compile_spec))) {
|
#undef COLLECT_PACKAGE_INFO
|
||||||
OV (OB_NOT_NULL(package_spec_info), OB_INVALID_ARGUMENT);
|
|
||||||
OX (pkg_arg.tenant_id_ = package_spec_info->get_tenant_id());
|
|
||||||
OX (pkg_arg.package_type_ = package_spec_info->get_type());
|
|
||||||
OX (pkg_arg.compatible_mode_ = package_spec_info->get_compatibility_mode());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// TODO: collect error info
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,20 +41,15 @@ private:
|
|||||||
const ObString &package_name,
|
const ObString &package_name,
|
||||||
obrpc::ObAlterPackageArg &pkg_arg);
|
obrpc::ObAlterPackageArg &pkg_arg);
|
||||||
int analyze_package(pl::ObPLCompiler &compiler,
|
int analyze_package(pl::ObPLCompiler &compiler,
|
||||||
const ObString &source,
|
|
||||||
const pl::ObPLBlockNS *parent_ns,
|
const pl::ObPLBlockNS *parent_ns,
|
||||||
pl::ObPLPackageAST &package_ast,
|
pl::ObPLPackageAST &package_ast,
|
||||||
bool is_for_trigger,
|
|
||||||
bool is_package,
|
|
||||||
const ObString& db_name,
|
const ObString& db_name,
|
||||||
const ObString &package_name,
|
|
||||||
const ObPackageInfo *package_info,
|
const ObPackageInfo *package_info,
|
||||||
share::schema::ObErrorInfo &error_info,
|
share::schema::ObErrorInfo &error_info,
|
||||||
bool &has_error);
|
bool &has_error);
|
||||||
int compile_package(const ObString& db_name,
|
int compile_package(const ObString& db_name,
|
||||||
const ObString &package_name,
|
const ObString &package_name,
|
||||||
bool compile_spec,
|
int16_t compile_flag,
|
||||||
bool compile_body,
|
|
||||||
obrpc::ObAlterPackageArg &pkg_arg);
|
obrpc::ObAlterPackageArg &pkg_arg);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Reference in New Issue
Block a user