bugfix: fix object privilege is lost after create or replace a view which was existed
This commit is contained in:
		| @ -1653,6 +1653,33 @@ int ObDDLService::print_view_expanded_definition( | ||||
|   return ret; | ||||
| } | ||||
| 
 | ||||
| int ObDDLService::get_obj_privs_ora(const uint64_t tenant_id, | ||||
|                                     const uint64_t obj_id, | ||||
|                                     const uint64_t obj_type, | ||||
|                                     ObSchemaGetterGuard &schema_guard, | ||||
|                                     ObIArray<ObObjPriv> &obj_privs) { | ||||
|   int ret = OB_SUCCESS; | ||||
|   ObArray<const ObObjPriv*> obj_privs_pointer; | ||||
|   if (OB_FAIL(schema_guard.get_obj_priv_with_obj_id(tenant_id, | ||||
|                                                     obj_id, | ||||
|                                                     obj_type, | ||||
|                                                     obj_privs_pointer, | ||||
|                                                     true))) { | ||||
|     LOG_WARN("fail to get_obj_priv_with_obj_id", KR(ret), K(tenant_id), K(obj_id), K(obj_type)); | ||||
|   } else { | ||||
|     for (int64_t i = 0; OB_SUCC(ret) && i < obj_privs_pointer.count(); ++i) { | ||||
|       if (OB_ISNULL(obj_privs_pointer.at(i))) { | ||||
|         ret = OB_ERR_UNEXPECTED; | ||||
|         LOG_WARN("obj_privs_pointer contains NULL", KR(ret), K(i)); | ||||
|       } else if(OB_FAIL(obj_privs.push_back(*(obj_privs_pointer.at(i))))) { | ||||
|         LOG_WARN("obj_privs fail to push back", KR(ret), K(i)); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   return ret; | ||||
| } | ||||
| 
 | ||||
| int ObDDLService::create_tables_in_trans(const bool if_not_exist, | ||||
|                                          const ObString &ddl_stmt_str, | ||||
|                                          const ObErrorInfo &error_info, | ||||
| @ -1684,6 +1711,9 @@ int ObDDLService::create_tables_in_trans(const bool if_not_exist, | ||||
|     ObSchemaGetterGuard schema_guard; | ||||
|     uint64_t tenant_id = table_schemas.at(0).get_tenant_id(); | ||||
|     share::schema::ObTableSchema &first_table = table_schemas.at(0); | ||||
|     ObArray<ObObjPriv> orig_obj_privs_ora; | ||||
|     const ObTableSchema *old_view_schema = NULL; | ||||
|     bool is_oracle_mode = false; | ||||
|     int64_t refreshed_schema_version = 0; | ||||
|     if (OB_FAIL(get_tenant_schema_guard_with_version_in_inner_table(tenant_id, schema_guard))) { | ||||
|       LOG_WARN("fail to get schema guard with version in inner table", K(ret), K(tenant_id)); | ||||
| @ -1692,6 +1722,8 @@ int ObDDLService::create_tables_in_trans(const bool if_not_exist, | ||||
|     } else if (OB_FAIL(trans.start(sql_proxy_, tenant_id, refreshed_schema_version))) { | ||||
|       LOG_WARN("failed to start trans", KR(ret), K(tenant_id), | ||||
|                K(tenant_id), K(refreshed_schema_version)); | ||||
|     } else if (OB_FAIL(first_table.check_if_oracle_compat_mode(is_oracle_mode))) { | ||||
|       LOG_WARN("fail to check is oracle mode", KR(ret), K(first_table)); | ||||
|     } else { | ||||
|     } | ||||
|     if (OB_SUCC(ret)) { | ||||
| @ -1712,7 +1744,6 @@ int ObDDLService::create_tables_in_trans(const bool if_not_exist, | ||||
|         if (OB_FAIL(ret)) { | ||||
|         } else if (table_schema.is_view_table() && if_not_exist) { | ||||
|           const ObString &view_name = table_schema.get_table_name(); | ||||
|           const ObTableSchema *old_view_schema = NULL; | ||||
|           if (OB_FAIL(schema_guard.get_table_schema(table_schema.get_tenant_id(), | ||||
|                                                     table_schema.get_database_id(), | ||||
|                                                     view_name, | ||||
| @ -1721,12 +1752,26 @@ int ObDDLService::create_tables_in_trans(const bool if_not_exist, | ||||
|             LOG_WARN("failed to get table schema", K(view_name), K(ret)); | ||||
|           } else if (OB_ISNULL(old_view_schema)) { | ||||
|             ret = OB_SUCCESS; | ||||
|           } else if (OB_FAIL(drop_trigger_in_drop_table(trans, ddl_operator, schema_guard, | ||||
|                                                         *old_view_schema, false))) { | ||||
|             // 兼容oracle,create or replace view时drop trigger,且不进回收站
 | ||||
|             LOG_WARN("failed to drop trigger", K(old_view_schema->get_table_id()), K(ret)); | ||||
|           } else if (OB_FAIL(ddl_operator.drop_table(*old_view_schema, trans))) { | ||||
|             LOG_WARN("failed to drop old view schema", K(ret)); | ||||
|           } else { | ||||
|             if (!is_oracle_mode) { | ||||
|               // no need to store obj privs
 | ||||
|             } else if (OB_FAIL(get_obj_privs_ora(table_schema.get_tenant_id(), | ||||
|                                                  old_view_schema->get_table_id(), | ||||
|                                                  static_cast<uint64_t>(ObObjectType::TABLE), | ||||
|                                                  schema_guard, | ||||
|                                                  orig_obj_privs_ora))) { | ||||
|               LOG_WARN("fial to get obj privs ora", KR(ret), K(table_schema.get_tenant_id()), | ||||
|                        K(old_view_schema->get_table_id())); | ||||
|             } | ||||
| 
 | ||||
|             if (OB_FAIL(ret)) { | ||||
|             } else if (OB_FAIL(drop_trigger_in_drop_table(trans, ddl_operator, schema_guard, | ||||
|                                                           *old_view_schema, false))) { | ||||
|               // 兼容oracle,create or replace view时drop trigger,且不进回收站
 | ||||
|               LOG_WARN("failed to drop trigger", KR(ret), K(old_view_schema->get_table_id())); | ||||
|             } else if (OB_FAIL(ddl_operator.drop_table(*old_view_schema, trans))) { | ||||
|               LOG_WARN("failed to drop old view schema", KR(ret)); | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|       } | ||||
| @ -1761,15 +1806,32 @@ int ObDDLService::create_tables_in_trans(const bool if_not_exist, | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|          | ||||
|         if (OB_SUCC(ret) && (0 == i) && table_schema.is_view_table() &&  | ||||
|             OB_NOT_NULL(old_view_schema) && is_oracle_mode) { | ||||
|           const uint64_t db_id = table_schema.get_database_id(); | ||||
|           const ObSimpleDatabaseSchema *db_schema = NULL; | ||||
|           if (OB_FAIL(schema_guard.get_database_schema(tenant_id, db_id, db_schema))) { | ||||
|             LOG_WARN("failed to get database schema", KR(ret), K(db_id)); | ||||
|           } else if (OB_ISNULL(db_schema)) { | ||||
|             ret = OB_ERR_BAD_DATABASE; | ||||
|             LOG_WARN("db schema is NULL", KR(ret), K(tenant_id), K(db_id)); | ||||
|           } else if (OB_FAIL(restore_obj_privs_for_table(table_schema.get_table_id(), | ||||
|                                                          db_schema->get_database_name_str(), | ||||
|                                                          table_schema.get_table_name_str(), | ||||
|                                                          ddl_operator, | ||||
|                                                          trans, | ||||
|                                                          orig_obj_privs_ora))) { | ||||
|             LOG_WARN("restore_obj_privs_for_table failed", KR(ret), K(table_schema.get_table_id()), | ||||
|                      K(db_schema->get_database_name_str()), K(table_schema.get_table_name_str())); | ||||
|           } | ||||
|         } | ||||
|       } | ||||
| 
 | ||||
|       // add error info for create force view
 | ||||
|       if (OB_SUCC(ret) && 1 == table_schemas.count() && first_table.is_user_view()) { | ||||
|         bool is_oracle_mode = false; | ||||
|         if (OB_LIKELY(ERROR_STATUS_HAS_ERROR != error_info.get_error_status())) { | ||||
|           /* do nothing */ | ||||
|         } else if (OB_FAIL(first_table.check_if_oracle_compat_mode(is_oracle_mode))) { | ||||
|           LOG_WARN("fail to check if tenant mode is oracle mode", K(ret)); | ||||
|         } else if (OB_UNLIKELY(!is_oracle_mode)) { | ||||
|           ret = OB_ERR_UNEXPECTED; | ||||
|           LOG_WARN("unexpected compat mode add create view error info", K(ret), K(is_oracle_mode)); | ||||
| @ -12338,7 +12400,6 @@ int ObDDLService::truncate_table_in_trans(const obrpc::ObTruncateTableArg &arg, | ||||
|     ObArenaAllocator allocator(ObModIds::OB_RS_PARTITION_TABLE_TEMP); | ||||
|     const uint64_t tenant_id = orig_table_schema.get_tenant_id(); | ||||
|     ObSArray<ObSAuditSchema> audit_schemas; | ||||
|     ObArray<const ObObjPriv *> orig_obj_privs_pointer_ora; | ||||
|     ObArray<ObObjPriv> orig_obj_privs_ora; | ||||
|     const bool to_recyclebin = false; | ||||
|     if (table_schemas.count() < 1) { | ||||
| @ -12370,24 +12431,12 @@ int ObDDLService::truncate_table_in_trans(const obrpc::ObTruncateTableArg &arg, | ||||
|       } | ||||
|     } | ||||
|     // Save Oracle obj privs on table for later restore
 | ||||
|     if (OB_SUCC(ret)) { | ||||
|       if (OB_FAIL(schema_guard.get_obj_priv_with_obj_id(tenant_id, | ||||
|                                    orig_table_schema.get_table_id(), | ||||
|                                    static_cast<uint64_t>(ObObjectType::TABLE), | ||||
|                                    orig_obj_privs_pointer_ora, | ||||
|                                    true /* reset flag */))) { | ||||
|         LOG_WARN("get_obj_priv_with_obj_id failed", K(ret), | ||||
|             K(tenant_id), K(orig_table_schema.get_table_id())); | ||||
|       } else { | ||||
|         for (int i = 0; OB_SUCC(ret) && i < orig_obj_privs_pointer_ora.count(); ++i) { | ||||
|           if (OB_ISNULL(orig_obj_privs_pointer_ora.at(i))) { | ||||
|             ret = OB_ERR_UNEXPECTED; | ||||
|             LOG_WARN("orig_obj_privs_pointer_ora contains NULL", K(ret), K(i)); | ||||
|           } else { | ||||
|             OZ (orig_obj_privs_ora.push_back(*(orig_obj_privs_pointer_ora.at(i)))); | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     if (OB_SUCC(ret) && OB_FAIL(get_obj_privs_ora(tenant_id, | ||||
|                                                   orig_table_schema.get_table_id(), | ||||
|                                                   static_cast<uint64_t>(ObObjectType::TABLE), | ||||
|                                                   schema_guard, | ||||
|                                                   orig_obj_privs_ora))) { | ||||
|       LOG_WARN("fail to get obj privs ora", KR(ret), K(tenant_id), K(orig_table_schema.get_table_id())); | ||||
|     } | ||||
|     if (OB_SUCC(ret) && OB_FAIL(drop_aux_table_in_truncate( | ||||
|         orig_table_schema, schema_guard, trans, ddl_operator, | ||||
| @ -12592,17 +12641,16 @@ int ObDDLService::truncate_table_in_trans(const obrpc::ObTruncateTableArg &arg, | ||||
|         } | ||||
|         if (OB_SUCC(ret) && (0 == i)) { | ||||
|           // truncate table needs to rebuild the audit rules for the newly created table
 | ||||
|           if (OB_FAIL(restore_obj_priv_after_truncation( | ||||
|                         ddl_operator, | ||||
|                         trans, | ||||
|                         orig_obj_privs_ora, | ||||
|                         tmp_schema.get_table_id(), | ||||
|                         database_name, | ||||
|                         tmp_schema.get_table_name_str()))) { | ||||
|             LOG_WARN("restore_obj_priv_after_truncation failed", K(ret), | ||||
|                 K(tmp_schema.get_table_id()), | ||||
|                 K(database_name), | ||||
|                 K(tmp_schema.get_table_name_str())); | ||||
|           if (OB_FAIL(restore_obj_privs_for_table(tmp_schema.get_table_id(), | ||||
|                                                   database_name, | ||||
|                                                   tmp_schema.get_table_name_str(), | ||||
|                                                   ddl_operator, | ||||
|                                                   trans, | ||||
|                                                   orig_obj_privs_ora))) { | ||||
|             LOG_WARN("restore_obj_privs_for_table failed", KR(ret), | ||||
|                      K(tmp_schema.get_table_id()), | ||||
|                      K(database_name), | ||||
|                      K(tmp_schema.get_table_name_str())); | ||||
|           } | ||||
|         } | ||||
|       } | ||||
| @ -12705,14 +12753,12 @@ int ObDDLService::truncate_table_in_trans(const obrpc::ObTruncateTableArg &arg, | ||||
|   return ret; | ||||
| } | ||||
| 
 | ||||
| int ObDDLService::restore_obj_priv_after_truncation( | ||||
|     ObDDLOperator &ddl_operator, | ||||
|     ObMySQLTransaction &trans, | ||||
|     ObIArray<ObObjPriv> &orig_obj_privs_ora, | ||||
|     uint64_t new_table_id, | ||||
|     const ObString &database_name, | ||||
|     const ObString &table_name) | ||||
| { | ||||
| int ObDDLService::restore_obj_privs_for_table(const uint64_t new_table_id, | ||||
|                                               const ObString &database_name, | ||||
|                                               const ObString &table_name, | ||||
|                                               ObDDLOperator &ddl_operator, | ||||
|                                               ObMySQLTransaction &trans, | ||||
|                                               ObIArray<ObObjPriv> &orig_obj_privs_ora) { | ||||
|   int ret = OB_SUCCESS; | ||||
|   for (int i = 0; OB_SUCC(ret) && i < orig_obj_privs_ora.count(); ++i) { | ||||
|     ObObjPriv &obj_priv = orig_obj_privs_ora.at(i); | ||||
| @ -13103,39 +13149,24 @@ int ObDDLService::rebuild_hidden_table_priv(const ObTableSchema &orig_table_sche | ||||
|                                             ObMySQLTransaction &trans) | ||||
| { | ||||
|   int ret = OB_SUCCESS; | ||||
|   ObArray<const ObObjPriv *> orig_obj_privs_pointer_ora; | ||||
|   ObArray<ObObjPriv> orig_obj_privs_ora; | ||||
|   if (OB_FAIL(schema_guard.get_obj_priv_with_obj_id( | ||||
|                            orig_table_schema.get_tenant_id(), | ||||
|                            orig_table_schema.get_table_id(), | ||||
|                            static_cast<uint64_t>(ObObjectType::TABLE), | ||||
|                            orig_obj_privs_pointer_ora, | ||||
|                            true /* reset flag */))) { | ||||
|     LOG_WARN("get_obj_priv_with_obj_id failed", K(ret), | ||||
|     K(orig_table_schema.get_table_id())); | ||||
|   } else { | ||||
|     for (int i = 0; OB_SUCC(ret) && i < orig_obj_privs_pointer_ora.count(); ++i) { | ||||
|       if (OB_ISNULL(orig_obj_privs_pointer_ora.at(i))) { | ||||
|         ret = OB_ERR_UNEXPECTED; | ||||
|         LOG_WARN("orig_obj_privs_pointer_ora contains NULL", K(ret), K(i)); | ||||
|       } else { | ||||
|         OZ (orig_obj_privs_ora.push_back(*(orig_obj_privs_pointer_ora.at(i)))); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   if (OB_SUCC(ret)) { | ||||
|   if (OB_FAIL(get_obj_privs_ora(orig_table_schema.get_tenant_id(), | ||||
|                                 orig_table_schema.get_table_id(), | ||||
|                                 static_cast<uint64_t>(ObObjectType::TABLE), | ||||
|                                 schema_guard, | ||||
|                                 orig_obj_privs_ora))) { | ||||
|     LOG_WARN("fail to get obj privs ora", KR(ret), K(orig_table_schema.get_tenant_id()), | ||||
|              K(orig_table_schema.get_table_id())); | ||||
|   } else if (OB_FAIL(restore_obj_privs_for_table(hidden_table_schema.get_table_id(), | ||||
|                                                  hidden_table_schema.get_link_database_name(), | ||||
|                                                  hidden_table_schema.get_table_name_str(), | ||||
|                                                  ddl_operator, | ||||
|                                                  trans, | ||||
|                                                  orig_obj_privs_ora))) { | ||||
|     // need to rebuild permissions for the newly created table
 | ||||
|     if (OB_FAIL(restore_obj_priv_after_truncation( | ||||
|                 ddl_operator, | ||||
|                 trans, | ||||
|                 orig_obj_privs_ora, | ||||
|                 hidden_table_schema.get_table_id(), | ||||
|                 hidden_table_schema.get_link_database_name(), | ||||
|                 hidden_table_schema.get_table_name_str()))) { | ||||
|       LOG_WARN("restore_obj_priv_after_truncation failed", K(ret), | ||||
|                K(hidden_table_schema.get_table_id()), | ||||
|                K(hidden_table_schema.get_table_name_str())); | ||||
|     } | ||||
|     LOG_WARN("restore_obj_privs_for_table failed", KR(ret), | ||||
|              K(hidden_table_schema.get_table_id()), | ||||
|              K(hidden_table_schema.get_table_name_str())); | ||||
|   } | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| @ -1435,13 +1435,6 @@ private: | ||||
|                               ObMySQLTransaction &trans, | ||||
|                               const common::ObString *ddl_stmt_str, | ||||
|                               const common::ObString &db_name); | ||||
|   int restore_obj_priv_after_truncation( | ||||
|       ObDDLOperator &ddl_operator, | ||||
|       ObMySQLTransaction &trans, | ||||
|       common::ObIArray<share::schema::ObObjPriv> &orig_obj_privs_ora, | ||||
|       uint64_t new_table_id, | ||||
|       const common::ObString &database_name, | ||||
|       const common::ObString &table_name); | ||||
|   int drop_aux_table_in_truncate( | ||||
|       const share::schema::ObTableSchema &orig_table_schema, | ||||
|       share::schema::ObSchemaGetterGuard &schema_guard, | ||||
| @ -2167,6 +2160,17 @@ private: | ||||
|   int alter_system_table_column_( | ||||
|       share::schema::ObSchemaGetterGuard &schema_guard, | ||||
|       const share::schema::ObTableSchema &hard_code_schema); | ||||
|   int get_obj_privs_ora(const uint64_t tenant_id, | ||||
|                         const uint64_t obj_id, | ||||
|                         const uint64_t obj_type, | ||||
|                         ObSchemaGetterGuard &schema_guard, | ||||
|                         ObIArray<ObObjPriv> &obj_privs); | ||||
|   int restore_obj_privs_for_table(const uint64_t new_table_id, | ||||
|                                   const common::ObString &database_name, | ||||
|                                   const common::ObString &table_name, | ||||
|                                   ObDDLOperator &ddl_operator, | ||||
|                                   ObMySQLTransaction &trans, | ||||
|                                   common::ObIArray<share::schema::ObObjPriv> &orig_obj_privs_ora); | ||||
| private: | ||||
|   bool inited_; | ||||
|   volatile bool stopped_; | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 obdev
					obdev