blob: e56f18f05aea930c54a047899d022eb8dd5809ba [file] [log] [blame]
// 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_user_scanner.h"
#include <gen_cpp/FrontendService_types.h>
#include <vector>
#include "exec/schema_scanner/schema_helper.h"
#include "runtime/runtime_state.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> SchemaUserScanner::_s_user_columns = {
{"Host", TYPE_CHAR, sizeof(StringRef), false},
{"User", TYPE_CHAR, sizeof(StringRef), false},
{"Node_priv", TYPE_CHAR, sizeof(StringRef), false},
{"Admin_priv", TYPE_CHAR, sizeof(StringRef), false},
{"Grant_priv", TYPE_CHAR, sizeof(StringRef), false},
{"Select_priv", TYPE_CHAR, sizeof(StringRef), false},
{"Load_priv", TYPE_CHAR, sizeof(StringRef), false},
{"Alter_priv", TYPE_CHAR, sizeof(StringRef), false},
{"Create_priv", TYPE_CHAR, sizeof(StringRef), false},
{"Drop_priv", TYPE_CHAR, sizeof(StringRef), false},
{"Usage_priv", TYPE_CHAR, sizeof(StringRef), false},
{"Show_view_priv", TYPE_CHAR, sizeof(StringRef), false},
{"Cluster_usage_priv", TYPE_CHAR, sizeof(StringRef), false},
{"Stage_usage_priv", TYPE_CHAR, sizeof(StringRef), false},
{"ssl_type", TYPE_CHAR, sizeof(StringRef), false},
{"ssl_cipher", TYPE_VARCHAR, sizeof(StringRef), false},
{"x509_issuer", TYPE_VARCHAR, sizeof(StringRef), false},
{"x509_subject", TYPE_VARCHAR, sizeof(StringRef), false},
{"max_questions", TYPE_BIGINT, sizeof(int64_t), false},
{"max_updates", TYPE_BIGINT, sizeof(int64_t), false},
{"max_connections", TYPE_BIGINT, sizeof(int64_t), false},
{"max_user_connections", TYPE_BIGINT, sizeof(int64_t), false},
{"plugin", TYPE_CHAR, sizeof(StringRef), false},
{"authentication_string", TYPE_VARCHAR, sizeof(StringRef), false},
{"password_policy.expiration_seconds", TYPE_VARCHAR, sizeof(StringRef), false},
{"password_policy.password_creation_time", TYPE_VARCHAR, sizeof(StringRef), false},
{"password_policy.history_num", TYPE_VARCHAR, sizeof(StringRef), false},
{"password_policy.history_passwords", TYPE_VARCHAR, sizeof(StringRef), false},
{"password_policy.num_failed_login", TYPE_VARCHAR, sizeof(StringRef), false},
{"password_policy.password_lock_seconds", TYPE_VARCHAR, sizeof(StringRef), false},
{"password_policy.failed_login_counter", TYPE_VARCHAR, sizeof(StringRef), false},
{"password_policy.lock_time", TYPE_VARCHAR, sizeof(StringRef), false}};
SchemaUserScanner::SchemaUserScanner()
: SchemaScanner(_s_user_columns, TSchemaTableType::SCH_USER) {}
SchemaUserScanner::~SchemaUserScanner() = default;
Status SchemaUserScanner::start(RuntimeState* state) {
TShowUserRequest request;
RETURN_IF_ERROR(SchemaHelper::show_user(*(_param->common_param->ip), _param->common_param->port,
request, &_user_result));
return Status::OK();
}
Status SchemaUserScanner::get_next_block_internal(vectorized::Block* block, bool* eos) {
if (!_is_init) {
return Status::InternalError("call this before initial.");
}
if (block == nullptr || eos == nullptr) {
return Status::InternalError("invalid parameter.");
}
*eos = true;
if (_user_result.userinfo_list.empty()) {
return Status::OK();
}
return _fill_block_impl(block);
}
Status SchemaUserScanner::_fill_block_impl(vectorized::Block* block) {
SCOPED_TIMER(_fill_block_timer);
const auto& userinfo_list = _user_result.userinfo_list;
size_t row_num = userinfo_list.size();
if (row_num == 0) {
return Status::OK();
}
for (size_t col_idx = 0; col_idx < _s_user_columns.size(); ++col_idx) {
std::vector<StringRef> str_refs(row_num);
std::vector<int64_t> int_vals(row_num);
std::vector<void*> datas(row_num);
std::vector<std::string> column_values(
row_num); // Store the strings to ensure their lifetime
for (size_t row_idx = 0; row_idx < row_num; ++row_idx) {
const auto& row = userinfo_list[row_idx];
std::string column_value = row.size() > col_idx ? row[col_idx] : "";
// Ensure column value assignment and type casting
column_values[row_idx] = column_value;
if (_s_user_columns[col_idx].type == TYPE_BIGINT) {
int64_t val = !column_value.empty() ? std::stoll(column_value) : 0;
int_vals[row_idx] = val;
datas[row_idx] = &int_vals[row_idx];
} else {
str_refs[row_idx] =
StringRef(column_values[row_idx].data(), column_values[row_idx].size());
datas[row_idx] = &str_refs[row_idx];
}
}
RETURN_IF_ERROR(fill_dest_column_for_range(block, col_idx, datas));
}
return Status::OK();
}
} // namespace doris