diff --git a/src/rootserver/ob_ddl_service.cpp b/src/rootserver/ob_ddl_service.cpp index 526f38ae69..e93335008b 100644 --- a/src/rootserver/ob_ddl_service.cpp +++ b/src/rootserver/ob_ddl_service.cpp @@ -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 &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 &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)); diff --git a/src/rootserver/ob_ddl_service.h b/src/rootserver/ob_ddl_service.h index 816d4e885c..ccdc817bfa 100644 --- a/src/rootserver/ob_ddl_service.h +++ b/src/rootserver/ob_ddl_service.h @@ -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 &foreign_key_infos, + bool &have_index); virtual int update_index_status(const obrpc::ObUpdateIndexStatusArg &arg); int upgrade_table_schema(const obrpc::ObUpgradeTableSchemaArg &arg); diff --git a/src/rootserver/ob_index_builder.cpp b/src/rootserver/ob_index_builder.cpp index 603bf15464..c12d99ad0f 100644 --- a/src/rootserver/ob_index_builder.cpp +++ b/src/rootserver/ob_index_builder.cpp @@ -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 &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));