This is an automated email from the ASF dual-hosted git repository. dataroaring pushed a commit to branch branch-3.0 in repository https://gitbox.apache.org/repos/asf/doris.git
commit 07af360a088de42436e916b117c8a372ec058c88 Author: wangbo <wan...@apache.org> AuthorDate: Wed Jul 31 12:11:02 2024 +0800 [Improment]Add schema table workload_group_privileges (#38436) ## Proposed changes Add schema table workload_group_privileges. ``` mysql [information_schema]>desc workload_group_privileges; +---------------------+--------------+------+-------+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------------------+--------------+------+-------+---------+-------+ | GRANTEE | varchar(64) | Yes | false | NULL | | | WORKLOAD_GROUP_NAME | varchar(256) | Yes | false | NULL | | | PRIVILEGE_TYPE | varchar(64) | Yes | false | NULL | | | IS_GRANTABLE | varchar(3) | Yes | false | NULL | | +---------------------+--------------+------+-------+---------+-------+ 4 rows in set (0.01 sec) ``` --- be/src/exec/schema_scanner.cpp | 3 + .../schema_workload_group_privileges.cpp | 136 +++++++++++++++++++++ .../schema_workload_group_privileges.h | 52 ++++++++ .../org/apache/doris/analysis/SchemaTableType.java | 4 +- .../java/org/apache/doris/catalog/SchemaTable.java | 8 ++ .../org/apache/doris/mysql/privilege/Auth.java | 42 +++++++ .../apache/doris/mysql/privilege/RoleManager.java | 26 ++++ .../doris/tablefunction/MetadataGenerator.java | 37 ++++++ gensrc/thrift/Descriptors.thrift | 3 +- gensrc/thrift/FrontendService.thrift | 1 + .../jdbc/test_mariadb_jdbc_catalog.out | 1 + .../jdbc/test_mysql_jdbc_catalog.out | 1 + .../jdbc/test_mysql_jdbc_catalog_nereids.out | 1 + .../jdbc/test_mysql_jdbc_driver5_catalog.out | 1 + .../data/workload_manager_p0/test_curd_wlg.out | 49 ++++++++ .../workload_manager_p0/test_curd_wlg.groovy | 58 +++++++++ 16 files changed, 421 insertions(+), 2 deletions(-) diff --git a/be/src/exec/schema_scanner.cpp b/be/src/exec/schema_scanner.cpp index b78083f39e2..2ddb3db295b 100644 --- a/be/src/exec/schema_scanner.cpp +++ b/be/src/exec/schema_scanner.cpp @@ -48,6 +48,7 @@ #include "exec/schema_scanner/schema_user_scanner.h" #include "exec/schema_scanner/schema_variables_scanner.h" #include "exec/schema_scanner/schema_views_scanner.h" +#include "exec/schema_scanner/schema_workload_group_privileges.h" #include "exec/schema_scanner/schema_workload_groups_scanner.h" #include "exec/schema_scanner/schema_workload_sched_policy_scanner.h" #include "olap/hll.h" @@ -227,6 +228,8 @@ std::unique_ptr<SchemaScanner> SchemaScanner::create(TSchemaTableType::type type return SchemaWorkloadSchedulePolicyScanner::create_unique(); case TSchemaTableType::SCH_TABLE_OPTIONS: return SchemaTableOptionsScanner::create_unique(); + case TSchemaTableType::SCH_WORKLOAD_GROUP_PRIVILEGES: + return SchemaWorkloadGroupPrivilegesScanner::create_unique(); default: return SchemaDummyScanner::create_unique(); break; diff --git a/be/src/exec/schema_scanner/schema_workload_group_privileges.cpp b/be/src/exec/schema_scanner/schema_workload_group_privileges.cpp new file mode 100644 index 00000000000..88baddb550e --- /dev/null +++ b/be/src/exec/schema_scanner/schema_workload_group_privileges.cpp @@ -0,0 +1,136 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +#include "exec/schema_scanner/schema_workload_group_privileges.h" + +#include "runtime/client_cache.h" +#include "runtime/exec_env.h" +#include "runtime/runtime_state.h" +#include "util/thrift_rpc_helper.h" +#include "vec/common/string_ref.h" +#include "vec/core/block.h" +#include "vec/data_types/data_type_factory.hpp" + +namespace doris { +std::vector<SchemaScanner::ColumnDesc> SchemaWorkloadGroupPrivilegesScanner::_s_tbls_columns = { + {"GRANTEE", TYPE_VARCHAR, sizeof(StringRef), true}, + {"WORKLOAD_GROUP_NAME", TYPE_VARCHAR, sizeof(StringRef), true}, + {"PRIVILEGE_TYPE", TYPE_VARCHAR, sizeof(StringRef), true}, + {"IS_GRANTABLE", TYPE_VARCHAR, sizeof(StringRef), true}, +}; + +SchemaWorkloadGroupPrivilegesScanner::SchemaWorkloadGroupPrivilegesScanner() + : SchemaScanner(_s_tbls_columns, TSchemaTableType::SCH_WORKLOAD_GROUPS) {} + +SchemaWorkloadGroupPrivilegesScanner::~SchemaWorkloadGroupPrivilegesScanner() {} + +Status SchemaWorkloadGroupPrivilegesScanner::start(RuntimeState* state) { + _block_rows_limit = state->batch_size(); + _rpc_timeout = state->execution_timeout() * 1000; + return Status::OK(); +} + +Status SchemaWorkloadGroupPrivilegesScanner::_get_workload_group_privs_block_from_fe() { + TNetworkAddress master_addr = ExecEnv::GetInstance()->master_info()->network_address; + + TSchemaTableRequestParams schema_table_request_params; + for (int i = 0; i < _s_tbls_columns.size(); i++) { + schema_table_request_params.__isset.columns_name = true; + schema_table_request_params.columns_name.emplace_back(_s_tbls_columns[i].name); + } + schema_table_request_params.__set_current_user_ident(*_param->common_param->current_user_ident); + + TFetchSchemaTableDataRequest request; + request.__set_schema_table_name(TSchemaTableName::WORKLOAD_GROUP_PRIVILEGES); + request.__set_schema_table_params(schema_table_request_params); + + TFetchSchemaTableDataResult result; + + RETURN_IF_ERROR(ThriftRpcHelper::rpc<FrontendServiceClient>( + master_addr.hostname, master_addr.port, + [&request, &result](FrontendServiceConnection& client) { + client->fetchSchemaTableData(result, request); + }, + _rpc_timeout)); + + Status status(Status::create(result.status)); + if (!status.ok()) { + LOG(WARNING) << "fetch workload group privileges from FE failed, errmsg=" << status; + return status; + } + std::vector<TRow> result_data = result.data_batch; + + _workload_groups_privs_block = vectorized::Block::create_unique(); + for (int i = 0; i < _s_tbls_columns.size(); ++i) { + TypeDescriptor descriptor(_s_tbls_columns[i].type); + auto data_type = vectorized::DataTypeFactory::instance().create_data_type(descriptor, true); + _workload_groups_privs_block->insert(vectorized::ColumnWithTypeAndName( + data_type->create_column(), data_type, _s_tbls_columns[i].name)); + } + + if (result_data.size() > 0) { + int col_size = result_data[0].column_value.size(); + if (col_size != _s_tbls_columns.size()) { + return Status::InternalError<false>( + "workload group privileges schema is not match for FE and BE"); + } + } + + _workload_groups_privs_block->reserve(result_data.size()); + + for (int i = 0; i < result_data.size(); i++) { + TRow row = result_data[i]; + + for (int j = 0; j < _s_tbls_columns.size(); j++) { + RETURN_IF_ERROR(insert_block_column(row.column_value[j], j, + _workload_groups_privs_block.get(), + _s_tbls_columns[j].type)); + } + } + return Status::OK(); +} + +Status SchemaWorkloadGroupPrivilegesScanner::get_next_block(vectorized::Block* block, bool* eos) { + if (!_is_init) { + return Status::InternalError("Used before initialized."); + } + + if (nullptr == block || nullptr == eos) { + return Status::InternalError("input pointer is nullptr."); + } + + if (_workload_groups_privs_block == nullptr) { + RETURN_IF_ERROR(_get_workload_group_privs_block_from_fe()); + _total_rows = _workload_groups_privs_block->rows(); + } + + if (_row_idx == _total_rows) { + *eos = true; + return Status::OK(); + } + + int current_batch_rows = std::min(_block_rows_limit, _total_rows - _row_idx); + vectorized::MutableBlock mblock = vectorized::MutableBlock::build_mutable_block(block); + RETURN_IF_ERROR( + mblock.add_rows(_workload_groups_privs_block.get(), _row_idx, current_batch_rows)); + _row_idx += current_batch_rows; + + *eos = _row_idx == _total_rows; + return Status::OK(); +} + +} // namespace doris \ No newline at end of file diff --git a/be/src/exec/schema_scanner/schema_workload_group_privileges.h b/be/src/exec/schema_scanner/schema_workload_group_privileges.h new file mode 100644 index 00000000000..cdf3c9697b1 --- /dev/null +++ b/be/src/exec/schema_scanner/schema_workload_group_privileges.h @@ -0,0 +1,52 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +#pragma once + +#include <vector> + +#include "common/status.h" +#include "exec/schema_scanner.h" + +namespace doris { +class RuntimeState; +namespace vectorized { +class Block; +} // namespace vectorized + +class SchemaWorkloadGroupPrivilegesScanner : public SchemaScanner { + ENABLE_FACTORY_CREATOR(SchemaWorkloadGroupPrivilegesScanner); + +public: + SchemaWorkloadGroupPrivilegesScanner(); + ~SchemaWorkloadGroupPrivilegesScanner() override; + + Status start(RuntimeState* state) override; + Status get_next_block(vectorized::Block* block, bool* eos) override; + + static std::vector<SchemaScanner::ColumnDesc> _s_tbls_columns; + +private: + Status _get_workload_group_privs_block_from_fe(); + + int _block_rows_limit = 4096; + int _row_idx = 0; + int _total_rows = 0; + std::unique_ptr<vectorized::Block> _workload_groups_privs_block = nullptr; + int _rpc_timeout = 3000; +}; +}; // namespace doris \ No newline at end of file diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/SchemaTableType.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/SchemaTableType.java index 988953ed4cb..d0a3a3728b2 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/SchemaTableType.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/SchemaTableType.java @@ -78,7 +78,9 @@ public enum SchemaTableType { SCH_WORKLOAD_POLICY("WORKLOAD_POLICY", "WORKLOAD_POLICY", TSchemaTableType.SCH_WORKLOAD_POLICY), SCH_TABLE_OPTIONS("TABLE_OPTIONS", "TABLE_OPTIONS", - TSchemaTableType.SCH_TABLE_OPTIONS); + TSchemaTableType.SCH_TABLE_OPTIONS), + SCH_WORKLOAD_GROUP_PRIVILEGES("WORKLOAD_GROUP_PRIVILEGES", + "WORKLOAD_GROUP_PRIVILEGES", TSchemaTableType.SCH_WORKLOAD_GROUP_PRIVILEGES); private static final String dbName = "INFORMATION_SCHEMA"; private static SelectList fullSelectLists; diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/SchemaTable.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/SchemaTable.java index 4b76785d9b4..8802d266526 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/SchemaTable.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/SchemaTable.java @@ -532,6 +532,14 @@ public class SchemaTable extends Table { .column("PARTITION_NUM", ScalarType.createType(PrimitiveType.INT)) .column("PROPERTIES", ScalarType.createStringType()) .build())) + .put("workload_group_privileges", + new SchemaTable(SystemIdGenerator.getNextId(), "workload_group_privileges", TableType.SCHEMA, + builder().column("GRANTEE", ScalarType.createVarchar(NAME_CHAR_LEN)) + .column("WORKLOAD_GROUP_NAME", ScalarType.createVarchar(256)) + .column("PRIVILEGE_TYPE", ScalarType.createVarchar(PRIVILEGE_TYPE_LEN)) + .column("IS_GRANTABLE", ScalarType.createVarchar(IS_GRANTABLE_LEN)) + .build()) + ) .build(); private boolean fetchAllFe = false; diff --git a/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/Auth.java b/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/Auth.java index 9fb6d9218b0..2073e33cb4f 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/Auth.java +++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/Auth.java @@ -82,6 +82,7 @@ import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -1407,6 +1408,47 @@ public class Auth implements Writable { userAuthInfos.add(userAuthInfo); } + public void getUserRoleWorkloadGroupPrivs(List<List<String>> result, UserIdentity currentUserIdentity) { + readLock(); + try { + boolean isCurrentUserAdmin = checkGlobalPriv(currentUserIdentity, PrivPredicate.ADMIN); + Map<String, List<User>> nameToUsers = userManager.getNameToUsers(); + for (List<User> users : nameToUsers.values()) { + for (User user : users) { + if (!user.isSetByDomainResolver()) { + if (!isCurrentUserAdmin && !currentUserIdentity.equals(user.getUserIdentity())) { + continue; + } + String isGrantable = checkGlobalPriv(user.getUserIdentity(), PrivPredicate.ADMIN) ? "YES" + : "NO"; + + // workload group + for (PrivEntry entry : getUserWorkloadGroupPrivTable(user.getUserIdentity()).entries) { + WorkloadGroupPrivEntry workloadGroupPrivEntry = (WorkloadGroupPrivEntry) entry; + PrivBitSet savedPrivs = workloadGroupPrivEntry.getPrivSet().copy(); + + List<String> row = Lists.newArrayList(); + row.add(user.getUserIdentity().toString()); + row.add(workloadGroupPrivEntry.getOrigWorkloadGroupName()); + row.add(savedPrivs.toString()); + row.add(isGrantable); + result.add(row); + } + } + } + } + + Set<String> currentUserRole = null; + if (!isCurrentUserAdmin) { + currentUserRole = userRoleManager.getRolesByUser(currentUserIdentity, false); + currentUserRole = currentUserRole == null ? new HashSet<>() : currentUserRole; + } + roleManager.getRoleWorkloadGroupPrivs(result, currentUserRole); + } finally { + readUnlock(); + } + } + private ResourcePrivTable getUserCloudClusterPrivTable(UserIdentity userIdentity) { ResourcePrivTable table = new ResourcePrivTable(); Set<String> roles = userRoleManager.getRolesByUser(userIdentity); diff --git a/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/RoleManager.java b/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/RoleManager.java index 93bd7f72fdc..6b215982c7d 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/RoleManager.java +++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/RoleManager.java @@ -37,6 +37,7 @@ import org.apache.doris.persist.gson.GsonUtils; import org.apache.doris.qe.ConnectContext; import org.apache.doris.resource.workloadgroup.WorkloadGroupMgr; +import com.aliyuncs.utils.StringUtils; import com.google.common.base.Joiner; import com.google.common.base.Strings; import com.google.common.collect.Lists; @@ -211,6 +212,31 @@ public class RoleManager implements Writable, GsonPostProcessable { } } + public void getRoleWorkloadGroupPrivs(List<List<String>> result, Set<String> limitedRole) { + for (Role role : roles.values()) { + if (ClusterNamespace.getNameFromFullName(role.getRoleName()).startsWith(DEFAULT_ROLE_PREFIX)) { + continue; + } + + if (limitedRole != null && !limitedRole.contains(role.getRoleName())) { + continue; + } + String isGrantable = role.checkGlobalPriv(PrivPredicate.ADMIN) ? "YES" : "NO"; + + for (Map.Entry<WorkloadGroupPattern, PrivBitSet> entry : role.getWorkloadGroupPatternToPrivs().entrySet()) { + List<String> row = Lists.newArrayList(); + row.add(role.getRoleName()); + row.add(entry.getKey().getworkloadGroupName()); + if (StringUtils.isEmpty(entry.getValue().toString())) { + continue; + } + row.add(entry.getValue().toString()); + row.add(isGrantable); + result.add(row); + } + } + } + public Role createDefaultRole(UserIdentity userIdent) throws DdlException { String userDefaultRoleName = getUserDefaultRoleName(userIdent); if (roles.containsKey(userDefaultRoleName)) { diff --git a/fe/fe-core/src/main/java/org/apache/doris/tablefunction/MetadataGenerator.java b/fe/fe-core/src/main/java/org/apache/doris/tablefunction/MetadataGenerator.java index 2f27b020cd8..b446cd4210a 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/tablefunction/MetadataGenerator.java +++ b/fe/fe-core/src/main/java/org/apache/doris/tablefunction/MetadataGenerator.java @@ -113,6 +113,8 @@ public class MetadataGenerator { private static final ImmutableMap<String, Integer> TABLE_OPTIONS_COLUMN_TO_INDEX; + private static final ImmutableMap<String, Integer> WORKLOAD_GROUP_PRIVILEGES_COLUMN_TO_INDEX; + static { ImmutableMap.Builder<String, Integer> activeQueriesbuilder = new ImmutableMap.Builder(); List<Column> activeQueriesColList = SchemaTable.TABLE_MAP.get("active_queries").getFullSchema(); @@ -146,6 +148,13 @@ public class MetadataGenerator { optionBuilder.put(optionColList.get(i).getName().toLowerCase(), i); } TABLE_OPTIONS_COLUMN_TO_INDEX = optionBuilder.build(); + + ImmutableMap.Builder<String, Integer> wgPrivsBuilder = new ImmutableMap.Builder(); + List<Column> wgPrivsColList = SchemaTable.TABLE_MAP.get("workload_group_privileges").getFullSchema(); + for (int i = 0; i < wgPrivsColList.size(); i++) { + wgPrivsBuilder.put(wgPrivsColList.get(i).getName().toLowerCase(), i); + } + WORKLOAD_GROUP_PRIVILEGES_COLUMN_TO_INDEX = wgPrivsBuilder.build(); } public static TFetchSchemaTableDataResult getMetadataTable(TFetchSchemaTableDataRequest request) throws TException { @@ -229,6 +238,10 @@ public class MetadataGenerator { result = tableOptionsMetadataResult(schemaTableParams); columnIndex = TABLE_OPTIONS_COLUMN_TO_INDEX; break; + case WORKLOAD_GROUP_PRIVILEGES: + result = workloadGroupPrivsMetadataResult(schemaTableParams); + columnIndex = WORKLOAD_GROUP_PRIVILEGES_COLUMN_TO_INDEX; + break; default: return errorResult("invalid schema table name."); } @@ -537,6 +550,30 @@ public class MetadataGenerator { return result; } + private static TFetchSchemaTableDataResult workloadGroupPrivsMetadataResult(TSchemaTableRequestParams params) { + if (!params.isSetCurrentUserIdent()) { + return errorResult("current user ident is not set."); + } + UserIdentity currentUserIdentity = UserIdentity.fromThrift(params.getCurrentUserIdent()); + + List<List<String>> rows = new ArrayList<>(); + Env.getCurrentEnv().getAuth().getUserRoleWorkloadGroupPrivs(rows, currentUserIdentity); + List<TRow> dataBatch = Lists.newArrayList(); + for (List<String> privRow : rows) { + TRow trow = new TRow(); + String workloadGroupName = privRow.get(1); + trow.addToColumnValue(new TCell().setStringVal(privRow.get(0))); // GRANTEE + trow.addToColumnValue(new TCell().setStringVal(workloadGroupName)); // WORKLOAD_GROUP_NAME + trow.addToColumnValue(new TCell().setStringVal(privRow.get(2))); // PRIVILEGE_TYPE + trow.addToColumnValue(new TCell().setStringVal(privRow.get(3))); // IS_GRANTABLE + dataBatch.add(trow); + } + TFetchSchemaTableDataResult result = new TFetchSchemaTableDataResult(); + result.setDataBatch(dataBatch); + result.setStatus(new TStatus(TStatusCode.OK)); + return result; + } + private static TFetchSchemaTableDataResult queriesMetadataResult(TSchemaTableRequestParams tSchemaTableParams, TFetchSchemaTableDataRequest parentRequest) { TFetchSchemaTableDataResult result = new TFetchSchemaTableDataResult(); diff --git a/gensrc/thrift/Descriptors.thrift b/gensrc/thrift/Descriptors.thrift index cb844c93361..20042adc42e 100644 --- a/gensrc/thrift/Descriptors.thrift +++ b/gensrc/thrift/Descriptors.thrift @@ -133,7 +133,8 @@ enum TSchemaTableType { SCH_USER, SCH_PROCS_PRIV, SCH_WORKLOAD_POLICY, - SCH_TABLE_OPTIONS; + SCH_TABLE_OPTIONS, + SCH_WORKLOAD_GROUP_PRIVILEGES; } enum THdfsCompression { diff --git a/gensrc/thrift/FrontendService.thrift b/gensrc/thrift/FrontendService.thrift index 7986c4f7cc6..07ed2c37369 100644 --- a/gensrc/thrift/FrontendService.thrift +++ b/gensrc/thrift/FrontendService.thrift @@ -1002,6 +1002,7 @@ enum TSchemaTableName { ROUTINES_INFO = 4, // db information_schema's table WORKLOAD_SCHEDULE_POLICY = 5, TABLE_OPTIONS = 6, + WORKLOAD_GROUP_PRIVILEGES = 7, } struct TMetadataTableRequestParams { diff --git a/regression-test/data/external_table_p0/jdbc/test_mariadb_jdbc_catalog.out b/regression-test/data/external_table_p0/jdbc/test_mariadb_jdbc_catalog.out index 0eb3e6ed9eb..c828848a8fa 100644 --- a/regression-test/data/external_table_p0/jdbc/test_mariadb_jdbc_catalog.out +++ b/regression-test/data/external_table_p0/jdbc/test_mariadb_jdbc_catalog.out @@ -59,6 +59,7 @@ tables triggers user_privileges views +workload_group_privileges workload_groups workload_policy diff --git a/regression-test/data/external_table_p0/jdbc/test_mysql_jdbc_catalog.out b/regression-test/data/external_table_p0/jdbc/test_mysql_jdbc_catalog.out index e79545774a1..ee5cb342440 100644 --- a/regression-test/data/external_table_p0/jdbc/test_mysql_jdbc_catalog.out +++ b/regression-test/data/external_table_p0/jdbc/test_mysql_jdbc_catalog.out @@ -223,6 +223,7 @@ tables triggers user_privileges views +workload_group_privileges workload_groups workload_policy diff --git a/regression-test/data/external_table_p0/jdbc/test_mysql_jdbc_catalog_nereids.out b/regression-test/data/external_table_p0/jdbc/test_mysql_jdbc_catalog_nereids.out index fb9bf51ad93..0d7e953567f 100644 --- a/regression-test/data/external_table_p0/jdbc/test_mysql_jdbc_catalog_nereids.out +++ b/regression-test/data/external_table_p0/jdbc/test_mysql_jdbc_catalog_nereids.out @@ -191,6 +191,7 @@ tables triggers user_privileges views +workload_group_privileges workload_groups workload_policy diff --git a/regression-test/data/external_table_p0/jdbc/test_mysql_jdbc_driver5_catalog.out b/regression-test/data/external_table_p0/jdbc/test_mysql_jdbc_driver5_catalog.out index 7e16cadc3c7..953b425394c 100644 --- a/regression-test/data/external_table_p0/jdbc/test_mysql_jdbc_driver5_catalog.out +++ b/regression-test/data/external_table_p0/jdbc/test_mysql_jdbc_driver5_catalog.out @@ -233,6 +233,7 @@ tables triggers user_privileges views +workload_group_privileges workload_groups workload_policy diff --git a/regression-test/data/workload_manager_p0/test_curd_wlg.out b/regression-test/data/workload_manager_p0/test_curd_wlg.out index 92de73f3278..5d9629aa440 100644 --- a/regression-test/data/workload_manager_p0/test_curd_wlg.out +++ b/regression-test/data/workload_manager_p0/test_curd_wlg.out @@ -97,3 +97,52 @@ tag1_wg3 0% 80% tag1 -- !select_remote_scan_num_8 -- -1 -1 +-- !select_wgp_1 -- +'test_wg_priv_user1'@'%' normal Usage_priv NO + +-- !select_wgp_2 -- +'test_wg_priv_user1'@'%' normal Usage_priv NO +'test_wg_priv_user1'@'%' test_wg_priv_g1 Usage_priv NO + +-- !select_wgp_3 -- +'test_wg_priv_user1'@'%' normal Usage_priv NO + +-- !select_wgp_4 -- +'test_wg_priv_user1'@'%' normal Usage_priv NO +'test_wg_priv_user1'@'%' test_wg_priv_g1 Usage_priv NO + +-- !select_wgp_5 -- +'test_wg_priv_user1'@'%' normal Usage_priv NO +'test_wg_priv_user1'@'%' test_wg_priv_g1 Usage_priv NO + +-- !select_wgp_6 -- +'test_wg_priv_user1'@'%' normal Usage_priv NO +'test_wg_priv_user1'@'%' test_wg_priv_g1 Usage_priv NO +test_wg_priv_role1 test_wg_priv_g1 Usage_priv NO + +-- !select_wgp_7 -- +'test_wg_priv_user1'@'%' normal Usage_priv NO +'test_wg_priv_user1'@'%' test_wg_priv_g1 Usage_priv NO + +-- !select_wgp_8 -- +'test_wg_priv_user1'@'%' normal Usage_priv NO +'test_wg_priv_user1'@'%' test_wg_priv_g1 Usage_priv NO +test_wg_priv_role1 test_wg_priv_g1 Usage_priv NO + +-- !select_wgp_9 -- +'test_wg_priv_user1'@'%' % Usage_priv NO +'test_wg_priv_user1'@'%' normal Usage_priv NO +'test_wg_priv_user1'@'%' test_wg_priv_g1 Usage_priv NO +test_wg_priv_role1 % Usage_priv NO +test_wg_priv_role1 test_wg_priv_g1 Usage_priv NO + +-- !select_wgp_10 -- +'test_wg_priv_user1'@'%' normal Usage_priv NO +'test_wg_priv_user1'@'%' test_wg_priv_g1 Usage_priv NO +test_wg_priv_role1 test_wg_priv_g1 Usage_priv NO + +-- !select_wgp_11 -- +'test_wg_priv_user2'@'%' normal Usage_priv NO + +-- !select_wgp_12 -- + diff --git a/regression-test/suites/workload_manager_p0/test_curd_wlg.groovy b/regression-test/suites/workload_manager_p0/test_curd_wlg.groovy index 0aa60af7fbd..76721728bf2 100644 --- a/regression-test/suites/workload_manager_p0/test_curd_wlg.groovy +++ b/regression-test/suites/workload_manager_p0/test_curd_wlg.groovy @@ -94,6 +94,7 @@ suite("test_crud_wlg") { sql "alter workload group normal properties ( 'scan_thread_num'='-1' );" sql "alter workload group normal properties ( 'scan_thread_num'='-1' );" sql "alter workload group normal properties ( 'remote_read_bytes_per_second'='-1' );" + sql "alter workload group normal properties ( 'read_bytes_per_second'='-1' );" sql "set workload_group=normal;" @@ -640,4 +641,61 @@ suite("test_crud_wlg") { sql "drop workload group tag1_mem_wg3;" sql "drop workload group bypass_group;" + // test workload group privilege table + sql "set workload_group=normal;" + sql "drop user if exists test_wg_priv_user1" + sql "drop user if exists test_wg_priv_user2" + sql "drop role if exists test_wg_priv_role1" + sql "drop workload group if exists test_wg_priv_g1;" + // 1 test grant user + sql "create workload group test_wg_priv_g1 properties('cpu_share'='1024')" + + sql "create user test_wg_priv_user1" + qt_select_wgp_1 "select GRANTEE,WORKLOAD_GROUP_NAME,PRIVILEGE_TYPE,IS_GRANTABLE from information_schema.workload_group_privileges where grantee like '%test_wg_priv%' order by GRANTEE,WORKLOAD_GROUP_NAME,PRIVILEGE_TYPE,IS_GRANTABLE; " + + sql "GRANT USAGE_PRIV ON WORKLOAD GROUP 'test_wg_priv_g1' TO test_wg_priv_user1;" + qt_select_wgp_2 "select GRANTEE,WORKLOAD_GROUP_NAME,PRIVILEGE_TYPE,IS_GRANTABLE from information_schema.workload_group_privileges where grantee like '%test_wg_priv%' order by GRANTEE,WORKLOAD_GROUP_NAME,PRIVILEGE_TYPE,IS_GRANTABLE; " + + sql "revoke USAGE_PRIV ON WORKLOAD GROUP 'test_wg_priv_g1' from test_wg_priv_user1;" + qt_select_wgp_3 "select GRANTEE,WORKLOAD_GROUP_NAME,PRIVILEGE_TYPE,IS_GRANTABLE from information_schema.workload_group_privileges where grantee like '%test_wg_priv%' order by GRANTEE,WORKLOAD_GROUP_NAME,PRIVILEGE_TYPE,IS_GRANTABLE; " + + sql "GRANT USAGE_PRIV ON WORKLOAD GROUP 'test_wg_priv_g1' TO test_wg_priv_user1;" + qt_select_wgp_4 "select GRANTEE,WORKLOAD_GROUP_NAME,PRIVILEGE_TYPE,IS_GRANTABLE from information_schema.workload_group_privileges where grantee like '%test_wg_priv%' order by GRANTEE,WORKLOAD_GROUP_NAME,PRIVILEGE_TYPE,IS_GRANTABLE; " + + + + // 2 test grant role + sql "create role test_wg_priv_role1;" + qt_select_wgp_5 "select GRANTEE,WORKLOAD_GROUP_NAME,PRIVILEGE_TYPE,IS_GRANTABLE from information_schema.workload_group_privileges where grantee like '%test_wg_priv%' order by GRANTEE,WORKLOAD_GROUP_NAME,PRIVILEGE_TYPE,IS_GRANTABLE; " + + sql "GRANT USAGE_PRIV ON WORKLOAD GROUP 'test_wg_priv_g1' TO role 'test_wg_priv_role1';" + qt_select_wgp_6 "select GRANTEE,WORKLOAD_GROUP_NAME,PRIVILEGE_TYPE,IS_GRANTABLE from information_schema.workload_group_privileges where grantee like '%test_wg_priv%' order by GRANTEE,WORKLOAD_GROUP_NAME,PRIVILEGE_TYPE,IS_GRANTABLE; " + + sql "revoke USAGE_PRIV ON WORKLOAD GROUP 'test_wg_priv_g1' from role 'test_wg_priv_role1';" + qt_select_wgp_7 "select GRANTEE,WORKLOAD_GROUP_NAME,PRIVILEGE_TYPE,IS_GRANTABLE from information_schema.workload_group_privileges where grantee like '%test_wg_priv%' order by GRANTEE,WORKLOAD_GROUP_NAME,PRIVILEGE_TYPE,IS_GRANTABLE; " + + sql "GRANT USAGE_PRIV ON WORKLOAD GROUP 'test_wg_priv_g1' TO role 'test_wg_priv_role1';" + qt_select_wgp_8 "select GRANTEE,WORKLOAD_GROUP_NAME,PRIVILEGE_TYPE,IS_GRANTABLE from information_schema.workload_group_privileges where grantee like '%test_wg_priv%' order by GRANTEE,WORKLOAD_GROUP_NAME,PRIVILEGE_TYPE,IS_GRANTABLE; " + + // 3 test grant % + sql "GRANT USAGE_PRIV ON WORKLOAD GROUP '%' TO test_wg_priv_user1; " + sql "GRANT USAGE_PRIV ON WORKLOAD GROUP '%' TO role 'test_wg_priv_role1'; " + qt_select_wgp_9 "select GRANTEE,WORKLOAD_GROUP_NAME,PRIVILEGE_TYPE,IS_GRANTABLE from information_schema.workload_group_privileges where grantee like '%test_wg_priv%' order by GRANTEE,WORKLOAD_GROUP_NAME,PRIVILEGE_TYPE,IS_GRANTABLE; " + sql "revoke USAGE_PRIV ON WORKLOAD GROUP '%' from test_wg_priv_user1; " + sql "revoke USAGE_PRIV ON WORKLOAD GROUP '%' from role 'test_wg_priv_role1'; " + qt_select_wgp_10 "select GRANTEE,WORKLOAD_GROUP_NAME,PRIVILEGE_TYPE,IS_GRANTABLE from information_schema.workload_group_privileges where grantee like '%test_wg_priv%' order by GRANTEE,WORKLOAD_GROUP_NAME,PRIVILEGE_TYPE,IS_GRANTABLE; " + + //4 test row filter + sql "create user test_wg_priv_user2" + sql "grant SELECT_PRIV on *.*.* to test_wg_priv_user2" + connect(user = 'test_wg_priv_user2', password = '', url = context.config.jdbcUrl) { + qt_select_wgp_11 "select GRANTEE,WORKLOAD_GROUP_NAME,PRIVILEGE_TYPE,IS_GRANTABLE from information_schema.workload_group_privileges where grantee like '%test_wg_priv%' order by GRANTEE,WORKLOAD_GROUP_NAME,PRIVILEGE_TYPE,IS_GRANTABLE; " + } + + sql "drop user test_wg_priv_user1" + sql "drop user test_wg_priv_user2" + sql "drop role test_wg_priv_role1" + qt_select_wgp_12 "select GRANTEE,WORKLOAD_GROUP_NAME,PRIVILEGE_TYPE,IS_GRANTABLE from information_schema.workload_group_privileges where grantee like '%test_wg_priv%' order by GRANTEE,WORKLOAD_GROUP_NAME,PRIVILEGE_TYPE,IS_GRANTABLE; " + sql "drop workload group test_wg_priv_g1" + } --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org