fix Foreign key columns can be indexed for deletion bug

This commit is contained in:
obdev
2023-06-02 11:53:20 +00:00
committed by ob-robot
parent 71ddf0f11c
commit 5dbd928a66
3 changed files with 44 additions and 3 deletions

View File

@ -4934,6 +4934,28 @@ int ObDDLService::create_index_tablet(const ObTableSchema &index_schema,
return ret;
}
int ObDDLService::check_index_on_foreign_key(const ObTableSchema *index_table_schema,
const common::ObIArray<ObForeignKeyInfo> &foreign_key_infos,
bool &have_index)
{
int ret = OB_SUCCESS;
have_index = false;
if (foreign_key_infos.count() <= 0) {
} else if (OB_ISNULL(index_table_schema)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("index table schema is nullptr", K(ret));
} else {
const uint64_t index_table_id = index_table_schema->get_table_id();
for (int64_t i = 0; OB_SUCC(ret) && i < foreign_key_infos.count(); i++) {
if (foreign_key_infos.at(i).ref_cst_id_ == index_table_id) {
have_index = true;
break;
}
}
}
return ret;
}
int ObDDLService::alter_table_index(const obrpc::ObAlterTableArg &alter_table_arg,
const ObTableSchema &origin_table_schema,
ObTableSchema &new_table_schema,
@ -5121,6 +5143,8 @@ int ObDDLService::alter_table_index(const obrpc::ObAlterTableArg &alter_table_ar
}
if (OB_SUCC(ret)) {
const ObTableSchema *index_table_schema = nullptr;
bool have_index = false;
const common::ObIArray<ObForeignKeyInfo> &foreign_key_infos = origin_table_schema.get_foreign_key_infos();
if (OB_FAIL(get_index_schema_by_name(
origin_table_schema.get_table_id(),
origin_table_schema.get_database_id(),
@ -5132,6 +5156,13 @@ int ObDDLService::alter_table_index(const obrpc::ObAlterTableArg &alter_table_ar
ret = OB_ERR_CANT_DROP_FIELD_OR_KEY;
LOG_WARN("index table schema should not be null", K(*drop_index_arg), K(ret));
LOG_USER_ERROR(OB_ERR_CANT_DROP_FIELD_OR_KEY, drop_index_arg->index_name_.length(), drop_index_arg->index_name_.ptr());
} else if (OB_FAIL(check_index_on_foreign_key(index_table_schema,
foreign_key_infos,
have_index))) {
LOG_WARN("fail to check index on foreign key", K(ret), K(foreign_key_infos), KPC(index_table_schema));
} else if (have_index) {
ret = OB_ERR_ATLER_TABLE_ILLEGAL_FK;
LOG_WARN("cannot delete index with foreign key dependency", K(ret));
} else if (!drop_index_arg->is_inner_ && index_table_schema->is_unavailable_index()) {
ret = OB_NOT_SUPPORTED;
LOG_WARN("not support to drop a building index", K(ret), K(drop_index_arg->is_inner_), KPC(index_table_schema));

View File

@ -238,6 +238,9 @@ public:
const share::schema::ObTableSchema **table_schema);
int create_hidden_table(const obrpc::ObCreateHiddenTableArg &create_hidden_table_arg,
obrpc::ObCreateHiddenTableRes &res);
int check_index_on_foreign_key(const ObTableSchema *index_table_schema,
const common::ObIArray<ObForeignKeyInfo> &foreign_key_infos,
bool &have_index);
virtual int update_index_status(const obrpc::ObUpdateIndexStatusArg &arg);
int upgrade_table_schema(const obrpc::ObUpgradeTableSchemaArg &arg);

View File

@ -127,7 +127,7 @@ int ObIndexBuilder::drop_index(const ObDropIndexArg &arg, obrpc::ObDropIndexRes
ret = OB_ERR_OPERATION_ON_RECYCLE_OBJECT;
LOG_WARN("can not drop index of table in recyclebin.", K(ret), K(arg));
} else if (OB_FAIL(schema_guard.check_database_in_recyclebin(tenant_id,
table_schema->get_database_id(), is_db_in_recyclebin))) {
table_schema->get_database_id(), is_db_in_recyclebin))) {
LOG_WARN("check database in recyclebin failed", K(ret), K(tenant_id));
} else if (is_db_in_recyclebin) {
ret = OB_ERR_OPERATION_ON_RECYCLE_OBJECT;
@ -135,7 +135,6 @@ int ObIndexBuilder::drop_index(const ObDropIndexArg &arg, obrpc::ObDropIndexRes
} else if (OB_FAIL(ddl_service_.check_fk_related_table_ddl(*table_schema))) {
LOG_WARN("check whether foreign key related table executes ddl failed", K(ret));
}
if (OB_SUCC(ret)) {
const uint64_t data_table_id = table_schema->get_table_id();
const ObTableSchema *index_table_schema = NULL;
@ -157,12 +156,20 @@ int ObIndexBuilder::drop_index(const ObDropIndexArg &arg, obrpc::ObDropIndexRes
LOG_WARN("fail to get table schema", K(ret), K(tenant_id), K(index_table_schema));
}
}
bool have_index = false;
const common::ObIArray<ObForeignKeyInfo> &foreign_key_infos = table_schema->get_foreign_key_infos();
if (OB_FAIL(ret)) {
} else if (OB_ISNULL(index_table_schema)) {
ret = OB_ERR_CANT_DROP_FIELD_OR_KEY;
LOG_WARN("index table schema should not be null", K(arg.index_name_), K(ret));
LOG_USER_ERROR(OB_ERR_CANT_DROP_FIELD_OR_KEY, arg.index_name_.length(), arg.index_name_.ptr());
} else if (OB_FAIL(ddl_service_.check_index_on_foreign_key(index_table_schema,
foreign_key_infos,
have_index))) {
LOG_WARN("fail to check index on foreign key", K(ret), K(foreign_key_infos), KPC(index_table_schema));
} else if (have_index) {
ret = OB_ERR_ATLER_TABLE_ILLEGAL_FK;
LOG_WARN("cannot delete index with foreign key dependency", K(ret));
} else if (!arg.is_inner_ && index_table_schema->is_unavailable_index()) {
ret = OB_NOT_SUPPORTED;
LOG_WARN("not support to drop a building index", K(ret), K(arg.is_inner_), KPC(index_table_schema));