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_views_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_views_scanner.h"
19
20
#include <gen_cpp/Descriptors_types.h>
21
#include <gen_cpp/FrontendService_types.h>
22
23
#include <string>
24
25
#include "core/data_type/define_primitive_type.h"
26
#include "core/string_ref.h"
27
#include "information_schema/schema_helper.h"
28
#include "runtime/runtime_profile.h"
29
30
namespace doris {
31
class RuntimeState;
32
class Block;
33
34
std::vector<SchemaScanner::ColumnDesc> SchemaViewsScanner::_s_tbls_columns = {
35
        //   name,       type,          size,     is_null
36
        {"TABLE_CATALOG", TYPE_VARCHAR, sizeof(StringRef), true},
37
        {"TABLE_SCHEMA", TYPE_VARCHAR, sizeof(StringRef), false},
38
        {"TABLE_NAME", TYPE_VARCHAR, sizeof(StringRef), false},
39
        {"VIEW_DEFINITION", TYPE_VARCHAR, sizeof(StringRef), true},
40
        {"CHECK_OPTION", TYPE_VARCHAR, sizeof(StringRef), true},
41
        {"IS_UPDATABLE", TYPE_VARCHAR, sizeof(StringRef), true},
42
        {"DEFINER", TYPE_VARCHAR, sizeof(StringRef), true},
43
        {"SECURITY_TYPE", TYPE_VARCHAR, sizeof(StringRef), true},
44
        {"CHARACTER_SET_CLIENT", TYPE_VARCHAR, sizeof(StringRef), true},
45
        {"COLLATION_CONNECTION", TYPE_VARCHAR, sizeof(StringRef), true},
46
};
47
48
SchemaViewsScanner::SchemaViewsScanner()
49
0
        : SchemaScanner(_s_tbls_columns, TSchemaTableType::SCH_VIEWS), _db_index(0) {}
50
51
0
SchemaViewsScanner::~SchemaViewsScanner() {}
52
53
0
Status SchemaViewsScanner::start(RuntimeState* state) {
54
0
    if (!_is_init) {
55
0
        return Status::InternalError("used before initialized.");
56
0
    }
57
0
    SCOPED_TIMER(_get_db_timer);
58
0
    TGetDbsParams db_params;
59
0
    if (nullptr != _param->common_param->db) {
60
0
        db_params.__set_pattern(*(_param->common_param->db));
61
0
    }
62
0
    if (nullptr != _param->common_param->catalog) {
63
0
        db_params.__set_catalog(*(_param->common_param->catalog));
64
0
    }
65
0
    if (nullptr != _param->common_param->current_user_ident) {
66
0
        db_params.__set_current_user_ident(*(_param->common_param->current_user_ident));
67
0
    } else {
68
0
        if (nullptr != _param->common_param->user) {
69
0
            db_params.__set_user(*(_param->common_param->user));
70
0
        }
71
0
        if (nullptr != _param->common_param->user_ip) {
72
0
            db_params.__set_user_ip(*(_param->common_param->user_ip));
73
0
        }
74
0
    }
75
76
0
    if (nullptr != _param->common_param->ip && 0 != _param->common_param->port) {
77
0
        RETURN_IF_ERROR(SchemaHelper::get_db_names(
78
0
                *(_param->common_param->ip), _param->common_param->port, db_params, &_db_result));
79
0
    } else {
80
0
        return Status::InternalError("IP or port doesn't exists");
81
0
    }
82
0
    return Status::OK();
83
0
}
84
85
0
Status SchemaViewsScanner::_get_new_table() {
86
0
    SCOPED_TIMER(_get_table_timer);
87
0
    TGetTablesParams table_params;
88
0
    table_params.__set_db(_db_result.dbs[_db_index++]);
89
0
    if (nullptr != _param->common_param->wild) {
90
0
        table_params.__set_pattern(*(_param->common_param->wild));
91
0
    }
92
0
    if (nullptr != _param->common_param->current_user_ident) {
93
0
        table_params.__set_current_user_ident(*(_param->common_param->current_user_ident));
94
0
    } else {
95
0
        if (nullptr != _param->common_param->user) {
96
0
            table_params.__set_user(*(_param->common_param->user));
97
0
        }
98
0
        if (nullptr != _param->common_param->user_ip) {
99
0
            table_params.__set_user_ip(*(_param->common_param->user_ip));
100
0
        }
101
0
    }
102
0
    table_params.__set_type("VIEW");
103
104
0
    if (nullptr != _param->common_param->ip && 0 != _param->common_param->port) {
105
0
        RETURN_IF_ERROR(SchemaHelper::list_table_status(*(_param->common_param->ip),
106
0
                                                        _param->common_param->port, table_params,
107
0
                                                        &_table_result));
108
0
    } else {
109
0
        return Status::InternalError("IP or port doesn't exists");
110
0
    }
111
0
    return Status::OK();
112
0
}
113
114
0
Status SchemaViewsScanner::get_next_block_internal(Block* block, bool* eos) {
115
0
    if (!_is_init) {
116
0
        return Status::InternalError("Used before initialized.");
117
0
    }
118
0
    if (nullptr == block || nullptr == eos) {
119
0
        return Status::InternalError("input pointer is nullptr.");
120
0
    }
121
0
    if (_db_index < _db_result.dbs.size()) {
122
0
        RETURN_IF_ERROR(_get_new_table());
123
0
    } else {
124
0
        *eos = true;
125
0
        return Status::OK();
126
0
    }
127
0
    *eos = false;
128
0
    return _fill_block_impl(block);
129
0
}
130
131
0
Status SchemaViewsScanner::_fill_block_impl(Block* block) {
132
0
    SCOPED_TIMER(_fill_block_timer);
133
0
    auto tables_num = _table_result.tables.size();
134
0
    if (tables_num == 0) {
135
0
        return Status::OK();
136
0
    }
137
0
    std::vector<void*> null_datas(tables_num, nullptr);
138
0
    std::vector<void*> datas(tables_num);
139
140
    // catalog
141
0
    {
142
0
        std::string catalog_name = _db_result.catalogs[_db_index - 1];
143
0
        StringRef str = StringRef(catalog_name.c_str(), catalog_name.size());
144
0
        for (int i = 0; i < tables_num; ++i) {
145
0
            datas[i] = &str;
146
0
        }
147
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 0, datas));
148
0
    }
149
    // schema
150
0
    {
151
0
        std::string db_name = SchemaHelper::extract_db_name(_db_result.dbs[_db_index - 1]);
152
0
        StringRef str = StringRef(db_name.c_str(), db_name.size());
153
0
        for (int i = 0; i < tables_num; ++i) {
154
0
            datas[i] = &str;
155
0
        }
156
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 1, datas));
157
0
    }
158
    // name
159
0
    {
160
0
        std::vector<StringRef> strs(tables_num);
161
0
        for (int i = 0; i < tables_num; ++i) {
162
0
            const TTableStatus& tbl_status = _table_result.tables[i];
163
0
            const std::string* src = &tbl_status.name;
164
0
            strs[i] = StringRef(src->c_str(), src->size());
165
0
            datas[i] = strs.data() + i;
166
0
        }
167
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 2, datas));
168
0
    }
169
    // definition
170
0
    {
171
0
        std::vector<StringRef> strs(tables_num);
172
0
        for (int i = 0; i < tables_num; ++i) {
173
0
            const TTableStatus& tbl_status = _table_result.tables[i];
174
0
            const std::string* src = &tbl_status.ddl_sql;
175
0
            strs[i] = StringRef(src->c_str(), src->length());
176
0
            datas[i] = strs.data() + i;
177
0
        }
178
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 3, datas));
179
0
    }
180
    // check_option
181
0
    {
182
0
        const std::string check_option = "NONE";
183
0
        StringRef str = StringRef(check_option.c_str(), check_option.length());
184
0
        for (int i = 0; i < tables_num; ++i) {
185
0
            datas[i] = &str;
186
0
        }
187
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 4, datas));
188
0
    }
189
    // is_updatable
190
0
    {
191
        // This is from views in mysql
192
0
        const std::string is_updatable = "NO";
193
0
        StringRef str = StringRef(is_updatable.c_str(), is_updatable.length());
194
0
        for (int i = 0; i < tables_num; ++i) {
195
0
            datas[i] = &str;
196
0
        }
197
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 5, datas));
198
0
    }
199
    // definer
200
0
    {
201
        // This is from views in mysql
202
0
        const std::string definer = "root@%";
203
0
        StringRef str = StringRef(definer.c_str(), definer.length());
204
0
        for (int i = 0; i < tables_num; ++i) {
205
0
            datas[i] = &str;
206
0
        }
207
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 6, datas));
208
0
    }
209
    // security_type
210
0
    {
211
        // This is from views in mysql
212
0
        const std::string security_type = "DEFINER";
213
0
        StringRef str = StringRef(security_type.c_str(), security_type.length());
214
0
        for (int i = 0; i < tables_num; ++i) {
215
0
            datas[i] = &str;
216
0
        }
217
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 7, datas));
218
0
    }
219
    // character_set_client
220
0
    {
221
        // This is from views in mysql
222
0
        const std::string encoding = "utf8";
223
0
        StringRef str = StringRef(encoding.c_str(), encoding.length());
224
0
        for (int i = 0; i < tables_num; ++i) {
225
0
            datas[i] = &str;
226
0
        }
227
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 8, datas));
228
0
    }
229
    // collation_connection
230
0
    { RETURN_IF_ERROR(fill_dest_column_for_range(block, 9, null_datas)); }
231
0
    return Status::OK();
232
0
}
233
234
} // namespace doris