[to #53767952]fix bug trigger not use das
This commit is contained in:
parent
c5aec9185b
commit
028d69f378
@ -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<ObDelUpdStmt*>(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<uint64_t> &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<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));
|
||||
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<uint64_t> &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<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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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()) {
|
||||
|
@ -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_)) {
|
||||
|
@ -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))) {
|
||||
|
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user