[CP] to issue<53838260>:fix rebulid package header cause dml execute plan vary
This commit is contained in:
@ -505,6 +505,18 @@ public:
|
||||
flag_ |= SP_FLAG_CONTAINS_SQL;
|
||||
}
|
||||
|
||||
OB_INLINE void reset_analyze_flag()
|
||||
{
|
||||
flag_ &= ~(uint64_t)SP_FLAG_NO_SQL;
|
||||
flag_ &= ~(uint64_t)SP_FLAG_READS_SQL_DATA;
|
||||
flag_ &= ~(uint64_t)SP_FLAG_MODIFIES_SQL_DATA;
|
||||
flag_ &= ~(uint64_t)SP_FLAG_CONTAINS_SQL;
|
||||
flag_ &= ~(uint64_t)SP_FLAG_WPS;
|
||||
flag_ &= ~(uint64_t)SP_FLAG_RPS;
|
||||
flag_ &= ~(uint64_t)SP_FLAG_HAS_SEQUENCE;
|
||||
flag_ &= ~(uint64_t)SP_FLAG_HAS_OUT_PARAM;
|
||||
flag_ &= ~(uint64_t)SP_FLAG_EXTERNAL_STATE;
|
||||
}
|
||||
|
||||
OB_INLINE bool is_wps() const { return SP_FLAG_WPS == (flag_ & SP_FLAG_WPS); }
|
||||
OB_INLINE bool is_rps() const { return SP_FLAG_RPS == (flag_ & SP_FLAG_RPS); }
|
||||
|
||||
@ -44,6 +44,8 @@ int ObCreatePackageResolver::resolve(const ParseNode &parse_tree)
|
||||
if (OB_SUCC(ret)) {
|
||||
bool resolve_success = true;
|
||||
HEAP_VAR(ObPLPackageAST, package_ast, *allocator_) {
|
||||
int64_t compatible_mode = lib::is_oracle_mode() ? COMPATIBLE_ORACLE_MODE
|
||||
: COMPATIBLE_MYSQL_MODE;
|
||||
ObPLPackageGuard package_guard(params_.session_info_->get_effective_tenant_id());
|
||||
ObPLResolver resolver(*params_.allocator_,
|
||||
*params_.session_info_,
|
||||
@ -90,9 +92,24 @@ int ObCreatePackageResolver::resolve(const ParseNode &parse_tree)
|
||||
has_accessible_by));
|
||||
//NOTE: null package stmts is possible
|
||||
if (OB_SUCC(ret) && OB_NOT_NULL(package_stmts_node)) {
|
||||
uint64_t db_id = OB_INVALID_ID;
|
||||
uint64_t package_id = OB_INVALID_ID;
|
||||
const ObPackageInfo *package_spec_info = NULL;
|
||||
OZ (schema_checker_->get_package_info(session_info_->get_effective_tenant_id(),
|
||||
db_name,
|
||||
package_name,
|
||||
PACKAGE_TYPE,
|
||||
compatible_mode,
|
||||
package_spec_info));
|
||||
if (OB_ERR_PACKAGE_DOSE_NOT_EXIST == ret) { // may be not old package header
|
||||
ret = OB_SUCCESS;
|
||||
} else if (OB_NOT_NULL(package_spec_info)) {
|
||||
db_id = package_spec_info->get_database_id();
|
||||
package_id = package_spec_info->get_package_id();
|
||||
}
|
||||
CK (T_PACKAGE_STMTS == package_stmts_node->type_);
|
||||
OZ (package_ast.init(db_name, package_name, PL_PACKAGE_SPEC,
|
||||
OB_INVALID_ID, OB_INVALID_ID, OB_INVALID_VERSION, NULL));
|
||||
db_id, package_id, OB_INVALID_VERSION, NULL));
|
||||
OZ (resolver.init(package_ast));
|
||||
if (OB_SUCC(ret)
|
||||
&& OB_FAIL(resolver.resolve(package_stmts_node, package_ast))) {
|
||||
@ -189,6 +206,69 @@ int ObCreatePackageResolver::resolve(const ParseNode &parse_tree)
|
||||
}
|
||||
}
|
||||
}
|
||||
// resolve package body to obtain analyze result again if it exists
|
||||
if (OB_SUCC(ret)) {
|
||||
HEAP_VAR(ObPLPackageAST, package_body_ast, *allocator_) {
|
||||
ObPLPackageGuard package_guard(params_.session_info_->get_effective_tenant_id());
|
||||
ObSchemaGetterGuard *schema_guard = schema_checker_->get_schema_mgr();
|
||||
ObPLCompiler compiler(*params_.allocator_,
|
||||
*params_.session_info_,
|
||||
*schema_guard,
|
||||
package_guard,
|
||||
*params_.sql_proxy_);
|
||||
const ObPackageInfo *package_body_info = NULL;
|
||||
OZ (schema_checker_->get_package_info(session_info_->get_effective_tenant_id(),
|
||||
db_name,
|
||||
package_name,
|
||||
PACKAGE_BODY_TYPE,
|
||||
compatible_mode,
|
||||
package_body_info));
|
||||
if (OB_SUCC(ret) && OB_NOT_NULL(package_body_info) && !package_body_info->is_for_trigger()) {
|
||||
ObString 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,
|
||||
package_name,
|
||||
PL_PACKAGE_BODY,
|
||||
OB_INVALID_ID,
|
||||
OB_INVALID_ID,
|
||||
OB_INVALID_VERSION,
|
||||
&package_ast));
|
||||
if (OB_NOT_NULL(package_ast.get_body())) {
|
||||
(const_cast<ObPLBlockNS &>(package_ast.get_body()->get_namespace())).set_external_ns(NULL);
|
||||
}
|
||||
OZ (compiler.analyze_package(source,
|
||||
&(package_ast.get_body()->get_namespace()),
|
||||
package_body_ast,
|
||||
false));
|
||||
if (OB_SUCC(ret)) {
|
||||
obrpc::ObCreatePackageArg &create_package_arg = stmt->get_create_package_arg();
|
||||
ObIArray<ObRoutineInfo> &routine_list = create_package_arg.public_routine_infos_;
|
||||
ObArray<ObRoutineInfo> routines;
|
||||
ObArray<const ObRoutineInfo*> routine_infos;
|
||||
const ObPLRoutineTable &spec_routine_table = package_ast.get_routine_table();
|
||||
const ObPLRoutineTable &body_routine_table = package_body_ast.get_routine_table();
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < routine_list.count(); ++i) {
|
||||
OZ (routine_infos.push_back(&routine_list.at(i)));
|
||||
}
|
||||
OZ (ObCreatePackageBodyResolver::update_routine_route_sql(*allocator_, *session_info_, routines,
|
||||
spec_routine_table, body_routine_table, routine_infos));
|
||||
if (OB_FAIL(ret)) {
|
||||
routines.reset();
|
||||
} else {
|
||||
CK (routine_list.count() == routines.count());
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < routine_list.count(); ++i) {
|
||||
routine_list.at(i) = routines.at(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
common::ob_reset_tsi_warning_buffer();
|
||||
ret = OB_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_NOT_NULL(session_info_)
|
||||
&& OB_SYS_TENANT_ID == session_info_->get_effective_tenant_id()
|
||||
@ -714,6 +794,8 @@ int ObCreatePackageBodyResolver::update_routine_route_sql(ObIAllocator &allocato
|
||||
OZ (ObSQLUtils::convert_sql_text_to_schema_for_storing(allocator, session_info.get_dtc_params(), routine_body));
|
||||
OX (routine_info.set_routine_body(routine_body));
|
||||
if (OB_SUCC(ret)) {
|
||||
// reset flag attr
|
||||
routine_info.reset_analyze_flag();
|
||||
if (pl_routine_info->is_modifies_sql_data()) {
|
||||
routine_info.set_modifies_sql_data();
|
||||
} else if (pl_routine_info->is_reads_sql_data()) {
|
||||
|
||||
Reference in New Issue
Block a user