From e4fff3f2f960cf6c989b8d272880e384f427b7d8 Mon Sep 17 00:00:00 2001 From: luozenglin Date: Fri, 13 Nov 2020 16:55:38 +0800 Subject: [PATCH 1/3] Added #4897: Add table_privileges, schema_privileges and user_privileges table in information_schema database. --- be/src/exec/CMakeLists.txt | 4 + be/src/exec/schema_scanner.cpp | 11 ++ be/src/exec/schema_scanner/schema_helper.cpp | 33 ++++ be/src/exec/schema_scanner/schema_helper.h | 18 ++ .../schema_schema_privileges_scanner.cpp | 164 ++++++++++++++++ .../schema_schema_privileges_scanner.h | 45 +++++ .../schema_table_privileges_scanner.cpp | 176 ++++++++++++++++++ .../schema_table_privileges_scanner.h | 45 +++++ .../schema_user_privileges_scanner.cpp | 150 +++++++++++++++ .../schema_user_privileges_scanner.h | 45 +++++ .../org/apache/doris/catalog/SchemaTable.java | 27 ++- .../doris/mysql/privilege/PaloAuth.java | 115 ++++++++++++ .../doris/mysql/privilege/PrivTable.java | 4 + .../doris/service/FrontendServiceImpl.java | 53 ++++++ gensrc/thrift/FrontendService.thrift | 15 ++ 15 files changed, 902 insertions(+), 3 deletions(-) create mode 100644 be/src/exec/schema_scanner/schema_schema_privileges_scanner.cpp create mode 100644 be/src/exec/schema_scanner/schema_schema_privileges_scanner.h create mode 100644 be/src/exec/schema_scanner/schema_table_privileges_scanner.cpp create mode 100644 be/src/exec/schema_scanner/schema_table_privileges_scanner.h create mode 100644 be/src/exec/schema_scanner/schema_user_privileges_scanner.cpp create mode 100644 be/src/exec/schema_scanner/schema_user_privileges_scanner.h diff --git a/be/src/exec/CMakeLists.txt b/be/src/exec/CMakeLists.txt index 044f82d507c370..5bf54673cb144d 100644 --- a/be/src/exec/CMakeLists.txt +++ b/be/src/exec/CMakeLists.txt @@ -85,6 +85,10 @@ set(EXEC_FILES schema_scanner/schema_collations_scanner.cpp schema_scanner/schema_helper.cpp schema_scanner/schema_views_scanner.cpp + schema_scanner/schema_table_privileges_scanner.cpp + schema_scanner/schema_schema_privileges_scanner.cpp + schema_scanner/schema_user_privileges_scanner.cpp + partitioned_hash_table.cc partitioned_hash_table_ir.cc partitioned_aggregation_node.cc diff --git a/be/src/exec/schema_scanner.cpp b/be/src/exec/schema_scanner.cpp index 4c25f9c0c0dfbd..f9d4e833738b43 100644 --- a/be/src/exec/schema_scanner.cpp +++ b/be/src/exec/schema_scanner.cpp @@ -24,6 +24,11 @@ #include "exec/schema_scanner/schema_charsets_scanner.h" #include "exec/schema_scanner/schema_collations_scanner.h" #include "exec/schema_scanner/schema_views_scanner.h" +#include "exec/schema_scanner/schema_table_privileges_scanner.h" +#include "exec/schema_scanner/schema_schema_privileges_scanner.h" +#include "exec/schema_scanner/schema_user_privileges_scanner.h" + + namespace doris { @@ -96,6 +101,12 @@ SchemaScanner* SchemaScanner::create(TSchemaTableType::type type) { return new(std::nothrow) SchemaVariablesScanner(TVarType::SESSION); case TSchemaTableType::SCH_VIEWS: return new(std::nothrow) SchemaViewsScanner(); + case TSchemaTableType::SCH_TABLE_PRIVILEGES: + return new(std::nothrow) SchemaTablePrivilegesScanner(); + case TSchemaTableType::SCH_SCHEMA_PRIVILEGES: + return new(std::nothrow) SchemaSchemaPrivilegesScanner(); + case TSchemaTableType::SCH_USER_PRIVILEGES: + return new(std::nothrow) SchemaUserPrivilegesScanner(); default: return new(std::nothrow) SchemaDummyScanner(); break; diff --git a/be/src/exec/schema_scanner/schema_helper.cpp b/be/src/exec/schema_scanner/schema_helper.cpp index edd03d3746a3ab..f35063fcb20d2a 100644 --- a/be/src/exec/schema_scanner/schema_helper.cpp +++ b/be/src/exec/schema_scanner/schema_helper.cpp @@ -98,6 +98,39 @@ Status SchemaHelper::show_variables( }); } +Status SchemaHelper::list_table_privilege_status( + const std::string& ip, + const int32_t port, + const TGetTablesParams &request, + TListPrivilegesResult *result) { + return ThriftRpcHelper::rpc(ip, port, + [&request, &result] (FrontendServiceConnection& client) { + client->listTablePrivilegeStatus(*result, request); + }); +} + +Status SchemaHelper::list_schema_privilege_status( + const std::string& ip, + const int32_t port, + const TGetTablesParams &request, + TListPrivilegesResult *result) { + return ThriftRpcHelper::rpc(ip, port, + [&request, &result] (FrontendServiceConnection& client) { + client->listSchemaPrivilegeStatus(*result, request); + }); +} + +Status SchemaHelper::list_user_privilege_status( + const std::string& ip, + const int32_t port, + const TGetTablesParams &request, + TListPrivilegesResult *result) { + return ThriftRpcHelper::rpc(ip, port, + [&request, &result] (FrontendServiceConnection& client) { + client->listUserPrivilegeStatus(*result, request); + }); +} + std::string SchemaHelper::extract_db_name(const std::string& full_name) { auto found = full_name.find(':'); if (found == std::string::npos) { diff --git a/be/src/exec/schema_scanner/schema_helper.h b/be/src/exec/schema_scanner/schema_helper.h index 964329dd0a5d1a..b9e7ed9a0c8b67 100644 --- a/be/src/exec/schema_scanner/schema_helper.h +++ b/be/src/exec/schema_scanner/schema_helper.h @@ -55,6 +55,24 @@ class SchemaHelper { const TShowVariableRequest &var_params, TShowVariableResult *var_result); + static Status list_table_privilege_status( + const std::string& ip, + const int32_t port, + const TGetTablesParams &table_params, + TListPrivilegesResult *privileges_result); + + static Status list_schema_privilege_status( + const std::string& ip, + const int32_t port, + const TGetTablesParams &table_params, + TListPrivilegesResult *privileges_result); + + static Status list_user_privilege_status( + const std::string& ip, + const int32_t port, + const TGetTablesParams &table_params, + TListPrivilegesResult *privileges_result); + static std::string extract_db_name(const std::string& full_name); }; diff --git a/be/src/exec/schema_scanner/schema_schema_privileges_scanner.cpp b/be/src/exec/schema_scanner/schema_schema_privileges_scanner.cpp new file mode 100644 index 00000000000000..2a3ce52bcb5bef --- /dev/null +++ b/be/src/exec/schema_scanner/schema_schema_privileges_scanner.cpp @@ -0,0 +1,164 @@ +// 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_helper.h" +#include "exec/schema_scanner/schema_schema_privileges_scanner.h" +#include "runtime/primitive_type.h" +#include "runtime/string_value.h" +//#include "runtime/datetime_value.h" + +namespace doris +{ + +SchemaScanner::ColumnDesc SchemaSchemaPrivilegesScanner::_s_tbls_columns[] = { + // name, type, size, is_null + { "GRANTEE", TYPE_VARCHAR, sizeof(StringValue), true}, + { "TABLE_CATALOG", TYPE_VARCHAR, sizeof(StringValue), true}, + { "TABLE_SCHEMA", TYPE_VARCHAR, sizeof(StringValue), false}, + { "PRIVILEGE_TYPE", TYPE_VARCHAR, sizeof(StringValue), false}, + { "IS_GRANTABLE", TYPE_VARCHAR, sizeof(StringValue), true}, +}; + +SchemaSchemaPrivilegesScanner::SchemaSchemaPrivilegesScanner() + : SchemaScanner(_s_tbls_columns, + sizeof(_s_tbls_columns) / sizeof(SchemaScanner::ColumnDesc)), + _priv_index(0) { +} + +SchemaSchemaPrivilegesScanner::~SchemaSchemaPrivilegesScanner() { +} + +Status SchemaSchemaPrivilegesScanner::start(RuntimeState *state) { + if (!_is_init) { + return Status::InternalError("used before initialized."); + } + RETURN_IF_ERROR(get_new_table()); + return Status::OK(); +} + +Status SchemaSchemaPrivilegesScanner::fill_one_row(Tuple *tuple, MemPool *pool) { + // set all bit to not null + memset((void *)tuple, 0, _tuple_desc->num_null_bytes()); + const TPrivilegeStatus& tbl_priv_status = _priv_result.privileges[_priv_index]; + // grantee + { + void *slot = tuple->get_slot(_tuple_desc->slots()[0]->tuple_offset()); + StringValue* str_slot = reinterpret_cast(slot); + const std::string* src = &tbl_priv_status.grantee; + str_slot->len = src->length(); + str_slot->ptr = (char *)pool->allocate(str_slot->len); + if (NULL == str_slot->ptr) { + return Status::InternalError("Allocate memcpy failed."); + } + memcpy(str_slot->ptr, src->c_str(), str_slot->len); + } + // catalog + //This value is always def. + { + void *slot = tuple->get_slot(_tuple_desc->slots()[1]->tuple_offset()); + StringValue* str_slot = reinterpret_cast(slot); + const std::string definer = "def"; + str_slot->len = definer.length(); + str_slot->ptr = (char *)pool->allocate(str_slot->len); + if (NULL == str_slot->ptr) { + return Status::InternalError("Allocate memcpy failed."); + } + memcpy(str_slot->ptr, definer.c_str(), str_slot->len); + } + // schema + { + void *slot = tuple->get_slot(_tuple_desc->slots()[2]->tuple_offset()); + StringValue* str_slot = reinterpret_cast(slot); + const std::string* src = &tbl_priv_status.schema; + str_slot->len = src->length(); + str_slot->ptr = (char *)pool->allocate(str_slot->len); + if (NULL == str_slot->ptr) { + return Status::InternalError("Allocate memcpy failed."); + } + memcpy(str_slot->ptr, src->c_str(), str_slot->len); + } + // privilege type + { + void *slot = tuple->get_slot(_tuple_desc->slots()[3]->tuple_offset()); + StringValue* str_slot = reinterpret_cast(slot); + const std::string* src = &tbl_priv_status.privilege_type; + str_slot->len = src->length(); + str_slot->ptr = (char *)pool->allocate(str_slot->len); + if (NULL == str_slot->ptr) { + return Status::InternalError("Allocate memcpy failed."); + } + memcpy(str_slot->ptr, src->c_str(), str_slot->len); + } + // is grantable + { + void *slot = tuple->get_slot(_tuple_desc->slots()[4]->tuple_offset()); + StringValue* str_slot = reinterpret_cast(slot); + const std::string* src = &tbl_priv_status.is_grantable; + str_slot->len = src->length(); + str_slot->ptr = (char *)pool->allocate(str_slot->len); + if (NULL == str_slot->ptr) { + return Status::InternalError("Allocate memcpy failed."); + } + memcpy(str_slot->ptr, src->c_str(), str_slot->len); + } + _priv_index++; + return Status::OK(); +} + + +Status SchemaSchemaPrivilegesScanner::get_new_table() { + TGetTablesParams table_params; + if (NULL != _param->wild) { + table_params.__set_pattern(*(_param->wild)); + } + if (NULL != _param->current_user_ident) { + table_params.__set_current_user_ident(*(_param->current_user_ident)); + } else { + if (NULL != _param->user) { + table_params.__set_user(*(_param->user)); + } + if (NULL != _param->user_ip) { + table_params.__set_user_ip(*(_param->user_ip)); + } + } + + if (NULL != _param->ip && 0 != _param->port) { + RETURN_IF_ERROR(SchemaHelper::list_schema_privilege_status(*(_param->ip), + _param->port, table_params, &_priv_result)); + } else { + return Status::InternalError("IP or port doesn't exists"); + } + _priv_index = 0; + return Status::OK(); +} + +Status SchemaSchemaPrivilegesScanner::get_next_row(Tuple *tuple, MemPool *pool, bool *eos) { + if (!_is_init) { + return Status::InternalError("Used before initialized."); + } + if (NULL == tuple || NULL == pool || NULL == eos) { + return Status::InternalError("input pointer is NULL."); + } + if (_priv_index >= _priv_result.privileges.size()) { + *eos = true; + return Status::OK(); + } + *eos = false; + return fill_one_row(tuple, pool); +} + +} \ No newline at end of file diff --git a/be/src/exec/schema_scanner/schema_schema_privileges_scanner.h b/be/src/exec/schema_scanner/schema_schema_privileges_scanner.h new file mode 100644 index 00000000000000..8d7c386b1fd114 --- /dev/null +++ b/be/src/exec/schema_scanner/schema_schema_privileges_scanner.h @@ -0,0 +1,45 @@ +// 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. + +#ifndef DORIS_BE_SRC_QUERY_EXEC_SCHEMA_SCANNER_SCHEMA_SCHEMA_PRIVILEGES_SCANNER_H +#define DORIS_BE_SRC_QUERY_EXEC_SCHEMA_SCANNER_SCHEMA_SCHEMA_PRIVILEGES_SCANNER_H + +#include "exec/schema_scanner.h" +#include "gen_cpp/FrontendService_types.h" + +namespace doris { + +class SchemaSchemaPrivilegesScanner : public SchemaScanner { +public: + SchemaSchemaPrivilegesScanner(); + virtual ~SchemaSchemaPrivilegesScanner(); + + virtual Status start(RuntimeState *state); + virtual Status get_next_row(Tuple *tuple, MemPool *pool, bool *eos); + +private: + Status get_new_table(); + Status fill_one_row(Tuple *tuple, MemPool *pool); + + int _priv_index; + TListPrivilegesResult _priv_result; + static SchemaScanner::ColumnDesc _s_tbls_columns[]; +}; + +} + +#endif diff --git a/be/src/exec/schema_scanner/schema_table_privileges_scanner.cpp b/be/src/exec/schema_scanner/schema_table_privileges_scanner.cpp new file mode 100644 index 00000000000000..d41a32a640fa61 --- /dev/null +++ b/be/src/exec/schema_scanner/schema_table_privileges_scanner.cpp @@ -0,0 +1,176 @@ +// 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_helper.h" +#include "exec/schema_scanner/schema_table_privileges_scanner.h" +#include "runtime/primitive_type.h" +#include "runtime/string_value.h" +//#include "runtime/datetime_value.h" + +namespace doris +{ + +SchemaScanner::ColumnDesc SchemaTablePrivilegesScanner::_s_tbls_columns[] = { + // name, type, size, is_null + { "GRANTEE", TYPE_VARCHAR, sizeof(StringValue), true}, + { "TABLE_CATALOG", TYPE_VARCHAR, sizeof(StringValue), true}, + { "TABLE_SCHEMA", TYPE_VARCHAR, sizeof(StringValue), false}, + { "TABLE_NAME", TYPE_VARCHAR, sizeof(StringValue), false}, + { "PRIVILEGE_TYPE", TYPE_VARCHAR, sizeof(StringValue), false}, + { "IS_GRANTABLE", TYPE_VARCHAR, sizeof(StringValue), true}, +}; + +SchemaTablePrivilegesScanner::SchemaTablePrivilegesScanner() + : SchemaScanner(_s_tbls_columns, + sizeof(_s_tbls_columns) / sizeof(SchemaScanner::ColumnDesc)), + _priv_index(0) { +} + +SchemaTablePrivilegesScanner::~SchemaTablePrivilegesScanner() { +} + +Status SchemaTablePrivilegesScanner::start(RuntimeState *state) { + if (!_is_init) { + return Status::InternalError("used before initialized."); + } + RETURN_IF_ERROR(get_new_table()); + return Status::OK(); +} + +Status SchemaTablePrivilegesScanner::fill_one_row(Tuple *tuple, MemPool *pool) { + // set all bit to not null + memset((void *)tuple, 0, _tuple_desc->num_null_bytes()); + const TPrivilegeStatus& tbl_priv_status = _priv_result.privileges[_priv_index]; + // grantee + { + void *slot = tuple->get_slot(_tuple_desc->slots()[0]->tuple_offset()); + StringValue* str_slot = reinterpret_cast(slot); + const std::string* src = &tbl_priv_status.grantee; + str_slot->len = src->length(); + str_slot->ptr = (char *)pool->allocate(str_slot->len); + if (NULL == str_slot->ptr) { + return Status::InternalError("Allocate memcpy failed."); + } + memcpy(str_slot->ptr, src->c_str(), str_slot->len); + } + // catalog + //This value is always def. + { + void *slot = tuple->get_slot(_tuple_desc->slots()[1]->tuple_offset()); + StringValue* str_slot = reinterpret_cast(slot); + const std::string definer = "def"; + str_slot->len = definer.length(); + str_slot->ptr = (char *)pool->allocate(str_slot->len); + if (NULL == str_slot->ptr) { + return Status::InternalError("Allocate memcpy failed."); + } + memcpy(str_slot->ptr, definer.c_str(), str_slot->len); + } + // schema + { + void *slot = tuple->get_slot(_tuple_desc->slots()[2]->tuple_offset()); + StringValue* str_slot = reinterpret_cast(slot); + const std::string* src = &tbl_priv_status.schema; + str_slot->len = src->length(); + str_slot->ptr = (char *)pool->allocate(str_slot->len); + if (NULL == str_slot->ptr) { + return Status::InternalError("Allocate memcpy failed."); + } + memcpy(str_slot->ptr, src->c_str(), str_slot->len); + } + // table name + { + void *slot = tuple->get_slot(_tuple_desc->slots()[3]->tuple_offset()); + StringValue* str_slot = reinterpret_cast(slot); + const std::string* src = &tbl_priv_status.table_name; + str_slot->len = src->length(); + str_slot->ptr = (char *)pool->allocate(str_slot->len); + if (NULL == str_slot->ptr) { + return Status::InternalError("Allocate memcpy failed."); + } + memcpy(str_slot->ptr, src->c_str(), str_slot->len); + } + // privilege type + { + void *slot = tuple->get_slot(_tuple_desc->slots()[4]->tuple_offset()); + StringValue* str_slot = reinterpret_cast(slot); + const std::string* src = &tbl_priv_status.privilege_type; + str_slot->len = src->length(); + str_slot->ptr = (char *)pool->allocate(str_slot->len); + if (NULL == str_slot->ptr) { + return Status::InternalError("Allocate memcpy failed."); + } + memcpy(str_slot->ptr, src->c_str(), str_slot->len); + } + // is grantable + { + void *slot = tuple->get_slot(_tuple_desc->slots()[5]->tuple_offset()); + StringValue* str_slot = reinterpret_cast(slot); + const std::string* src = &tbl_priv_status.is_grantable; + str_slot->len = src->length(); + str_slot->ptr = (char *)pool->allocate(str_slot->len); + if (NULL == str_slot->ptr) { + return Status::InternalError("Allocate memcpy failed."); + } + memcpy(str_slot->ptr, src->c_str(), str_slot->len); + } + _priv_index++; + return Status::OK(); +} + +Status SchemaTablePrivilegesScanner::get_new_table() { + TGetTablesParams table_params; + if (NULL != _param->wild) { + table_params.__set_pattern(*(_param->wild)); + } + if (NULL != _param->current_user_ident) { + table_params.__set_current_user_ident(*(_param->current_user_ident)); + } else { + if (NULL != _param->user) { + table_params.__set_user(*(_param->user)); + } + if (NULL != _param->user_ip) { + table_params.__set_user_ip(*(_param->user_ip)); + } + } + + if (NULL != _param->ip && 0 != _param->port) { + RETURN_IF_ERROR(SchemaHelper::list_table_privilege_status(*(_param->ip), + _param->port, table_params, &_priv_result)); + } else { + return Status::InternalError("IP or port doesn't exists"); + } + _priv_index = 0; + return Status::OK(); +} + +Status SchemaTablePrivilegesScanner::get_next_row(Tuple *tuple, MemPool *pool, bool *eos) { + if (!_is_init) { + return Status::InternalError("Used before initialized."); + } + if (NULL == tuple || NULL == pool || NULL == eos) { + return Status::InternalError("input pointer is NULL."); + } + if (_priv_index >= _priv_result.privileges.size()) { + *eos = true; + return Status::OK(); + } + *eos = false; + return fill_one_row(tuple, pool); +} + +} \ No newline at end of file diff --git a/be/src/exec/schema_scanner/schema_table_privileges_scanner.h b/be/src/exec/schema_scanner/schema_table_privileges_scanner.h new file mode 100644 index 00000000000000..7ca7002f4d613a --- /dev/null +++ b/be/src/exec/schema_scanner/schema_table_privileges_scanner.h @@ -0,0 +1,45 @@ +// 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. + +#ifndef DORIS_BE_SRC_QUERY_EXEC_SCHEMA_SCANNER_SCHEMA_TABLE_PRIVILEGES_SCANNER_H +#define DORIS_BE_SRC_QUERY_EXEC_SCHEMA_SCANNER_SCHEMA_TABLE_PRIVILEGES_SCANNER_H + +#include "exec/schema_scanner.h" +#include "gen_cpp/FrontendService_types.h" + +namespace doris { + +class SchemaTablePrivilegesScanner : public SchemaScanner { +public: + SchemaTablePrivilegesScanner(); + virtual ~SchemaTablePrivilegesScanner(); + + virtual Status start(RuntimeState *state); + virtual Status get_next_row(Tuple *tuple, MemPool *pool, bool *eos); + +private: + Status get_new_table(); + Status fill_one_row(Tuple *tuple, MemPool *pool); + + int _priv_index; + TListPrivilegesResult _priv_result; + static SchemaScanner::ColumnDesc _s_tbls_columns[]; +}; + +} + +#endif diff --git a/be/src/exec/schema_scanner/schema_user_privileges_scanner.cpp b/be/src/exec/schema_scanner/schema_user_privileges_scanner.cpp new file mode 100644 index 00000000000000..8e63a1fb841cb9 --- /dev/null +++ b/be/src/exec/schema_scanner/schema_user_privileges_scanner.cpp @@ -0,0 +1,150 @@ +// 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_helper.h" +#include "exec/schema_scanner/schema_user_privileges_scanner.h" +#include "runtime/primitive_type.h" +#include "runtime/string_value.h" +//#include "runtime/datetime_value.h" + +namespace doris +{ + +SchemaScanner::ColumnDesc SchemaUserPrivilegesScanner::_s_tbls_columns[] = { + // name, type, size, is_null + { "GRANTEE", TYPE_VARCHAR, sizeof(StringValue), true}, + { "TABLE_CATALOG", TYPE_VARCHAR, sizeof(StringValue), true}, + { "PRIVILEGE_TYPE", TYPE_VARCHAR, sizeof(StringValue), false}, + { "IS_GRANTABLE", TYPE_VARCHAR, sizeof(StringValue), true}, +}; + +SchemaUserPrivilegesScanner::SchemaUserPrivilegesScanner() + : SchemaScanner(_s_tbls_columns, + sizeof(_s_tbls_columns) / sizeof(SchemaScanner::ColumnDesc)), + _priv_index(0) { +} + +SchemaUserPrivilegesScanner::~SchemaUserPrivilegesScanner() { +} + +Status SchemaUserPrivilegesScanner::start(RuntimeState *state) { + if (!_is_init) { + return Status::InternalError("used before initialized."); + } + RETURN_IF_ERROR(get_new_table()); + return Status::OK(); +} + +Status SchemaUserPrivilegesScanner::fill_one_row(Tuple *tuple, MemPool *pool) { + // set all bit to not null + memset((void *)tuple, 0, _tuple_desc->num_null_bytes()); + const TPrivilegeStatus& tbl_priv_status = _priv_result.privileges[_priv_index]; + // grantee + { + void *slot = tuple->get_slot(_tuple_desc->slots()[0]->tuple_offset()); + StringValue* str_slot = reinterpret_cast(slot); + const std::string* src = &tbl_priv_status.grantee; + str_slot->len = src->length(); + str_slot->ptr = (char *)pool->allocate(str_slot->len); + if (NULL == str_slot->ptr) { + return Status::InternalError("Allocate memcpy failed."); + } + memcpy(str_slot->ptr, src->c_str(), str_slot->len); + } + // catalog + //This value is always def. + { + void *slot = tuple->get_slot(_tuple_desc->slots()[1]->tuple_offset()); + StringValue* str_slot = reinterpret_cast(slot); + const std::string definer = "def"; + str_slot->len = definer.length(); + str_slot->ptr = (char *)pool->allocate(str_slot->len); + if (NULL == str_slot->ptr) { + return Status::InternalError("Allocate memcpy failed."); + } + memcpy(str_slot->ptr, definer.c_str(), str_slot->len); + } + // privilege type + { + void *slot = tuple->get_slot(_tuple_desc->slots()[2]->tuple_offset()); + StringValue* str_slot = reinterpret_cast(slot); + const std::string* src = &tbl_priv_status.privilege_type; + str_slot->len = src->length(); + str_slot->ptr = (char *)pool->allocate(str_slot->len); + if (NULL == str_slot->ptr) { + return Status::InternalError("Allocate memcpy failed."); + } + memcpy(str_slot->ptr, src->c_str(), str_slot->len); + } + // is grantable + { + void *slot = tuple->get_slot(_tuple_desc->slots()[3]->tuple_offset()); + StringValue* str_slot = reinterpret_cast(slot); + const std::string* src = &tbl_priv_status.is_grantable; + str_slot->len = src->length(); + str_slot->ptr = (char *)pool->allocate(str_slot->len); + if (NULL == str_slot->ptr) { + return Status::InternalError("Allocate memcpy failed."); + } + memcpy(str_slot->ptr, src->c_str(), str_slot->len); + } + _priv_index++; + return Status::OK(); +} + +Status SchemaUserPrivilegesScanner::get_new_table() { + TGetTablesParams table_params; + if (NULL != _param->wild) { + table_params.__set_pattern(*(_param->wild)); + } + if (NULL != _param->current_user_ident) { + table_params.__set_current_user_ident(*(_param->current_user_ident)); + } else { + if (NULL != _param->user) { + table_params.__set_user(*(_param->user)); + } + if (NULL != _param->user_ip) { + table_params.__set_user_ip(*(_param->user_ip)); + } + } + + if (NULL != _param->ip && 0 != _param->port) { + RETURN_IF_ERROR(SchemaHelper::list_user_privilege_status(*(_param->ip), + _param->port, table_params, &_priv_result)); + } else { + return Status::InternalError("IP or port doesn't exists"); + } + _priv_index = 0; + return Status::OK(); +} + +Status SchemaUserPrivilegesScanner::get_next_row(Tuple *tuple, MemPool *pool, bool *eos) { + if (!_is_init) { + return Status::InternalError("Used before initialized."); + } + if (NULL == tuple || NULL == pool || NULL == eos) { + return Status::InternalError("input pointer is NULL."); + } + if (_priv_index >= _priv_result.privileges.size()) { + *eos = true; + return Status::OK(); + } + *eos = false; + return fill_one_row(tuple, pool); +} + +} diff --git a/be/src/exec/schema_scanner/schema_user_privileges_scanner.h b/be/src/exec/schema_scanner/schema_user_privileges_scanner.h new file mode 100644 index 00000000000000..b89fbeb1a0f6ae --- /dev/null +++ b/be/src/exec/schema_scanner/schema_user_privileges_scanner.h @@ -0,0 +1,45 @@ +// 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. + +#ifndef DORIS_BE_SRC_QUERY_EXEC_SCHEMA_SCANNER_SCHEMA_USER_PRIVILEGES_SCANNER_H +#define DORIS_BE_SRC_QUERY_EXEC_SCHEMA_SCANNER_SCHEMA_USER_PRIVILEGES_SCANNER_H + +#include "exec/schema_scanner.h" +#include "gen_cpp/FrontendService_types.h" + +namespace doris { + +class SchemaUserPrivilegesScanner : public SchemaScanner { +public: + SchemaUserPrivilegesScanner(); + virtual ~SchemaUserPrivilegesScanner(); + + virtual Status start(RuntimeState *state); + virtual Status get_next_row(Tuple *tuple, MemPool *pool, bool *eos); + +private: + Status get_new_table(); + Status fill_one_row(Tuple *tuple, MemPool *pool); + + int _priv_index; + TListPrivilegesResult _priv_result; + static SchemaScanner::ColumnDesc _s_tbls_columns[]; +}; + +} + +#endif 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 97ec5be3144b0c..832085ed5c26bd 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 @@ -104,11 +104,32 @@ public static Builder builder() { TableType.SCHEMA, builder() .column("GRANTEE", ScalarType.createVarchar(NAME_CHAR_LEN)) - .column("TABLE_CATALOG", ScalarType.createVarchar(NAME_CHAR_LEN)) + .column("TABLE_CATALOG", ScalarType.createVarchar(FN_REFLEN)) .column("TABLE_SCHEMA", ScalarType.createVarchar(NAME_CHAR_LEN)) .column("TABLE_NAME", ScalarType.createVarchar(NAME_CHAR_LEN)) - .column("PRIVILEGE_TYPE", ScalarType.createVarchar(NAME_CHAR_LEN)) - .column("IS_GRANTABLE", ScalarType.createVarchar(NAME_CHAR_LEN)) + .column("PRIVILEGE_TYPE", ScalarType.createVarchar(64)) + .column("IS_GRANTABLE", ScalarType.createVarchar(3)) + .build())) + .put("schema_privileges", new SchemaTable( + SystemIdGenerator.getNextId(), + "schema_privileges", + TableType.SCHEMA, + builder() + .column("GRANTEE", ScalarType.createVarchar(NAME_CHAR_LEN)) + .column("TABLE_CATALOG", ScalarType.createVarchar(FN_REFLEN)) + .column("TABLE_SCHEMA", ScalarType.createVarchar(NAME_CHAR_LEN)) + .column("PRIVILEGE_TYPE", ScalarType.createVarchar(64)) + .column("IS_GRANTABLE", ScalarType.createVarchar(3)) + .build())) + .put("user_privileges", new SchemaTable( + SystemIdGenerator.getNextId(), + "user_privileges", + TableType.SCHEMA, + builder() + .column("GRANTEE", ScalarType.createVarchar(NAME_CHAR_LEN)) + .column("TABLE_CATALOG", ScalarType.createVarchar(FN_REFLEN)) + .column("PRIVILEGE_TYPE", ScalarType.createVarchar(64)) + .column("IS_GRANTABLE", ScalarType.createVarchar(3)) .build())) .put("referential_constraints", new SchemaTable( SystemIdGenerator.getNextId(), diff --git a/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/PaloAuth.java b/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/PaloAuth.java index 9154c7c7af743b..4ae8ec53cb4016 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/PaloAuth.java +++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/PaloAuth.java @@ -43,6 +43,7 @@ import org.apache.doris.persist.PrivInfo; import org.apache.doris.qe.ConnectContext; import org.apache.doris.thrift.TFetchResourceResult; +import org.apache.doris.thrift.TPrivilegeStatus; import com.google.common.base.Joiner; import com.google.common.base.Preconditions; @@ -1300,6 +1301,120 @@ public List> getRoleInfo() { } } + // Used for transforming privileges in palo to mysql. + private final String[] privilegesInMysql = new String[]{"", "", "", "SELECT", "INSERT", "ALTER", + "CREATE", "DROP", "USAGE"}; + + // Used for creating table_privileges table in information_schema. + public void getTablePrivStatus(List tblPrivResult, UserIdentity currentUser) { + readLock(); + try { + for (PrivEntry entry : tablePrivTable.getEntries()) { + TablePrivEntry tblPrivEntry = (TablePrivEntry) entry; + String dbName = ClusterNamespace.getNameFromFullName(tblPrivEntry.getOrigDb()); + String tblName = tblPrivEntry.getOrigTbl(); + + if (dbName.equals("information_schema" /* Don't show privileges in information_schema */) + || !checkTblPriv(currentUser, tblPrivEntry.getOrigDb(), tblName, PrivPredicate.SHOW)) { + continue; + } + + String grantee = new String("\'").concat(ClusterNamespace.getNameFromFullName(tblPrivEntry.getOrigUser())) + .concat("\'@\'").concat(tblPrivEntry.getOrigHost()).concat("\'"); + String isGrantable = tblPrivEntry.getPrivSet().get(2) ? "yes" : "no"; //Grant_priv + for (PaloPrivilege paloPriv : tblPrivEntry.getPrivSet().toPrivilegeList()) { + if (paloPriv == PaloPrivilege.GRANT_PRIV) { + continue; + } + TPrivilegeStatus status = new TPrivilegeStatus(); + status.setTableName(tblName); + status.setPrivilegeType(privilegesInMysql[paloPriv.getIdx()]); + status.setGrantee(grantee); + status.setSchema(dbName); + status.setIsGrantable(isGrantable); + tblPrivResult.add(status); + } + } + } finally { + readUnlock(); + } + } + + // Used for creating schema_privileges table in information_schema. + public void getSchemaPrivStatus(List dbPrivResult, UserIdentity currentUser) { + readLock(); + try { + for (PrivEntry entry : dbPrivTable.getEntries()) { + DbPrivEntry dbPrivEntry = (DbPrivEntry) entry; + String origDb = dbPrivEntry.getOrigDb(); + String dbName = ClusterNamespace.getNameFromFullName(dbPrivEntry.getOrigDb()); + + if (dbName.equals("information_schema" /* Don't show privileges in information_schema */) + || !checkDbPriv(currentUser, origDb, PrivPredicate.SHOW)) { + continue; + } + + String grantee = new String("\'").concat(ClusterNamespace.getNameFromFullName(dbPrivEntry.getOrigUser())) + .concat("\'@\'").concat(dbPrivEntry.getOrigHost()).concat("\'"); + String isGrantable = dbPrivEntry.getPrivSet().get(2) ? "yes" : "no"; //Grant_priv + for (PaloPrivilege paloPriv : dbPrivEntry.getPrivSet().toPrivilegeList()) { + if (paloPriv == PaloPrivilege.GRANT_PRIV) { + continue; + } + TPrivilegeStatus status = new TPrivilegeStatus(); + status.setPrivilegeType(privilegesInMysql[paloPriv.getIdx()]); + status.setGrantee(grantee); + status.setSchema(dbName); + status.setIsGrantable(isGrantable); + dbPrivResult.add(status); + } + } + } finally { + readUnlock(); + } + } + + // Used for creating user_privileges table in information_schema. + public void getGlobalPrivStatus(List userPrivResult, UserIdentity currentUser) { + readLock(); + try { + if (!checkGlobalPriv(currentUser, PrivPredicate.SHOW)) { + return; + } + + for (PrivEntry userPrivEntry : userPrivTable.getEntries()) { + String grantee = new String("\'").concat(ClusterNamespace.getNameFromFullName(userPrivEntry.getOrigUser())) + .concat("\'@\'").concat(userPrivEntry.getOrigHost()).concat("\'"); + String isGrantable = userPrivEntry.getPrivSet().get(2) ? "yes" : "no"; //Grant_priv + for (PaloPrivilege paloPriv : userPrivEntry.getPrivSet().toPrivilegeList()) { + if (paloPriv == PaloPrivilege.GRANT_PRIV + || paloPriv == PaloPrivilege.NODE_PRIV /* Don't show NODE_PRIV, which doesn't exist in mysql */) { + continue; + } + if (paloPriv == PaloPrivilege.ADMIN_PRIV) { + for (String priv : privilegesInMysql) { //ADMIN_PRIV includes all privileges of table and resource. + if(!priv.isEmpty()){ + TPrivilegeStatus status = new TPrivilegeStatus(); + status.setPrivilegeType(priv); + status.setGrantee(grantee); + status.setIsGrantable("yes"); + userPrivResult.add(status); + } + } + break; + } + TPrivilegeStatus status = new TPrivilegeStatus(); + status.setPrivilegeType(paloPriv.toString()); + status.setGrantee(grantee); + status.setIsGrantable(isGrantable); + userPrivResult.add(status); + } + } + } finally { + readUnlock(); + } + } + public static PaloAuth read(DataInput in) throws IOException { PaloAuth auth = new PaloAuth(); auth.readFields(in); diff --git a/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/PrivTable.java b/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/PrivTable.java index 423dfed4f14a96..7c3b042713ab54 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/PrivTable.java +++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/PrivTable.java @@ -83,6 +83,10 @@ public PrivEntry addEntry(PrivEntry newEntry, boolean errOnExist, boolean errOnN } } + public List getEntries() { + return entries; + } + public void dropEntry(PrivEntry entry) { Iterator iter = entries.iterator(); while (iter.hasNext()) { diff --git a/fe/fe-core/src/main/java/org/apache/doris/service/FrontendServiceImpl.java b/fe/fe-core/src/main/java/org/apache/doris/service/FrontendServiceImpl.java index c44d2730351f79..1892e7f560ab9b 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/service/FrontendServiceImpl.java +++ b/fe/fe-core/src/main/java/org/apache/doris/service/FrontendServiceImpl.java @@ -70,6 +70,7 @@ import org.apache.doris.thrift.TGetTablesResult; import org.apache.doris.thrift.TIsMethodSupportedRequest; import org.apache.doris.thrift.TListTableStatusResult; +import org.apache.doris.thrift.TListPrivilegesResult; import org.apache.doris.thrift.TLoadCheckRequest; import org.apache.doris.thrift.TLoadTxnBeginRequest; import org.apache.doris.thrift.TLoadTxnBeginResult; @@ -96,6 +97,7 @@ import org.apache.doris.thrift.TStreamLoadPutRequest; import org.apache.doris.thrift.TStreamLoadPutResult; import org.apache.doris.thrift.TTableStatus; +import org.apache.doris.thrift.TPrivilegeStatus; import org.apache.doris.thrift.TUniqueId; import org.apache.doris.thrift.TUpdateExportTaskStatusRequest; import org.apache.doris.thrift.TUpdateMiniEtlTaskStatusRequest; @@ -286,6 +288,57 @@ public TListTableStatusResult listTableStatus(TGetTablesParams params) throws TE return result; } + @Override + public TListPrivilegesResult listTablePrivilegeStatus(TGetTablesParams params) throws TException { + LOG.debug("get list table privileges request: {}", params); + TListPrivilegesResult result = new TListPrivilegesResult(); + List tblPrivResult = Lists.newArrayList(); + result.setPrivileges(tblPrivResult); + + UserIdentity currentUser = null; + if (params.isSetCurrentUserIdent()) { + currentUser = UserIdentity.fromThrift(params.current_user_ident); + } else { + currentUser = UserIdentity.createAnalyzedUserIdentWithIp(params.user, params.user_ip); + } + Catalog.getCurrentCatalog().getAuth().getTablePrivStatus(tblPrivResult, currentUser); + return result; + } + + @Override + public TListPrivilegesResult listSchemaPrivilegeStatus(TGetTablesParams params) throws TException { + LOG.debug("get list schema privileges request: {}", params); + TListPrivilegesResult result = new TListPrivilegesResult(); + List tblPrivResult = Lists.newArrayList(); + result.setPrivileges(tblPrivResult); + + UserIdentity currentUser = null; + if (params.isSetCurrentUserIdent()) { + currentUser = UserIdentity.fromThrift(params.current_user_ident); + } else { + currentUser = UserIdentity.createAnalyzedUserIdentWithIp(params.user, params.user_ip); + } + Catalog.getCurrentCatalog().getAuth().getSchemaPrivStatus(tblPrivResult, currentUser); + return result; + } + + @Override + public TListPrivilegesResult listUserPrivilegeStatus(TGetTablesParams params) throws TException { + LOG.debug("get list user privileges request: {}", params); + TListPrivilegesResult result = new TListPrivilegesResult(); + List userPrivResult = Lists.newArrayList(); + result.setPrivileges(userPrivResult); + + UserIdentity currentUser = null; + if (params.isSetCurrentUserIdent()) { + currentUser = UserIdentity.fromThrift(params.current_user_ident); + } else { + currentUser = UserIdentity.createAnalyzedUserIdentWithIp(params.user, params.user_ip); + } + Catalog.getCurrentCatalog().getAuth().getGlobalPrivStatus(userPrivResult, currentUser); + return result; + } + @Override public TFeResult updateExportTaskStatus(TUpdateExportTaskStatusRequest request) throws TException { TStatus status = new TStatus(TStatusCode.OK); diff --git a/gensrc/thrift/FrontendService.thrift b/gensrc/thrift/FrontendService.thrift index 71b969c79bb798..33b25fb135701d 100644 --- a/gensrc/thrift/FrontendService.thrift +++ b/gensrc/thrift/FrontendService.thrift @@ -324,6 +324,18 @@ struct TGetTablesResult { 1: list tables } +struct TPrivilegeStatus { + 1: optional string table_name + 2: optional string privilege_type + 3: optional string grantee + 4: optional string schema + 5: optional string is_grantable +} + +struct TListPrivilegesResult{ + 1: required list privileges +} + struct TReportExecStatusResult { // required in V1 1: optional Status.TStatus status @@ -662,6 +674,9 @@ service FrontendService { TMasterOpResult forward(TMasterOpRequest params) TListTableStatusResult listTableStatus(1:TGetTablesParams params) + TListPrivilegesResult listTablePrivilegeStatus(1:TGetTablesParams params) + TListPrivilegesResult listSchemaPrivilegeStatus(1:TGetTablesParams params) + TListPrivilegesResult listUserPrivilegeStatus(1:TGetTablesParams params) TFeResult updateExportTaskStatus(1:TUpdateExportTaskStatusRequest request) From 1ff6c6dab966e201ce34e190884a28164d779381 Mon Sep 17 00:00:00 2001 From: Zenglin Luo Date: Sat, 14 Nov 2020 17:41:48 +0800 Subject: [PATCH 2/3] [Compatibility] Add table table_privileges, schema_privileges and user_privileges to the information_schema database (#4897) to improve compatibility with the mysql --- .../org/apache/doris/catalog/SchemaTable.java | 21 ++++++---- .../doris/mysql/privilege/PaloAuth.java | 41 ++++++++----------- .../doris/mysql/privilege/PaloPrivilege.java | 14 +++++++ 3 files changed, 43 insertions(+), 33 deletions(-) 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 832085ed5c26bd..01da908510df2c 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 @@ -40,6 +40,9 @@ public class SchemaTable extends Table { private final static int NAME_CHAR_LEN = 64; private final static int MAX_FIELD_VARCHARLENGTH = 65535; private final static int MY_CS_NAME_SIZE = 32; + private final static int GRANTEE_len = 81; + private final static int PRIVILEGE_TYPE_LEN = 64; + private final static int IS_GRANTABLE_LEN = 3; private SchemaTableType schemaTableType; protected SchemaTable(long id, String name, TableType type, List baseSchema) { @@ -103,33 +106,33 @@ public static Builder builder() { "table_privileges", TableType.SCHEMA, builder() - .column("GRANTEE", ScalarType.createVarchar(NAME_CHAR_LEN)) + .column("GRANTEE", ScalarType.createVarchar(GRANTEE_len)) .column("TABLE_CATALOG", ScalarType.createVarchar(FN_REFLEN)) .column("TABLE_SCHEMA", ScalarType.createVarchar(NAME_CHAR_LEN)) .column("TABLE_NAME", ScalarType.createVarchar(NAME_CHAR_LEN)) - .column("PRIVILEGE_TYPE", ScalarType.createVarchar(64)) - .column("IS_GRANTABLE", ScalarType.createVarchar(3)) + .column("PRIVILEGE_TYPE", ScalarType.createVarchar(PRIVILEGE_TYPE_LEN)) + .column("IS_GRANTABLE", ScalarType.createVarchar(IS_GRANTABLE_LEN)) .build())) .put("schema_privileges", new SchemaTable( SystemIdGenerator.getNextId(), "schema_privileges", TableType.SCHEMA, builder() - .column("GRANTEE", ScalarType.createVarchar(NAME_CHAR_LEN)) + .column("GRANTEE", ScalarType.createVarchar(GRANTEE_len)) .column("TABLE_CATALOG", ScalarType.createVarchar(FN_REFLEN)) .column("TABLE_SCHEMA", ScalarType.createVarchar(NAME_CHAR_LEN)) - .column("PRIVILEGE_TYPE", ScalarType.createVarchar(64)) - .column("IS_GRANTABLE", ScalarType.createVarchar(3)) + .column("PRIVILEGE_TYPE", ScalarType.createVarchar(PRIVILEGE_TYPE_LEN)) + .column("IS_GRANTABLE", ScalarType.createVarchar(IS_GRANTABLE_LEN)) .build())) .put("user_privileges", new SchemaTable( SystemIdGenerator.getNextId(), "user_privileges", TableType.SCHEMA, builder() - .column("GRANTEE", ScalarType.createVarchar(NAME_CHAR_LEN)) + .column("GRANTEE", ScalarType.createVarchar(GRANTEE_len)) .column("TABLE_CATALOG", ScalarType.createVarchar(FN_REFLEN)) - .column("PRIVILEGE_TYPE", ScalarType.createVarchar(64)) - .column("IS_GRANTABLE", ScalarType.createVarchar(3)) + .column("PRIVILEGE_TYPE", ScalarType.createVarchar(PRIVILEGE_TYPE_LEN)) + .column("IS_GRANTABLE", ScalarType.createVarchar(IS_GRANTABLE_LEN)) .build())) .put("referential_constraints", new SchemaTable( SystemIdGenerator.getNextId(), diff --git a/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/PaloAuth.java b/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/PaloAuth.java index 4ae8ec53cb4016..4cbe28cfce70b5 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/PaloAuth.java +++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/PaloAuth.java @@ -1301,10 +1301,6 @@ public List> getRoleInfo() { } } - // Used for transforming privileges in palo to mysql. - private final String[] privilegesInMysql = new String[]{"", "", "", "SELECT", "INSERT", "ALTER", - "CREATE", "DROP", "USAGE"}; - // Used for creating table_privileges table in information_schema. public void getTablePrivStatus(List tblPrivResult, UserIdentity currentUser) { readLock(); @@ -1321,14 +1317,14 @@ public void getTablePrivStatus(List tblPrivResult, UserIdentit String grantee = new String("\'").concat(ClusterNamespace.getNameFromFullName(tblPrivEntry.getOrigUser())) .concat("\'@\'").concat(tblPrivEntry.getOrigHost()).concat("\'"); - String isGrantable = tblPrivEntry.getPrivSet().get(2) ? "yes" : "no"; //Grant_priv + String isGrantable = tblPrivEntry.getPrivSet().get(2) ? "YES" : "NO"; // GRANT_PRIV for (PaloPrivilege paloPriv : tblPrivEntry.getPrivSet().toPrivilegeList()) { - if (paloPriv == PaloPrivilege.GRANT_PRIV) { + if (!PaloPrivilege.privInPaloToMysql.containsKey(paloPriv)) { continue; } TPrivilegeStatus status = new TPrivilegeStatus(); status.setTableName(tblName); - status.setPrivilegeType(privilegesInMysql[paloPriv.getIdx()]); + status.setPrivilegeType(PaloPrivilege.privInPaloToMysql.get(paloPriv)); status.setGrantee(grantee); status.setSchema(dbName); status.setIsGrantable(isGrantable); @@ -1356,13 +1352,13 @@ public void getSchemaPrivStatus(List dbPrivResult, UserIdentit String grantee = new String("\'").concat(ClusterNamespace.getNameFromFullName(dbPrivEntry.getOrigUser())) .concat("\'@\'").concat(dbPrivEntry.getOrigHost()).concat("\'"); - String isGrantable = dbPrivEntry.getPrivSet().get(2) ? "yes" : "no"; //Grant_priv + String isGrantable = dbPrivEntry.getPrivSet().get(2) ? "YES" : "NO"; // GRANT_PRIV for (PaloPrivilege paloPriv : dbPrivEntry.getPrivSet().toPrivilegeList()) { - if (paloPriv == PaloPrivilege.GRANT_PRIV) { + if (!PaloPrivilege.privInPaloToMysql.containsKey(paloPriv)) { continue; } TPrivilegeStatus status = new TPrivilegeStatus(); - status.setPrivilegeType(privilegesInMysql[paloPriv.getIdx()]); + status.setPrivilegeType(PaloPrivilege.privInPaloToMysql.get(paloPriv)); status.setGrantee(grantee); status.setSchema(dbName); status.setIsGrantable(isGrantable); @@ -1385,26 +1381,23 @@ public void getGlobalPrivStatus(List userPrivResult, UserIdent for (PrivEntry userPrivEntry : userPrivTable.getEntries()) { String grantee = new String("\'").concat(ClusterNamespace.getNameFromFullName(userPrivEntry.getOrigUser())) .concat("\'@\'").concat(userPrivEntry.getOrigHost()).concat("\'"); - String isGrantable = userPrivEntry.getPrivSet().get(2) ? "yes" : "no"; //Grant_priv + String isGrantable = userPrivEntry.getPrivSet().get(2) ? "YES" : "NO"; // GRANT_PRIV for (PaloPrivilege paloPriv : userPrivEntry.getPrivSet().toPrivilegeList()) { - if (paloPriv == PaloPrivilege.GRANT_PRIV - || paloPriv == PaloPrivilege.NODE_PRIV /* Don't show NODE_PRIV, which doesn't exist in mysql */) { - continue; - } if (paloPriv == PaloPrivilege.ADMIN_PRIV) { - for (String priv : privilegesInMysql) { //ADMIN_PRIV includes all privileges of table and resource. - if(!priv.isEmpty()){ - TPrivilegeStatus status = new TPrivilegeStatus(); - status.setPrivilegeType(priv); - status.setGrantee(grantee); - status.setIsGrantable("yes"); - userPrivResult.add(status); - } + for (String priv : PaloPrivilege.privInPaloToMysql.values()) { // ADMIN_PRIV includes all privileges of table and resource. + TPrivilegeStatus status = new TPrivilegeStatus(); + status.setPrivilegeType(priv); + status.setGrantee(grantee); + status.setIsGrantable("YES"); + userPrivResult.add(status); } break; } + if (!PaloPrivilege.privInPaloToMysql.containsKey(paloPriv)) { + continue; + } TPrivilegeStatus status = new TPrivilegeStatus(); - status.setPrivilegeType(paloPriv.toString()); + status.setPrivilegeType(PaloPrivilege.privInPaloToMysql.get(paloPriv)); status.setGrantee(grantee); status.setIsGrantable(isGrantable); userPrivResult.add(status); diff --git a/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/PaloPrivilege.java b/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/PaloPrivilege.java index 120adbf3466336..fb4599c233b56c 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/PaloPrivilege.java +++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/PaloPrivilege.java @@ -17,6 +17,10 @@ package org.apache.doris.mysql.privilege; +import com.google.common.collect.ImmutableMap; + +import java.util.Map; + public enum PaloPrivilege { NODE_PRIV("Node_priv", 0, "Privilege for cluster node operations"), ADMIN_PRIV("Admin_priv", 1, "Privilege for admin user"), @@ -40,6 +44,16 @@ public enum PaloPrivilege { USAGE_PRIV }; + public static Map privInPaloToMysql = + ImmutableMap.builder() // No NODE_PRIV and ADMIN_PRIV in the mysql + .put(SELECT_PRIV, "SELECT") + .put(LOAD_PRIV, "INSERT") + .put(ALTER_PRIV, "ALTER") + .put(CREATE_PRIV, "CREATE") + .put(DROP_PRIV, "DROP") + .put(USAGE_PRIV, "USAGE") + .build(); + private String name; private int idx; private String desc; From 25db3ef2dd4735a23dd100e22b7227f8d7041003 Mon Sep 17 00:00:00 2001 From: Zenglin Luo Date: Sun, 15 Nov 2020 17:57:19 +0800 Subject: [PATCH 3/3] [Compatibility] Add table table_privileges, schema_privileges and user_privileges to the information_schema database (#4897) to improve compatibility with the mysql --- .../schema_schema_privileges_scanner.cpp | 80 ++++++++-------- .../schema_schema_privileges_scanner.h | 1 + .../schema_table_privileges_scanner.cpp | 92 +++++++++---------- .../schema_table_privileges_scanner.h | 1 + .../schema_user_privileges_scanner.cpp | 68 +++++++------- .../schema_user_privileges_scanner.h | 1 + 6 files changed, 117 insertions(+), 126 deletions(-) diff --git a/be/src/exec/schema_scanner/schema_schema_privileges_scanner.cpp b/be/src/exec/schema_scanner/schema_schema_privileges_scanner.cpp index 2a3ce52bcb5bef..b5589ee4de56a1 100644 --- a/be/src/exec/schema_scanner/schema_schema_privileges_scanner.cpp +++ b/be/src/exec/schema_scanner/schema_schema_privileges_scanner.cpp @@ -53,72 +53,68 @@ Status SchemaSchemaPrivilegesScanner::start(RuntimeState *state) { Status SchemaSchemaPrivilegesScanner::fill_one_row(Tuple *tuple, MemPool *pool) { // set all bit to not null memset((void *)tuple, 0, _tuple_desc->num_null_bytes()); - const TPrivilegeStatus& tbl_priv_status = _priv_result.privileges[_priv_index]; + const TPrivilegeStatus& priv_status = _priv_result.privileges[_priv_index]; // grantee { - void *slot = tuple->get_slot(_tuple_desc->slots()[0]->tuple_offset()); - StringValue* str_slot = reinterpret_cast(slot); - const std::string* src = &tbl_priv_status.grantee; - str_slot->len = src->length(); - str_slot->ptr = (char *)pool->allocate(str_slot->len); - if (NULL == str_slot->ptr) { - return Status::InternalError("Allocate memcpy failed."); + Status status = fill_one_col(&priv_status.grantee, pool, + tuple->get_slot(_tuple_desc->slots()[0]->tuple_offset())); + if (!status.ok()) { + return status; } - memcpy(str_slot->ptr, src->c_str(), str_slot->len); } // catalog - //This value is always def. + // This value is always def. { - void *slot = tuple->get_slot(_tuple_desc->slots()[1]->tuple_offset()); - StringValue* str_slot = reinterpret_cast(slot); - const std::string definer = "def"; - str_slot->len = definer.length(); - str_slot->ptr = (char *)pool->allocate(str_slot->len); - if (NULL == str_slot->ptr) { - return Status::InternalError("Allocate memcpy failed."); + std::string definer = "def"; + Status status = fill_one_col(&definer, pool, + tuple->get_slot(_tuple_desc->slots()[1]->tuple_offset())); + if (!status.ok()) { + return status; } - memcpy(str_slot->ptr, definer.c_str(), str_slot->len); } // schema { - void *slot = tuple->get_slot(_tuple_desc->slots()[2]->tuple_offset()); - StringValue* str_slot = reinterpret_cast(slot); - const std::string* src = &tbl_priv_status.schema; - str_slot->len = src->length(); - str_slot->ptr = (char *)pool->allocate(str_slot->len); - if (NULL == str_slot->ptr) { - return Status::InternalError("Allocate memcpy failed."); + Status status = fill_one_col(&priv_status.schema, pool, + tuple->get_slot(_tuple_desc->slots()[2]->tuple_offset())); + if (!status.ok()) { + return status; } - memcpy(str_slot->ptr, src->c_str(), str_slot->len); } // privilege type { - void *slot = tuple->get_slot(_tuple_desc->slots()[3]->tuple_offset()); - StringValue* str_slot = reinterpret_cast(slot); - const std::string* src = &tbl_priv_status.privilege_type; - str_slot->len = src->length(); - str_slot->ptr = (char *)pool->allocate(str_slot->len); - if (NULL == str_slot->ptr) { - return Status::InternalError("Allocate memcpy failed."); + Status status = fill_one_col(&priv_status.privilege_type, pool, + tuple->get_slot(_tuple_desc->slots()[3]->tuple_offset())); + if (!status.ok()) { + return status; } - memcpy(str_slot->ptr, src->c_str(), str_slot->len); } // is grantable { - void *slot = tuple->get_slot(_tuple_desc->slots()[4]->tuple_offset()); - StringValue* str_slot = reinterpret_cast(slot); - const std::string* src = &tbl_priv_status.is_grantable; - str_slot->len = src->length(); - str_slot->ptr = (char *)pool->allocate(str_slot->len); - if (NULL == str_slot->ptr) { - return Status::InternalError("Allocate memcpy failed."); + Status status = fill_one_col(&priv_status.is_grantable, pool, + tuple->get_slot(_tuple_desc->slots()[4]->tuple_offset())); + if (!status.ok()) { + return status; } - memcpy(str_slot->ptr, src->c_str(), str_slot->len); } _priv_index++; return Status::OK(); } +Status SchemaSchemaPrivilegesScanner::fill_one_col(const std::string* src, + MemPool *pool, void *slot) { + if (NULL == slot || NULL == pool || NULL == src) { + return Status::InternalError("input pointer is NULL."); + } + StringValue* str_slot = reinterpret_cast(slot); + str_slot->len = src->length(); + str_slot->ptr = (char *)pool->allocate(str_slot->len); + if (NULL == str_slot->ptr) { + return Status::InternalError("Allocate memcpy failed."); + } + memcpy(str_slot->ptr, src->c_str(), str_slot->len); + return Status::OK(); +} + Status SchemaSchemaPrivilegesScanner::get_new_table() { TGetTablesParams table_params; diff --git a/be/src/exec/schema_scanner/schema_schema_privileges_scanner.h b/be/src/exec/schema_scanner/schema_schema_privileges_scanner.h index 8d7c386b1fd114..6d9fc03867b443 100644 --- a/be/src/exec/schema_scanner/schema_schema_privileges_scanner.h +++ b/be/src/exec/schema_scanner/schema_schema_privileges_scanner.h @@ -34,6 +34,7 @@ class SchemaSchemaPrivilegesScanner : public SchemaScanner { private: Status get_new_table(); Status fill_one_row(Tuple *tuple, MemPool *pool); + Status fill_one_col(const std::string* src, MemPool *pool, void* slot); int _priv_index; TListPrivilegesResult _priv_result; diff --git a/be/src/exec/schema_scanner/schema_table_privileges_scanner.cpp b/be/src/exec/schema_scanner/schema_table_privileges_scanner.cpp index d41a32a640fa61..6d3d39000450a8 100644 --- a/be/src/exec/schema_scanner/schema_table_privileges_scanner.cpp +++ b/be/src/exec/schema_scanner/schema_table_privileges_scanner.cpp @@ -54,84 +54,76 @@ Status SchemaTablePrivilegesScanner::start(RuntimeState *state) { Status SchemaTablePrivilegesScanner::fill_one_row(Tuple *tuple, MemPool *pool) { // set all bit to not null memset((void *)tuple, 0, _tuple_desc->num_null_bytes()); - const TPrivilegeStatus& tbl_priv_status = _priv_result.privileges[_priv_index]; + const TPrivilegeStatus& priv_status = _priv_result.privileges[_priv_index]; // grantee { - void *slot = tuple->get_slot(_tuple_desc->slots()[0]->tuple_offset()); - StringValue* str_slot = reinterpret_cast(slot); - const std::string* src = &tbl_priv_status.grantee; - str_slot->len = src->length(); - str_slot->ptr = (char *)pool->allocate(str_slot->len); - if (NULL == str_slot->ptr) { - return Status::InternalError("Allocate memcpy failed."); + Status status = fill_one_col(&priv_status.grantee, pool, + tuple->get_slot(_tuple_desc->slots()[0]->tuple_offset())); + if (!status.ok()) { + return status; } - memcpy(str_slot->ptr, src->c_str(), str_slot->len); } // catalog - //This value is always def. + // This value is always def. { - void *slot = tuple->get_slot(_tuple_desc->slots()[1]->tuple_offset()); - StringValue* str_slot = reinterpret_cast(slot); - const std::string definer = "def"; - str_slot->len = definer.length(); - str_slot->ptr = (char *)pool->allocate(str_slot->len); - if (NULL == str_slot->ptr) { - return Status::InternalError("Allocate memcpy failed."); + std::string definer = "def"; + Status status = fill_one_col(&definer, pool, + tuple->get_slot(_tuple_desc->slots()[1]->tuple_offset())); + if (!status.ok()) { + return status; } - memcpy(str_slot->ptr, definer.c_str(), str_slot->len); } // schema { - void *slot = tuple->get_slot(_tuple_desc->slots()[2]->tuple_offset()); - StringValue* str_slot = reinterpret_cast(slot); - const std::string* src = &tbl_priv_status.schema; - str_slot->len = src->length(); - str_slot->ptr = (char *)pool->allocate(str_slot->len); - if (NULL == str_slot->ptr) { - return Status::InternalError("Allocate memcpy failed."); + Status status = fill_one_col(&priv_status.schema, pool, + tuple->get_slot(_tuple_desc->slots()[2]->tuple_offset())); + if (!status.ok()) { + return status; } - memcpy(str_slot->ptr, src->c_str(), str_slot->len); } // table name { - void *slot = tuple->get_slot(_tuple_desc->slots()[3]->tuple_offset()); - StringValue* str_slot = reinterpret_cast(slot); - const std::string* src = &tbl_priv_status.table_name; - str_slot->len = src->length(); - str_slot->ptr = (char *)pool->allocate(str_slot->len); - if (NULL == str_slot->ptr) { - return Status::InternalError("Allocate memcpy failed."); + Status status = fill_one_col(&priv_status.table_name, pool, + tuple->get_slot(_tuple_desc->slots()[3]->tuple_offset())); + if (!status.ok()) { + return status; } - memcpy(str_slot->ptr, src->c_str(), str_slot->len); } // privilege type { - void *slot = tuple->get_slot(_tuple_desc->slots()[4]->tuple_offset()); - StringValue* str_slot = reinterpret_cast(slot); - const std::string* src = &tbl_priv_status.privilege_type; - str_slot->len = src->length(); - str_slot->ptr = (char *)pool->allocate(str_slot->len); - if (NULL == str_slot->ptr) { - return Status::InternalError("Allocate memcpy failed."); + Status status = fill_one_col(&priv_status.privilege_type, pool, + tuple->get_slot(_tuple_desc->slots()[4]->tuple_offset())); + if (!status.ok()) { + return status; } - memcpy(str_slot->ptr, src->c_str(), str_slot->len); } // is grantable { - void *slot = tuple->get_slot(_tuple_desc->slots()[5]->tuple_offset()); - StringValue* str_slot = reinterpret_cast(slot); - const std::string* src = &tbl_priv_status.is_grantable; - str_slot->len = src->length(); - str_slot->ptr = (char *)pool->allocate(str_slot->len); - if (NULL == str_slot->ptr) { - return Status::InternalError("Allocate memcpy failed."); + Status status = fill_one_col(&priv_status.is_grantable, pool, + tuple->get_slot(_tuple_desc->slots()[5]->tuple_offset())); + if (!status.ok()) { + return status; } - memcpy(str_slot->ptr, src->c_str(), str_slot->len); } _priv_index++; return Status::OK(); } +Status SchemaTablePrivilegesScanner::fill_one_col(const std::string* src, + MemPool *pool, void* slot) { + if (NULL == slot || NULL == pool || NULL == src) { + return Status::InternalError("input pointer is NULL."); + } + StringValue* str_slot = reinterpret_cast(slot); + str_slot->len = src->length(); + str_slot->ptr = (char *)pool->allocate(str_slot->len); + if (NULL == str_slot->ptr) { + return Status::InternalError("Allocate memcpy failed."); + } + memcpy(str_slot->ptr, src->c_str(), str_slot->len); + return Status::OK(); +} + Status SchemaTablePrivilegesScanner::get_new_table() { TGetTablesParams table_params; if (NULL != _param->wild) { diff --git a/be/src/exec/schema_scanner/schema_table_privileges_scanner.h b/be/src/exec/schema_scanner/schema_table_privileges_scanner.h index 7ca7002f4d613a..1e5f2e6e864b34 100644 --- a/be/src/exec/schema_scanner/schema_table_privileges_scanner.h +++ b/be/src/exec/schema_scanner/schema_table_privileges_scanner.h @@ -34,6 +34,7 @@ class SchemaTablePrivilegesScanner : public SchemaScanner { private: Status get_new_table(); Status fill_one_row(Tuple *tuple, MemPool *pool); + Status fill_one_col(const std::string* src, MemPool *pool, void* slot); int _priv_index; TListPrivilegesResult _priv_result; diff --git a/be/src/exec/schema_scanner/schema_user_privileges_scanner.cpp b/be/src/exec/schema_scanner/schema_user_privileges_scanner.cpp index 8e63a1fb841cb9..3d56b89dd9f706 100644 --- a/be/src/exec/schema_scanner/schema_user_privileges_scanner.cpp +++ b/be/src/exec/schema_scanner/schema_user_privileges_scanner.cpp @@ -52,60 +52,60 @@ Status SchemaUserPrivilegesScanner::start(RuntimeState *state) { Status SchemaUserPrivilegesScanner::fill_one_row(Tuple *tuple, MemPool *pool) { // set all bit to not null memset((void *)tuple, 0, _tuple_desc->num_null_bytes()); - const TPrivilegeStatus& tbl_priv_status = _priv_result.privileges[_priv_index]; + const TPrivilegeStatus& priv_status = _priv_result.privileges[_priv_index]; // grantee { - void *slot = tuple->get_slot(_tuple_desc->slots()[0]->tuple_offset()); - StringValue* str_slot = reinterpret_cast(slot); - const std::string* src = &tbl_priv_status.grantee; - str_slot->len = src->length(); - str_slot->ptr = (char *)pool->allocate(str_slot->len); - if (NULL == str_slot->ptr) { - return Status::InternalError("Allocate memcpy failed."); + Status status = fill_one_col(&priv_status.grantee, pool, + tuple->get_slot(_tuple_desc->slots()[0]->tuple_offset())); + if (!status.ok()) { + return status; } - memcpy(str_slot->ptr, src->c_str(), str_slot->len); } // catalog - //This value is always def. + // This value is always def. { - void *slot = tuple->get_slot(_tuple_desc->slots()[1]->tuple_offset()); - StringValue* str_slot = reinterpret_cast(slot); - const std::string definer = "def"; - str_slot->len = definer.length(); - str_slot->ptr = (char *)pool->allocate(str_slot->len); - if (NULL == str_slot->ptr) { - return Status::InternalError("Allocate memcpy failed."); + std::string definer = "def"; + Status status = fill_one_col(&definer, pool, + tuple->get_slot(_tuple_desc->slots()[1]->tuple_offset())); + if (!status.ok()) { + return status; } - memcpy(str_slot->ptr, definer.c_str(), str_slot->len); } // privilege type { - void *slot = tuple->get_slot(_tuple_desc->slots()[2]->tuple_offset()); - StringValue* str_slot = reinterpret_cast(slot); - const std::string* src = &tbl_priv_status.privilege_type; - str_slot->len = src->length(); - str_slot->ptr = (char *)pool->allocate(str_slot->len); - if (NULL == str_slot->ptr) { - return Status::InternalError("Allocate memcpy failed."); + Status status = fill_one_col(&priv_status.privilege_type, pool, + tuple->get_slot(_tuple_desc->slots()[2]->tuple_offset())); + if (!status.ok()) { + return status; } - memcpy(str_slot->ptr, src->c_str(), str_slot->len); } // is grantable { - void *slot = tuple->get_slot(_tuple_desc->slots()[3]->tuple_offset()); - StringValue* str_slot = reinterpret_cast(slot); - const std::string* src = &tbl_priv_status.is_grantable; - str_slot->len = src->length(); - str_slot->ptr = (char *)pool->allocate(str_slot->len); - if (NULL == str_slot->ptr) { - return Status::InternalError("Allocate memcpy failed."); + Status status = fill_one_col(&priv_status.is_grantable, pool, + tuple->get_slot(_tuple_desc->slots()[3]->tuple_offset())); + if (!status.ok()) { + return status; } - memcpy(str_slot->ptr, src->c_str(), str_slot->len); } _priv_index++; return Status::OK(); } +Status SchemaUserPrivilegesScanner::fill_one_col(const std::string* src, + MemPool *pool, void *slot) { + if (NULL == slot || NULL == pool || NULL == src) { + return Status::InternalError("input pointer is NULL."); + } + StringValue* str_slot = reinterpret_cast(slot); + str_slot->len = src->length(); + str_slot->ptr = (char *)pool->allocate(str_slot->len); + if (NULL == str_slot->ptr) { + return Status::InternalError("Allocate memcpy failed."); + } + memcpy(str_slot->ptr, src->c_str(), str_slot->len); + return Status::OK(); +} + Status SchemaUserPrivilegesScanner::get_new_table() { TGetTablesParams table_params; if (NULL != _param->wild) { diff --git a/be/src/exec/schema_scanner/schema_user_privileges_scanner.h b/be/src/exec/schema_scanner/schema_user_privileges_scanner.h index b89fbeb1a0f6ae..aada2e7b69c782 100644 --- a/be/src/exec/schema_scanner/schema_user_privileges_scanner.h +++ b/be/src/exec/schema_scanner/schema_user_privileges_scanner.h @@ -34,6 +34,7 @@ class SchemaUserPrivilegesScanner : public SchemaScanner { private: Status get_new_table(); Status fill_one_row(Tuple *tuple, MemPool *pool); + Status fill_one_col(const std::string* src, MemPool *pool, void* slot); int _priv_index; TListPrivilegesResult _priv_result;