Coverage Report

Created: 2026-04-16 17:24

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/information_schema/schema_columns_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_columns_scanner.h"
19
20
#include <fmt/format.h>
21
#include <gen_cpp/Descriptors_types.h>
22
#include <gen_cpp/FrontendService_types.h>
23
#include <gen_cpp/Types_types.h>
24
25
#include <cstdint>
26
27
#include "core/data_type/define_primitive_type.h"
28
#include "core/string_ref.h"
29
#include "information_schema/schema_helper.h"
30
#include "runtime/runtime_profile.h"
31
32
namespace doris {
33
34
class RuntimeState;
35
36
class Block;
37
38
std::vector<SchemaScanner::ColumnDesc> SchemaColumnsScanner::_s_col_columns = {
39
        //   name,       type,          size,                     is_null
40
        {"TABLE_CATALOG", TYPE_VARCHAR, sizeof(StringRef), true},
41
        {"TABLE_SCHEMA", TYPE_VARCHAR, sizeof(StringRef), false},
42
        {"TABLE_NAME", TYPE_VARCHAR, sizeof(StringRef), false},
43
        {"COLUMN_NAME", TYPE_VARCHAR, sizeof(StringRef), false},
44
        {"ORDINAL_POSITION", TYPE_BIGINT, sizeof(int64_t), false},
45
        {"COLUMN_DEFAULT", TYPE_VARCHAR, sizeof(StringRef), true},
46
        {"IS_NULLABLE", TYPE_VARCHAR, sizeof(StringRef), false},
47
        {"DATA_TYPE", TYPE_VARCHAR, sizeof(StringRef), false},
48
        {"CHARACTER_MAXIMUM_LENGTH", TYPE_BIGINT, sizeof(int64_t), true},
49
        {"CHARACTER_OCTET_LENGTH", TYPE_BIGINT, sizeof(int64_t), true},
50
        {"NUMERIC_PRECISION", TYPE_BIGINT, sizeof(int64_t), true},
51
        {"NUMERIC_SCALE", TYPE_BIGINT, sizeof(int64_t), true},
52
        {"DATETIME_PRECISION", TYPE_BIGINT, sizeof(int64_t), true},
53
        {"CHARACTER_SET_NAME", TYPE_VARCHAR, sizeof(StringRef), true},
54
        {"COLLATION_NAME", TYPE_VARCHAR, sizeof(StringRef), true},
55
        {"COLUMN_TYPE", TYPE_VARCHAR, sizeof(StringRef), false},
56
        {"COLUMN_KEY", TYPE_VARCHAR, sizeof(StringRef), false},
57
        {"EXTRA", TYPE_VARCHAR, sizeof(StringRef), false},
58
        {"PRIVILEGES", TYPE_VARCHAR, sizeof(StringRef), false},
59
        {"COLUMN_COMMENT", TYPE_VARCHAR, sizeof(StringRef), false},
60
        {"COLUMN_SIZE", TYPE_BIGINT, sizeof(int64_t), true},
61
        {"DECIMAL_DIGITS", TYPE_BIGINT, sizeof(int64_t), true},
62
        {"GENERATION_EXPRESSION", TYPE_VARCHAR, sizeof(StringRef), true},
63
        {"SRS_ID", TYPE_BIGINT, sizeof(int64_t), true},
64
};
65
66
SchemaColumnsScanner::SchemaColumnsScanner()
67
0
        : SchemaScanner(_s_col_columns, TSchemaTableType::SCH_COLUMNS),
68
0
          _db_index(0),
69
0
          _table_index(0) {}
70
71
0
SchemaColumnsScanner::~SchemaColumnsScanner() = default;
72
73
0
Status SchemaColumnsScanner::start(RuntimeState* state) {
74
0
    SCOPED_TIMER(_get_db_timer);
75
0
    if (!_is_init) {
76
0
        return Status::InternalError("schema columns scanner not inited.");
77
0
    }
78
    // get all database
79
0
    TGetDbsParams db_params;
80
0
    if (nullptr != _param->common_param->db) {
81
0
        db_params.__set_pattern(*(_param->common_param->db));
82
0
    }
83
0
    if (nullptr != _param->common_param->catalog) {
84
0
        db_params.__set_catalog(*(_param->common_param->catalog));
85
0
    }
86
0
    if (nullptr != _param->common_param->current_user_ident) {
87
0
        db_params.__set_current_user_ident(*_param->common_param->current_user_ident);
88
0
    } else {
89
0
        if (nullptr != _param->common_param->user) {
90
0
            db_params.__set_user(*(_param->common_param->user));
91
0
        }
92
0
        if (nullptr != _param->common_param->user_ip) {
93
0
            db_params.__set_user_ip(*(_param->common_param->user_ip));
94
0
        }
95
0
    }
96
97
0
    if (nullptr != _param->common_param->ip && 0 != _param->common_param->port) {
98
0
        RETURN_IF_ERROR(SchemaHelper::get_db_names(
99
0
                *(_param->common_param->ip), _param->common_param->port, db_params, &_db_result));
100
0
    } else {
101
0
        return Status::InternalError("IP or port doesn't exists");
102
0
    }
103
104
0
    return Status::OK();
105
0
}
106
107
//For compatibility with mysql the result of DATA_TYPE in information_schema.columns
108
0
std::string SchemaColumnsScanner::_to_mysql_data_type_string(TColumnDesc& desc) {
109
0
    switch (desc.columnType) {
110
0
    case TPrimitiveType::BOOLEAN:
111
0
        return "tinyint";
112
0
    case TPrimitiveType::TINYINT:
113
0
        return "tinyint";
114
0
    case TPrimitiveType::SMALLINT:
115
0
        return "smallint";
116
0
    case TPrimitiveType::INT:
117
0
        return "int";
118
0
    case TPrimitiveType::BIGINT:
119
0
        return "bigint";
120
0
    case TPrimitiveType::LARGEINT:
121
0
        return "bigint unsigned";
122
0
    case TPrimitiveType::FLOAT:
123
0
        return "float";
124
0
    case TPrimitiveType::DOUBLE:
125
0
        return "double";
126
0
    case TPrimitiveType::VARCHAR:
127
0
    case TPrimitiveType::STRING:
128
0
        return "varchar";
129
0
    case TPrimitiveType::CHAR:
130
0
        return "char";
131
0
    case TPrimitiveType::DATE:
132
0
    case TPrimitiveType::DATEV2:
133
0
        return "date";
134
0
    case TPrimitiveType::DATETIME:
135
0
    case TPrimitiveType::DATETIMEV2:
136
0
        return "datetime";
137
0
    case TPrimitiveType::TIMESTAMPTZ:
138
0
        return "timestamp";
139
0
    case TPrimitiveType::DECIMAL32:
140
0
    case TPrimitiveType::DECIMAL64:
141
0
    case TPrimitiveType::DECIMAL128I:
142
0
    case TPrimitiveType::DECIMAL256:
143
0
    case TPrimitiveType::DECIMALV2: {
144
0
        return "decimal";
145
0
    }
146
0
    case TPrimitiveType::HLL: {
147
0
        return "hll";
148
0
    }
149
0
    case TPrimitiveType::BITMAP: {
150
0
        return "bitmap";
151
0
    }
152
0
    case TPrimitiveType::JSONB: {
153
0
        return "json";
154
0
    }
155
0
    case TPrimitiveType::MAP: {
156
0
        return "map";
157
0
    }
158
0
    case TPrimitiveType::ARRAY: {
159
0
        return "array";
160
0
    }
161
0
    case TPrimitiveType::STRUCT: {
162
0
        return "struct";
163
0
    }
164
0
    case TPrimitiveType::IPV4:
165
0
        return "ipv4";
166
0
    case TPrimitiveType::IPV6:
167
0
        return "ipv6";
168
0
    case TPrimitiveType::VARIANT:
169
0
        return "variant";
170
0
    default:
171
0
        return "unknown";
172
0
    }
173
0
}
174
175
0
std::string SchemaColumnsScanner::_type_to_string(TColumnDesc& desc) {
176
0
    switch (desc.columnType) {
177
0
    case TPrimitiveType::BOOLEAN:
178
0
        return "tinyint(1)";
179
0
    case TPrimitiveType::TINYINT:
180
0
        return "tinyint(4)";
181
0
    case TPrimitiveType::SMALLINT:
182
0
        return "smallint(6)";
183
0
    case TPrimitiveType::INT:
184
0
        return "int(11)";
185
0
    case TPrimitiveType::BIGINT:
186
0
        return "bigint(20)";
187
0
    case TPrimitiveType::LARGEINT:
188
0
        return "largeint";
189
0
    case TPrimitiveType::FLOAT:
190
0
        return "float";
191
0
    case TPrimitiveType::DOUBLE:
192
0
        return "double";
193
0
    case TPrimitiveType::VARCHAR:
194
0
        if (desc.__isset.columnLength) {
195
0
            return "varchar(" + std::to_string(desc.columnLength) + ")";
196
0
        } else {
197
0
            return "varchar(20)";
198
0
        }
199
0
    case TPrimitiveType::STRING:
200
0
        return "string";
201
0
    case TPrimitiveType::CHAR:
202
0
        if (desc.__isset.columnLength) {
203
0
            return "char(" + std::to_string(desc.columnLength) + ")";
204
0
        } else {
205
0
            return "char(20)";
206
0
        }
207
0
    case TPrimitiveType::DATE:
208
0
        return "date";
209
0
    case TPrimitiveType::DATETIME:
210
0
        return "datetime";
211
0
    case TPrimitiveType::DECIMALV2: {
212
0
        return fmt::format(
213
0
                "decimal({}, {})",
214
0
                desc.__isset.columnPrecision ? std::to_string(desc.columnPrecision) : "27",
215
0
                desc.__isset.columnScale ? std::to_string(desc.columnScale) : "9");
216
0
    }
217
0
    case TPrimitiveType::DECIMAL32:
218
0
    case TPrimitiveType::DECIMAL64:
219
0
    case TPrimitiveType::DECIMAL128I:
220
0
    case TPrimitiveType::DECIMAL256: {
221
0
        fmt::memory_buffer debug_string_buffer;
222
0
        fmt::format_to(
223
0
                debug_string_buffer, "decimalv3({}, {})",
224
0
                desc.__isset.columnPrecision ? std::to_string(desc.columnPrecision) : "UNKNOWN",
225
0
                desc.__isset.columnScale ? std::to_string(desc.columnScale) : "UNKNOWN");
226
0
        return fmt::to_string(debug_string_buffer);
227
0
    }
228
0
    case TPrimitiveType::DATEV2:
229
0
        return "date";
230
0
    case TPrimitiveType::DATETIMEV2: {
231
0
        fmt::memory_buffer debug_string_buffer;
232
0
        if (!desc.__isset.columnScale || desc.columnScale == 0) {
233
0
            fmt::format_to(debug_string_buffer, "datetime");
234
0
        } else {
235
0
            fmt::format_to(debug_string_buffer, "datetime({})",
236
0
                           desc.__isset.columnScale ? std::to_string(desc.columnScale) : "UNKNOWN");
237
0
        }
238
0
        return fmt::to_string(debug_string_buffer);
239
0
    }
240
0
    case TPrimitiveType::TIMESTAMPTZ: {
241
0
        fmt::memory_buffer debug_string_buffer;
242
0
        if (!desc.__isset.columnScale || desc.columnScale == 0) {
243
0
            fmt::format_to(debug_string_buffer, "timestamp");
244
0
        } else {
245
0
            fmt::format_to(debug_string_buffer, "timestamp({})",
246
0
                           desc.__isset.columnScale ? std::to_string(desc.columnScale) : "UNKNOWN");
247
0
        }
248
0
        return fmt::to_string(debug_string_buffer);
249
0
    }
250
0
    case TPrimitiveType::HLL: {
251
0
        return "hll";
252
0
    }
253
0
    case TPrimitiveType::BITMAP: {
254
0
        return "bitmap";
255
0
    }
256
0
    case TPrimitiveType::JSONB: {
257
0
        return "json";
258
0
    }
259
0
    case TPrimitiveType::MAP: {
260
        // for old be service we should compatible
261
0
        std::string ret = "map<";
262
0
        if (!desc.children.empty()) {
263
0
            for (int i = 0; i < desc.children.size() - 1; ++i) {
264
0
                ret += _type_to_string(desc.children[i]) + ",";
265
0
            }
266
0
            ret += _type_to_string(desc.children[desc.children.size() - 1]);
267
0
        }
268
0
        ret += ">";
269
0
        return ret;
270
0
    }
271
0
    case TPrimitiveType::ARRAY: {
272
        // for old be service we should compitable
273
0
        std::string ret = "array<";
274
0
        if (!desc.children.empty()) {
275
0
            ret += _type_to_string(desc.children[0]);
276
0
        }
277
0
        ret += ">";
278
0
        return ret;
279
0
    }
280
0
    case TPrimitiveType::STRUCT: {
281
        // for old be service we should compitable
282
0
        std::string ret = "struct<";
283
0
        if (!desc.children.empty()) {
284
0
            for (int i = 0; i < desc.children.size() - 1; ++i) {
285
0
                ret += _type_to_string(desc.children[i]) + ",";
286
0
            }
287
0
            ret += _type_to_string(desc.children[desc.children.size() - 1]);
288
0
        }
289
0
        ret += ">";
290
0
        return ret;
291
0
    }
292
0
    case TPrimitiveType::IPV4:
293
0
        return "ipv4";
294
0
    case TPrimitiveType::IPV6:
295
0
        return "ipv6";
296
0
    case TPrimitiveType::VARIANT:
297
0
        return "variant";
298
0
    default:
299
0
        return "unknown";
300
0
    }
301
0
}
302
303
0
Status SchemaColumnsScanner::_get_new_desc() {
304
0
    SCOPED_TIMER(_get_describe_timer);
305
0
    TDescribeTablesParams desc_params;
306
0
    desc_params.__set_db(_db_result.dbs[_db_index - 1]);
307
0
    if (_db_result.__isset.catalogs) {
308
0
        desc_params.__set_catalog(_db_result.catalogs[_db_index - 1]);
309
0
    }
310
0
    for (int i = 0; i < 100; ++i) {
311
0
        if (_table_index >= _table_result.tables.size()) {
312
0
            break;
313
0
        }
314
0
        desc_params.tables_name.push_back(_table_result.tables[_table_index++]);
315
0
    }
316
317
0
    if (nullptr != _param->common_param->current_user_ident) {
318
0
        desc_params.__set_current_user_ident(*(_param->common_param->current_user_ident));
319
0
    } else {
320
0
        if (nullptr != _param->common_param->user) {
321
0
            desc_params.__set_user(*(_param->common_param->user));
322
0
        }
323
0
        if (nullptr != _param->common_param->user_ip) {
324
0
            desc_params.__set_user_ip(*(_param->common_param->user_ip));
325
0
        }
326
0
    }
327
328
0
    if (nullptr != _param->common_param->ip && 0 != _param->common_param->port) {
329
0
        RETURN_IF_ERROR(SchemaHelper::describe_tables(*(_param->common_param->ip),
330
0
                                                      _param->common_param->port, desc_params,
331
0
                                                      &_desc_result));
332
0
    } else {
333
0
        return Status::InternalError("IP or port doesn't exists");
334
0
    }
335
336
0
    return Status::OK();
337
0
}
338
339
0
Status SchemaColumnsScanner::_get_new_table() {
340
0
    SCOPED_TIMER(_get_table_timer);
341
0
    TGetTablesParams table_params;
342
0
    table_params.__set_db(_db_result.dbs[_db_index]);
343
0
    if (_db_result.__isset.catalogs) {
344
0
        table_params.__set_catalog(_db_result.catalogs[_db_index]);
345
0
    }
346
0
    _db_index++;
347
0
    if (nullptr != _param->common_param->table) {
348
0
        table_params.__set_pattern(*(_param->common_param->table));
349
0
    }
350
0
    if (nullptr != _param->common_param->current_user_ident) {
351
0
        table_params.__set_current_user_ident(*(_param->common_param->current_user_ident));
352
0
    } else {
353
0
        if (nullptr != _param->common_param->user) {
354
0
            table_params.__set_user(*(_param->common_param->user));
355
0
        }
356
0
        if (nullptr != _param->common_param->user_ip) {
357
0
            table_params.__set_user_ip(*(_param->common_param->user_ip));
358
0
        }
359
0
    }
360
361
0
    if (nullptr != _param->common_param->ip && 0 != _param->common_param->port) {
362
0
        RETURN_IF_ERROR(SchemaHelper::get_table_names(*(_param->common_param->ip),
363
0
                                                      _param->common_param->port, table_params,
364
0
                                                      &_table_result));
365
0
    } else {
366
0
        return Status::InternalError("IP or port doesn't exists");
367
0
    }
368
0
    _table_index = 0;
369
0
    return Status::OK();
370
0
}
371
372
0
Status SchemaColumnsScanner::get_next_block_internal(Block* block, bool* eos) {
373
0
    if (!_is_init) {
374
0
        return Status::InternalError("use this class before inited.");
375
0
    }
376
0
    if (nullptr == block || nullptr == eos) {
377
0
        return Status::InternalError("input parameter is nullptr.");
378
0
    }
379
380
0
    while (_table_index >= _table_result.tables.size()) {
381
0
        if (_db_index < _db_result.dbs.size()) {
382
0
            RETURN_IF_ERROR(_get_new_table());
383
0
        } else {
384
0
            *eos = true;
385
0
            return Status::OK();
386
0
        }
387
0
    }
388
0
    RETURN_IF_ERROR(_get_new_desc());
389
390
0
    *eos = false;
391
0
    return _fill_block_impl(block);
392
0
}
393
394
0
Status SchemaColumnsScanner::_fill_block_impl(Block* block) {
395
0
    SCOPED_TIMER(_fill_block_timer);
396
0
    auto columns_num = _desc_result.columns.size();
397
0
    std::vector<void*> null_datas(columns_num, nullptr);
398
0
    std::vector<void*> datas(columns_num);
399
    // TABLE_CATALOG
400
0
    {
401
0
        if (!_db_result.__isset.catalogs) {
402
0
            RETURN_IF_ERROR(fill_dest_column_for_range(block, 0, null_datas));
403
0
        } else {
404
0
            std::string catalog_name = _db_result.catalogs[_db_index - 1];
405
0
            StringRef str = StringRef(catalog_name.c_str(), catalog_name.size());
406
0
            for (int i = 0; i < columns_num; ++i) {
407
0
                datas[i] = &str;
408
0
            }
409
0
            RETURN_IF_ERROR(fill_dest_column_for_range(block, 0, datas));
410
0
        }
411
0
    }
412
    // TABLE_SCHEMA
413
0
    {
414
0
        std::string db_name = SchemaHelper::extract_db_name(_db_result.dbs[_db_index - 1]);
415
0
        StringRef str = StringRef(db_name.c_str(), db_name.size());
416
0
        for (int i = 0; i < columns_num; ++i) {
417
0
            datas[i] = &str;
418
0
        }
419
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 1, datas));
420
0
    }
421
    // TABLE_NAME
422
0
    {
423
0
        std::vector<StringRef> strs(columns_num);
424
0
        int offset_index = 0;
425
0
        int cur_table_index = int(_table_index - _desc_result.tables_offset.size());
426
427
0
        for (int i = 0; i < columns_num; ++i) {
428
0
            while (_desc_result.tables_offset[offset_index] <= i) {
429
0
                ++offset_index;
430
0
                ++cur_table_index;
431
0
            }
432
0
            strs[i] = StringRef(_table_result.tables[cur_table_index].c_str(),
433
0
                                _table_result.tables[cur_table_index].length());
434
0
            datas[i] = strs.data() + i;
435
0
        }
436
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 2, datas));
437
0
    }
438
    // COLUMN_NAME
439
0
    {
440
0
        std::vector<StringRef> strs(columns_num);
441
0
        for (int i = 0; i < columns_num; ++i) {
442
0
            strs[i] = StringRef(_desc_result.columns[i].columnDesc.columnName.c_str(),
443
0
                                _desc_result.columns[i].columnDesc.columnName.length());
444
0
            datas[i] = strs.data() + i;
445
0
        }
446
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 3, datas));
447
0
    }
448
    // ORDINAL_POSITION
449
0
    {
450
0
        std::vector<int64_t> srcs(columns_num);
451
0
        int offset_index = 0;
452
0
        int columns_index = 1;
453
0
        for (int i = 0; i < columns_num; ++i) {
454
0
            while (_desc_result.tables_offset[offset_index] <= i) {
455
0
                ++offset_index;
456
0
                columns_index = 1;
457
0
            }
458
0
            srcs[i] = columns_index++;
459
0
            datas[i] = srcs.data() + i;
460
0
        }
461
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 4, datas));
462
0
    }
463
    // COLUMN_DEFAULT
464
0
    {
465
0
        std::vector<StringRef> strs(columns_num);
466
0
        for (int i = 0; i < columns_num; ++i) {
467
0
            if (_desc_result.columns[i].columnDesc.__isset.defaultValue) {
468
0
                strs[i] = StringRef(_desc_result.columns[i].columnDesc.defaultValue.c_str(),
469
0
                                    _desc_result.columns[i].columnDesc.defaultValue.length());
470
0
                datas[i] = strs.data() + i;
471
0
            } else {
472
0
                datas[i] = nullptr;
473
0
            }
474
0
        }
475
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 5, datas));
476
0
    }
477
    // IS_NULLABLE
478
0
    {
479
0
        StringRef str_yes = StringRef("YES", 3);
480
0
        StringRef str_no = StringRef("NO", 2);
481
0
        for (int i = 0; i < columns_num; ++i) {
482
0
            if (_desc_result.columns[i].columnDesc.__isset.isAllowNull) {
483
0
                if (_desc_result.columns[i].columnDesc.isAllowNull) {
484
0
                    datas[i] = &str_yes;
485
0
                } else {
486
0
                    datas[i] = &str_no;
487
0
                }
488
0
            } else {
489
0
                datas[i] = &str_no;
490
0
            }
491
0
        }
492
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 6, datas));
493
0
    }
494
    // DATA_TYPE
495
0
    {
496
0
        std::vector<std::string> buffers(columns_num);
497
0
        std::vector<StringRef> strs(columns_num);
498
0
        for (int i = 0; i < columns_num; ++i) {
499
0
            buffers[i] = _to_mysql_data_type_string(_desc_result.columns[i].columnDesc);
500
0
            strs[i] = StringRef(buffers[i].c_str(), buffers[i].length());
501
0
            datas[i] = strs.data() + i;
502
0
        }
503
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 7, datas));
504
0
    }
505
    // CHARACTER_MAXIMUM_LENGTH
506
    // For string columns, the maximum length in characters.
507
0
    {
508
0
        std::vector<int64_t> srcs(columns_num);
509
0
        for (int i = 0; i < columns_num; ++i) {
510
0
            int data_type = _desc_result.columns[i].columnDesc.columnType;
511
0
            if (data_type == TPrimitiveType::VARCHAR || data_type == TPrimitiveType::CHAR ||
512
0
                data_type == TPrimitiveType::STRING) {
513
0
                if (_desc_result.columns[i].columnDesc.__isset.columnLength) {
514
0
                    srcs[i] = _desc_result.columns[i].columnDesc.columnLength;
515
0
                    datas[i] = srcs.data() + i;
516
0
                } else {
517
0
                    datas[i] = nullptr;
518
0
                }
519
0
            } else {
520
0
                datas[i] = nullptr;
521
0
            }
522
0
        }
523
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 8, datas));
524
0
    }
525
    // CHARACTER_OCTET_LENGTH
526
    // For string columns, the maximum length in bytes.
527
0
    {
528
0
        std::vector<int64_t> srcs(columns_num);
529
0
        for (int i = 0; i < columns_num; ++i) {
530
0
            int data_type = _desc_result.columns[i].columnDesc.columnType;
531
0
            if (data_type == TPrimitiveType::VARCHAR || data_type == TPrimitiveType::CHAR ||
532
0
                data_type == TPrimitiveType::STRING) {
533
0
                if (_desc_result.columns[i].columnDesc.__isset.columnLength) {
534
0
                    srcs[i] = _desc_result.columns[i].columnDesc.columnLength * 4L;
535
0
                    datas[i] = srcs.data() + i;
536
0
                } else {
537
0
                    datas[i] = nullptr;
538
0
                }
539
0
            } else {
540
0
                datas[i] = nullptr;
541
0
            }
542
0
        }
543
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 9, datas));
544
0
    }
545
    // NUMERIC_PRECISION
546
0
    {
547
0
        std::vector<int64_t> srcs(columns_num);
548
0
        for (int i = 0; i < columns_num; ++i) {
549
0
            int data_type = _desc_result.columns[i].columnDesc.columnType;
550
0
            if (_desc_result.columns[i].columnDesc.__isset.columnPrecision &&
551
0
                data_type != TPrimitiveType::DATETIMEV2) {
552
0
                srcs[i] = _desc_result.columns[i].columnDesc.columnPrecision;
553
0
                datas[i] = srcs.data() + i;
554
0
            } else {
555
0
                datas[i] = nullptr;
556
0
            }
557
0
        }
558
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 10, datas));
559
0
    }
560
    // NUMERIC_SCALE
561
0
    {
562
0
        std::vector<int64_t> srcs(columns_num);
563
0
        for (int i = 0; i < columns_num; ++i) {
564
0
            int data_type = _desc_result.columns[i].columnDesc.columnType;
565
0
            if (_desc_result.columns[i].columnDesc.__isset.columnScale &&
566
0
                data_type != TPrimitiveType::DATETIMEV2) {
567
0
                srcs[i] = _desc_result.columns[i].columnDesc.columnScale;
568
0
                datas[i] = srcs.data() + i;
569
0
            } else {
570
0
                datas[i] = nullptr;
571
0
            }
572
0
        }
573
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 11, datas));
574
0
    }
575
    // DATETIME_PRECISION
576
0
    {
577
0
        std::vector<int64_t> srcs(columns_num);
578
0
        for (int i = 0; i < columns_num; ++i) {
579
0
            int data_type = _desc_result.columns[i].columnDesc.columnType;
580
0
            if (_desc_result.columns[i].columnDesc.__isset.columnScale &&
581
0
                (data_type == TPrimitiveType::DATETIMEV2 ||
582
0
                 data_type == TPrimitiveType::TIMESTAMPTZ)) {
583
0
                srcs[i] = _desc_result.columns[i].columnDesc.columnScale;
584
0
                datas[i] = srcs.data() + i;
585
0
            } else {
586
0
                datas[i] = nullptr;
587
0
            }
588
0
        }
589
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 12, datas));
590
0
    }
591
    // CHARACTER_SET_NAME
592
0
    { RETURN_IF_ERROR(fill_dest_column_for_range(block, 13, null_datas)); }
593
    // COLLATION_NAME
594
0
    { RETURN_IF_ERROR(fill_dest_column_for_range(block, 14, null_datas)); }
595
    // COLUMN_TYPE
596
0
    {
597
0
        std::vector<std::string> buffers(columns_num);
598
0
        std::vector<StringRef> strs(columns_num);
599
0
        for (int i = 0; i < columns_num; ++i) {
600
0
            buffers[i] = _type_to_string(_desc_result.columns[i].columnDesc);
601
0
            strs[i] = StringRef(buffers[i].c_str(), buffers[i].length());
602
0
            datas[i] = strs.data() + i;
603
0
        }
604
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 15, datas));
605
0
    }
606
    // COLUMN_KEY
607
0
    {
608
0
        StringRef str = StringRef("", 0);
609
0
        std::vector<StringRef> strs(columns_num);
610
0
        for (int i = 0; i < columns_num; ++i) {
611
0
            if (_desc_result.columns[i].columnDesc.__isset.columnKey) {
612
0
                strs[i] = StringRef(_desc_result.columns[i].columnDesc.columnKey.c_str(),
613
0
                                    _desc_result.columns[i].columnDesc.columnKey.length());
614
0
                datas[i] = strs.data() + i;
615
0
            } else {
616
0
                datas[i] = &str;
617
0
            }
618
0
        }
619
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 16, datas));
620
0
    }
621
    // EXTRA
622
0
    {
623
0
        StringRef str = StringRef("", 0);
624
0
        std::vector<void*> filled_values(columns_num, &str);
625
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 17, filled_values));
626
0
    }
627
    // PRIVILEGES
628
0
    {
629
0
        StringRef str = StringRef("", 0);
630
0
        std::vector<void*> filled_values(columns_num, &str);
631
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 18, filled_values));
632
0
    }
633
    // COLUMN_COMMENT
634
0
    {
635
0
        std::vector<StringRef> strs(columns_num);
636
0
        for (int i = 0; i < columns_num; ++i) {
637
0
            strs[i] = StringRef(_desc_result.columns[i].comment.c_str(),
638
0
                                _desc_result.columns[i].comment.length());
639
0
            datas[i] = strs.data() + i;
640
0
        }
641
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 19, datas));
642
0
    }
643
    // COLUMN_SIZE
644
0
    {
645
0
        std::vector<int64_t> srcs(columns_num);
646
0
        for (int i = 0; i < columns_num; ++i) {
647
0
            if (_desc_result.columns[i].columnDesc.__isset.columnLength) {
648
0
                srcs[i] = _desc_result.columns[i].columnDesc.columnLength;
649
0
                datas[i] = srcs.data() + i;
650
0
            } else {
651
0
                datas[i] = nullptr;
652
0
            }
653
0
        }
654
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 20, datas));
655
0
    }
656
    // DECIMAL_DIGITS
657
0
    {
658
0
        std::vector<int64_t> srcs(columns_num);
659
0
        for (int i = 0; i < columns_num; ++i) {
660
0
            int data_type = _desc_result.columns[i].columnDesc.columnType;
661
0
            if (_desc_result.columns[i].columnDesc.__isset.columnScale &&
662
0
                data_type != TPrimitiveType::DATETIMEV2) {
663
0
                srcs[i] = _desc_result.columns[i].columnDesc.columnScale;
664
0
                datas[i] = srcs.data() + i;
665
0
            } else {
666
0
                datas[i] = nullptr;
667
0
            }
668
0
        }
669
0
        RETURN_IF_ERROR(fill_dest_column_for_range(block, 21, datas));
670
0
    }
671
    // GENERATION_EXPRESSION
672
0
    { RETURN_IF_ERROR(fill_dest_column_for_range(block, 22, null_datas)); }
673
    // SRS_ID
674
0
    { RETURN_IF_ERROR(fill_dest_column_for_range(block, 23, null_datas)); }
675
0
    return Status::OK();
676
0
}
677
678
} // namespace doris