Coverage Report

Created: 2026-03-14 06:50

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/information_schema/schema_tables_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_tables_scanner.h"
19
20
#include <gen_cpp/Descriptors_types.h>
21
#include <gen_cpp/FrontendService_types.h>
22
#include <stdint.h>
23
24
#include <string>
25
26
#include "common/status.h"
27
#include "core/data_type/define_primitive_type.h"
28
#include "core/string_ref.h"
29
#include "core/value/decimalv2_value.h"
30
#include "core/value/vdatetime_value.h"
31
#include "information_schema/schema_helper.h"
32
#include "runtime/runtime_profile.h"
33
#include "runtime/runtime_state.h"
34
#include "util/timezone_utils.h"
35
36
namespace doris {
37
class RuntimeState;
38
39
class Block;
40
41
std::vector<SchemaScanner::ColumnDesc> SchemaTablesScanner::_s_tbls_columns = {
42
        //   name,       type,          size,     is_null
43
        {"TABLE_CATALOG", TYPE_VARCHAR, sizeof(StringRef), true},
44
        {"TABLE_SCHEMA", TYPE_VARCHAR, sizeof(StringRef), false},
45
        {"TABLE_NAME", TYPE_VARCHAR, sizeof(StringRef), false},
46
        {"TABLE_TYPE", TYPE_VARCHAR, sizeof(StringRef), false},
47
        {"ENGINE", TYPE_VARCHAR, sizeof(StringRef), true},
48
        {"VERSION", TYPE_BIGINT, sizeof(int64_t), true},
49
        {"ROW_FORMAT", TYPE_VARCHAR, sizeof(StringRef), true},
50
        {"TABLE_ROWS", TYPE_BIGINT, sizeof(int64_t), true},
51
        {"AVG_ROW_LENGTH", TYPE_BIGINT, sizeof(int64_t), true},
52
        {"DATA_LENGTH", TYPE_BIGINT, sizeof(int64_t), true},
53
        {"MAX_DATA_LENGTH", TYPE_BIGINT, sizeof(int64_t), true},
54
        {"INDEX_LENGTH", TYPE_BIGINT, sizeof(int64_t), true},
55
        {"DATA_FREE", TYPE_BIGINT, sizeof(int64_t), true},
56
        {"AUTO_INCREMENT", TYPE_BIGINT, sizeof(int64_t), true},
57
        {"CREATE_TIME", TYPE_DATETIME, sizeof(int128_t), true},
58
        {"UPDATE_TIME", TYPE_DATETIME, sizeof(int128_t), true},
59
        {"CHECK_TIME", TYPE_DATETIME, sizeof(int128_t), true},
60
        {"TABLE_COLLATION", TYPE_VARCHAR, sizeof(StringRef), true},
61
        {"CHECKSUM", TYPE_BIGINT, sizeof(int64_t), true},
62
        {"CREATE_OPTIONS", TYPE_VARCHAR, sizeof(StringRef), true},
63
        {"TABLE_COMMENT", TYPE_VARCHAR, sizeof(StringRef), false},
64
};
65
66
SchemaTablesScanner::SchemaTablesScanner()
67
0
        : SchemaScanner(_s_tbls_columns, TSchemaTableType::SCH_TABLES), _db_index(0) {}
68
69
0
SchemaTablesScanner::~SchemaTablesScanner() {}
70
71
0
Status SchemaTablesScanner::start(RuntimeState* state) {
72
0
    if (!_is_init) {
73
0
        return Status::InternalError("used before initialized.");
74
0
    }
75
0
    SCOPED_TIMER(_get_db_timer);
76
0
    TGetDbsParams db_params;
77
0
    if (nullptr != _param->common_param->db) {
78
0
        db_params.__set_pattern(*(_param->common_param->db));
79
0
    }
80
0
    if (nullptr != _param->common_param->catalog) {
81
0
        db_params.__set_catalog(*(_param->common_param->catalog));
82
0
    }
83
0
    if (nullptr != _param->common_param->current_user_ident) {
84
0
        db_params.__set_current_user_ident(*(_param->common_param->current_user_ident));
85
0
    } else {
86
0
        if (nullptr != _param->common_param->user) {
87
0
            db_params.__set_user(*(_param->common_param->user));
88
0
        }
89
0
        if (nullptr != _param->common_param->user_ip) {
90
0
            db_params.__set_user_ip(*(_param->common_param->user_ip));
91
0
        }
92
0
    }
93
94
0
    if (nullptr != _param->common_param->ip && 0 != _param->common_param->port) {
95
0
        RETURN_IF_ERROR(SchemaHelper::get_db_names(
96
0
                *(_param->common_param->ip), _param->common_param->port, db_params, &_db_result));
97
0
    } else {
98
0
        return Status::InternalError("IP or port doesn't exists");
99
0
    }
100
0
    return Status::OK();
101
0
}
102
103
0
Status SchemaTablesScanner::_get_new_table() {
104
0
    SCOPED_TIMER(_get_table_timer);
105
0
    TGetTablesParams table_params;
106
0
    table_params.__set_db(_db_result.dbs[_db_index]);
107
0
    if (_db_result.__isset.catalogs) {
108
0
        table_params.__set_catalog(_db_result.catalogs[_db_index]);
109
0
    }
110
0
    _db_index++;
111
0
    if (nullptr != _param->common_param->wild) {
112
0
        table_params.__set_pattern(*(_param->common_param->wild));
113
0
    }
114
0
    if (nullptr != _param->common_param->table) {
115
0
        table_params.__set_table(*(_param->common_param->table));
116
0
    }
117
0
    if (nullptr != _param->common_param->current_user_ident) {
118
0
        table_params.__set_current_user_ident(*(_param->common_param->current_user_ident));
119
0
    } else {
120
0
        if (nullptr != _param->common_param->user) {
121
0
            table_params.__set_user(*(_param->common_param->user));
122
0
        }
123
0
        if (nullptr != _param->common_param->user_ip) {
124
0
            table_params.__set_user_ip(*(_param->common_param->user_ip));
125
0
        }
126
0
    }
127
128
0
    if (nullptr != _param->common_param->ip && 0 != _param->common_param->port) {
129
0
        RETURN_IF_ERROR(SchemaHelper::list_table_status(*(_param->common_param->ip),
130
0
                                                        _param->common_param->port, table_params,
131
0
                                                        &_table_result));
132
0
    } else {
133
0
        return Status::InternalError("IP or port doesn't exists");
134
0
    }
135
0
    return Status::OK();
136
0
}
137
138
0
Status SchemaTablesScanner::_fill_block_impl(Block* block) {
139
0
    SCOPED_TIMER(_fill_block_timer);
140
0
    auto table_num = _table_result.tables.size();
141
0
    if (table_num == 0) {
142
0
        return Status::OK();
143
0
    }
144
0
    std::vector<void*> null_datas(table_num, nullptr);
145
0
    std::vector<void*> datas(table_num);
146
147
    // catalog
148
0
    {
149
0
        if (_db_result.__isset.catalogs) {
150
0
            std::string catalog_name = _db_result.catalogs[_db_index - 1];
151
0
            StringRef str_slot = StringRef(catalog_name.c_str(), catalog_name.size());
152
0
            for (int i = 0; i < table_num; ++i) {
153
0
                datas[i] = &str_slot;
154
0
            }
155
0
            RETURN_IF_ERROR(fill_dest_column_for_range(block, 0, datas));
156
0
        } else {
157
0
            RETURN_IF_ERROR(fill_dest_column_for_range(block, 0, null_datas));
158
0
        }
159
0
    }
160
    // schema
161
0
    {
162
0
        std::string db_name = SchemaHelper::extract_db_name(_db_result.dbs[_db_index - 1]);
163
0
        StringRef str_slot = StringRef(db_name.c_str(), db_name.size());
164
0
        for (int i = 0; i < table_num; ++i) {
165
0
            datas[i] = &str_slot;
166
0
        }
167
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 1, datas));
168
0
    }
169
    // name
170
0
    {
171
0
        std::vector<StringRef> strs(table_num);
172
0
        for (int i = 0; i < table_num; ++i) {
173
0
            const std::string* src = &_table_result.tables[i].name;
174
0
            strs[i] = StringRef(src->c_str(), src->size());
175
0
            datas[i] = strs.data() + i;
176
0
        }
177
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 2, datas));
178
0
    }
179
    // type
180
0
    {
181
0
        std::vector<StringRef> strs(table_num);
182
0
        for (int i = 0; i < table_num; ++i) {
183
0
            const std::string* src = &_table_result.tables[i].type;
184
0
            strs[i] = StringRef(src->c_str(), src->size());
185
0
            datas[i] = strs.data() + i;
186
0
        }
187
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 3, datas));
188
0
    }
189
    // engine
190
0
    {
191
0
        std::vector<StringRef> strs(table_num);
192
0
        for (int i = 0; i < table_num; ++i) {
193
0
            const TTableStatus& tbl_status = _table_result.tables[i];
194
0
            if (tbl_status.__isset.engine) {
195
0
                const std::string* src = &tbl_status.engine;
196
0
                strs[i] = StringRef(src->c_str(), src->size());
197
0
                datas[i] = strs.data() + i;
198
0
            } else {
199
0
                datas[i] = nullptr;
200
0
            }
201
0
        }
202
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 4, datas));
203
0
    }
204
    // version
205
0
    { RETURN_IF_ERROR(fill_dest_column_for_range(block, 5, null_datas)); }
206
    // row_format
207
0
    { RETURN_IF_ERROR(fill_dest_column_for_range(block, 6, null_datas)); }
208
    // rows
209
0
    {
210
0
        std::vector<int64_t> srcs(table_num);
211
0
        for (int i = 0; i < table_num; ++i) {
212
0
            const TTableStatus& tbl_status = _table_result.tables[i];
213
0
            if (tbl_status.__isset.rows) {
214
0
                srcs[i] = tbl_status.rows;
215
0
                datas[i] = srcs.data() + i;
216
0
            } else {
217
0
                datas[i] = nullptr;
218
0
            }
219
0
        }
220
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 7, datas));
221
0
    }
222
    // avg_row_length
223
0
    {
224
0
        std::vector<int64_t> srcs(table_num);
225
0
        for (int i = 0; i < table_num; ++i) {
226
0
            const TTableStatus& tbl_status = _table_result.tables[i];
227
0
            if (tbl_status.__isset.avg_row_length) {
228
0
                srcs[i] = tbl_status.avg_row_length;
229
0
                datas[i] = srcs.data() + i;
230
0
            } else {
231
0
                datas[i] = nullptr;
232
0
            }
233
0
        }
234
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 8, datas));
235
0
    }
236
    // data_length
237
0
    {
238
0
        std::vector<int64_t> srcs(table_num);
239
0
        for (int i = 0; i < table_num; ++i) {
240
0
            const TTableStatus& tbl_status = _table_result.tables[i];
241
0
            if (tbl_status.__isset.data_length) {
242
0
                srcs[i] = tbl_status.data_length;
243
0
                datas[i] = srcs.data() + i;
244
0
            } else {
245
0
                datas[i] = nullptr;
246
0
            }
247
0
        }
248
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 9, datas));
249
0
    }
250
    // max_data_length
251
0
    { RETURN_IF_ERROR(fill_dest_column_for_range(block, 10, null_datas)); }
252
    // index_length
253
0
    {
254
0
        std::vector<int64_t> srcs(table_num);
255
0
        for (int i = 0; i < table_num; ++i) {
256
0
            const TTableStatus& tbl_status = _table_result.tables[i];
257
0
            if (tbl_status.__isset.index_length) {
258
0
                srcs[i] = tbl_status.index_length;
259
0
                datas[i] = srcs.data() + i;
260
0
            } else {
261
0
                datas[i] = nullptr;
262
0
            }
263
0
        }
264
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 11, datas));
265
0
    }
266
    // data_free
267
0
    { RETURN_IF_ERROR(fill_dest_column_for_range(block, 12, null_datas)); }
268
    // auto_increment
269
0
    { RETURN_IF_ERROR(fill_dest_column_for_range(block, 13, null_datas)); }
270
    // creation_time
271
0
    {
272
0
        std::vector<VecDateTimeValue> srcs(table_num);
273
0
        for (int i = 0; i < table_num; ++i) {
274
0
            const TTableStatus& tbl_status = _table_result.tables[i];
275
0
            if (tbl_status.__isset.create_time) {
276
0
                int64_t create_time = tbl_status.create_time;
277
0
                if (create_time <= 0) {
278
0
                    datas[i] = nullptr;
279
0
                } else {
280
0
                    srcs[i].from_unixtime(create_time, _timezone_obj);
281
0
                    datas[i] = srcs.data() + i;
282
0
                }
283
0
            } else {
284
0
                datas[i] = nullptr;
285
0
            }
286
0
        }
287
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 14, datas));
288
0
    }
289
    // update_time
290
0
    {
291
0
        std::vector<VecDateTimeValue> srcs(table_num);
292
0
        for (int i = 0; i < table_num; ++i) {
293
0
            const TTableStatus& tbl_status = _table_result.tables[i];
294
0
            if (tbl_status.__isset.update_time) {
295
0
                int64_t update_time = tbl_status.update_time;
296
0
                if (update_time <= 0) {
297
0
                    datas[i] = nullptr;
298
0
                } else {
299
0
                    srcs[i].from_unixtime(update_time, _timezone_obj);
300
0
                    datas[i] = srcs.data() + i;
301
0
                }
302
0
            } else {
303
0
                datas[i] = nullptr;
304
0
            }
305
0
        }
306
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 15, datas));
307
0
    }
308
    // check_time
309
0
    {
310
0
        std::vector<VecDateTimeValue> srcs(table_num);
311
0
        for (int i = 0; i < table_num; ++i) {
312
0
            const TTableStatus& tbl_status = _table_result.tables[i];
313
0
            if (tbl_status.__isset.last_check_time) {
314
0
                int64_t check_time = tbl_status.last_check_time;
315
0
                if (check_time <= 0) {
316
0
                    datas[i] = nullptr;
317
0
                } else {
318
0
                    srcs[i].from_unixtime(check_time, _timezone_obj);
319
0
                    datas[i] = srcs.data() + i;
320
0
                }
321
0
            } else {
322
0
                datas[i] = nullptr;
323
0
            }
324
0
        }
325
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 16, datas));
326
0
    }
327
    // collation
328
0
    {
329
0
        std::vector<StringRef> strs(table_num);
330
0
        for (int i = 0; i < table_num; ++i) {
331
0
            const TTableStatus& tbl_status = _table_result.tables[i];
332
0
            if (tbl_status.__isset.collation) {
333
0
                const std::string* src = &tbl_status.collation;
334
0
                strs[i] = StringRef(src->c_str(), src->size());
335
0
                datas[i] = strs.data() + i;
336
0
            } else {
337
0
                datas[i] = nullptr;
338
0
            }
339
0
        }
340
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 17, datas));
341
0
    }
342
    // checksum
343
0
    { RETURN_IF_ERROR(fill_dest_column_for_range(block, 18, null_datas)); }
344
    // create_options
345
0
    { RETURN_IF_ERROR(fill_dest_column_for_range(block, 19, null_datas)); }
346
    // create_comment
347
0
    {
348
0
        std::vector<StringRef> strs(table_num);
349
0
        for (int i = 0; i < table_num; ++i) {
350
0
            const std::string* src = &_table_result.tables[i].comment;
351
0
            strs[i] = StringRef(src->c_str(), src->size());
352
0
            datas[i] = strs.data() + i;
353
0
        }
354
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 20, datas));
355
0
    }
356
0
    return Status::OK();
357
0
}
358
359
0
Status SchemaTablesScanner::get_next_block_internal(Block* block, bool* eos) {
360
0
    if (!_is_init) {
361
0
        return Status::InternalError("Used before initialized.");
362
0
    }
363
0
    if (nullptr == block || nullptr == eos) {
364
0
        return Status::InternalError("input pointer is nullptr.");
365
0
    }
366
0
    if (_db_index < _db_result.dbs.size()) {
367
0
        RETURN_IF_ERROR(_get_new_table());
368
0
    } else {
369
0
        *eos = true;
370
0
        return Status::OK();
371
0
    }
372
0
    *eos = false;
373
0
    return _fill_block_impl(block);
374
0
}
375
376
} // namespace doris