Coverage Report

Created: 2026-07-08 16:24

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
    table_params.__set_required_columns(_param->common_param->required_columns);
118
0
    if (nullptr != _param->common_param->current_user_ident) {
119
0
        table_params.__set_current_user_ident(*(_param->common_param->current_user_ident));
120
0
    } else {
121
0
        if (nullptr != _param->common_param->user) {
122
0
            table_params.__set_user(*(_param->common_param->user));
123
0
        }
124
0
        if (nullptr != _param->common_param->user_ip) {
125
0
            table_params.__set_user_ip(*(_param->common_param->user_ip));
126
0
        }
127
0
    }
128
129
0
    if (nullptr != _param->common_param->ip && 0 != _param->common_param->port) {
130
0
        RETURN_IF_ERROR(SchemaHelper::list_table_status(*(_param->common_param->ip),
131
0
                                                        _param->common_param->port, table_params,
132
0
                                                        &_table_result));
133
0
    } else {
134
0
        return Status::InternalError("IP or port doesn't exists");
135
0
    }
136
0
    return Status::OK();
137
0
}
138
139
0
Status SchemaTablesScanner::_fill_block_impl(Block* block) {
140
0
    SCOPED_TIMER(_fill_block_timer);
141
0
    auto table_num = _table_result.tables.size();
142
0
    if (table_num == 0) {
143
0
        return Status::OK();
144
0
    }
145
0
    std::vector<void*> null_datas(table_num, nullptr);
146
0
    std::vector<void*> datas(table_num);
147
148
    // catalog
149
0
    {
150
0
        if (_db_result.__isset.catalogs) {
151
0
            std::string catalog_name = _db_result.catalogs[_db_index - 1];
152
0
            StringRef str_slot = StringRef(catalog_name.c_str(), catalog_name.size());
153
0
            for (int i = 0; i < table_num; ++i) {
154
0
                datas[i] = &str_slot;
155
0
            }
156
0
            RETURN_IF_ERROR(fill_dest_column_for_range(block, 0, datas));
157
0
        } else {
158
0
            RETURN_IF_ERROR(fill_dest_column_for_range(block, 0, null_datas));
159
0
        }
160
0
    }
161
    // schema
162
0
    {
163
0
        std::string db_name = SchemaHelper::extract_db_name(_db_result.dbs[_db_index - 1]);
164
0
        StringRef str_slot = StringRef(db_name.c_str(), db_name.size());
165
0
        for (int i = 0; i < table_num; ++i) {
166
0
            datas[i] = &str_slot;
167
0
        }
168
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 1, datas));
169
0
    }
170
    // name
171
0
    {
172
0
        std::vector<StringRef> strs(table_num);
173
0
        for (int i = 0; i < table_num; ++i) {
174
0
            const std::string* src = &_table_result.tables[i].name;
175
0
            strs[i] = StringRef(src->c_str(), src->size());
176
0
            datas[i] = strs.data() + i;
177
0
        }
178
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 2, datas));
179
0
    }
180
    // type
181
0
    {
182
0
        std::vector<StringRef> strs(table_num);
183
0
        for (int i = 0; i < table_num; ++i) {
184
0
            const std::string* src = &_table_result.tables[i].type;
185
0
            strs[i] = StringRef(src->c_str(), src->size());
186
0
            datas[i] = strs.data() + i;
187
0
        }
188
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 3, datas));
189
0
    }
190
    // engine
191
0
    {
192
0
        std::vector<StringRef> strs(table_num);
193
0
        for (int i = 0; i < table_num; ++i) {
194
0
            const TTableStatus& tbl_status = _table_result.tables[i];
195
0
            if (tbl_status.__isset.engine) {
196
0
                const std::string* src = &tbl_status.engine;
197
0
                strs[i] = StringRef(src->c_str(), src->size());
198
0
                datas[i] = strs.data() + i;
199
0
            } else {
200
0
                datas[i] = nullptr;
201
0
            }
202
0
        }
203
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 4, datas));
204
0
    }
205
    // version
206
0
    { RETURN_IF_ERROR(fill_dest_column_for_range(block, 5, null_datas)); }
207
    // row_format
208
0
    { RETURN_IF_ERROR(fill_dest_column_for_range(block, 6, null_datas)); }
209
    // rows
210
0
    {
211
0
        std::vector<int64_t> srcs(table_num);
212
0
        for (int i = 0; i < table_num; ++i) {
213
0
            const TTableStatus& tbl_status = _table_result.tables[i];
214
0
            if (tbl_status.__isset.rows) {
215
0
                srcs[i] = tbl_status.rows;
216
0
                datas[i] = srcs.data() + i;
217
0
            } else {
218
0
                datas[i] = nullptr;
219
0
            }
220
0
        }
221
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 7, datas));
222
0
    }
223
    // avg_row_length
224
0
    {
225
0
        std::vector<int64_t> srcs(table_num);
226
0
        for (int i = 0; i < table_num; ++i) {
227
0
            const TTableStatus& tbl_status = _table_result.tables[i];
228
0
            if (tbl_status.__isset.avg_row_length) {
229
0
                srcs[i] = tbl_status.avg_row_length;
230
0
                datas[i] = srcs.data() + i;
231
0
            } else {
232
0
                datas[i] = nullptr;
233
0
            }
234
0
        }
235
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 8, datas));
236
0
    }
237
    // data_length
238
0
    {
239
0
        std::vector<int64_t> srcs(table_num);
240
0
        for (int i = 0; i < table_num; ++i) {
241
0
            const TTableStatus& tbl_status = _table_result.tables[i];
242
0
            if (tbl_status.__isset.data_length) {
243
0
                srcs[i] = tbl_status.data_length;
244
0
                datas[i] = srcs.data() + i;
245
0
            } else {
246
0
                datas[i] = nullptr;
247
0
            }
248
0
        }
249
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 9, datas));
250
0
    }
251
    // max_data_length
252
0
    { RETURN_IF_ERROR(fill_dest_column_for_range(block, 10, null_datas)); }
253
    // index_length
254
0
    {
255
0
        std::vector<int64_t> srcs(table_num);
256
0
        for (int i = 0; i < table_num; ++i) {
257
0
            const TTableStatus& tbl_status = _table_result.tables[i];
258
0
            if (tbl_status.__isset.index_length) {
259
0
                srcs[i] = tbl_status.index_length;
260
0
                datas[i] = srcs.data() + i;
261
0
            } else {
262
0
                datas[i] = nullptr;
263
0
            }
264
0
        }
265
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 11, datas));
266
0
    }
267
    // data_free
268
0
    { RETURN_IF_ERROR(fill_dest_column_for_range(block, 12, null_datas)); }
269
    // auto_increment
270
0
    { RETURN_IF_ERROR(fill_dest_column_for_range(block, 13, null_datas)); }
271
    // creation_time
272
0
    {
273
0
        std::vector<VecDateTimeValue> srcs(table_num);
274
0
        for (int i = 0; i < table_num; ++i) {
275
0
            const TTableStatus& tbl_status = _table_result.tables[i];
276
0
            if (tbl_status.__isset.create_time) {
277
0
                int64_t create_time = tbl_status.create_time;
278
0
                if (create_time <= 0) {
279
0
                    datas[i] = nullptr;
280
0
                } else {
281
0
                    srcs[i].from_unixtime(create_time, _timezone_obj);
282
0
                    datas[i] = srcs.data() + i;
283
0
                }
284
0
            } else {
285
0
                datas[i] = nullptr;
286
0
            }
287
0
        }
288
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 14, datas));
289
0
    }
290
    // update_time
291
0
    {
292
0
        std::vector<VecDateTimeValue> srcs(table_num);
293
0
        for (int i = 0; i < table_num; ++i) {
294
0
            const TTableStatus& tbl_status = _table_result.tables[i];
295
0
            if (tbl_status.__isset.update_time) {
296
0
                int64_t update_time = tbl_status.update_time;
297
0
                if (update_time <= 0) {
298
0
                    datas[i] = nullptr;
299
0
                } else {
300
0
                    srcs[i].from_unixtime(update_time, _timezone_obj);
301
0
                    datas[i] = srcs.data() + i;
302
0
                }
303
0
            } else {
304
0
                datas[i] = nullptr;
305
0
            }
306
0
        }
307
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 15, datas));
308
0
    }
309
    // check_time
310
0
    {
311
0
        std::vector<VecDateTimeValue> srcs(table_num);
312
0
        for (int i = 0; i < table_num; ++i) {
313
0
            const TTableStatus& tbl_status = _table_result.tables[i];
314
0
            if (tbl_status.__isset.last_check_time) {
315
0
                int64_t check_time = tbl_status.last_check_time;
316
0
                if (check_time <= 0) {
317
0
                    datas[i] = nullptr;
318
0
                } else {
319
0
                    srcs[i].from_unixtime(check_time, _timezone_obj);
320
0
                    datas[i] = srcs.data() + i;
321
0
                }
322
0
            } else {
323
0
                datas[i] = nullptr;
324
0
            }
325
0
        }
326
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 16, datas));
327
0
    }
328
    // collation
329
0
    {
330
0
        std::vector<StringRef> strs(table_num);
331
0
        for (int i = 0; i < table_num; ++i) {
332
0
            const TTableStatus& tbl_status = _table_result.tables[i];
333
0
            if (tbl_status.__isset.collation) {
334
0
                const std::string* src = &tbl_status.collation;
335
0
                strs[i] = StringRef(src->c_str(), src->size());
336
0
                datas[i] = strs.data() + i;
337
0
            } else {
338
0
                datas[i] = nullptr;
339
0
            }
340
0
        }
341
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 17, datas));
342
0
    }
343
    // checksum
344
0
    { RETURN_IF_ERROR(fill_dest_column_for_range(block, 18, null_datas)); }
345
    // create_options
346
0
    { RETURN_IF_ERROR(fill_dest_column_for_range(block, 19, null_datas)); }
347
    // create_comment
348
0
    {
349
0
        std::vector<StringRef> strs(table_num);
350
0
        for (int i = 0; i < table_num; ++i) {
351
0
            const std::string* src = &_table_result.tables[i].comment;
352
0
            strs[i] = StringRef(src->c_str(), src->size());
353
0
            datas[i] = strs.data() + i;
354
0
        }
355
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 20, datas));
356
0
    }
357
0
    return Status::OK();
358
0
}
359
360
0
Status SchemaTablesScanner::get_next_block_internal(Block* block, bool* eos) {
361
0
    if (!_is_init) {
362
0
        return Status::InternalError("Used before initialized.");
363
0
    }
364
0
    if (nullptr == block || nullptr == eos) {
365
0
        return Status::InternalError("input pointer is nullptr.");
366
0
    }
367
0
    if (_db_index < _db_result.dbs.size()) {
368
0
        RETURN_IF_ERROR(_get_new_table());
369
0
    } else {
370
0
        *eos = true;
371
0
        return Status::OK();
372
0
    }
373
0
    *eos = false;
374
0
    return _fill_block_impl(block);
375
0
}
376
377
} // namespace doris