diff --git a/src/rootserver/ddl_task/ob_constraint_task.cpp b/src/rootserver/ddl_task/ob_constraint_task.cpp index b828390d6a..a80f95ea1a 100755 --- a/src/rootserver/ddl_task/ob_constraint_task.cpp +++ b/src/rootserver/ddl_task/ob_constraint_task.cpp @@ -68,7 +68,7 @@ int ObCheckConstraintValidationTask::process() ret = OB_ERR_SYS; LOG_WARN("error sys, root service must not be nullptr", K(ret)); } else if (!check_table_empty_ && OB_ISNULL(constraint = table_schema->get_constraint(constraint_id_))) { - ret = OB_ERR_UNEXPECTED; + ret = OB_ERR_CONTRAINT_NOT_FOUND; LOG_WARN("error unexpected, can not get constraint", K(ret)); } else if (OB_FAIL(table_schema->check_if_oracle_compat_mode(is_oracle_mode))) { LOG_WARN("check tenant is oracle mode failed", K(ret)); @@ -1143,7 +1143,7 @@ int ObConstraintTask::set_foreign_key_constraint_validated() LOG_WARN("fail to alter table", K(ret), K(alter_table_arg), K(fk_arg)); } } else { - if (OB_FAIL(ObDDLUtil::refresh_alter_table_arg(tenant_id_, object_id_, alter_table_arg))) { + if (OB_FAIL(ObDDLUtil::refresh_alter_table_arg(tenant_id_, object_id_, target_object_id_, alter_table_arg))) { LOG_WARN("failed to refresh name for alter table schema", K(ret)); } else if (OB_FAIL(root_service->get_ddl_service().get_common_rpc()->to(obrpc::ObRpcProxy::myaddr_).timeout(rpc_timeout). alter_table(alter_table_arg, res))) { @@ -1178,7 +1178,7 @@ int ObConstraintTask::set_check_constraint_validated() alter_table_arg.based_schema_object_infos_.reset(); } if (OB_FAIL(ret)) { - } else if (OB_FAIL(ObDDLUtil::refresh_alter_table_arg(tenant_id_, object_id_, alter_table_arg))) { + } else if (OB_FAIL(ObDDLUtil::refresh_alter_table_arg(tenant_id_, object_id_, OB_INVALID_ID/*foreign_key_id*/, alter_table_arg))) { LOG_WARN("failed to refresh name for alter table schema", K(ret)); } else { alter_table_arg.index_arg_list_.reset(); @@ -1377,8 +1377,8 @@ int ObConstraintTask::rollback_failed_check_constraint() } } if (OB_FAIL(ret)) { - } else if (OB_FAIL(ObDDLUtil::refresh_alter_table_arg(tenant_id_, object_id_, alter_table_arg))) { - if (ret == OB_TABLE_NOT_EXIST) { + } else if (OB_FAIL(ObDDLUtil::refresh_alter_table_arg(tenant_id_, object_id_, OB_INVALID_ID/*foreign_key_id*/, alter_table_arg))) { + if (OB_TABLE_NOT_EXIST == ret || OB_ERR_CONTRAINT_NOT_FOUND == ret) { ret = OB_NO_NEED_UPDATE; } else { LOG_WARN("failed to refresh name for alter table schema", K(ret)); @@ -1448,14 +1448,22 @@ int ObConstraintTask::rollback_failed_foregin_key() ObArenaAllocator allocator(lib::ObLabel("ConstraiTask")); if (OB_FAIL(deep_copy_table_arg(allocator, alter_table_arg_, alter_table_arg))) { LOG_WARN("deep copy table arg failed", K(ret)); + } else if (FALSE_IT(alter_table_arg.based_schema_object_infos_.reset())) { + } else if (!is_table_hidden_ && OB_FAIL(ObDDLUtil::refresh_alter_table_arg(tenant_id_, object_id_, target_object_id_, alter_table_arg))) { + if (OB_TABLE_NOT_EXIST == ret || OB_ERR_CONTRAINT_NOT_FOUND == ret) { + ret = OB_NO_NEED_UPDATE; + } else { + LOG_WARN("failed to refresh name for alter table schema", K(ret)); + } } else if (!fk_arg.is_modify_fk_state_) { // alter table tbl_name drop constraint fk_cst_name without ddl_stmt_str drop_foreign_key_arg.index_action_type_ = obrpc::ObIndexArg::DROP_FOREIGN_KEY; - drop_foreign_key_arg.foreign_key_name_ = fk_arg.foreign_key_name_; + drop_foreign_key_arg.foreign_key_name_ = alter_table_arg.foreign_key_arg_list_.at(0).foreign_key_name_; alter_table_arg.index_arg_list_.reset(); if (OB_FAIL(alter_table_arg.index_arg_list_.push_back(&drop_foreign_key_arg))) { LOG_WARN("fail to push back arg to index_arg_list", K(ret)); } else { + alter_table_arg.ddl_stmt_str_.reset(); alter_table_arg.foreign_key_arg_list_.reset(); } } else { @@ -1481,7 +1489,6 @@ int ObConstraintTask::rollback_failed_foregin_key() LOG_WARN("get ddl rpc timeout failed", K(ret)); } if (OB_SUCC(ret)) { - alter_table_arg.based_schema_object_infos_.reset(); alter_table_arg.is_inner_ = true; if (is_table_hidden_) { ObSArray unused_ids; @@ -1496,13 +1503,7 @@ int ObConstraintTask::rollback_failed_foregin_key() } } } else { - if (OB_FAIL(ObDDLUtil::refresh_alter_table_arg(tenant_id_, object_id_, alter_table_arg))) { - if (OB_TABLE_NOT_EXIST == ret) { - ret = OB_NO_NEED_UPDATE; - } else { - LOG_WARN("failed to refresh name for alter table schema", K(ret)); - } - } else if (OB_FAIL(root_service_->get_ddl_service().get_common_rpc()->to(obrpc::ObRpcProxy::myaddr_).timeout(rpc_timeout). + if (OB_FAIL(root_service_->get_ddl_service().get_common_rpc()->to(obrpc::ObRpcProxy::myaddr_).timeout(rpc_timeout). alter_table(alter_table_arg, tmp_res))) { LOG_WARN("alter table failed", K(ret)); if (OB_TABLE_NOT_EXIST == ret || OB_ERR_CANT_DROP_FIELD_OR_KEY == ret) { diff --git a/src/share/ob_ddl_common.cpp b/src/share/ob_ddl_common.cpp index 01375419ba..bd1b85057e 100644 --- a/src/share/ob_ddl_common.cpp +++ b/src/share/ob_ddl_common.cpp @@ -277,6 +277,7 @@ int ObDDLUtil::get_tablet_count(const uint64_t tenant_id, int ObDDLUtil::refresh_alter_table_arg( const uint64_t tenant_id, const int64_t orig_table_id, + const uint64_t foreign_key_id, obrpc::ObAlterTableArg &alter_table_arg) { int ret = OB_SUCCESS; @@ -314,12 +315,42 @@ int ObDDLUtil::refresh_alter_table_arg( ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid cst", K(ret)); } else if (OB_ISNULL(cur_cst = table_schema->get_constraint(cst->get_constraint_id()))) { - LOG_INFO("current constraint not exists, maybe dropped", K(ret), KPC(cst), K(table_schema)); + ret = OB_ERR_CONTRAINT_NOT_FOUND; + LOG_WARN("current constraint not exists, maybe dropped", K(ret), KPC(cst), K(table_schema)); } else if (OB_FAIL(cst->set_constraint_name(cur_cst->get_constraint_name_str()))) { LOG_WARN("failed to set new constraint name", K(ret)); } } + // refresh fk arg list + if (OB_FAIL(ret)) { + } else if (OB_INVALID_ID == foreign_key_id) { + if (OB_UNLIKELY(0 != alter_table_arg.foreign_key_arg_list_.count())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("must specify foreign key id to refresh fk arg list", K(ret), K(alter_table_arg.foreign_key_arg_list_)); + } + } else { + if (1 != alter_table_arg.foreign_key_arg_list_.count()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("only support refresh one fk arg", K(ret)); + } else { + const ObIArray &fk_infos = table_schema->get_foreign_key_infos(); + const ObForeignKeyInfo *found_fk_info = nullptr; + for (int64_t i = 0; nullptr == found_fk_info && i < fk_infos.count(); i++) { + const ObForeignKeyInfo &fk_info = fk_infos.at(i); + if (fk_info.foreign_key_id_ == foreign_key_id) { + found_fk_info = &fk_info; + } + } + if (OB_ISNULL(found_fk_info)) { + ret = OB_ERR_CONTRAINT_NOT_FOUND; + LOG_WARN("fk info not found, maybe dropped", K(ret), K(orig_table_id), K(foreign_key_id), K(fk_infos)); + } else if (OB_FAIL(ob_write_string(alter_table_arg.allocator_, found_fk_info->foreign_key_name_, alter_table_arg.foreign_key_arg_list_.at(0).foreign_key_name_, true/*c_style*/))) { + LOG_WARN("failed to deep copy str", K(ret)); + } + } + } + if (OB_SUCC(ret)) { if (OB_FAIL(alter_table_arg.based_schema_object_infos_.push_back(ObBasedSchemaObjectInfo( table_schema->get_table_id(), diff --git a/src/share/ob_ddl_common.h b/src/share/ob_ddl_common.h index 9c94ef06d0..5acb73e56c 100644 --- a/src/share/ob_ddl_common.h +++ b/src/share/ob_ddl_common.h @@ -352,6 +352,7 @@ public: static int refresh_alter_table_arg( const uint64_t tenant_id, const int64_t orig_table_id, + const uint64_t foreign_key_id, obrpc::ObAlterTableArg &alter_table_arg); static int generate_ddl_schema_hint_str(