Coverage Report

Created: 2026-03-14 20:54

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