[to #53767952]fix bug trigger not use das

This commit is contained in:
seuwebber
2023-12-14 09:17:42 +00:00
committed by ob-robot
parent e1155848a1
commit df81fcb12c
7 changed files with 91 additions and 78 deletions

View File

@ -895,16 +895,11 @@ int ObDelUpdResolver::set_base_table_for_updatable_view(TableItem &table_item,
} }
} else if (new_table_item->is_generated_table() || new_table_item->is_temp_table()) { } else if (new_table_item->is_generated_table() || new_table_item->is_temp_table()) {
const bool inner_log_error = false; const bool inner_log_error = false;
if (new_table_item->is_view_table_ && is_oracle_mode() if (OB_FAIL(check_need_fired_trigger(new_table_item))) {
&& stmt_->is_support_instead_of_trigger_stmt()) { LOG_WARN("check has need fired trigger failed", K(ret));
bool has_tg = false; } else if (OB_FAIL(SMART_CALL(set_base_table_for_updatable_view(*new_table_item,
OZ (has_need_fired_trigger_on_view(new_table_item, has_tg)); *new_col_ref,
OX ((static_cast<ObDelUpdStmt*>(stmt_)) inner_log_error)))) {
->set_has_instead_of_trigger(has_tg));
}
if (OB_FAIL(SMART_CALL(set_base_table_for_updatable_view(*new_table_item,
*new_col_ref,
inner_log_error)))) {
LOG_WARN("find base table for updatable view failed", K(ret)); LOG_WARN("find base table for updatable view failed", K(ret));
} }
} else if (new_table_item->is_fake_cte_table()) { } else if (new_table_item->is_fake_cte_table()) {
@ -2146,63 +2141,86 @@ int ObDelUpdResolver::uv_check_key_preserved(const TableItem &table_item, bool &
return ret; return ret;
} }
//检查user_view上是否有对应dml事件触发且状态为enabled的instead of trigger int ObDelUpdResolver::check_need_fired_trigger(const TableItem* table_item)
int ObDelUpdResolver::has_need_fired_trigger_on_view(const TableItem* view_item, bool &has)
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
has = false; bool has = false;
const ObTableSchema *view_schema = NULL; const ObTableSchema *table_schema = NULL;
ObSchemaGetterGuard *schema_guard = NULL; ObSchemaGetterGuard *schema_guard = NULL;
uint64_t view_id = OB_INVALID_ID; uint64_t table_id = OB_INVALID_ID;
CK (OB_NOT_NULL(view_item)); CK (OB_NOT_NULL(table_item));
CK (OB_NOT_NULL(schema_checker_)); if (OB_SUCC(ret)
CK (OB_NOT_NULL(schema_guard = schema_checker_->get_schema_guard())); && !session_info_->get_ddl_info().is_ddl()
OX (view_id = view_item->ref_id_); && !table_item->is_index_table_
if (OB_SUCC(ret) && !view_item->alias_name_.empty()) { && (table_item->is_basic_table() || table_item->is_view_table_)) {
uint64_t tenant_id = session_info_->get_effective_tenant_id();
CK (OB_NOT_NULL(schema_checker_)); CK (OB_NOT_NULL(schema_checker_));
CK (OB_NOT_NULL(schema_guard = schema_checker_->get_schema_guard())) CK (OB_NOT_NULL(schema_guard = schema_checker_->get_schema_guard()));
OZ (schema_guard->get_table_id(tenant_id, view_item->database_name_, OX (table_id = table_item->ref_id_);
view_item->table_name_, false /*is_index*/, if (OB_SUCC(ret)) {
ObSchemaGetterGuard::ALL_NON_HIDDEN_TYPES, view_id)); if (stmt::T_INSERT == stmt_->get_stmt_type() || stmt::T_INSERT_ALL == stmt_->get_stmt_type()) {
} table_id = (!OB_ISNULL(table_item->ref_query_) && table_item->ref_query_->is_view_stmt())
OZ (schema_checker_->get_table_schema(session_info_->get_effective_tenant_id(), view_id, view_schema), view_id); ? table_item->ref_query_->get_view_ref_id()
CK (OB_NOT_NULL(view_schema)); : table_item->get_base_table_item().ref_id_;
if (OB_SUCC(ret) && view_schema->is_user_view()) { } else if (!table_item->alias_name_.empty() && table_item->is_view_table_) {
const uint64_t tenant_id = view_schema->get_tenant_id(); uint64_t tenant_id = session_info_->get_effective_tenant_id();
const ObIArray<uint64_t> &tg_list = view_schema->get_trigger_list(); CK (OB_NOT_NULL(schema_checker_));
const ObTriggerInfo *tg_info = NULL; CK (OB_NOT_NULL(schema_guard = schema_checker_->get_schema_guard()))
uint64_t tg_id = OB_INVALID_ID; OZ (schema_guard->get_table_id(tenant_id, table_item->database_name_,
uint64_t dml_event = 0; table_item->table_name_, false /*is_index*/,
switch (stmt_->get_stmt_type()) ObSchemaGetterGuard::ALL_NON_HIDDEN_TYPES, table_id));
{ }
case stmt::T_INSERT:
dml_event = ObTriggerEvents::get_insert_event();
break;
case stmt::T_UPDATE:
dml_event = ObTriggerEvents::get_update_event();
break;
case stmt::T_DELETE:
dml_event = ObTriggerEvents::get_delete_event();
break;
default:
ret = OB_ERR_UNEXPECTED;
LOG_WARN("stmt type is error", K(stmt_->get_stmt_type()), K(ret));
break;
} }
for (int64_t i = 0; OB_SUCC(ret) && !has && i < tg_list.count(); i++) { OZ (schema_checker_->get_table_schema(session_info_->get_effective_tenant_id(), table_id, table_schema), table_id);
OX (tg_id = tg_list.at(i)); CK (OB_NOT_NULL(table_schema));
OZ (schema_guard->get_trigger_info(tenant_id, tg_id, tg_info)); if (OB_SUCC(ret)) {
OV (OB_NOT_NULL(tg_info)); const uint64_t tenant_id = table_schema->get_tenant_id();
OX (has = (tg_info->is_enable() && tg_info->has_event(dml_event))); const ObIArray<uint64_t> &tg_list = table_schema->get_trigger_list();
} const ObTriggerInfo *tg_info = NULL;
if (OB_SUCC(ret) && has) { uint64_t tg_id = OB_INVALID_ID;
CK (stmt_->is_support_instead_of_trigger_stmt()); uint64_t dml_event = 0;
if (OB_SUCC(ret)) { switch (stmt_->get_stmt_type())
ObDelUpdStmt *del_upd_stmt = static_cast<ObDelUpdStmt *>(stmt_); {
if (del_upd_stmt->is_returning()) { case stmt::T_INSERT:
ret = OB_ERR_RETURNING_CLAUSE; case stmt::T_INSERT_ALL:
LOG_WARN("RETURNING clause is currently not supported for INSTEAD OF Triggers", K(ret)); dml_event = ObTriggerEvents::get_insert_event();
break;
case stmt::T_UPDATE:
dml_event = ObTriggerEvents::get_update_event();
break;
case stmt::T_DELETE:
dml_event = ObTriggerEvents::get_delete_event();
break;
case stmt::T_MERGE:
dml_event = ObTriggerEvents::get_all_event();
break;
case stmt::T_REPLACE:
dml_event = ObTriggerEvents::get_insert_event() + ObTriggerEvents::get_update_event();
break;
default:
ret = OB_ERR_UNEXPECTED;
LOG_WARN("stmt type is error", K(stmt_->get_stmt_type()), K(ret));
break;
}
for (int64_t i = 0; OB_SUCC(ret) && !has && i < tg_list.count(); i++) {
OX (tg_id = tg_list.at(i));
OZ (schema_guard->get_trigger_info(tenant_id, tg_id, tg_info));
OV (OB_NOT_NULL(tg_info));
OX (has = (tg_info->is_enable() && tg_info->has_event(dml_event)));
}
OX (stmt_->get_query_ctx()->disable_udf_parallel_ |= has);
if (OB_SUCC(ret) && has && table_schema->is_user_view()) {
if (!stmt_->is_support_instead_of_trigger_stmt()) {
ret = OB_NOT_SUPPORTED;
LOG_WARN("only insert/update/delete stmt support instead of trigger", K(ret), K(stmt_->get_stmt_type()));
LOG_USER_ERROR(OB_NOT_SUPPORTED, "except for insert/update/delete statement, instead of trigger is");
} else {
ObDelUpdStmt *del_upd_stmt = static_cast<ObDelUpdStmt *>(stmt_);
if (del_upd_stmt->is_returning()) {
ret = OB_ERR_RETURNING_CLAUSE;
LOG_WARN("RETURNING clause is currently not supported for INSTEAD OF Triggers", K(ret));
} else {
del_upd_stmt->set_has_instead_of_trigger(true);
}
} }
} }
} }

View File

@ -149,7 +149,7 @@ protected:
// check the update view is key preserved // check the update view is key preserved
int uv_check_key_preserved(const TableItem &table_item, bool &key_preserved); int uv_check_key_preserved(const TableItem &table_item, bool &key_preserved);
int has_need_fired_trigger_on_view(const TableItem* view_item, bool &has); int check_need_fired_trigger(const TableItem* table_item);
int view_pullup_special_column_exprs(); int view_pullup_special_column_exprs();
int view_pullup_part_exprs(); int view_pullup_part_exprs();

View File

@ -263,10 +263,7 @@ int ObDeleteResolver::resolve_table_list(const ParseNode &table_list, bool &is_m
//single table delete, delete list is same with from list //single table delete, delete list is same with from list
CK(delete_stmt->get_table_size() == 1); CK(delete_stmt->get_table_size() == 1);
OZ(delete_tables_.push_back(delete_stmt->get_table_item(0))); OZ(delete_tables_.push_back(delete_stmt->get_table_item(0)));
if (OB_SUCC(ret) && delete_stmt->get_table_item(0)->is_view_table_ && is_oracle_mode()) { OZ (check_need_fired_trigger(table_item));
OZ(has_need_fired_trigger_on_view(delete_stmt->get_table_item(0), has_tg));
}
OX(delete_stmt->set_has_instead_of_trigger(has_tg));
} else { } else {
//multi table delete //multi table delete
is_multi_table_delete = true; is_multi_table_delete = true;
@ -289,6 +286,8 @@ int ObDeleteResolver::resolve_table_list(const ParseNode &table_list, bool &is_m
ret = OB_ERR_NONUNIQ_TABLE; ret = OB_ERR_NONUNIQ_TABLE;
LOG_USER_ERROR(OB_ERR_NONUNIQ_TABLE, table_item->table_name_.length(), LOG_USER_ERROR(OB_ERR_NONUNIQ_TABLE, table_item->table_name_.length(),
table_item->table_name_.ptr()); table_item->table_name_.ptr());
} else if (OB_FAIL(check_need_fired_trigger(table_item))) {
LOG_WARN("failed to check need fired trigger", K(ret));
} else if (OB_FAIL(delete_tables_.push_back(table_item))) { } else if (OB_FAIL(delete_tables_.push_back(table_item))) {
LOG_WARN("failed to push back table item", K(ret)); LOG_WARN("failed to push back table item", K(ret));
} }

View File

@ -429,12 +429,7 @@ int ObInsertResolver::resolve_insert_field(const ParseNode &insert_into, TableIt
? table_item->ref_query_->get_view_ref_id() ? table_item->ref_query_->get_view_ref_id()
: table_item->get_base_table_item().ref_id_; : table_item->get_base_table_item().ref_id_;
OZ(schema_checker_->get_table_schema(session_info_->get_effective_tenant_id(), ref_id, table_schema, table_item->is_link_table())); OZ(schema_checker_->get_table_schema(session_info_->get_effective_tenant_id(), ref_id, table_schema, table_item->is_link_table()));
OZ (check_need_fired_trigger(table_item));
if (OB_SUCC(ret) && table_item->is_view_table_ && is_oracle_mode()) {
bool has_tg = false;
OZ (has_need_fired_trigger_on_view(table_item, has_tg));
OX (insert_stmt->set_has_instead_of_trigger(has_tg));
}
if (OB_SUCC(ret)) { if (OB_SUCC(ret)) {
if (table_schema->is_oracle_tmp_table()) { if (table_schema->is_oracle_tmp_table()) {

View File

@ -232,6 +232,8 @@ int ObMergeResolver::resolve_target_relation(const ParseNode *target_node)
LOG_WARN("failed to resolve foreign key constraint", K(ret), K(table_item->ref_id_)); LOG_WARN("failed to resolve foreign key constraint", K(ret), K(table_item->ref_id_));
} else if (OB_FAIL(column_namespace_checker_.add_reference_table(table_item))) { } else if (OB_FAIL(column_namespace_checker_.add_reference_table(table_item))) {
LOG_WARN("add reference table to column namespace checker failed", K(ret)); LOG_WARN("add reference table to column namespace checker failed", K(ret));
} else if (OB_FAIL(check_need_fired_trigger(table_item))) {
LOG_WARN("check has need fired trigger failed");
} else if (table_item->is_generated_table()) { } else if (table_item->is_generated_table()) {
ObSelectStmt *ref_stmt = NULL; ObSelectStmt *ref_stmt = NULL;
if (OB_ISNULL(ref_stmt = table_item->ref_query_)) { if (OB_ISNULL(ref_stmt = table_item->ref_query_)) {

View File

@ -364,6 +364,8 @@ int ObMultiTableInsertResolver::resolve_insert_table_node(const ParseNode &inser
LOG_WARN("failed to resolve basic table"); LOG_WARN("failed to resolve basic table");
} else if (OB_FAIL(resolve_foreign_key_constraint(table_item))) { } else if (OB_FAIL(resolve_foreign_key_constraint(table_item))) {
LOG_WARN("failed to resolve foreign key constraint", K(ret), K(table_item->ref_id_)); LOG_WARN("failed to resolve foreign key constraint", K(ret), K(table_item->ref_id_));
} else if (OB_FAIL(check_need_fired_trigger(table_item))) {
LOG_WARN("failed to check has need fired trigger", K(ret), K(table_item->ref_id_));
} else { } else {
//提前设置好解析参数,对于多表插入会出现相同的表的场景,因此检查时需要提前设置好参数 //提前设置好解析参数,对于多表插入会出现相同的表的场景,因此检查时需要提前设置好参数
if (OB_FAIL(generate_insert_all_table_info(*table_item, when_conds_idx, table_info))) { if (OB_FAIL(generate_insert_all_table_info(*table_item, when_conds_idx, table_info))) {

View File

@ -451,12 +451,9 @@ int ObUpdateResolver::resolve_table_list(const ParseNode &parse_tree)
LOG_WARN("add reference table to namespace checker failed", K(ret)); LOG_WARN("add reference table to namespace checker failed", K(ret));
} else if (OB_FAIL(update_stmt->add_from_item(table_item->table_id_, table_item->is_joined_table()))) { } else if (OB_FAIL(update_stmt->add_from_item(table_item->table_id_, table_item->is_joined_table()))) {
LOG_WARN("failed to add from item", K(ret)); LOG_WARN("failed to add from item", K(ret));
} else if (check_need_fired_trigger(table_item)) {
LOG_WARN("failed to check need fired trigger", K(ret));
} else { } else {
if (is_oracle_mode() && table_item->is_view_table_) {
bool has_tg = false;
OZ (has_need_fired_trigger_on_view(table_item, has_tg));
OX (update_stmt->set_has_instead_of_trigger(has_tg));
}
/* /*
In order to share the same logic with 'select' to generate access path costly, we In order to share the same logic with 'select' to generate access path costly, we
add the table in the udpate stmt in the from_item list as well. add the table in the udpate stmt in the from_item list as well.