[CP] to issue<53838260>:fix rebulid package header cause dml execute plan vary

This commit is contained in:
obdev
2024-02-09 11:00:58 +00:00
committed by ob-robot
parent 8d1d9ff55b
commit 277027c705
2 changed files with 95 additions and 1 deletions

View File

@ -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); }

View File

@ -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()) {