[FEAT MERGE] 4.1 PL/SQL enhence & development

This commit is contained in:
obdev
2023-01-09 08:47:31 +00:00
committed by ob-robot
parent 322032b9ca
commit 08802d94f6
98 changed files with 5260 additions and 2676 deletions

View File

@ -18,6 +18,9 @@
#include "pl/ob_pl_resolver.h"
#include "sql/resolver/ob_stmt_resolver.h"
#include "sql/resolver/ddl/ob_create_routine_resolver.h"
#include "pl/parser/parse_stmt_item_type.h"
#include "pl/ob_pl_package.h"
#include "pl/ob_pl_compile.h"
namespace oceanbase
{
@ -26,6 +29,7 @@ namespace sql
using namespace common;
using namespace obrpc;
using namespace share::schema;
using namespace pl;
int ObTriggerResolver::resolve(const ParseNode &parse_tree)
{
@ -194,27 +198,28 @@ int ObTriggerResolver::resolve_alter_trigger_stmt(const ParseNode &parse_node,
const ObTriggerInfo *old_tg_info = NULL;
ObTriggerInfo new_tg_info;
OV (parse_node.type_ == T_TG_ALTER, OB_ERR_UNEXPECTED, parse_node.type_);
OV (parse_node.num_child_ == 1, OB_ERR_UNEXPECTED, parse_node.num_child_);
OV (parse_node.num_child_ == 2, OB_ERR_UNEXPECTED, parse_node.num_child_);
OV (OB_NOT_NULL(parse_node.children_));
OV (OB_NOT_NULL(parse_node.children_[0])); //trigger name.
OV (OB_NOT_NULL(parse_node.children_[1])); //alter clause.
OV (OB_NOT_NULL(session_info_) && OB_NOT_NULL(schema_checker_));
OZ (resolve_schema_name(*parse_node.children_[0], trigger_db_name, trigger_name));
OZ (new_tg_info.set_trigger_name(trigger_name), trigger_name);
OZ (schema_checker_->get_trigger_info(session_info_->get_effective_tenant_id(), trigger_db_name,
trigger_name, old_tg_info));
if (OB_SUCC(ret) && OB_ISNULL(old_tg_info)) {
ret = OB_ERR_TRIGGER_NOT_EXIST;
LOG_ORACLE_USER_ERROR(OB_ERR_TRIGGER_NOT_EXIST, trigger_name.length(), trigger_name.ptr());
}
OX (new_tg_info.set_trigger_id(old_tg_info->get_trigger_id()));
OZ (resolve_alter_clause(parse_node, new_tg_info));
OZ (trigger_arg.trigger_infos_.push_back(new_tg_info));
if (OB_SUCC(ret) && ObSchemaChecker::is_ora_priv_check()) {
OZ(schema_checker_->check_ora_ddl_priv(session_info_->get_effective_tenant_id(),
session_info_->get_priv_user_id(),
trigger_db_name, stmt::T_ALTER_TRIGGER,
session_info_->get_enable_role_array()));
}
if (OB_SUCC(ret) && OB_ISNULL(old_tg_info)) {
ret = OB_ERR_TRIGGER_NOT_EXIST;
LOG_ORACLE_USER_ERROR(OB_ERR_TRIGGER_NOT_EXIST, trigger_name.length(), trigger_name.ptr());
}
OZ (new_tg_info.deep_copy(*old_tg_info));
OZ (resolve_alter_clause(*parse_node.children_[1], new_tg_info, trigger_db_name,
trigger_arg.is_set_status_, trigger_arg.is_alter_compile_));
OZ (trigger_arg.trigger_infos_.push_back(new_tg_info));
return ret;
}
@ -783,16 +788,28 @@ int ObTriggerResolver::resolve_schema_name(const ParseNode &parse_node,
}
int ObTriggerResolver::resolve_alter_clause(const ParseNode &alter_clause,
ObTriggerInfo &tg_info)
ObTriggerInfo &tg_info,
const ObString &db_name,
bool &is_set_status,
bool &is_alter_compile)
{
int ret = OB_SUCCESS;
if (T_ENABLE == static_cast<ObItemType>(alter_clause.value_)) {
tg_info.set_enable();
} else if (T_DISABLE == static_cast<ObItemType>(alter_clause.value_)) {
tg_info.set_disable();
} else {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("alter clause must be ENABLE/DISABLE", K(ret));
CK (OB_LIKELY(OB_NOT_NULL(schema_checker_)));
CK (OB_LIKELY(OB_NOT_NULL(schema_checker_->get_schema_guard())));
CK (OB_LIKELY(OB_NOT_NULL(allocator_)));
CK (OB_LIKELY(T_TG_ALTER_OPTIONS == alter_clause.type_));
if (FAILEDx(TRIGGER_ALTER_IF_EDITIONABLE == alter_clause.int16_values_[0])) {
ret = OB_NOT_SUPPORTED;
LOG_WARN("alter editionable is not supported yet!", K(ret));
LOG_USER_ERROR(OB_NOT_SUPPORTED, "alter editionable");
} else if (TRIGGER_ALTER_IF_ENABLE == alter_clause.int16_values_[0]) {
is_set_status = true;
is_alter_compile = false;
if (T_ENABLE == static_cast<ObItemType>(alter_clause.int16_values_[1])) {
tg_info.set_enable();
} else {
tg_info.set_disable();
}
}
return ret;
}
@ -923,6 +940,66 @@ int ObTriggerResolver::resolve_base_object(ObCreateTriggerArg &tg_arg,
return ret;
}
int ObTriggerResolver::analyze_trigger(ObSchemaGetterGuard &schema_guard,
ObSQLSessionInfo *session_info,
ObMySQLProxy *sql_proxy,
ObIAllocator &allocator,
const ObTriggerInfo &trigger_info,
const ObString &db_name,
ObIArray<ObDependencyInfo> &dep_infos,
bool is_alter_compile)
{
int ret = OB_SUCCESS;
CK (OB_LIKELY(OB_NOT_NULL(session_info)));
CK (OB_LIKELY(OB_NOT_NULL(sql_proxy)));
if (OB_SUCC(ret)) {
HEAP_VARS_2((ObPLPackageAST, package_spec_ast, allocator),
(ObPLPackageAST, package_body_ast, allocator)) {
ObPLPackageGuard package_guard(PACKAGE_RESV_HANDLE);
const ObString &pkg_name = trigger_info.get_package_body_info().get_package_name();
ObPLCompiler compiler(allocator, *session_info, schema_guard, package_guard, *sql_proxy);
const ObPackageInfo &package_spec_info = trigger_info.get_package_spec_info();
OZ (package_spec_ast.init(db_name,
package_spec_info.get_package_name(),
PL_PACKAGE_SPEC,
package_spec_info.get_database_id(),
package_spec_info.get_package_id(),
package_spec_info.get_schema_version(),
NULL));
OZ (compiler.analyze_package(trigger_info.get_package_spec_source(), NULL, package_spec_ast, true));
OZ (package_body_ast.init(db_name,
pkg_name,
PL_PACKAGE_BODY,
trigger_info.get_package_body_info().get_database_id(),
trigger_info.get_package_body_info().get_package_id(),
trigger_info.get_package_body_info().get_schema_version(),
&package_spec_ast));
OZ (compiler.analyze_package(trigger_info.get_package_body_source(),
&(package_spec_ast.get_body()->get_namespace()),
package_body_ast,
true));
if (OB_SUCC(ret) && lib::is_oracle_mode()) {
if (is_alter_compile) {
OZ (ObPLCompiler::update_schema_object_dep_info(package_body_ast,
trigger_info.get_tenant_id(),
trigger_info.get_trigger_id(),
trigger_info.get_schema_version(),
trigger_info.get_owner_id(),
trigger_info.get_object_type()));
} else {
ObString dep_attr;
OZ (ObDependencyInfo::collect_dep_infos(package_body_ast.get_dependency_table(),
dep_infos,
trigger_info.get_object_type(),
0, dep_attr, dep_attr));
}
}
}
}
return ret;
}
const ObString ObTriggerResolver::REF_OLD = "OLD";
const ObString ObTriggerResolver::REF_NEW = "NEW";
const ObString ObTriggerResolver::REF_PARENT = "PARENT";