support truncate fk parent table while foreign_key_checks is off
This commit is contained in:
@ -12540,14 +12540,21 @@ int ObDDLService::truncate_table_in_trans(const obrpc::ObTruncateTableArg &arg,
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < foreign_key_infos.count(); i++) {
|
||||
ObForeignKeyInfo &foreign_key_info = foreign_key_infos.at(i);
|
||||
foreign_key_info.foreign_key_id_ = OB_INVALID_ID;
|
||||
if (OB_FAIL(schema_service->fetch_new_constraint_id(tmp_schema.get_tenant_id(), foreign_key_info.foreign_key_id_))) {
|
||||
if (OB_FAIL(schema_service->fetch_new_constraint_id(
|
||||
tmp_schema.get_tenant_id(), foreign_key_info.foreign_key_id_))) {
|
||||
LOG_WARN("failed to fetch new foreign key id", K(ret), K(tmp_schema.get_tenant_id()));
|
||||
} else if (foreign_key_info.child_table_id_ == foreign_key_info.parent_table_id_) {
|
||||
} else if (orig_table_schema.get_table_id() == foreign_key_info.child_table_id_) {
|
||||
if (foreign_key_info.child_table_id_ == foreign_key_info.parent_table_id_) {
|
||||
// When it depends on itself, the parent table ID also needs to be updated
|
||||
foreign_key_info.parent_table_id_ = tmp_schema.get_table_id();
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
foreign_key_info.child_table_id_ = tmp_schema.get_table_id();
|
||||
} else if (orig_table_schema.get_table_id() == foreign_key_info.parent_table_id_) {
|
||||
foreign_key_info.parent_table_id_ = tmp_schema.get_table_id();
|
||||
} else {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("orig table id is not equal to orig parent_table_id_ or orig child_table_id_ of foreign_key_info ",
|
||||
K(ret), K(orig_table_schema.get_table_id()), K(foreign_key_info));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -15577,7 +15584,7 @@ int ObDDLService::truncate_table(const ObTruncateTableArg &arg,
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_WARN("not support trunate table has materialized view", K(ret));
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_SUCC(ret) && arg.foreign_key_checks_) {
|
||||
// When truncate table, check whether the table being truncate is the parent table
|
||||
// of the foreign key constraint
|
||||
// if it is parent table, not allow truncate
|
||||
|
||||
@ -1779,7 +1779,8 @@ OB_SERIALIZE_MEMBER((ObTruncateTableArg, ObDDLArg),
|
||||
table_name_,
|
||||
session_id_,
|
||||
is_add_to_scheduler_,
|
||||
compat_mode_);
|
||||
compat_mode_,
|
||||
foreign_key_checks_);
|
||||
|
||||
DEF_TO_STRING(ObTruncateTableArg)
|
||||
{
|
||||
@ -1790,7 +1791,8 @@ DEF_TO_STRING(ObTruncateTableArg)
|
||||
K_(table_name),
|
||||
K_(session_id),
|
||||
K_(is_add_to_scheduler),
|
||||
K_(compat_mode));
|
||||
K_(compat_mode),
|
||||
K_(foreign_key_checks));
|
||||
J_OBJ_END();
|
||||
return pos;
|
||||
}
|
||||
|
||||
@ -1461,7 +1461,8 @@ public:
|
||||
database_name_(),
|
||||
table_name_(),
|
||||
is_add_to_scheduler_(false),
|
||||
compat_mode_(lib::Worker::CompatMode::INVALID)
|
||||
compat_mode_(lib::Worker::CompatMode::INVALID),
|
||||
foreign_key_checks_(false)
|
||||
{}
|
||||
|
||||
ObTruncateTableArg &operator=(const ObTruncateTableArg &other) = delete;
|
||||
@ -1475,6 +1476,7 @@ public:
|
||||
common::ObString table_name_;
|
||||
bool is_add_to_scheduler_;
|
||||
lib::Worker::CompatMode compat_mode_;
|
||||
bool foreign_key_checks_;
|
||||
};
|
||||
|
||||
struct ObRenameTableItem
|
||||
|
||||
@ -694,7 +694,7 @@ int ObTableSqlService::drop_table(const ObTableSchema &table_schema,
|
||||
|
||||
if (OB_SUCC(ret)) {
|
||||
// For oracle compatibility, foreign key should be dropped while drop table.
|
||||
if (OB_FAIL(delete_foreign_key(sql_client, table_schema, new_schema_version))) {
|
||||
if (OB_FAIL(delete_foreign_key(sql_client, table_schema, new_schema_version, is_truncate_table))) {
|
||||
LOG_WARN("failed to delete foreign key", K(ret));
|
||||
}
|
||||
}
|
||||
@ -1883,7 +1883,7 @@ int ObTableSqlService::update_table_options(ObISQLClient &sql_client,
|
||||
|| (OB_DDL_TRUNCATE_DROP_TABLE_TO_RECYCLEBIN == operation_type)) {
|
||||
// 1. For oracle compatibility, drop foreign key while drop table.
|
||||
// 2. Foreign key will be rebuilded while truncate table.
|
||||
if (OB_FAIL(delete_foreign_key(sql_client, new_table_schema, new_table_schema.get_schema_version()))) {
|
||||
if (OB_FAIL(delete_foreign_key(sql_client, new_table_schema, new_table_schema.get_schema_version(), OB_DDL_TRUNCATE_DROP_TABLE_TO_RECYCLEBIN == operation_type))) {
|
||||
LOG_WARN("failed to delete foreign key", K(ret));
|
||||
}
|
||||
}
|
||||
@ -4226,7 +4226,9 @@ int ObTableSqlService::delete_from_all_foreign_key_column(ObISQLClient &sql_clie
|
||||
}
|
||||
|
||||
// drop fk child table or drop fk child table into recyclebin will come here
|
||||
int ObTableSqlService::delete_foreign_key(common::ObISQLClient &sql_client, const ObTableSchema &table_schema, const int64_t new_schema_version)
|
||||
int ObTableSqlService::delete_foreign_key(
|
||||
common::ObISQLClient &sql_client, const ObTableSchema &table_schema,
|
||||
const int64_t new_schema_version, const bool is_truncate_table)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const ObIArray<ObForeignKeyInfo> &foreign_key_infos = table_schema.get_foreign_key_infos();
|
||||
@ -4236,8 +4238,9 @@ int ObTableSqlService::delete_foreign_key(common::ObISQLClient &sql_client, cons
|
||||
}
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < foreign_key_infos.count(); i++) {
|
||||
const ObForeignKeyInfo &foreign_key_info = foreign_key_infos.at(i);
|
||||
if (table_schema.get_table_id() == foreign_key_info.child_table_id_
|
||||
|| table_schema.is_offline_ddl_table()) { // offline ddl table will swap and drop parent table
|
||||
if (is_truncate_table // truncate table will drop parent table and create it again
|
||||
|| table_schema.is_offline_ddl_table() // offline ddl table will swap and drop parent table
|
||||
|| table_schema.get_table_id() == foreign_key_info.child_table_id_) {
|
||||
uint64_t foreign_key_id = foreign_key_info.foreign_key_id_;
|
||||
if (OB_FAIL(delete_from_all_foreign_key(sql_client, tenant_id, new_schema_version, foreign_key_info))) {
|
||||
LOG_WARN("failed to delete __all_foreign_key_history", K(table_schema), K(ret));
|
||||
@ -4450,8 +4453,8 @@ int ObTableSqlService::add_foreign_key(
|
||||
} else if (!foreign_key_info.is_parent_table_mock_) {
|
||||
// If parent table is mock, it may not exist. And we will deal with mock fk parent table after add_foreign_key.
|
||||
if (OB_FAIL(update_data_table_schema_version(sql_client, tenant_id,
|
||||
foreign_key_info.parent_table_id_, table.get_in_offline_ddl_white_list()))) {
|
||||
LOG_WARN("failed to update parent table schema version", K(ret));
|
||||
table.get_table_id() == foreign_key_info.child_table_id_ ? foreign_key_info.parent_table_id_ : foreign_key_info.child_table_id_, table.get_in_offline_ddl_white_list()))) {
|
||||
LOG_WARN("failed to update parent table schema version", K(ret), K(foreign_key_info));
|
||||
}
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
|
||||
@ -311,7 +311,8 @@ private:
|
||||
int add_table_part_info(common::ObISQLClient &sql_client, const ObTableSchema &table);
|
||||
int delete_foreign_key(common::ObISQLClient &sql_client,
|
||||
const ObTableSchema &table_schema,
|
||||
const int64_t new_schema_version);
|
||||
const int64_t new_schema_version,
|
||||
const bool is_truncate_table);
|
||||
int delete_from_all_foreign_key(common::ObISQLClient &sql_client,
|
||||
const uint64_t tenant_id,
|
||||
const int64_t new_schema_version,
|
||||
|
||||
@ -1818,6 +1818,9 @@ int ObTruncateTableExecutor::execute(ObExecContext &ctx, ObTruncateTableStmt &st
|
||||
&& FALSE_IT(const_cast<obrpc::ObTruncateTableArg&>(truncate_table_arg).session_id_ = my_session->get_sessid_for_table())) {
|
||||
//impossible
|
||||
} else if (!stmt.is_truncate_oracle_temp_table()) {
|
||||
int64_t foreign_key_checks = 0;
|
||||
my_session->get_foreign_key_checks(foreign_key_checks);
|
||||
const_cast<obrpc::ObTruncateTableArg&>(truncate_table_arg).foreign_key_checks_ = is_oracle_mode() || (is_mysql_mode() && foreign_key_checks);
|
||||
const_cast<obrpc::ObTruncateTableArg&>(truncate_table_arg).compat_mode_ = ORACLE_MODE == my_session->get_compatibility_mode()
|
||||
? lib::Worker::CompatMode::ORACLE : lib::Worker::CompatMode::MYSQL;
|
||||
int64_t affected_rows = 0;
|
||||
|
||||
Reference in New Issue
Block a user