Coverage Report

Created: 2026-09-09 13:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/runtime/descriptors.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
// This file is copied from
18
// https://github.com/apache/impala/blob/branch-2.9.0/be/src/runtime/descriptors.cc
19
// and modified by Doris
20
21
#include "runtime/descriptors.h"
22
23
#include <fmt/format.h>
24
#include <gen_cpp/Descriptors_types.h>
25
#include <gen_cpp/Types_types.h>
26
#include <gen_cpp/descriptors.pb.h>
27
#include <stddef.h>
28
#include <thrift/protocol/TDebugProtocol.h>
29
30
#include <algorithm>
31
#include <boost/algorithm/string/join.hpp>
32
33
#include "common/exception.h"
34
#include "common/object_pool.h"
35
#include "core/column/column_nothing.h"
36
#include "core/data_type/data_type_array.h"
37
#include "core/data_type/data_type_decimal.h"
38
#include "core/data_type/data_type_factory.hpp"
39
#include "core/data_type/data_type_map.h"
40
#include "core/data_type/data_type_struct.h"
41
#include "core/types.h"
42
#include "exec/common/util.hpp"
43
#include "exprs/aggregate/aggregate_function.h"
44
#include "exprs/function/function_helpers.h"
45
#include "exprs/vexpr.h"
46
#include "util/string_util.h"
47
48
namespace doris {
49
const int RowDescriptor::INVALID_IDX = -1;
50
51
SlotDescriptor::SlotDescriptor(const TSlotDescriptor& tdesc)
52
8.85M
        : _id(tdesc.id),
53
8.85M
          _type(DataTypeFactory::instance().create_data_type(tdesc.slotType,
54
8.85M
                                                             tdesc.nullIndicatorBit != -1)),
55
8.85M
          _parent(tdesc.parent),
56
8.85M
          _col_pos(tdesc.columnPos),
57
8.85M
          _col_name(tdesc.colName),
58
8.85M
          _col_name_lower_case(to_lower(tdesc.colName)),
59
8.85M
          _col_unique_id(tdesc.col_unique_id),
60
8.85M
          _slot_idx(tdesc.slotIdx),
61
8.85M
          _field_idx(-1),
62
8.85M
          _is_key(tdesc.is_key),
63
8.85M
          _column_paths(tdesc.column_paths),
64
8.85M
          _all_access_paths(tdesc.__isset.all_access_paths ? tdesc.all_access_paths
65
8.85M
                                                           : TColumnAccessPaths {}),
66
8.85M
          _predicate_access_paths(tdesc.__isset.predicate_access_paths
67
8.85M
                                          ? tdesc.predicate_access_paths
68
8.85M
                                          : TColumnAccessPaths {}),
69
18.4E
          _is_auto_increment(tdesc.__isset.is_auto_increment ? tdesc.is_auto_increment : false),
70
8.85M
          _col_default_value(tdesc.__isset.col_default_value ? tdesc.col_default_value : "") {
71
8.85M
    if (tdesc.__isset.virtual_column_expr) {
72
        // Make sure virtual column is valid.
73
416
        if (tdesc.virtual_column_expr.nodes.empty()) {
74
2
            throw doris::Exception(doris::ErrorCode::FATAL_ERROR,
75
2
                                   "Virtual column expr node is empty, col_name: {}, "
76
2
                                   "col_unique_id: {}",
77
2
                                   tdesc.colName, tdesc.col_unique_id);
78
2
        }
79
414
        const auto& node = tdesc.virtual_column_expr.nodes[0];
80
414
        if (node.node_type == TExprNodeType::SLOT_REF) {
81
2
            throw doris::Exception(doris::ErrorCode::FATAL_ERROR,
82
2
                                   "Virtual column expr node is slot ref, col_name: {}, "
83
2
                                   "col_unique_id: {}",
84
2
                                   tdesc.colName, tdesc.col_unique_id);
85
2
        }
86
412
        this->virtual_column_expr = std::make_shared<doris::TExpr>(tdesc.virtual_column_expr);
87
412
    }
88
8.85M
}
89
90
SlotDescriptor::SlotDescriptor(const PSlotDescriptor& pdesc)
91
283k
        : _id(pdesc.id()),
92
283k
          _type(DataTypeFactory::instance().create_data_type(pdesc.slot_type(),
93
283k
                                                             pdesc.null_indicator_bit() != -1)),
94
283k
          _parent(pdesc.parent()),
95
283k
          _col_pos(pdesc.column_pos()),
96
283k
          _col_name(pdesc.col_name()),
97
283k
          _col_name_lower_case(to_lower(pdesc.col_name())),
98
283k
          _col_unique_id(pdesc.col_unique_id()),
99
283k
          _slot_idx(pdesc.slot_idx()),
100
283k
          _field_idx(-1),
101
283k
          _is_key(pdesc.is_key()),
102
283k
          _column_paths(pdesc.column_paths().begin(), pdesc.column_paths().end()),
103
283k
          _is_auto_increment(pdesc.is_auto_increment()) {
104
283k
    auto convert_to_thrift_column_access_path = [](const PColumnAccessPath& pb_path) {
105
848
        TColumnAccessPath thrift_path;
106
848
        thrift_path.type = (TAccessPathType::type)pb_path.type();
107
848
        if (pb_path.has_version()) {
108
848
            thrift_path.__set_version(pb_path.version());
109
848
        }
110
848
        if (pb_path.has_data_access_path()) {
111
848
            thrift_path.__isset.data_access_path = true;
112
2.04k
            for (int i = 0; i < pb_path.data_access_path().path_size(); ++i) {
113
1.19k
                thrift_path.data_access_path.path.push_back(pb_path.data_access_path().path(i));
114
1.19k
            }
115
848
        }
116
848
        if (pb_path.has_meta_access_path()) {
117
0
            thrift_path.__isset.meta_access_path = true;
118
0
            for (int i = 0; i < pb_path.meta_access_path().path_size(); ++i) {
119
0
                thrift_path.meta_access_path.path.push_back(pb_path.meta_access_path().path(i));
120
0
            }
121
0
        }
122
848
        return thrift_path;
123
848
    };
124
283k
    for (const auto& pb_path : pdesc.all_access_paths()) {
125
852
        _all_access_paths.push_back(convert_to_thrift_column_access_path(pb_path));
126
852
    }
127
283k
    for (const auto& pb_path : pdesc.predicate_access_paths()) {
128
1
        _predicate_access_paths.push_back(convert_to_thrift_column_access_path(pb_path));
129
1
    }
130
283k
}
131
132
#ifdef BE_TEST
133
SlotDescriptor::SlotDescriptor()
134
        : _id(0),
135
          _type(nullptr),
136
          _parent(0),
137
          _col_pos(0),
138
          _col_unique_id(0),
139
          _slot_idx(0),
140
          _field_idx(-1),
141
          _is_key(false),
142
          _is_auto_increment(false) {}
143
#endif
144
145
367k
void SlotDescriptor::to_protobuf(PSlotDescriptor* pslot) const {
146
367k
    pslot->set_id(_id);
147
367k
    pslot->set_parent(_parent);
148
367k
    _type->to_protobuf(pslot->mutable_slot_type());
149
367k
    pslot->set_column_pos(_col_pos);
150
367k
    pslot->set_byte_offset(0);
151
367k
    pslot->set_null_indicator_byte(0);
152
367k
    pslot->set_null_indicator_bit(_type->is_nullable() ? 0 : -1);
153
367k
    pslot->set_col_name(_col_name);
154
367k
    pslot->set_slot_idx(_slot_idx);
155
367k
    pslot->set_col_unique_id(_col_unique_id);
156
367k
    pslot->set_is_key(_is_key);
157
367k
    pslot->set_is_auto_increment(_is_auto_increment);
158
367k
    pslot->set_col_type(_type->get_primitive_type());
159
367k
    for (const std::string& path : _column_paths) {
160
97
        pslot->add_column_paths(path);
161
97
    }
162
367k
    auto convert_to_protobuf_column_access_path = [](const TColumnAccessPath& thrift_path,
163
367k
                                                     doris::PColumnAccessPath* pb_path) {
164
807
        pb_path->Clear();
165
807
        pb_path->set_type((PAccessPathType)thrift_path.type); // 使用 reinterpret_cast 进行类型转换
166
807
        if (thrift_path.__isset.version) {
167
807
            pb_path->set_version(thrift_path.version);
168
807
        }
169
807
        if (thrift_path.__isset.data_access_path) {
170
807
            auto* pb_data = pb_path->mutable_data_access_path();
171
807
            pb_data->Clear();
172
1.14k
            for (const auto& s : thrift_path.data_access_path.path) {
173
1.14k
                pb_data->add_path(s);
174
1.14k
            }
175
807
        }
176
807
        if (thrift_path.__isset.meta_access_path) {
177
0
            auto* pb_meta = pb_path->mutable_meta_access_path();
178
0
            pb_meta->Clear();
179
0
            for (const auto& s : thrift_path.meta_access_path.path) {
180
0
                pb_meta->add_path(s);
181
0
            }
182
0
        }
183
807
    };
184
367k
    for (const auto& path : _all_access_paths) {
185
811
        auto* pb_path = pslot->add_all_access_paths();
186
811
        convert_to_protobuf_column_access_path(path, pb_path);
187
811
    }
188
367k
    for (const auto& path : _predicate_access_paths) {
189
1
        auto* pb_path = pslot->add_predicate_access_paths();
190
1
        convert_to_protobuf_column_access_path(path, pb_path);
191
1
    }
192
367k
}
193
194
25.5M
DataTypePtr SlotDescriptor::get_data_type_ptr() const {
195
25.5M
    return get_data_type_with_default_argument(type());
196
25.5M
}
197
198
12.2M
MutableColumnPtr SlotDescriptor::get_empty_mutable_column() const {
199
12.2M
    if (this->get_virtual_column_expr() != nullptr) {
200
509
        return ColumnNothing::create(0);
201
509
    }
202
203
12.2M
    return type()->create_column();
204
12.2M
}
205
206
23.0M
bool SlotDescriptor::is_nullable() const {
207
23.0M
    return _type->is_nullable();
208
23.0M
}
209
210
1.07M
PrimitiveType SlotDescriptor::col_type() const {
211
1.07M
    return _type->get_primitive_type();
212
1.07M
}
213
214
8
std::string SlotDescriptor::debug_string() const {
215
8
    const bool is_virtual = this->get_virtual_column_expr() != nullptr;
216
8
    return fmt::format(
217
8
            "SlotDescriptor(id={}, type={}, col_name={}, col_unique_id={}, "
218
8
            "is_virtual={})",
219
8
            _id, _type->get_name(), _col_name, _col_unique_id, is_virtual);
220
8
}
221
222
TableDescriptor::TableDescriptor(const TTableDescriptor& tdesc)
223
395k
        : _table_type(tdesc.tableType),
224
395k
          _name(tdesc.tableName),
225
395k
          _database(tdesc.dbName),
226
395k
          _table_id(tdesc.id),
227
395k
          _num_cols(tdesc.numCols),
228
395k
          _num_clustering_cols(tdesc.numClusteringCols) {}
229
230
0
std::string TableDescriptor::debug_string() const {
231
0
    std::stringstream out;
232
0
    out << "#cols=" << _num_cols << " #clustering_cols=" << _num_clustering_cols;
233
0
    return out.str();
234
0
}
235
236
392k
OlapTableDescriptor::OlapTableDescriptor(const TTableDescriptor& tdesc) : TableDescriptor(tdesc) {}
237
238
0
std::string OlapTableDescriptor::debug_string() const {
239
0
    std::stringstream out;
240
0
    out << "OlapTable(" << TableDescriptor::debug_string() << ")";
241
0
    return out.str();
242
0
}
243
244
DictionaryTableDescriptor::DictionaryTableDescriptor(const TTableDescriptor& tdesc)
245
0
        : TableDescriptor(tdesc) {}
246
247
0
std::string DictionaryTableDescriptor::debug_string() const {
248
0
    std::stringstream out;
249
0
    out << "Dictionary(" << TableDescriptor::debug_string() << ")";
250
0
    return out.str();
251
0
}
252
253
SchemaTableDescriptor::SchemaTableDescriptor(const TTableDescriptor& tdesc)
254
3.21k
        : TableDescriptor(tdesc), _schema_table_type(tdesc.schemaTable.tableType) {}
255
3.21k
SchemaTableDescriptor::~SchemaTableDescriptor() = default;
256
257
0
std::string SchemaTableDescriptor::debug_string() const {
258
0
    std::stringstream out;
259
0
    out << "SchemaTable(" << TableDescriptor::debug_string() << ")";
260
0
    return out.str();
261
0
}
262
263
BrokerTableDescriptor::BrokerTableDescriptor(const TTableDescriptor& tdesc)
264
0
        : TableDescriptor(tdesc) {}
265
266
0
BrokerTableDescriptor::~BrokerTableDescriptor() = default;
267
268
0
std::string BrokerTableDescriptor::debug_string() const {
269
0
    std::stringstream out;
270
0
    out << "BrokerTable(" << TableDescriptor::debug_string() << ")";
271
0
    return out.str();
272
0
}
273
274
36
HiveTableDescriptor::HiveTableDescriptor(const TTableDescriptor& tdesc) : TableDescriptor(tdesc) {}
275
276
36
HiveTableDescriptor::~HiveTableDescriptor() = default;
277
278
0
std::string HiveTableDescriptor::debug_string() const {
279
0
    std::stringstream out;
280
0
    out << "HiveTable(" << TableDescriptor::debug_string() << ")";
281
0
    return out.str();
282
0
}
283
284
IcebergTableDescriptor::IcebergTableDescriptor(const TTableDescriptor& tdesc)
285
0
        : TableDescriptor(tdesc) {}
286
287
0
IcebergTableDescriptor::~IcebergTableDescriptor() = default;
288
289
0
std::string IcebergTableDescriptor::debug_string() const {
290
0
    std::stringstream out;
291
0
    out << "IcebergTable(" << TableDescriptor::debug_string() << ")";
292
0
    return out.str();
293
0
}
294
295
MaxComputeTableDescriptor::MaxComputeTableDescriptor(const TTableDescriptor& tdesc)
296
0
        : TableDescriptor(tdesc),
297
0
          _region(tdesc.mcTable.region),
298
0
          _project(tdesc.mcTable.project),
299
0
          _table(tdesc.mcTable.table),
300
0
          _odps_url(tdesc.mcTable.odps_url),
301
0
          _tunnel_url(tdesc.mcTable.tunnel_url),
302
0
          _access_key(tdesc.mcTable.access_key),
303
0
          _secret_key(tdesc.mcTable.secret_key),
304
0
          _public_access(tdesc.mcTable.public_access) {
305
0
    if (tdesc.mcTable.__isset.endpoint) {
306
0
        _endpoint = tdesc.mcTable.endpoint;
307
0
    } else {
308
0
        _init_status = Status::InvalidArgument(
309
0
                "fail to init MaxComputeTableDescriptor, missing endpoint.");
310
0
    }
311
312
0
    if (tdesc.mcTable.__isset.quota) {
313
0
        _quota = tdesc.mcTable.quota;
314
0
    } else {
315
0
        _init_status =
316
0
                Status::InvalidArgument("fail to init MaxComputeTableDescriptor, missing quota.");
317
0
    }
318
319
0
    if (tdesc.mcTable.__isset.properties) [[likely]] {
320
0
        _props = tdesc.mcTable.properties;
321
0
    } else {
322
0
        static const std::string MC_ACCESS_KEY = "mc.access_key";
323
0
        static const std::string MC_SECRET_KEY = "mc.secret_key";
324
0
        _props.insert({MC_ACCESS_KEY, _access_key});
325
0
        _props.insert({MC_SECRET_KEY, _secret_key});
326
0
    }
327
0
}
328
329
0
MaxComputeTableDescriptor::~MaxComputeTableDescriptor() = default;
330
331
0
std::string MaxComputeTableDescriptor::debug_string() const {
332
0
    std::stringstream out;
333
0
    out << "MaxComputeTable(" << TableDescriptor::debug_string() << ")";
334
0
    return out.str();
335
0
}
336
337
TrinoConnectorTableDescriptor::TrinoConnectorTableDescriptor(const TTableDescriptor& tdesc)
338
0
        : TableDescriptor(tdesc) {}
339
340
0
TrinoConnectorTableDescriptor::~TrinoConnectorTableDescriptor() = default;
341
342
0
std::string TrinoConnectorTableDescriptor::debug_string() const {
343
0
    std::stringstream out;
344
0
    out << "TrinoConnectorTable(" << TableDescriptor::debug_string() << ")";
345
0
    return out.str();
346
0
}
347
348
0
EsTableDescriptor::EsTableDescriptor(const TTableDescriptor& tdesc) : TableDescriptor(tdesc) {}
349
350
0
EsTableDescriptor::~EsTableDescriptor() = default;
351
352
0
std::string EsTableDescriptor::debug_string() const {
353
0
    std::stringstream out;
354
0
    out << "EsTable(" << TableDescriptor::debug_string() << ")";
355
0
    return out.str();
356
0
}
357
358
MySQLTableDescriptor::MySQLTableDescriptor(const TTableDescriptor& tdesc)
359
91
        : TableDescriptor(tdesc),
360
91
          _mysql_db(tdesc.mysqlTable.db),
361
91
          _mysql_table(tdesc.mysqlTable.table),
362
91
          _host(tdesc.mysqlTable.host),
363
91
          _port(tdesc.mysqlTable.port),
364
91
          _user(tdesc.mysqlTable.user),
365
91
          _passwd(tdesc.mysqlTable.passwd),
366
91
          _charset(tdesc.mysqlTable.charset) {}
367
368
0
std::string MySQLTableDescriptor::debug_string() const {
369
0
    std::stringstream out;
370
0
    out << "MySQLTable(" << TableDescriptor::debug_string() << " _db" << _mysql_db
371
0
        << " table=" << _mysql_table << " host=" << _host << " port=" << _port << " user=" << _user
372
0
        << " passwd=" << _passwd << " charset=" << _charset;
373
0
    return out.str();
374
0
}
375
376
JdbcTableDescriptor::JdbcTableDescriptor(const TTableDescriptor& tdesc)
377
4
        : TableDescriptor(tdesc),
378
4
          _jdbc_catalog_id(tdesc.jdbcTable.catalog_id),
379
4
          _jdbc_resource_name(tdesc.jdbcTable.jdbc_resource_name),
380
4
          _jdbc_driver_url(tdesc.jdbcTable.jdbc_driver_url),
381
4
          _jdbc_driver_class(tdesc.jdbcTable.jdbc_driver_class),
382
4
          _jdbc_driver_checksum(tdesc.jdbcTable.jdbc_driver_checksum),
383
4
          _jdbc_url(tdesc.jdbcTable.jdbc_url),
384
4
          _jdbc_table_name(tdesc.jdbcTable.jdbc_table_name),
385
4
          _jdbc_user(tdesc.jdbcTable.jdbc_user),
386
4
          _jdbc_passwd(tdesc.jdbcTable.jdbc_password),
387
4
          _connection_pool_min_size(tdesc.jdbcTable.connection_pool_min_size),
388
4
          _connection_pool_max_size(tdesc.jdbcTable.connection_pool_max_size),
389
4
          _connection_pool_max_wait_time(tdesc.jdbcTable.connection_pool_max_wait_time),
390
4
          _connection_pool_max_life_time(tdesc.jdbcTable.connection_pool_max_life_time),
391
4
          _connection_pool_keep_alive(tdesc.jdbcTable.connection_pool_keep_alive) {}
392
393
0
std::string JdbcTableDescriptor::debug_string() const {
394
0
    fmt::memory_buffer buf;
395
0
    fmt::format_to(
396
0
            buf,
397
0
            "JDBCTable({} ,_jdbc_catalog_id = {}, _jdbc_resource_name={} ,_jdbc_driver_url={} "
398
0
            ",_jdbc_driver_class={} ,_jdbc_driver_checksum={} ,_jdbc_url={} "
399
0
            ",_jdbc_table_name={} ,_jdbc_user={} ,_jdbc_passwd={} ,_connection_pool_min_size={} "
400
0
            ",_connection_pool_max_size={} ,_connection_pool_max_wait_time={} "
401
0
            ",_connection_pool_max_life_time={} ,_connection_pool_keep_alive={})",
402
0
            TableDescriptor::debug_string(), _jdbc_catalog_id, _jdbc_resource_name,
403
0
            _jdbc_driver_url, _jdbc_driver_class, _jdbc_driver_checksum, _jdbc_url,
404
0
            _jdbc_table_name, _jdbc_user, _jdbc_passwd, _connection_pool_min_size,
405
0
            _connection_pool_max_size, _connection_pool_max_wait_time,
406
0
            _connection_pool_max_life_time, _connection_pool_keep_alive);
407
0
    return fmt::to_string(buf);
408
0
}
409
410
RemoteDorisTableDescriptor::RemoteDorisTableDescriptor(const TTableDescriptor& tdesc)
411
0
        : TableDescriptor(tdesc) {}
412
413
0
RemoteDorisTableDescriptor::~RemoteDorisTableDescriptor() = default;
414
415
0
std::string RemoteDorisTableDescriptor::debug_string() const {
416
0
    std::stringstream out;
417
0
    out << "RemoteDorisTable(" << TableDescriptor::debug_string() << ")";
418
0
    return out.str();
419
0
}
420
421
TupleDescriptor::TupleDescriptor(const TTupleDescriptor& tdesc, bool own_slots)
422
1.72M
        : _id(tdesc.id),
423
1.72M
          _num_materialized_slots(0),
424
1.72M
          _has_varlen_slots(false),
425
1.72M
          _own_slots(own_slots) {}
426
427
TupleDescriptor::TupleDescriptor(const PTupleDescriptor& pdesc, bool own_slots)
428
31.6k
        : _id(pdesc.id()),
429
31.6k
          _num_materialized_slots(0),
430
31.6k
          _has_varlen_slots(false),
431
31.6k
          _own_slots(own_slots) {}
432
433
9.15M
void TupleDescriptor::add_slot(SlotDescriptor* slot) {
434
9.15M
    _slots.push_back(slot);
435
9.15M
    ++_num_materialized_slots;
436
437
9.15M
    if (is_complex_type(slot->type()->get_primitive_type()) ||
438
9.15M
        is_var_len_object(slot->type()->get_primitive_type()) ||
439
9.15M
        is_string_type(slot->type()->get_primitive_type())) {
440
3.88M
        _has_varlen_slots = true;
441
3.88M
    }
442
9.15M
}
443
444
47.4k
void TupleDescriptor::to_protobuf(PTupleDescriptor* ptuple) const {
445
47.4k
    ptuple->Clear();
446
47.4k
    ptuple->set_id(_id);
447
    // Useless not set
448
47.4k
    ptuple->set_byte_size(0);
449
47.4k
    ptuple->set_table_id(-1);
450
47.4k
    ptuple->set_num_null_bytes(0);
451
47.4k
}
452
453
2
std::string TupleDescriptor::debug_string() const {
454
2
    std::stringstream out;
455
2
    out << "Tuple(id=" << _id;
456
2
    if (_table_desc != nullptr) {
457
        //out << " " << _table_desc->debug_string();
458
0
    }
459
460
2
    out << " slots=[";
461
8
    for (size_t i = 0; i < _slots.size(); ++i) {
462
6
        if (i > 0) {
463
4
            out << ", ";
464
4
        }
465
6
        out << _slots[i]->debug_string();
466
6
    }
467
468
2
    out << "]";
469
2
    out << " has_varlen_slots=" << _has_varlen_slots;
470
2
    out << ")";
471
2
    return out.str();
472
2
}
473
474
770
int TupleDescriptor::get_column_id(SlotId slot_id) const {
475
1.77k
    for (int column_id = 0; auto* slot : slots()) {
476
1.77k
        if (slot->id() == slot_id) {
477
769
            return column_id;
478
769
        }
479
1.00k
        ++column_id;
480
1.00k
    }
481
1
    return -1;
482
770
}
483
484
RowDescriptor::RowDescriptor(const DescriptorTbl& desc_tbl,
485
1.30M
                             const std::vector<TTupleId>& row_tuples) {
486
1.30M
    DCHECK_GT(row_tuples.size(), 0);
487
1.30M
    _num_materialized_slots = 0;
488
1.30M
    _num_slots = 0;
489
490
1.39M
    for (int row_tuple : row_tuples) {
491
1.39M
        TupleDescriptor* tupleDesc = desc_tbl.get_tuple_descriptor(row_tuple);
492
1.39M
        _num_materialized_slots += tupleDesc->num_materialized_slots();
493
1.39M
        _num_slots += tupleDesc->slots().size();
494
1.39M
        _tuple_desc_map.push_back(tupleDesc);
495
1.39M
        DCHECK(_tuple_desc_map.back() != nullptr);
496
1.39M
    }
497
498
1.30M
    init_tuple_idx_map();
499
1.30M
    init_has_varlen_slots();
500
1.30M
}
501
502
101k
RowDescriptor::RowDescriptor(TupleDescriptor* tuple_desc) : _tuple_desc_map(1, tuple_desc) {
503
101k
    init_tuple_idx_map();
504
101k
    init_has_varlen_slots();
505
101k
    _num_slots = static_cast<int32_t>(tuple_desc->slots().size());
506
101k
}
507
508
0
RowDescriptor::RowDescriptor(const RowDescriptor& lhs_row_desc, const RowDescriptor& rhs_row_desc) {
509
0
    _tuple_desc_map.insert(_tuple_desc_map.end(), lhs_row_desc._tuple_desc_map.begin(),
510
0
                           lhs_row_desc._tuple_desc_map.end());
511
0
    _tuple_desc_map.insert(_tuple_desc_map.end(), rhs_row_desc._tuple_desc_map.begin(),
512
0
                           rhs_row_desc._tuple_desc_map.end());
513
0
    init_tuple_idx_map();
514
0
    init_has_varlen_slots();
515
516
0
    _num_slots = lhs_row_desc.num_slots() + rhs_row_desc.num_slots();
517
0
}
518
519
1.41M
void RowDescriptor::init_tuple_idx_map() {
520
    // find max id
521
1.41M
    TupleId max_id = 0;
522
1.50M
    for (auto& i : _tuple_desc_map) {
523
1.50M
        max_id = std::max(i->id(), max_id);
524
1.50M
    }
525
526
1.41M
    _tuple_idx_map.resize(max_id + 1, INVALID_IDX);
527
2.91M
    for (int i = 0; i < _tuple_desc_map.size(); ++i) {
528
1.50M
        _tuple_idx_map[_tuple_desc_map[i]->id()] = i;
529
1.50M
    }
530
1.41M
}
531
532
1.41M
void RowDescriptor::init_has_varlen_slots() {
533
1.41M
    _has_varlen_slots = false;
534
1.47M
    for (auto& i : _tuple_desc_map) {
535
1.47M
        if (i->has_varlen_slots()) {
536
553k
            _has_varlen_slots = true;
537
553k
            break;
538
553k
        }
539
1.47M
    }
540
1.41M
}
541
542
2.32k
int RowDescriptor::get_tuple_idx(TupleId id) const {
543
    // comment CHECK temporarily to make fuzzy test run smoothly
544
    // DCHECK_LT(id, _tuple_idx_map.size()) << "RowDescriptor: " << debug_string();
545
2.32k
    if (_tuple_idx_map.size() <= id) {
546
0
        return RowDescriptor::INVALID_IDX;
547
0
    }
548
2.32k
    return _tuple_idx_map[id];
549
2.32k
}
550
551
0
void RowDescriptor::to_thrift(std::vector<TTupleId>* row_tuple_ids) {
552
0
    row_tuple_ids->clear();
553
554
0
    for (auto& i : _tuple_desc_map) {
555
0
        row_tuple_ids->push_back(i->id());
556
0
    }
557
0
}
558
559
void RowDescriptor::to_protobuf(
560
0
        google::protobuf::RepeatedField<google::protobuf::int32>* row_tuple_ids) const {
561
0
    row_tuple_ids->Clear();
562
0
    for (auto* desc : _tuple_desc_map) {
563
0
        row_tuple_ids->Add(desc->id());
564
0
    }
565
0
}
566
567
1.82k
bool RowDescriptor::is_prefix_of(const RowDescriptor& other_desc) const {
568
1.82k
    if (_tuple_desc_map.size() > other_desc._tuple_desc_map.size()) {
569
0
        return false;
570
0
    }
571
572
3.80k
    for (int i = 0; i < _tuple_desc_map.size(); ++i) {
573
        // pointer comparison okay, descriptors are unique
574
1.97k
        if (_tuple_desc_map[i] != other_desc._tuple_desc_map[i]) {
575
0
            return false;
576
0
        }
577
1.97k
    }
578
579
1.82k
    return true;
580
1.82k
}
581
582
0
bool RowDescriptor::equals(const RowDescriptor& other_desc) const {
583
0
    if (_tuple_desc_map.size() != other_desc._tuple_desc_map.size()) {
584
0
        return false;
585
0
    }
586
587
0
    for (int i = 0; i < _tuple_desc_map.size(); ++i) {
588
        // pointer comparison okay, descriptors are unique
589
0
        if (_tuple_desc_map[i] != other_desc._tuple_desc_map[i]) {
590
0
            return false;
591
0
        }
592
0
    }
593
594
0
    return true;
595
0
}
596
597
0
std::string RowDescriptor::debug_string() const {
598
0
    std::stringstream ss;
599
600
0
    ss << "tuple_desc_map: [";
601
0
    for (int i = 0; i < _tuple_desc_map.size(); ++i) {
602
0
        ss << _tuple_desc_map[i]->debug_string();
603
0
        if (i != _tuple_desc_map.size() - 1) {
604
0
            ss << ", ";
605
0
        }
606
0
    }
607
0
    ss << "] ";
608
609
0
    ss << "tuple_id_map: [";
610
0
    for (int i = 0; i < _tuple_idx_map.size(); ++i) {
611
0
        ss << _tuple_idx_map[i];
612
0
        if (i != _tuple_idx_map.size() - 1) {
613
0
            ss << ", ";
614
0
        }
615
0
    }
616
0
    ss << "] ";
617
618
0
    return ss.str();
619
0
}
620
621
4.37M
int RowDescriptor::get_column_id(int slot_id) const {
622
4.37M
    int column_id_counter = 0;
623
4.37M
    for (auto* const tuple_desc : _tuple_desc_map) {
624
26.1M
        for (auto* const slot : tuple_desc->slots()) {
625
26.1M
            if (slot->id() == slot_id) {
626
4.37M
                return column_id_counter;
627
4.37M
            }
628
21.7M
            column_id_counter++;
629
21.7M
        }
630
4.37M
    }
631
2.22k
    return -1;
632
4.37M
}
633
634
Status DescriptorTbl::create(ObjectPool* pool, const TDescriptorTable& thrift_tbl,
635
529k
                             DescriptorTbl** tbl) {
636
529k
    *tbl = pool->add(new DescriptorTbl());
637
638
    // deserialize table descriptors first, they are being referenced by tuple descriptors
639
529k
    for (const auto& tdesc : thrift_tbl.tableDescriptors) {
640
398k
        TableDescriptor* desc = nullptr;
641
642
398k
        switch (tdesc.tableType) {
643
91
        case TTableType::MYSQL_TABLE:
644
91
            desc = pool->add(new MySQLTableDescriptor(tdesc));
645
91
            break;
646
647
394k
        case TTableType::OLAP_TABLE:
648
394k
            desc = pool->add(new OlapTableDescriptor(tdesc));
649
394k
            break;
650
651
3.21k
        case TTableType::SCHEMA_TABLE:
652
3.21k
            desc = pool->add(new SchemaTableDescriptor(tdesc));
653
3.21k
            break;
654
0
        case TTableType::BROKER_TABLE:
655
0
            desc = pool->add(new BrokerTableDescriptor(tdesc));
656
0
            break;
657
0
        case TTableType::ES_TABLE:
658
0
            desc = pool->add(new EsTableDescriptor(tdesc));
659
0
            break;
660
36
        case TTableType::HIVE_TABLE:
661
36
            desc = pool->add(new HiveTableDescriptor(tdesc));
662
36
            break;
663
0
        case TTableType::ICEBERG_TABLE:
664
0
            desc = pool->add(new IcebergTableDescriptor(tdesc));
665
0
            break;
666
4
        case TTableType::JDBC_TABLE:
667
4
            desc = pool->add(new JdbcTableDescriptor(tdesc));
668
4
            break;
669
0
        case TTableType::MAX_COMPUTE_TABLE:
670
0
            desc = pool->add(new MaxComputeTableDescriptor(tdesc));
671
0
            break;
672
0
        case TTableType::TRINO_CONNECTOR_TABLE:
673
0
            desc = pool->add(new TrinoConnectorTableDescriptor(tdesc));
674
0
            break;
675
0
        case TTableType::DICTIONARY_TABLE:
676
0
            desc = pool->add(new DictionaryTableDescriptor(tdesc));
677
0
            break;
678
0
        case TTableType::REMOTE_DORIS_TABLE:
679
0
            desc = pool->add(new RemoteDorisTableDescriptor(tdesc));
680
0
            break;
681
0
        default:
682
0
            DCHECK(false) << "invalid table type: " << tdesc.tableType;
683
398k
        }
684
685
397k
        (*tbl)->_tbl_desc_map[static_cast<int32_t>(tdesc.id)] = desc;
686
397k
    }
687
688
1.62M
    for (const auto& tdesc : thrift_tbl.tupleDescriptors) {
689
1.62M
        TupleDescriptor* desc = pool->add(new TupleDescriptor(tdesc));
690
691
        // fix up table pointer
692
1.62M
        if (tdesc.__isset.tableId) {
693
741k
            desc->_table_desc = (*tbl)->get_table_descriptor(static_cast<int32_t>(tdesc.tableId));
694
741k
            DCHECK(desc->_table_desc != nullptr);
695
741k
        }
696
697
1.62M
        (*tbl)->_tuple_desc_map[tdesc.id] = desc;
698
1.62M
        (*tbl)->_row_tuples.emplace_back(tdesc.id);
699
1.62M
    }
700
701
8.11M
    for (const auto& tdesc : thrift_tbl.slotDescriptors) {
702
8.11M
        SlotDescriptor* slot_d = pool->add(new SlotDescriptor(tdesc));
703
8.11M
        (*tbl)->_slot_desc_map[tdesc.id] = slot_d;
704
705
        // link to parent
706
8.11M
        auto entry = (*tbl)->_tuple_desc_map.find(tdesc.parent);
707
708
8.11M
        if (entry == (*tbl)->_tuple_desc_map.end()) {
709
0
            return Status::InternalError("unknown tid in slot descriptor msg");
710
0
        }
711
8.11M
        entry->second->add_slot(slot_d);
712
8.11M
    }
713
714
529k
    return Status::OK();
715
529k
}
716
717
736k
TableDescriptor* DescriptorTbl::get_table_descriptor(TableId id) const {
718
    // TODO: is there some boost function to do exactly this?
719
736k
    auto i = _tbl_desc_map.find(id);
720
721
736k
    if (i == _tbl_desc_map.end()) {
722
0
        return nullptr;
723
736k
    } else {
724
736k
        return i->second;
725
736k
    }
726
736k
}
727
728
2.03M
TupleDescriptor* DescriptorTbl::get_tuple_descriptor(TupleId id) const {
729
    // TODO: is there some boost function to do exactly this?
730
2.03M
    auto i = _tuple_desc_map.find(id);
731
732
2.03M
    if (i == _tuple_desc_map.end()) {
733
553
        return nullptr;
734
2.03M
    } else {
735
2.03M
        return i->second;
736
2.03M
    }
737
2.03M
}
738
739
4.06M
SlotDescriptor* DescriptorTbl::get_slot_descriptor(SlotId id) const {
740
    // TODO: is there some boost function to do exactly this?
741
4.06M
    auto i = _slot_desc_map.find(id);
742
743
4.06M
    if (i == _slot_desc_map.end()) {
744
0
        return nullptr;
745
4.06M
    } else {
746
4.06M
        return i->second;
747
4.06M
    }
748
4.06M
}
749
750
0
std::string DescriptorTbl::debug_string() const {
751
0
    std::stringstream out;
752
0
    out << "tuples:\n";
753
754
0
    for (auto i : _tuple_desc_map) {
755
0
        out << i.second->debug_string() << '\n';
756
0
    }
757
758
0
    return out.str();
759
0
}
760
} // namespace doris