Coverage Report

Created: 2026-03-15 20:53

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/information_schema/schema_user_scanner.cpp
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
#include "information_schema/schema_user_scanner.h"
19
20
#include <gen_cpp/FrontendService_types.h>
21
22
#include <vector>
23
24
#include "core/block/block.h"
25
#include "core/data_type/data_type_factory.hpp"
26
#include "core/string_ref.h"
27
#include "information_schema/schema_helper.h"
28
#include "runtime/runtime_state.h"
29
30
namespace doris {
31
32
std::vector<SchemaScanner::ColumnDesc> SchemaUserScanner::_s_user_columns = {
33
        {"Host", TYPE_CHAR, sizeof(StringRef), false},
34
        {"User", TYPE_CHAR, sizeof(StringRef), false},
35
        {"Node_priv", TYPE_CHAR, sizeof(StringRef), false},
36
        {"Admin_priv", TYPE_CHAR, sizeof(StringRef), false},
37
        {"Grant_priv", TYPE_CHAR, sizeof(StringRef), false},
38
        {"Select_priv", TYPE_CHAR, sizeof(StringRef), false},
39
        {"Load_priv", TYPE_CHAR, sizeof(StringRef), false},
40
        {"Alter_priv", TYPE_CHAR, sizeof(StringRef), false},
41
        {"Create_priv", TYPE_CHAR, sizeof(StringRef), false},
42
        {"Drop_priv", TYPE_CHAR, sizeof(StringRef), false},
43
        {"Usage_priv", TYPE_CHAR, sizeof(StringRef), false},
44
        {"Show_view_priv", TYPE_CHAR, sizeof(StringRef), false},
45
        {"Cluster_usage_priv", TYPE_CHAR, sizeof(StringRef), false},
46
        {"Stage_usage_priv", TYPE_CHAR, sizeof(StringRef), false},
47
        {"ssl_type", TYPE_CHAR, sizeof(StringRef), false},
48
        {"ssl_cipher", TYPE_VARCHAR, sizeof(StringRef), false},
49
        {"x509_issuer", TYPE_VARCHAR, sizeof(StringRef), false},
50
        {"x509_subject", TYPE_VARCHAR, sizeof(StringRef), false},
51
        {"max_questions", TYPE_BIGINT, sizeof(int64_t), false},
52
        {"max_updates", TYPE_BIGINT, sizeof(int64_t), false},
53
        {"max_connections", TYPE_BIGINT, sizeof(int64_t), false},
54
        {"max_user_connections", TYPE_BIGINT, sizeof(int64_t), false},
55
        {"plugin", TYPE_CHAR, sizeof(StringRef), false},
56
        {"authentication_string", TYPE_VARCHAR, sizeof(StringRef), false},
57
        {"password_policy.expiration_seconds", TYPE_VARCHAR, sizeof(StringRef), false},
58
        {"password_policy.password_creation_time", TYPE_VARCHAR, sizeof(StringRef), false},
59
        {"password_policy.history_num", TYPE_VARCHAR, sizeof(StringRef), false},
60
        {"password_policy.history_passwords", TYPE_VARCHAR, sizeof(StringRef), false},
61
        {"password_policy.num_failed_login", TYPE_VARCHAR, sizeof(StringRef), false},
62
        {"password_policy.password_lock_seconds", TYPE_VARCHAR, sizeof(StringRef), false},
63
        {"password_policy.failed_login_counter", TYPE_VARCHAR, sizeof(StringRef), false},
64
        {"password_policy.lock_time", TYPE_VARCHAR, sizeof(StringRef), false}};
65
66
SchemaUserScanner::SchemaUserScanner()
67
0
        : SchemaScanner(_s_user_columns, TSchemaTableType::SCH_USER) {}
68
69
0
SchemaUserScanner::~SchemaUserScanner() = default;
70
71
0
Status SchemaUserScanner::start(RuntimeState* state) {
72
0
    TShowUserRequest request;
73
0
    RETURN_IF_ERROR(SchemaHelper::show_user(*(_param->common_param->ip), _param->common_param->port,
74
0
                                            request, &_user_result));
75
76
0
    return Status::OK();
77
0
}
78
79
0
Status SchemaUserScanner::get_next_block_internal(Block* block, bool* eos) {
80
0
    if (!_is_init) {
81
0
        return Status::InternalError("call this before initial.");
82
0
    }
83
0
    if (block == nullptr || eos == nullptr) {
84
0
        return Status::InternalError("invalid parameter.");
85
0
    }
86
87
0
    *eos = true;
88
0
    if (_user_result.userinfo_list.empty()) {
89
0
        return Status::OK();
90
0
    }
91
92
0
    return _fill_block_impl(block);
93
0
}
94
95
0
Status SchemaUserScanner::_fill_block_impl(Block* block) {
96
0
    SCOPED_TIMER(_fill_block_timer);
97
98
0
    const auto& userinfo_list = _user_result.userinfo_list;
99
0
    size_t row_num = userinfo_list.size();
100
0
    if (row_num == 0) {
101
0
        return Status::OK();
102
0
    }
103
104
0
    for (size_t col_idx = 0; col_idx < _s_user_columns.size(); ++col_idx) {
105
0
        std::vector<StringRef> str_refs(row_num);
106
0
        std::vector<int64_t> int_vals(row_num);
107
0
        std::vector<void*> datas(row_num);
108
0
        std::vector<std::string> column_values(
109
0
                row_num); // Store the strings to ensure their lifetime
110
111
0
        for (size_t row_idx = 0; row_idx < row_num; ++row_idx) {
112
0
            const auto& row = userinfo_list[row_idx];
113
0
            std::string column_value = row.size() > col_idx ? row[col_idx] : "";
114
115
            // Ensure column value assignment and type casting
116
0
            column_values[row_idx] = column_value;
117
0
            if (_s_user_columns[col_idx].type == TYPE_BIGINT) {
118
0
                int64_t val = !column_value.empty() ? std::stoll(column_value) : 0;
119
0
                int_vals[row_idx] = val;
120
0
                datas[row_idx] = &int_vals[row_idx];
121
0
            } else {
122
0
                str_refs[row_idx] =
123
0
                        StringRef(column_values[row_idx].data(), column_values[row_idx].size());
124
0
                datas[row_idx] = &str_refs[row_idx];
125
0
            }
126
0
        }
127
128
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, col_idx, datas));
129
0
    }
130
131
0
    return Status::OK();
132
0
}
133
134
} // namespace doris