From 028d69f378137f628b41278cf4db71569bf0db65 Mon Sep 17 00:00:00 2001 From: seuwebber Date: Wed, 7 Feb 2024 20:43:16 +0000 Subject: [PATCH] [to #53767952]fix bug trigger not use das --- src/sql/resolver/dml/ob_del_upd_resolver.cpp | 142 ++++++++++-------- src/sql/resolver/dml/ob_del_upd_resolver.h | 2 +- src/sql/resolver/dml/ob_delete_resolver.cpp | 7 +- src/sql/resolver/dml/ob_insert_resolver.cpp | 7 +- src/sql/resolver/dml/ob_merge_resolver.cpp | 2 + .../dml/ob_multi_table_insert_resolver.cpp | 2 + src/sql/resolver/dml/ob_update_resolver.cpp | 7 +- 7 files changed, 91 insertions(+), 78 deletions(-) diff --git a/src/sql/resolver/dml/ob_del_upd_resolver.cpp b/src/sql/resolver/dml/ob_del_upd_resolver.cpp index 1e569b8b12..0d18003946 100644 --- a/src/sql/resolver/dml/ob_del_upd_resolver.cpp +++ b/src/sql/resolver/dml/ob_del_upd_resolver.cpp @@ -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()) { const bool inner_log_error = false; - if (new_table_item->is_view_table_ && is_oracle_mode() - && stmt_->is_support_instead_of_trigger_stmt()) { - bool has_tg = false; - OZ (has_need_fired_trigger_on_view(new_table_item, has_tg)); - OX ((static_cast(stmt_)) - ->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)))) { + if (OB_FAIL(check_need_fired_trigger(new_table_item))) { + LOG_WARN("check has need fired trigger failed", K(ret)); + } else 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)); } } 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; } -//检查user_view上是否有对应dml事件触发且状态为enabled的instead of trigger -int ObDelUpdResolver::has_need_fired_trigger_on_view(const TableItem* view_item, bool &has) +int ObDelUpdResolver::check_need_fired_trigger(const TableItem* table_item) { int ret = OB_SUCCESS; - has = false; - const ObTableSchema *view_schema = NULL; + bool has = false; + const ObTableSchema *table_schema = NULL; ObSchemaGetterGuard *schema_guard = NULL; - uint64_t view_id = OB_INVALID_ID; - CK (OB_NOT_NULL(view_item)); - CK (OB_NOT_NULL(schema_checker_)); - CK (OB_NOT_NULL(schema_guard = schema_checker_->get_schema_guard())); - OX (view_id = view_item->ref_id_); - if (OB_SUCC(ret) && !view_item->alias_name_.empty()) { - uint64_t tenant_id = session_info_->get_effective_tenant_id(); + uint64_t table_id = OB_INVALID_ID; + CK (OB_NOT_NULL(table_item)); + if (OB_SUCC(ret) + && !session_info_->get_ddl_info().is_ddl() + && !table_item->is_index_table_ + && (table_item->is_basic_table() || table_item->is_view_table_)) { CK (OB_NOT_NULL(schema_checker_)); - CK (OB_NOT_NULL(schema_guard = schema_checker_->get_schema_guard())) - OZ (schema_guard->get_table_id(tenant_id, view_item->database_name_, - view_item->table_name_, false /*is_index*/, - ObSchemaGetterGuard::ALL_NON_HIDDEN_TYPES, view_id)); - } - OZ (schema_checker_->get_table_schema(session_info_->get_effective_tenant_id(), view_id, view_schema), view_id); - CK (OB_NOT_NULL(view_schema)); - if (OB_SUCC(ret) && view_schema->is_user_view()) { - const uint64_t tenant_id = view_schema->get_tenant_id(); - const ObIArray &tg_list = view_schema->get_trigger_list(); - const ObTriggerInfo *tg_info = NULL; - uint64_t tg_id = OB_INVALID_ID; - uint64_t dml_event = 0; - switch (stmt_->get_stmt_type()) - { - 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; + CK (OB_NOT_NULL(schema_guard = schema_checker_->get_schema_guard())); + OX (table_id = table_item->ref_id_); + if (OB_SUCC(ret)) { + 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()) + ? table_item->ref_query_->get_view_ref_id() + : table_item->get_base_table_item().ref_id_; + } else if (!table_item->alias_name_.empty() && 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_guard = schema_checker_->get_schema_guard())) + OZ (schema_guard->get_table_id(tenant_id, table_item->database_name_, + table_item->table_name_, false /*is_index*/, + ObSchemaGetterGuard::ALL_NON_HIDDEN_TYPES, table_id)); + } } - 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))); - } - if (OB_SUCC(ret) && has) { - CK (stmt_->is_support_instead_of_trigger_stmt()); - if (OB_SUCC(ret)) { - ObDelUpdStmt *del_upd_stmt = static_cast(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)); + OZ (schema_checker_->get_table_schema(session_info_->get_effective_tenant_id(), table_id, table_schema), table_id); + CK (OB_NOT_NULL(table_schema)); + if (OB_SUCC(ret)) { + const uint64_t tenant_id = table_schema->get_tenant_id(); + const ObIArray &tg_list = table_schema->get_trigger_list(); + const ObTriggerInfo *tg_info = NULL; + uint64_t tg_id = OB_INVALID_ID; + uint64_t dml_event = 0; + switch (stmt_->get_stmt_type()) + { + case stmt::T_INSERT: + case stmt::T_INSERT_ALL: + 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(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); + } } } } diff --git a/src/sql/resolver/dml/ob_del_upd_resolver.h b/src/sql/resolver/dml/ob_del_upd_resolver.h index 1eae556fbc..b4bc2d4600 100644 --- a/src/sql/resolver/dml/ob_del_upd_resolver.h +++ b/src/sql/resolver/dml/ob_del_upd_resolver.h @@ -149,7 +149,7 @@ protected: // check the update view is 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_part_exprs(); diff --git a/src/sql/resolver/dml/ob_delete_resolver.cpp b/src/sql/resolver/dml/ob_delete_resolver.cpp index 646d7dd3b9..aafedc6467 100644 --- a/src/sql/resolver/dml/ob_delete_resolver.cpp +++ b/src/sql/resolver/dml/ob_delete_resolver.cpp @@ -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 CK(delete_stmt->get_table_size() == 1); 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(has_need_fired_trigger_on_view(delete_stmt->get_table_item(0), has_tg)); - } - OX(delete_stmt->set_has_instead_of_trigger(has_tg)); + OZ (check_need_fired_trigger(table_item)); } else { //multi table delete 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; LOG_USER_ERROR(OB_ERR_NONUNIQ_TABLE, table_item->table_name_.length(), 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))) { LOG_WARN("failed to push back table item", K(ret)); } diff --git a/src/sql/resolver/dml/ob_insert_resolver.cpp b/src/sql/resolver/dml/ob_insert_resolver.cpp index e7e05aa899..5603fd88af 100644 --- a/src/sql/resolver/dml/ob_insert_resolver.cpp +++ b/src/sql/resolver/dml/ob_insert_resolver.cpp @@ -429,12 +429,7 @@ int ObInsertResolver::resolve_insert_field(const ParseNode &insert_into, TableIt ? table_item->ref_query_->get_view_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())); - - 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)); - } + OZ (check_need_fired_trigger(table_item)); if (OB_SUCC(ret)) { if (table_schema->is_oracle_tmp_table()) { diff --git a/src/sql/resolver/dml/ob_merge_resolver.cpp b/src/sql/resolver/dml/ob_merge_resolver.cpp index a361d898a6..fb675f59a8 100644 --- a/src/sql/resolver/dml/ob_merge_resolver.cpp +++ b/src/sql/resolver/dml/ob_merge_resolver.cpp @@ -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_)); } else if (OB_FAIL(column_namespace_checker_.add_reference_table(table_item))) { 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()) { ObSelectStmt *ref_stmt = NULL; if (OB_ISNULL(ref_stmt = table_item->ref_query_)) { diff --git a/src/sql/resolver/dml/ob_multi_table_insert_resolver.cpp b/src/sql/resolver/dml/ob_multi_table_insert_resolver.cpp index 0b87189e63..c76bad70eb 100644 --- a/src/sql/resolver/dml/ob_multi_table_insert_resolver.cpp +++ b/src/sql/resolver/dml/ob_multi_table_insert_resolver.cpp @@ -364,6 +364,8 @@ int ObMultiTableInsertResolver::resolve_insert_table_node(const ParseNode &inser LOG_WARN("failed to resolve basic table"); } 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_)); + } 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 { //提前设置好解析参数,对于多表插入会出现相同的表的场景,因此检查时需要提前设置好参数 if (OB_FAIL(generate_insert_all_table_info(*table_item, when_conds_idx, table_info))) { diff --git a/src/sql/resolver/dml/ob_update_resolver.cpp b/src/sql/resolver/dml/ob_update_resolver.cpp index 5c0acdc9f4..bfb6a1fc74 100644 --- a/src/sql/resolver/dml/ob_update_resolver.cpp +++ b/src/sql/resolver/dml/ob_update_resolver.cpp @@ -451,12 +451,9 @@ int ObUpdateResolver::resolve_table_list(const ParseNode &parse_tree) 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()))) { 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 { - 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 add the table in the udpate stmt in the from_item list as well.